aboutsummaryrefslogtreecommitdiffstats
path: root/core
diff options
context:
space:
mode:
authorWei-Ning Huang <w@dexon.org>2019-01-24 17:30:03 +0800
committerGitHub <noreply@github.com>2019-01-24 17:30:03 +0800
commit0bb42a73d6e38f590cc61bf13a5cb9882c4ef6d8 (patch)
tree82b94b329aa17942ea223e762a870d82ee95ef1a /core
parentb643af7bc592979e177ee56284e5de7125416593 (diff)
downloaddexon-0bb42a73d6e38f590cc61bf13a5cb9882c4ef6d8.tar
dexon-0bb42a73d6e38f590cc61bf13a5cb9882c4ef6d8.tar.gz
dexon-0bb42a73d6e38f590cc61bf13a5cb9882c4ef6d8.tar.bz2
dexon-0bb42a73d6e38f590cc61bf13a5cb9882c4ef6d8.tar.lz
dexon-0bb42a73d6e38f590cc61bf13a5cb9882c4ef6d8.tar.xz
dexon-0bb42a73d6e38f590cc61bf13a5cb9882c4ef6d8.tar.zst
dexon-0bb42a73d6e38f590cc61bf13a5cb9882c4ef6d8.zip
core: vm: modify randomness calculation algorithm (#173)
The original algorithm used for calculating algorithm is vulnerable to cross context re-entry attack. Example as follows: contract B { event Value(uint256 value); uint256 public value; function call() public { value = rand; emit Value(value); } } contract A { function randTwice(address bAddr) public { B b = B(bAddr); b.call.gas(100000)(); b.call.gas(100000)(); } } The two `b.call` will result in the same randomness value. This commit fix the issue by recording a called index used to store how many times opRand is called, and use it as argument to the Keccak call.
Diffstat (limited to 'core')
-rw-r--r--core/vm/evm.go2
-rw-r--r--core/vm/instructions.go8
2 files changed, 7 insertions, 3 deletions
diff --git a/core/vm/evm.go b/core/vm/evm.go
index 64f71e530..2eba9c2cb 100644
--- a/core/vm/evm.go
+++ b/core/vm/evm.go
@@ -101,6 +101,8 @@ type Context struct {
Time *big.Int // Provides information for TIME
Randomness []byte // Provides information for RAND
Difficulty *big.Int // Provides information for DIFFICULTY
+
+ RandCallIndex uint64 // Number of times opRand is called
}
// EVM is the Ethereum Virtual Machine base object and provides
diff --git a/core/vm/instructions.go b/core/vm/instructions.go
index beb4c6b73..84e3dfd78 100644
--- a/core/vm/instructions.go
+++ b/core/vm/instructions.go
@@ -417,14 +417,16 @@ func opRand(pc *uint64, interpreter *EVMInterpreter, contract *Contract, memory
binaryNonce := make([]byte, binary.MaxVarintLen64)
binary.PutUvarint(binaryNonce, nonce)
- binaryGas := make([]byte, binary.MaxVarintLen64)
- binary.PutUvarint(binaryGas, contract.Gas)
+ binaryUsedIndex := make([]byte, binary.MaxVarintLen64)
+ binary.PutUvarint(binaryUsedIndex, evm.RandCallIndex)
+
+ evm.RandCallIndex += 1
hash := crypto.Keccak256(
evm.Randomness,
contract.Caller().Bytes(),
binaryNonce,
- binaryGas)
+ binaryUsedIndex)
stack.push(interpreter.intPool.get().SetBytes(hash))
return nil, nil