diff options
author | Péter Szilágyi <peterke@gmail.com> | 2016-10-05 21:31:48 +0800 |
---|---|---|
committer | Felix Lange <fjl@twurst.com> | 2016-10-06 22:25:17 +0800 |
commit | f7e6fb7d1c95a5c7f844c2786c7cd273a2d77ced (patch) | |
tree | 21d723298025fa82c9bd87fd0ac9a200b8620f2c /eth | |
parent | 718881bd3557119e0e84ad04d55b604d9a246782 (diff) | |
download | go-tangerine-f7e6fb7d1c95a5c7f844c2786c7cd273a2d77ced.tar go-tangerine-f7e6fb7d1c95a5c7f844c2786c7cd273a2d77ced.tar.gz go-tangerine-f7e6fb7d1c95a5c7f844c2786c7cd273a2d77ced.tar.bz2 go-tangerine-f7e6fb7d1c95a5c7f844c2786c7cd273a2d77ced.tar.lz go-tangerine-f7e6fb7d1c95a5c7f844c2786c7cd273a2d77ced.tar.xz go-tangerine-f7e6fb7d1c95a5c7f844c2786c7cd273a2d77ced.tar.zst go-tangerine-f7e6fb7d1c95a5c7f844c2786c7cd273a2d77ced.zip |
[release/1.4.16] eth: monitor malicious header retrieval requests
(cherry picked from commit e482b5694faece927a29289f88d7a87b1ce1fbd1)
Diffstat (limited to 'eth')
-rw-r--r-- | eth/handler.go | 21 | ||||
-rw-r--r-- | eth/handler_test.go | 15 |
2 files changed, 31 insertions, 5 deletions
diff --git a/eth/handler.go b/eth/handler.go index 3fa47c269..ca73a7d54 100644 --- a/eth/handler.go +++ b/eth/handler.go @@ -17,6 +17,7 @@ package eth import ( + "encoding/json" "errors" "fmt" "math" @@ -369,14 +370,24 @@ func (pm *ProtocolManager) handleMsg(p *peer) error { } case query.Origin.Hash != (common.Hash{}) && !query.Reverse: // Hash based traversal towards the leaf block - if header := pm.blockchain.GetHeaderByNumber(origin.Number.Uint64() + query.Skip + 1); header != nil { - if pm.blockchain.GetBlockHashesFromHash(header.Hash(), query.Skip+1)[query.Skip] == query.Origin.Hash { - query.Origin.Hash = header.Hash() + var ( + current = origin.Number.Uint64() + next = current + query.Skip + 1 + ) + if next <= current { + infos, _ := json.MarshalIndent(p.Peer.Info(), "", " ") + 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) + 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 { unknown = true } - } else { - unknown = true } case query.Reverse: // Number based traversal towards the genesis block diff --git a/eth/handler_test.go b/eth/handler_test.go index c745408a8..571defd81 100644 --- a/eth/handler_test.go +++ b/eth/handler_test.go @@ -17,6 +17,7 @@ package eth import ( + "math" "math/big" "math/rand" "testing" @@ -173,6 +174,20 @@ func testGetBlockHeaders(t *testing.T, protocol int) { pm.blockchain.GetBlockByNumber(0).Hash(), }, }, + // Check a corner case where skipping overflow loops back into the chain start + { + &getBlockHeadersData{Origin: hashOrNumber{Hash: pm.blockchain.GetBlockByNumber(3).Hash()}, Amount: 2, Reverse: false, Skip: math.MaxUint64 - 1}, + []common.Hash{ + pm.blockchain.GetBlockByNumber(3).Hash(), + }, + }, + // Check a corner case where skipping overflow loops back to the same header + { + &getBlockHeadersData{Origin: hashOrNumber{Hash: pm.blockchain.GetBlockByNumber(1).Hash()}, Amount: 2, Reverse: false, Skip: math.MaxUint64}, + []common.Hash{ + pm.blockchain.GetBlockByNumber(1).Hash(), + }, + }, // Check that non existing headers aren't returned { &getBlockHeadersData{Origin: hashOrNumber{Hash: unknown}, Amount: 1}, |