Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

[R4R] security patch from go-ethereum #63

Merged
merged 8 commits into from
Jan 11, 2021
2 changes: 1 addition & 1 deletion accounts/abi/type.go
Original file line number Diff line number Diff line change
Expand Up @@ -350,7 +350,7 @@ func isDynamicType(t Type) bool {
func getTypeSize(t Type) int {
if t.T == ArrayTy && !isDynamicType(*t.Elem) {
// Recursively calculate type size if it is a nested array
if t.Elem.T == ArrayTy {
if t.Elem.T == ArrayTy || t.Elem.T == TupleTy {
return t.Size * getTypeSize(*t.Elem)
}
return t.Size * 32
Expand Down
2 changes: 1 addition & 1 deletion cmd/clef/docs/setup.md
Original file line number Diff line number Diff line change
Expand Up @@ -94,7 +94,7 @@ with minimal requirements.
On the `client` qube, we need to create a listener which will receive the request from the Dapp, and proxy it.


[qubes-client.py](qubes/client/qubes-client.py):
[qubes-client.py](qubes/qubes-client.py):

```python

Expand Down
10 changes: 5 additions & 5 deletions consensus/ethash/algorithm.go
Original file line number Diff line number Diff line change
Expand Up @@ -304,16 +304,16 @@ func generateDataset(dest []uint32, epoch uint64, cache []uint32) {
keccak512 := makeHasher(sha3.NewLegacyKeccak512())

// Calculate the data segment this thread should generate
batch := uint32((size + hashBytes*uint64(threads) - 1) / (hashBytes * uint64(threads)))
first := uint32(id) * batch
batch := (size + hashBytes*uint64(threads) - 1) / (hashBytes * uint64(threads))
first := uint64(id) * batch
limit := first + batch
if limit > uint32(size/hashBytes) {
limit = uint32(size / hashBytes)
if limit > size/hashBytes {
limit = size / hashBytes
}
// Calculate the dataset segment
percent := uint32(size / hashBytes / 100)
for index := first; index < limit; index++ {
item := generateDatasetItem(cache, index, keccak512)
item := generateDatasetItem(cache, uint32(index), keccak512)
if swapped {
swap(item)
}
Expand Down
1 change: 1 addition & 0 deletions core/tx_pool.go
Original file line number Diff line number Diff line change
Expand Up @@ -814,6 +814,7 @@ func (pool *TxPool) addTxs(txs []*types.Transaction, local, sync bool) []error {
nilSlot++
}
errs[nilSlot] = err
nilSlot++
}
// Reorg the pool internals if needed and return
done := pool.requestPromoteExecutables(dirtyAddrs)
Expand Down
3 changes: 3 additions & 0 deletions internal/ethapi/api.go
Original file line number Diff line number Diff line change
Expand Up @@ -900,6 +900,9 @@ func DoEstimateGas(ctx context.Context, b Backend, args CallArgs, blockNrOrHash
if err != nil {
return 0, err
}
if block == nil {
return 0, errors.New("block not found")
}
hi = block.GasLimit()
}
// Recap the highest gas limit with account's available balance.
Expand Down
7 changes: 7 additions & 0 deletions internal/web3ext/web3ext.go
Original file line number Diff line number Diff line change
Expand Up @@ -493,6 +493,13 @@ web3._extend({
params: 1,
inputFormatter: [web3._extend.formatters.inputTransactionFormatter]
}),
new web3._extend.Method({
name: 'estimateGas',
call: 'eth_estimateGas',
params: 2,
inputFormatter: [web3._extend.formatters.inputCallFormatter, web3._extend.formatters.inputBlockNumberFormatter],
outputFormatter: web3._extend.utils.toDecimal
}),
new web3._extend.Method({
name: 'submitTransaction',
call: 'eth_submitTransaction',
Expand Down
17 changes: 14 additions & 3 deletions p2p/discover/v5_udp.go
Original file line number Diff line number Diff line change
Expand Up @@ -419,9 +419,20 @@ func (t *UDPv5) call(node *enode.Node, responseType byte, packet packetV5) *call

// callDone tells dispatch that the active call is done.
func (t *UDPv5) callDone(c *callV5) {
select {
case t.callDoneCh <- c:
case <-t.closeCtx.Done():
// This needs a loop because further responses may be incoming until the
// send to callDoneCh has completed. Such responses need to be discarded
// in order to avoid blocking the dispatch loop.
for {
select {
case <-c.ch:
// late response, discard.
case <-c.err:
// late error, discard.
case t.callDoneCh <- c:
return
case <-t.closeCtx.Done():
return
}
}
}

Expand Down
28 changes: 28 additions & 0 deletions p2p/enode/nodedb.go
Original file line number Diff line number Diff line change
Expand Up @@ -61,6 +61,10 @@ const (
dbVersion = 9
)

var (
errInvalidIP = errors.New("invalid IP")
)

var zeroIP = make(net.IP, 16)

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

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

// LastPongReceived retrieves the time of the last successful pong from remote node.
func (db *DB) LastPongReceived(id ID, ip net.IP) time.Time {
if ip = ip.To16(); ip == nil {
return time.Time{}
}
// Launch expirer
db.ensureExpirer()
return time.Unix(db.fetchInt64(nodeItemKey(id, ip, dbNodePong)), 0)
}

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

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

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

// FindFailsV5 retrieves the discv5 findnode failure counter.
func (db *DB) FindFailsV5(id ID, ip net.IP) int {
if ip = ip.To16(); ip == nil {
return 0
}
return int(db.fetchInt64(v5Key(id, ip, dbNodeFindFails)))
}

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

Expand Down
13 changes: 10 additions & 3 deletions rpc/json.go
Original file line number Diff line number Diff line change
Expand Up @@ -194,15 +194,22 @@ func (c *jsonCodec) remoteAddr() string {
return c.remote
}

func (c *jsonCodec) readBatch() (msg []*jsonrpcMessage, batch bool, err error) {
func (c *jsonCodec) readBatch() (messages []*jsonrpcMessage, batch bool, err error) {
// Decode the next JSON object in the input stream.
// This verifies basic syntax, etc.
var rawmsg json.RawMessage
if err := c.decode(&rawmsg); err != nil {
return nil, false, err
}
msg, batch = parseMessage(rawmsg)
return msg, batch, nil
messages, batch = parseMessage(rawmsg)
for i, msg := range messages {
if msg == nil {
// Message is JSON 'null'. Replace with zero value so it
// will be treated like any other invalid message.
messages[i] = new(jsonrpcMessage)
}
}
return messages, batch, nil
}

func (c *jsonCodec) writeJSON(ctx context.Context, v interface{}) error {
Expand Down
3 changes: 3 additions & 0 deletions rpc/testdata/invalid-batch.js
Original file line number Diff line number Diff line change
Expand Up @@ -10,5 +10,8 @@
--> [1,2,3]
<-- [{"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"}}]

--> [null]
<-- [{"jsonrpc":"2.0","id":null,"error":{"code":-32600,"message":"invalid request"}}]

--> [{"jsonrpc":"2.0","id":1,"method":"test_echo","params":["foo",1]},55,{"jsonrpc":"2.0","id":2,"method":"unknown_method"},{"foo":"bar"}]
<-- [{"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"}}]
3 changes: 3 additions & 0 deletions rpc/testdata/invalid-nonobj.js
Original file line number Diff line number Diff line change
Expand Up @@ -2,3 +2,6 @@

--> 1
<-- {"jsonrpc":"2.0","id":null,"error":{"code":-32600,"message":"invalid request"}}

--> null
<-- {"jsonrpc":"2.0","id":null,"error":{"code":-32600,"message":"invalid request"}}
6 changes: 3 additions & 3 deletions signer/storage/aes_gcm_storage.go
Original file line number Diff line number Diff line change
Expand Up @@ -151,11 +151,11 @@ func encrypt(key []byte, plaintext []byte, additionalData []byte) ([]byte, []byt
return nil, nil, err
}
aesgcm, err := cipher.NewGCM(block)
nonce := make([]byte, aesgcm.NonceSize())
if _, err := io.ReadFull(rand.Reader, nonce); err != nil {
if err != nil {
return nil, nil, err
}
if err != nil {
nonce := make([]byte, aesgcm.NonceSize())
if _, err := io.ReadFull(rand.Reader, nonce); err != nil {
return nil, nil, err
}
ciphertext := aesgcm.Seal(nil, nonce, plaintext, additionalData)
Expand Down