les: add Skip overflow check to GetBlockHeadersMsg handler (#16891) (#250)

Co-authored-by: Felföldi Zsolt <zsfelfoldi@gmail.com>
This commit is contained in:
wgr523 2023-05-25 12:22:01 +08:00 committed by GitHub
parent 706292e1a1
commit 62de42db68
No known key found for this signature in database
GPG key ID: 4AEE18F83AFDEB23

View file

@ -19,6 +19,7 @@ package les
import ( import (
"encoding/binary" "encoding/binary"
"encoding/json"
"errors" "errors"
"fmt" "fmt"
"math/big" "math/big"
@ -447,7 +448,7 @@ func (pm *ProtocolManager) handleMsg(p *peer) error {
// Advance to the next header of the query // Advance to the next header of the query
switch { switch {
case query.Origin.Hash != (common.Hash{}) && query.Reverse: case hashMode && query.Reverse:
// Hash based traversal towards the genesis block // Hash based traversal towards the genesis block
for i := 0; i < int(query.Skip)+1; i++ { for i := 0; i < int(query.Skip)+1; i++ {
if header := pm.blockchain.GetHeader(query.Origin.Hash, number); header != nil { if header := pm.blockchain.GetHeader(query.Origin.Hash, number); header != nil {
@ -458,16 +459,26 @@ func (pm *ProtocolManager) handleMsg(p *peer) error {
break break
} }
} }
case query.Origin.Hash != (common.Hash{}) && !query.Reverse: case hashMode && !query.Reverse:
// Hash based traversal towards the leaf block // Hash based traversal towards the leaf block
if header := pm.blockchain.GetHeaderByNumber(origin.Number.Uint64() + query.Skip + 1); header != nil { var (
if pm.blockchain.GetBlockHashesFromHash(header.Hash(), query.Skip+1)[query.Skip] == query.Origin.Hash { current = origin.Number.Uint64()
query.Origin.Hash = header.Hash() next = current + query.Skip + 1
)
if next <= current {
infos, _ := json.MarshalIndent(p.Peer.Info(), "", " ")
p.Log().Warn("GetBlockHeaders skip overflow attack", "current", current, "skip", query.Skip, "next", next, "attacker", infos)
unknown = true
} else {
if header := pm.blockchain.GetHeaderByNumber(next); header != nil {
if pm.blockchain.GetBlockHashesFromHash(header.Hash(), query.Skip+1)[query.Skip] == query.Origin.Hash {
query.Origin.Hash = header.Hash()
} else {
unknown = true
}
} else { } else {
unknown = true unknown = true
} }
} else {
unknown = true
} }
case query.Reverse: case query.Reverse:
// Number based traversal towards the genesis block // Number based traversal towards the genesis block