aboutsummaryrefslogtreecommitdiffstats
path: root/eth
diff options
context:
space:
mode:
authorMartin Holst Swende <martin@swende.se>2019-07-08 17:42:22 +0800
committerFelix Lange <fjl@twurst.com>2019-07-08 17:42:22 +0800
commitcdfe9a3a2a257dcd2506e9a0eaf3bf3b0986c43a (patch)
treea6889c88919d76f825514c2cecc789fc6f62a39d /eth
parent5bc9ccfa0af6e2892c1f40689dfb90a056ba81d6 (diff)
downloadgo-tangerine-cdfe9a3a2a257dcd2506e9a0eaf3bf3b0986c43a.tar
go-tangerine-cdfe9a3a2a257dcd2506e9a0eaf3bf3b0986c43a.tar.gz
go-tangerine-cdfe9a3a2a257dcd2506e9a0eaf3bf3b0986c43a.tar.bz2
go-tangerine-cdfe9a3a2a257dcd2506e9a0eaf3bf3b0986c43a.tar.lz
go-tangerine-cdfe9a3a2a257dcd2506e9a0eaf3bf3b0986c43a.tar.xz
go-tangerine-cdfe9a3a2a257dcd2506e9a0eaf3bf3b0986c43a.tar.zst
go-tangerine-cdfe9a3a2a257dcd2506e9a0eaf3bf3b0986c43a.zip
eth, les: add sanity checks for unbounded block fields (#19573)
This PR adds some hardening in the lower levels of the protocol stack, to bail early on invalid data. Primarily, attacks that this PR protects against are on the "annoyance"-level, which would otherwise write a couple of megabytes of data into the log output, which is a bit resource intensive.
Diffstat (limited to 'eth')
-rw-r--r--eth/fetcher/fetcher.go8
-rw-r--r--eth/handler.go3
-rw-r--r--eth/protocol.go13
3 files changed, 20 insertions, 4 deletions
diff --git a/eth/fetcher/fetcher.go b/eth/fetcher/fetcher.go
index 94f05f967..28c532d9b 100644
--- a/eth/fetcher/fetcher.go
+++ b/eth/fetcher/fetcher.go
@@ -685,7 +685,7 @@ func (f *Fetcher) forgetHash(hash common.Hash) {
// Remove all pending announces and decrement DOS counters
for _, announce := range f.announced[hash] {
f.announces[announce.origin]--
- if f.announces[announce.origin] == 0 {
+ if f.announces[announce.origin] <= 0 {
delete(f.announces, announce.origin)
}
}
@@ -696,7 +696,7 @@ func (f *Fetcher) forgetHash(hash common.Hash) {
// Remove any pending fetches and decrement the DOS counters
if announce := f.fetching[hash]; announce != nil {
f.announces[announce.origin]--
- if f.announces[announce.origin] == 0 {
+ if f.announces[announce.origin] <= 0 {
delete(f.announces, announce.origin)
}
delete(f.fetching, hash)
@@ -705,7 +705,7 @@ func (f *Fetcher) forgetHash(hash common.Hash) {
// Remove any pending completion requests and decrement the DOS counters
for _, announce := range f.fetched[hash] {
f.announces[announce.origin]--
- if f.announces[announce.origin] == 0 {
+ if f.announces[announce.origin] <= 0 {
delete(f.announces, announce.origin)
}
}
@@ -714,7 +714,7 @@ func (f *Fetcher) forgetHash(hash common.Hash) {
// Remove any pending completions and decrement the DOS counters
if announce := f.completing[hash]; announce != nil {
f.announces[announce.origin]--
- if f.announces[announce.origin] == 0 {
+ if f.announces[announce.origin] <= 0 {
delete(f.announces, announce.origin)
}
delete(f.completing, hash)
diff --git a/eth/handler.go b/eth/handler.go
index db6901a23..fe9f8b53b 100644
--- a/eth/handler.go
+++ b/eth/handler.go
@@ -697,6 +697,9 @@ func (pm *ProtocolManager) handleMsg(p *peer) error {
if err := msg.Decode(&request); err != nil {
return errResp(ErrDecode, "%v: %v", msg, err)
}
+ if err := request.sanityCheck(); err != nil {
+ return err
+ }
request.Block.ReceivedAt = msg.ReceivedAt
request.Block.ReceivedFrom = p
diff --git a/eth/protocol.go b/eth/protocol.go
index 497ba4c59..5beb562f8 100644
--- a/eth/protocol.go
+++ b/eth/protocol.go
@@ -173,6 +173,19 @@ type newBlockData struct {
TD *big.Int
}
+// sanityCheck verifies that the values are reasonable, as a DoS protection
+func (request *newBlockData) sanityCheck() error {
+ if err := request.Block.SanityCheck(); err != nil {
+ return err
+ }
+ //TD at mainnet block #7753254 is 76 bits. If it becomes 100 million times
+ // larger, it will still fit within 100 bits
+ if tdlen := request.TD.BitLen(); tdlen > 100 {
+ return fmt.Errorf("too large block TD: bitlen %d", tdlen)
+ }
+ return nil
+}
+
// blockBody represents the data content of a single block.
type blockBody struct {
Transactions []*types.Transaction // Transactions contained within a block