Skip to content

Commit f7e6fb7

Browse files
karalabefjl
authored andcommitted
[release/1.4.16] eth: monitor malicious header retrieval requests
(cherry picked from commit e482b56)
1 parent 718881b commit f7e6fb7

File tree

2 files changed

+31
-5
lines changed

2 files changed

+31
-5
lines changed

eth/handler.go

Lines changed: 16 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -17,6 +17,7 @@
1717
package eth
1818

1919
import (
20+
"encoding/json"
2021
"errors"
2122
"fmt"
2223
"math"
@@ -369,14 +370,24 @@ func (pm *ProtocolManager) handleMsg(p *peer) error {
369370
}
370371
case query.Origin.Hash != (common.Hash{}) && !query.Reverse:
371372
// Hash based traversal towards the leaf block
372-
if header := pm.blockchain.GetHeaderByNumber(origin.Number.Uint64() + query.Skip + 1); header != nil {
373-
if pm.blockchain.GetBlockHashesFromHash(header.Hash(), query.Skip+1)[query.Skip] == query.Origin.Hash {
374-
query.Origin.Hash = header.Hash()
373+
var (
374+
current = origin.Number.Uint64()
375+
next = current + query.Skip + 1
376+
)
377+
if next <= current {
378+
infos, _ := json.MarshalIndent(p.Peer.Info(), "", " ")
379+
glog.V(logger.Warn).Infof("%v: GetBlockHeaders skip overflow attack (current %v, skip %v, next %v)\nMalicious peer infos: %s", p, current, query.Skip, next, infos)
380+
unknown = true
381+
} else {
382+
if header := pm.blockchain.GetHeaderByNumber(next); header != nil {
383+
if pm.blockchain.GetBlockHashesFromHash(header.Hash(), query.Skip+1)[query.Skip] == query.Origin.Hash {
384+
query.Origin.Hash = header.Hash()
385+
} else {
386+
unknown = true
387+
}
375388
} else {
376389
unknown = true
377390
}
378-
} else {
379-
unknown = true
380391
}
381392
case query.Reverse:
382393
// Number based traversal towards the genesis block

eth/handler_test.go

Lines changed: 15 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -17,6 +17,7 @@
1717
package eth
1818

1919
import (
20+
"math"
2021
"math/big"
2122
"math/rand"
2223
"testing"
@@ -173,6 +174,20 @@ func testGetBlockHeaders(t *testing.T, protocol int) {
173174
pm.blockchain.GetBlockByNumber(0).Hash(),
174175
},
175176
},
177+
// Check a corner case where skipping overflow loops back into the chain start
178+
{
179+
&getBlockHeadersData{Origin: hashOrNumber{Hash: pm.blockchain.GetBlockByNumber(3).Hash()}, Amount: 2, Reverse: false, Skip: math.MaxUint64 - 1},
180+
[]common.Hash{
181+
pm.blockchain.GetBlockByNumber(3).Hash(),
182+
},
183+
},
184+
// Check a corner case where skipping overflow loops back to the same header
185+
{
186+
&getBlockHeadersData{Origin: hashOrNumber{Hash: pm.blockchain.GetBlockByNumber(1).Hash()}, Amount: 2, Reverse: false, Skip: math.MaxUint64},
187+
[]common.Hash{
188+
pm.blockchain.GetBlockByNumber(1).Hash(),
189+
},
190+
},
176191
// Check that non existing headers aren't returned
177192
{
178193
&getBlockHeadersData{Origin: hashOrNumber{Hash: unknown}, Amount: 1},

0 commit comments

Comments
 (0)