mirror of
https://github.com/status-im/nimbus-eth1.git
synced 2025-01-11 21:04:11 +00:00
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:
parent
467a9c3d7a
commit
2136bc74fd
16
VMTests.md
16
VMTests.md
@ -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
|
||||||
|
@ -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),
|
||||||
|
Loading…
x
Reference in New Issue
Block a user