Sanitize memory addresses and lengths (#97)

* add a helper function to ensure for memory addressing and length purposes, especially as applied to array indexing and bounds-checking, that non-negative UInt256 numbers remain non-negative when lossily converted to int's
This commit is contained in:
Dustin Brody 2018-08-06 16:33:20 +00:00 committed by GitHub
parent 467a9c3d7a
commit 2136bc74fd
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
2 changed files with 28 additions and 20 deletions

View File

@ -295,15 +295,15 @@ OK: 5/5 Fail: 0/5 Skip: 0/5
+ calldatacopyUnderFlow.json OK + calldatacopyUnderFlow.json OK
+ calldatacopyZeroMemExpansion.json OK + calldatacopyZeroMemExpansion.json OK
+ calldatacopyZeroMemExpansion_return.json OK + calldatacopyZeroMemExpansion_return.json OK
- calldatacopy_DataIndexTooHigh.json Fail + calldatacopy_DataIndexTooHigh.json OK
- calldatacopy_DataIndexTooHigh2.json Fail + calldatacopy_DataIndexTooHigh2.json OK
- calldatacopy_DataIndexTooHigh2_return.json Fail + calldatacopy_DataIndexTooHigh2_return.json OK
- calldatacopy_DataIndexTooHigh_return.json Fail + calldatacopy_DataIndexTooHigh_return.json OK
+ calldatacopy_sec.json OK + calldatacopy_sec.json OK
+ calldataload0.json OK + calldataload0.json OK
+ calldataload1.json OK + calldataload1.json OK
+ calldataload2.json OK + calldataload2.json OK
- calldataloadSizeTooHigh.json Fail + calldataloadSizeTooHigh.json OK
+ calldataloadSizeTooHighPartial.json OK + calldataloadSizeTooHighPartial.json OK
+ calldataload_BigOffset.json OK + calldataload_BigOffset.json OK
+ calldatasize0.json OK + calldatasize0.json OK
@ -313,20 +313,20 @@ OK: 5/5 Fail: 0/5 Skip: 0/5
+ callvalue.json OK + callvalue.json OK
+ codecopy0.json OK + codecopy0.json OK
+ codecopyZeroMemExpansion.json OK + codecopyZeroMemExpansion.json OK
- codecopy_DataIndexTooHigh.json Fail + codecopy_DataIndexTooHigh.json OK
+ codesize.json OK + codesize.json OK
+ extcodecopy0.json OK + extcodecopy0.json OK
+ extcodecopy0AddressTooBigLeft.json OK + extcodecopy0AddressTooBigLeft.json OK
+ extcodecopy0AddressTooBigRight.json OK + extcodecopy0AddressTooBigRight.json OK
+ extcodecopyZeroMemExpansion.json OK + extcodecopyZeroMemExpansion.json OK
- extcodecopy_DataIndexTooHigh.json Fail + extcodecopy_DataIndexTooHigh.json OK
+ extcodesize0.json OK + extcodesize0.json OK
+ extcodesize1.json OK + extcodesize1.json OK
+ extcodesizeUnderFlow.json OK + extcodesizeUnderFlow.json OK
+ gasprice.json OK + gasprice.json OK
+ origin.json OK + origin.json OK
``` ```
OK: 44/51 Fail: 7/51 Skip: 0/51 OK: 51/51 Fail: 0/51 Skip: 0/51
## vmIOandFlowOperations ## vmIOandFlowOperations
```diff ```diff
+ BlockNumberDynamicJump0_AfterJumpdest.json OK + BlockNumberDynamicJump0_AfterJumpdest.json OK

View File

@ -224,6 +224,14 @@ proc writePaddedResult(mem: var Memory,
# Note, we don't need to write padding bytes # Note, we don't need to write padding bytes
# mem.extend already pads with zero properly # mem.extend already pads with zero properly
func cleanMemRef(x: UInt256): int {.inline.} =
## Sanitize memory addresses, catch negative or impossibly big offsets
# See https://github.com/status-im/nimbus/pull/97 for more info
const upperBound = high(int32).u256
if x > upperBound:
return high(int32)
return x.toInt
op address, inline = true: op address, inline = true:
## 0x30, Get address of currently executing account. ## 0x30, Get address of currently executing account.
push: computation.msg.storageAddress push: computation.msg.storageAddress
@ -249,7 +257,7 @@ op callValue, inline = true:
op callDataLoad, inline = false, startPos: op callDataLoad, inline = false, startPos:
## 0x35, Get input data of current environment ## 0x35, Get input data of current environment
# TODO simplification: https://github.com/status-im/nimbus/issues/67 # TODO simplification: https://github.com/status-im/nimbus/issues/67
let dataPos = startPos.toInt let dataPos = startPos.cleanMemRef
if dataPos >= computation.msg.data.len: if dataPos >= computation.msg.data.len:
push: 0 push: 0
return return
@ -278,7 +286,7 @@ op callDataCopy, inline = false, memStartPos, copyStartPos, size:
## 0x37, Copy input data in current environment to memory. ## 0x37, Copy input data in current environment to memory.
# TODO tests: https://github.com/status-im/nimbus/issues/67 # TODO tests: https://github.com/status-im/nimbus/issues/67
let (memPos, copyPos, len) = (memStartPos.toInt, copyStartPos.toInt, size.toInt) let (memPos, copyPos, len) = (memStartPos.cleanMemRef, copyStartPos.cleanMemRef, size.cleanMemRef)
computation.gasMeter.consumeGas( computation.gasMeter.consumeGas(
computation.gasCosts[CallDataCopy].m_handler(computation.memory.len, memPos, len), computation.gasCosts[CallDataCopy].m_handler(computation.memory.len, memPos, len),
@ -294,7 +302,7 @@ op codecopy, inline = false, memStartPos, copyStartPos, size:
## 0x39, Copy code running in current environment to memory. ## 0x39, Copy code running in current environment to memory.
# TODO tests: https://github.com/status-im/nimbus/issues/67 # TODO tests: https://github.com/status-im/nimbus/issues/67
let (memPos, copyPos, len) = (memStartPos.toInt, copyStartPos.toInt, size.toInt) let (memPos, copyPos, len) = (memStartPos.cleanMemRef, copyStartPos.cleanMemRef, size.cleanMemRef)
computation.gasMeter.consumeGas( computation.gasMeter.consumeGas(
computation.gasCosts[CodeCopy].m_handler(computation.memory.len, memPos, len), computation.gasCosts[CodeCopy].m_handler(computation.memory.len, memPos, len),
@ -316,7 +324,7 @@ op extCodeCopy, inline = true:
## 0x3c, Copy an account's code to memory. ## 0x3c, Copy an account's code to memory.
let account = computation.stack.popAddress() let account = computation.stack.popAddress()
let (memStartPos, codeStartPos, size) = computation.stack.popInt(3) let (memStartPos, codeStartPos, size) = computation.stack.popInt(3)
let (memPos, codePos, len) = (memStartPos.toInt, codeStartPos.toInt, size.toInt) let (memPos, codePos, len) = (memStartPos.cleanMemRef, codeStartPos.cleanMemRef, size.cleanMemRef)
computation.gasMeter.consumeGas( computation.gasMeter.consumeGas(
computation.gasCosts[ExtCodeCopy].m_handler(computation.memory.len, memPos, len), computation.gasCosts[ExtCodeCopy].m_handler(computation.memory.len, memPos, len),
@ -331,7 +339,7 @@ op returnDataSize, inline = true:
op returnDataCopy, inline = false, memStartPos, copyStartPos, size: op returnDataCopy, inline = false, memStartPos, copyStartPos, size:
## 0x3e, Copy output data from the previous call to memory. ## 0x3e, Copy output data from the previous call to memory.
let (memPos, copyPos, len) = (memStartPos.toInt, copyStartPos.toInt, size.toInt) let (memPos, copyPos, len) = (memStartPos.cleanMemRef, copyStartPos.cleanMemRef, size.cleanMemRef)
computation.gasMeter.consumeGas( computation.gasMeter.consumeGas(
computation.gasCosts[CodeCopy].m_handler(memPos, copyPos, len), computation.gasCosts[CodeCopy].m_handler(memPos, copyPos, len),
@ -387,7 +395,7 @@ op pop, inline = true:
op mload, inline = true, memStartPos: op mload, inline = true, memStartPos:
## 0x51, Load word from memory ## 0x51, Load word from memory
let memPos = memStartPos.toInt let memPos = memStartPos.cleanMemRef
computation.gasMeter.consumeGas( computation.gasMeter.consumeGas(
computation.gasCosts[MLoad].m_handler(computation.memory.len, memPos, 32), computation.gasCosts[MLoad].m_handler(computation.memory.len, memPos, 32),
@ -399,7 +407,7 @@ op mload, inline = true, memStartPos:
op mstore, inline = true, memStartPos, value: op mstore, inline = true, memStartPos, value:
## 0x52, Save word to memory ## 0x52, Save word to memory
let memPos = memStartPos.toInt let memPos = memStartPos.cleanMemRef
computation.gasMeter.consumeGas( computation.gasMeter.consumeGas(
computation.gasCosts[MStore].m_handler(computation.memory.len, memPos, 32), computation.gasCosts[MStore].m_handler(computation.memory.len, memPos, 32),
@ -411,7 +419,7 @@ op mstore, inline = true, memStartPos, value:
op mstore8, inline = true, memStartPos, value: op mstore8, inline = true, memStartPos, value:
## 0x53, Save byte to memory ## 0x53, Save byte to memory
let memPos = memStartPos.toInt let memPos = memStartPos.cleanMemRef
computation.gasMeter.consumeGas( computation.gasMeter.consumeGas(
computation.gasCosts[MStore].m_handler(computation.memory.len, memPos, 1), computation.gasCosts[MStore].m_handler(computation.memory.len, memPos, 1),
@ -501,7 +509,7 @@ op create, inline = false, value, startPosition, size:
## 0xf0, Create a new account with associated code. ## 0xf0, Create a new account with associated code.
# TODO: Forked create for Homestead # TODO: Forked create for Homestead
let (memPos, len) = (startPosition.toInt, size.toInt) let (memPos, len) = (startPosition.cleanMemRef, size.cleanMemRef)
computation.gasMeter.consumeGas( computation.gasMeter.consumeGas(
computation.gasCosts[CodeCopy].m_handler(computation.memory.len, memPos, len), computation.gasCosts[CodeCopy].m_handler(computation.memory.len, memPos, len),
@ -663,7 +671,7 @@ template genCall(callName: untyped): untyped =
shouldTransferValue, shouldTransferValue,
isStatic) = `callName Params`(computation) isStatic) = `callName Params`(computation)
let (memInPos, memInLen, memOutPos, memOutLen) = (memoryInputStartPosition.toInt, memoryInputSize.toInt, memoryOutputStartPosition.toInt, memoryOutputSize.toInt) let (memInPos, memInLen, memOutPos, memOutLen) = (memoryInputStartPosition.cleanMemRef, memoryInputSize.cleanMemRef, memoryOutputStartPosition.cleanMemRef, memoryOutputSize.cleanMemRef)
let (gasCost, childMsgGas) = computation.gasCosts[Op.Call].c_handler( let (gasCost, childMsgGas) = computation.gasCosts[Op.Call].c_handler(
value, value,
@ -751,7 +759,7 @@ genCall(staticCall)
op returnOp, inline = false, startPos, size: op returnOp, inline = false, startPos, size:
## 0xf3, Halt execution returning output data. ## 0xf3, Halt execution returning output data.
let (pos, len) = (startPos.toInt, size.toInt) let (pos, len) = (startPos.cleanMemRef, size.cleanMemRef)
computation.gasMeter.consumeGas( computation.gasMeter.consumeGas(
computation.gasCosts[Return].m_handler(computation.memory.len, pos, len), computation.gasCosts[Return].m_handler(computation.memory.len, pos, len),
@ -763,7 +771,7 @@ op returnOp, inline = false, startPos, size:
op revert, inline = false, startPos, size: op revert, inline = false, startPos, size:
## 0xfd, Halt execution reverting state changes but returning data and remaining gas. ## 0xfd, Halt execution reverting state changes but returning data and remaining gas.
let (pos, len) = (startPos.toInt, size.toInt) let (pos, len) = (startPos.cleanMemRef, size.cleanMemRef)
computation.gasMeter.consumeGas( computation.gasMeter.consumeGas(
computation.gasCosts[Revert].m_handler(computation.memory.len, pos, len), computation.gasCosts[Revert].m_handler(computation.memory.len, pos, len),