Skip to content

Commit b605f1f

Browse files
authored
Merge pull request ethereum#63 from binance-chain/secure_patch
[R4R] security patch from go-ethereum
2 parents 9fedf19 + 9e8ee51 commit b605f1f

File tree

12 files changed

+79
-16
lines changed

12 files changed

+79
-16
lines changed

accounts/abi/type.go

+1-1
Original file line numberDiff line numberDiff line change
@@ -350,7 +350,7 @@ func isDynamicType(t Type) bool {
350350
func getTypeSize(t Type) int {
351351
if t.T == ArrayTy && !isDynamicType(*t.Elem) {
352352
// Recursively calculate type size if it is a nested array
353-
if t.Elem.T == ArrayTy {
353+
if t.Elem.T == ArrayTy || t.Elem.T == TupleTy {
354354
return t.Size * getTypeSize(*t.Elem)
355355
}
356356
return t.Size * 32

cmd/clef/docs/setup.md

+1-1
Original file line numberDiff line numberDiff line change
@@ -94,7 +94,7 @@ with minimal requirements.
9494
On the `client` qube, we need to create a listener which will receive the request from the Dapp, and proxy it.
9595

9696

97-
[qubes-client.py](qubes/client/qubes-client.py):
97+
[qubes-client.py](qubes/qubes-client.py):
9898

9999
```python
100100

consensus/ethash/algorithm.go

+5-5
Original file line numberDiff line numberDiff line change
@@ -304,16 +304,16 @@ func generateDataset(dest []uint32, epoch uint64, cache []uint32) {
304304
keccak512 := makeHasher(sha3.NewLegacyKeccak512())
305305

306306
// Calculate the data segment this thread should generate
307-
batch := uint32((size + hashBytes*uint64(threads) - 1) / (hashBytes * uint64(threads)))
308-
first := uint32(id) * batch
307+
batch := (size + hashBytes*uint64(threads) - 1) / (hashBytes * uint64(threads))
308+
first := uint64(id) * batch
309309
limit := first + batch
310-
if limit > uint32(size/hashBytes) {
311-
limit = uint32(size / hashBytes)
310+
if limit > size/hashBytes {
311+
limit = size / hashBytes
312312
}
313313
// Calculate the dataset segment
314314
percent := uint32(size / hashBytes / 100)
315315
for index := first; index < limit; index++ {
316-
item := generateDatasetItem(cache, index, keccak512)
316+
item := generateDatasetItem(cache, uint32(index), keccak512)
317317
if swapped {
318318
swap(item)
319319
}

core/tx_pool.go

+1
Original file line numberDiff line numberDiff line change
@@ -814,6 +814,7 @@ func (pool *TxPool) addTxs(txs []*types.Transaction, local, sync bool) []error {
814814
nilSlot++
815815
}
816816
errs[nilSlot] = err
817+
nilSlot++
817818
}
818819
// Reorg the pool internals if needed and return
819820
done := pool.requestPromoteExecutables(dirtyAddrs)

internal/ethapi/api.go

+3
Original file line numberDiff line numberDiff line change
@@ -900,6 +900,9 @@ func DoEstimateGas(ctx context.Context, b Backend, args CallArgs, blockNrOrHash
900900
if err != nil {
901901
return 0, err
902902
}
903+
if block == nil {
904+
return 0, errors.New("block not found")
905+
}
903906
hi = block.GasLimit()
904907
}
905908
// Recap the highest gas limit with account's available balance.

internal/web3ext/web3ext.go

+7
Original file line numberDiff line numberDiff line change
@@ -493,6 +493,13 @@ web3._extend({
493493
params: 1,
494494
inputFormatter: [web3._extend.formatters.inputTransactionFormatter]
495495
}),
496+
new web3._extend.Method({
497+
name: 'estimateGas',
498+
call: 'eth_estimateGas',
499+
params: 2,
500+
inputFormatter: [web3._extend.formatters.inputCallFormatter, web3._extend.formatters.inputBlockNumberFormatter],
501+
outputFormatter: web3._extend.utils.toDecimal
502+
}),
496503
new web3._extend.Method({
497504
name: 'submitTransaction',
498505
call: 'eth_submitTransaction',

p2p/discover/v5_udp.go

+14-3
Original file line numberDiff line numberDiff line change
@@ -419,9 +419,20 @@ func (t *UDPv5) call(node *enode.Node, responseType byte, packet packetV5) *call
419419

420420
// callDone tells dispatch that the active call is done.
421421
func (t *UDPv5) callDone(c *callV5) {
422-
select {
423-
case t.callDoneCh <- c:
424-
case <-t.closeCtx.Done():
422+
// This needs a loop because further responses may be incoming until the
423+
// send to callDoneCh has completed. Such responses need to be discarded
424+
// in order to avoid blocking the dispatch loop.
425+
for {
426+
select {
427+
case <-c.ch:
428+
// late response, discard.
429+
case <-c.err:
430+
// late error, discard.
431+
case t.callDoneCh <- c:
432+
return
433+
case <-t.closeCtx.Done():
434+
return
435+
}
425436
}
426437
}
427438

p2p/enode/nodedb.go

+28
Original file line numberDiff line numberDiff line change
@@ -61,6 +61,10 @@ const (
6161
dbVersion = 9
6262
)
6363

64+
var (
65+
errInvalidIP = errors.New("invalid IP")
66+
)
67+
6468
var zeroIP = make(net.IP, 16)
6569

6670
// DB is the node database, storing previously seen nodes and any collected metadata about
@@ -359,43 +363,67 @@ func (db *DB) expireNodes() {
359363
// LastPingReceived retrieves the time of the last ping packet received from
360364
// a remote node.
361365
func (db *DB) LastPingReceived(id ID, ip net.IP) time.Time {
366+
if ip = ip.To16(); ip == nil {
367+
return time.Time{}
368+
}
362369
return time.Unix(db.fetchInt64(nodeItemKey(id, ip, dbNodePing)), 0)
363370
}
364371

365372
// UpdateLastPingReceived updates the last time we tried contacting a remote node.
366373
func (db *DB) UpdateLastPingReceived(id ID, ip net.IP, instance time.Time) error {
374+
if ip = ip.To16(); ip == nil {
375+
return errInvalidIP
376+
}
367377
return db.storeInt64(nodeItemKey(id, ip, dbNodePing), instance.Unix())
368378
}
369379

370380
// LastPongReceived retrieves the time of the last successful pong from remote node.
371381
func (db *DB) LastPongReceived(id ID, ip net.IP) time.Time {
382+
if ip = ip.To16(); ip == nil {
383+
return time.Time{}
384+
}
372385
// Launch expirer
373386
db.ensureExpirer()
374387
return time.Unix(db.fetchInt64(nodeItemKey(id, ip, dbNodePong)), 0)
375388
}
376389

377390
// UpdateLastPongReceived updates the last pong time of a node.
378391
func (db *DB) UpdateLastPongReceived(id ID, ip net.IP, instance time.Time) error {
392+
if ip = ip.To16(); ip == nil {
393+
return errInvalidIP
394+
}
379395
return db.storeInt64(nodeItemKey(id, ip, dbNodePong), instance.Unix())
380396
}
381397

382398
// FindFails retrieves the number of findnode failures since bonding.
383399
func (db *DB) FindFails(id ID, ip net.IP) int {
400+
if ip = ip.To16(); ip == nil {
401+
return 0
402+
}
384403
return int(db.fetchInt64(nodeItemKey(id, ip, dbNodeFindFails)))
385404
}
386405

387406
// UpdateFindFails updates the number of findnode failures since bonding.
388407
func (db *DB) UpdateFindFails(id ID, ip net.IP, fails int) error {
408+
if ip = ip.To16(); ip == nil {
409+
return errInvalidIP
410+
}
389411
return db.storeInt64(nodeItemKey(id, ip, dbNodeFindFails), int64(fails))
390412
}
391413

392414
// FindFailsV5 retrieves the discv5 findnode failure counter.
393415
func (db *DB) FindFailsV5(id ID, ip net.IP) int {
416+
if ip = ip.To16(); ip == nil {
417+
return 0
418+
}
394419
return int(db.fetchInt64(v5Key(id, ip, dbNodeFindFails)))
395420
}
396421

397422
// UpdateFindFailsV5 stores the discv5 findnode failure counter.
398423
func (db *DB) UpdateFindFailsV5(id ID, ip net.IP, fails int) error {
424+
if ip = ip.To16(); ip == nil {
425+
return errInvalidIP
426+
}
399427
return db.storeInt64(v5Key(id, ip, dbNodeFindFails), int64(fails))
400428
}
401429

rpc/json.go

+10-3
Original file line numberDiff line numberDiff line change
@@ -194,15 +194,22 @@ func (c *jsonCodec) remoteAddr() string {
194194
return c.remote
195195
}
196196

197-
func (c *jsonCodec) readBatch() (msg []*jsonrpcMessage, batch bool, err error) {
197+
func (c *jsonCodec) readBatch() (messages []*jsonrpcMessage, batch bool, err error) {
198198
// Decode the next JSON object in the input stream.
199199
// This verifies basic syntax, etc.
200200
var rawmsg json.RawMessage
201201
if err := c.decode(&rawmsg); err != nil {
202202
return nil, false, err
203203
}
204-
msg, batch = parseMessage(rawmsg)
205-
return msg, batch, nil
204+
messages, batch = parseMessage(rawmsg)
205+
for i, msg := range messages {
206+
if msg == nil {
207+
// Message is JSON 'null'. Replace with zero value so it
208+
// will be treated like any other invalid message.
209+
messages[i] = new(jsonrpcMessage)
210+
}
211+
}
212+
return messages, batch, nil
206213
}
207214

208215
func (c *jsonCodec) writeJSON(ctx context.Context, v interface{}) error {

rpc/testdata/invalid-batch.js

+3
Original file line numberDiff line numberDiff line change
@@ -10,5 +10,8 @@
1010
--> [1,2,3]
1111
<-- [{"jsonrpc":"2.0","id":null,"error":{"code":-32600,"message":"invalid request"}},{"jsonrpc":"2.0","id":null,"error":{"code":-32600,"message":"invalid request"}},{"jsonrpc":"2.0","id":null,"error":{"code":-32600,"message":"invalid request"}}]
1212

13+
--> [null]
14+
<-- [{"jsonrpc":"2.0","id":null,"error":{"code":-32600,"message":"invalid request"}}]
15+
1316
--> [{"jsonrpc":"2.0","id":1,"method":"test_echo","params":["foo",1]},55,{"jsonrpc":"2.0","id":2,"method":"unknown_method"},{"foo":"bar"}]
1417
<-- [{"jsonrpc":"2.0","id":1,"result":{"String":"foo","Int":1,"Args":null}},{"jsonrpc":"2.0","id":null,"error":{"code":-32600,"message":"invalid request"}},{"jsonrpc":"2.0","id":2,"error":{"code":-32601,"message":"the method unknown_method does not exist/is not available"}},{"jsonrpc":"2.0","id":null,"error":{"code":-32600,"message":"invalid request"}}]

rpc/testdata/invalid-nonobj.js

+3
Original file line numberDiff line numberDiff line change
@@ -2,3 +2,6 @@
22

33
--> 1
44
<-- {"jsonrpc":"2.0","id":null,"error":{"code":-32600,"message":"invalid request"}}
5+
6+
--> null
7+
<-- {"jsonrpc":"2.0","id":null,"error":{"code":-32600,"message":"invalid request"}}

signer/storage/aes_gcm_storage.go

+3-3
Original file line numberDiff line numberDiff line change
@@ -151,11 +151,11 @@ func encrypt(key []byte, plaintext []byte, additionalData []byte) ([]byte, []byt
151151
return nil, nil, err
152152
}
153153
aesgcm, err := cipher.NewGCM(block)
154-
nonce := make([]byte, aesgcm.NonceSize())
155-
if _, err := io.ReadFull(rand.Reader, nonce); err != nil {
154+
if err != nil {
156155
return nil, nil, err
157156
}
158-
if err != nil {
157+
nonce := make([]byte, aesgcm.NonceSize())
158+
if _, err := io.ReadFull(rand.Reader, nonce); err != nil {
159159
return nil, nil, err
160160
}
161161
ciphertext := aesgcm.Seal(nil, nonce, plaintext, additionalData)

0 commit comments

Comments
 (0)