Skip to content

Commit

Permalink
fix(levm): avoid overflow in calldataload (#1461)
Browse files Browse the repository at this point in the history
If the offset is larger than calldata, then there is no data to show.
Return 0 to the stack

**Motivation**
The calldata operand tried to cast the value it got as an argument to
usize everytime. However, that number could be larger than usize and an
error is raised.

<!-- Why does this pull request exist? What are its goals? -->

**Description**
This tries to check the offset value before casting it to usize. If the
offset value (in U256) is _larger_ than the actual length of contents of
the calldata (also in U256), then we simply return 0 (since the offset
would've removed all the values from calldata).

<!-- A clear and concise general description of the changes this PR
introduces -->

<!-- Link to issues: Resolves #111, Resolves #222 -->
  • Loading branch information
lima-limon-inc authored Dec 10, 2024
1 parent a55b6bf commit 6959e76
Showing 1 changed file with 12 additions and 4 deletions.
16 changes: 12 additions & 4 deletions crates/vm/levm/src/opcode_handlers/environment.rs
Original file line number Diff line number Diff line change
Expand Up @@ -93,11 +93,19 @@ impl VM {
) -> Result<OpcodeSuccess, VMError> {
self.increase_consumed_gas(current_call_frame, gas_cost::CALLDATALOAD)?;

let offset: usize = current_call_frame
.stack
.pop()?
let calldata_size: U256 = current_call_frame.calldata.len().into();

let offset = current_call_frame.stack.pop()?;

// If the offset is larger than the actual calldata, then you
// have no data to return.
if offset > calldata_size {
current_call_frame.stack.push(U256::zero())?;
return Ok(OpcodeSuccess::Continue);
};
let offset: usize = offset
.try_into()
.map_err(|_| VMError::VeryLargeNumber)?;
.map_err(|_| VMError::Internal(InternalError::ConversionError))?;

// All bytes after the end of the calldata are set to 0.
let mut data = [0u8; 32];
Expand Down

0 comments on commit 6959e76

Please sign in to comment.