diff options
-rw-r--r-- | eth/handler.go | 21 | ||||
-rw-r--r-- | eth/handler_test.go | 15 | ||||
-rw-r--r-- | internal/build/env.go | 2 | ||||
-rw-r--r-- | internal/ethapi/api.go | 7 | ||||
-rw-r--r-- | rpc/http.go | 1 |
5 files changed, 36 insertions, 10 deletions
diff --git a/eth/handler.go b/eth/handler.go index e6c547c02..d72185dd3 100644 --- a/eth/handler.go +++ b/eth/handler.go @@ -17,6 +17,7 @@ package eth import ( + "encoding/json" "errors" "fmt" "math" @@ -371,14 +372,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 91989cb8f..f0f18d0a6 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}, diff --git a/internal/build/env.go b/internal/build/env.go index 3f63239ca..cd3355092 100644 --- a/internal/build/env.go +++ b/internal/build/env.go @@ -65,7 +65,7 @@ func Env() Environment { Repo: os.Getenv("APPVEYOR_REPO_NAME"), Commit: os.Getenv("APPVEYOR_REPO_COMMIT"), Branch: os.Getenv("APPVEYOR_REPO_BRANCH"), - Tag: os.Getenv("APPVEYOR_REPO_TAG"), + Tag: os.Getenv("APPVEYOR_REPO_TAG_NAME"), Buildnum: os.Getenv("APPVEYOR_BUILD_NUMBER"), IsPullRequest: os.Getenv("APPVEYOR_PULL_REQUEST_NUMBER") != "", } diff --git a/internal/ethapi/api.go b/internal/ethapi/api.go index 9a97be25f..333c39965 100644 --- a/internal/ethapi/api.go +++ b/internal/ethapi/api.go @@ -1170,8 +1170,7 @@ func (s *PublicTransactionPoolAPI) PendingTransactions() []*RPCTransaction { // Resend accepts an existing transaction and a new gas price and limit. It will remove the given transaction from the // pool and reinsert it with the new gas price and limit. -func (s *PublicTransactionPoolAPI) Resend(ctx context.Context, tx *Tx, gasPrice, gasLimit *rpc.HexNumber) (common.Hash, error) { - +func (s *PublicTransactionPoolAPI) Resend(ctx context.Context, tx Tx, gasPrice, gasLimit *rpc.HexNumber) (common.Hash, error) { pending := s.b.GetPoolTransactions() for _, p := range pending { if pFrom, err := p.FromFrontier(); err == nil && pFrom == tx.From && p.SigHash() == tx.tx.SigHash() { @@ -1184,9 +1183,9 @@ func (s *PublicTransactionPoolAPI) Resend(ctx context.Context, tx *Tx, gasPrice, var newTx *types.Transaction if tx.tx.To() == nil { - newTx = types.NewContractCreation(tx.tx.Nonce(), tx.tx.Value(), gasPrice.BigInt(), gasLimit.BigInt(), tx.tx.Data()) + newTx = types.NewContractCreation(tx.tx.Nonce(), tx.tx.Value(), gasLimit.BigInt(), gasPrice.BigInt(), tx.tx.Data()) } else { - newTx = types.NewTransaction(tx.tx.Nonce(), *tx.tx.To(), tx.tx.Value(), gasPrice.BigInt(), gasLimit.BigInt(), tx.tx.Data()) + newTx = types.NewTransaction(tx.tx.Nonce(), *tx.tx.To(), tx.tx.Value(), gasLimit.BigInt(), gasPrice.BigInt(), tx.tx.Data()) } signedTx, err := s.sign(tx.From, newTx) diff --git a/rpc/http.go b/rpc/http.go index afcdd4bd6..c923580bf 100644 --- a/rpc/http.go +++ b/rpc/http.go @@ -170,6 +170,7 @@ func newCorsHandler(srv *Server, corsString string) http.Handler { c := cors.New(cors.Options{ AllowedOrigins: allowedOrigins, AllowedMethods: []string{"POST", "GET"}, + MaxAge: 600, }) return c.Handler(srv) } |