diff options
author | Wei-Ning Huang <w@dexon.org> | 2019-01-24 17:30:03 +0800 |
---|---|---|
committer | Wei-Ning Huang <w@byzantine-lab.io> | 2019-06-12 17:27:21 +0800 |
commit | 730751e28ee246c7ba082e2d10e782408fbadda8 (patch) | |
tree | 52d07ef53a07718d8478b0bbf622b6c033fa61e3 | |
parent | f55616df4fb5de81f25997feefd52d0554f985c6 (diff) | |
download | go-tangerine-730751e28ee246c7ba082e2d10e782408fbadda8.tar go-tangerine-730751e28ee246c7ba082e2d10e782408fbadda8.tar.gz go-tangerine-730751e28ee246c7ba082e2d10e782408fbadda8.tar.bz2 go-tangerine-730751e28ee246c7ba082e2d10e782408fbadda8.tar.lz go-tangerine-730751e28ee246c7ba082e2d10e782408fbadda8.tar.xz go-tangerine-730751e28ee246c7ba082e2d10e782408fbadda8.tar.zst go-tangerine-730751e28ee246c7ba082e2d10e782408fbadda8.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.
-rw-r--r-- | core/vm/evm.go | 2 | ||||
-rw-r--r-- | core/vm/instructions.go | 8 |
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 3a82190da..3d17287ed 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 |