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.
This commit is contained in:
committed by
Felix Lange
parent
5bc9ccfa0a
commit
cdfe9a3a2a
@ -19,6 +19,7 @@ package types
|
||||
|
||||
import (
|
||||
"encoding/binary"
|
||||
"fmt"
|
||||
"io"
|
||||
"math/big"
|
||||
"reflect"
|
||||
@ -110,6 +111,25 @@ func (h *Header) Size() common.StorageSize {
|
||||
return headerSize + common.StorageSize(len(h.Extra)+(h.Difficulty.BitLen()+h.Number.BitLen())/8)
|
||||
}
|
||||
|
||||
// SanityCheck checks a few basic things -- these checks are way beyond what
|
||||
// any 'sane' production values should hold, and can mainly be used to prevent
|
||||
// that the unbounded fields are stuffed with junk data to add processing
|
||||
// overhead
|
||||
func (h *Header) SanityCheck() error {
|
||||
if h.Number != nil && !h.Number.IsUint64() {
|
||||
return fmt.Errorf("too large block number: bitlen %d", h.Number.BitLen())
|
||||
}
|
||||
if h.Difficulty != nil {
|
||||
if diffLen := h.Difficulty.BitLen(); diffLen > 80 {
|
||||
return fmt.Errorf("too large block difficulty: bitlen %d", diffLen)
|
||||
}
|
||||
}
|
||||
if eLen := len(h.Extra); eLen > 100*1024 {
|
||||
return fmt.Errorf("too large block extradata: size %d", eLen)
|
||||
}
|
||||
return nil
|
||||
}
|
||||
|
||||
func rlpHash(x interface{}) (h common.Hash) {
|
||||
hw := sha3.NewLegacyKeccak256()
|
||||
rlp.Encode(hw, x)
|
||||
@ -316,6 +336,12 @@ func (b *Block) Size() common.StorageSize {
|
||||
return common.StorageSize(c)
|
||||
}
|
||||
|
||||
// SanityCheck can be used to prevent that unbounded fields are
|
||||
// stuffed with junk data to add processing overhead
|
||||
func (b *Block) SanityCheck() error {
|
||||
return b.header.SanityCheck()
|
||||
}
|
||||
|
||||
type writeCounter common.StorageSize
|
||||
|
||||
func (c *writeCounter) Write(b []byte) (int, error) {
|
||||
|
Reference in New Issue
Block a user