aboutsummaryrefslogtreecommitdiffstats
path: root/eth
diff options
context:
space:
mode:
authorPéter Szilágyi <peterke@gmail.com>2016-10-05 21:31:48 +0800
committerFelix Lange <fjl@twurst.com>2016-10-06 22:25:17 +0800
commitf7e6fb7d1c95a5c7f844c2786c7cd273a2d77ced (patch)
tree21d723298025fa82c9bd87fd0ac9a200b8620f2c /eth
parent718881bd3557119e0e84ad04d55b604d9a246782 (diff)
downloadgo-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.go21
-rw-r--r--eth/handler_test.go15
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},