Merge pull request #63 from binance-chain/secure_patch
[R4R] security patch from go-ethereum
This commit is contained in:
commit
b605f1f913
@ -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
|
||||
|
@ -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
|
||||
|
||||
|
@ -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)
|
||||
}
|
||||
|
@ -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)
|
||||
|
@ -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.
|
||||
|
@ -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',
|
||||
|
@ -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
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -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
|
||||
@ -359,16 +363,25 @@ 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)
|
||||
@ -376,26 +389,41 @@ func (db *DB) LastPongReceived(id ID, ip net.IP) time.Time {
|
||||
|
||||
// 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))
|
||||
}
|
||||
|
||||
|
13
rpc/json.go
13
rpc/json.go
@ -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 {
|
||||
|
3
rpc/testdata/invalid-batch.js
vendored
3
rpc/testdata/invalid-batch.js
vendored
@ -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
rpc/testdata/invalid-nonobj.js
vendored
3
rpc/testdata/invalid-nonobj.js
vendored
@ -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"}}
|
||||
|
@ -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)
|
||||
|
Loading…
Reference in New Issue
Block a user