Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

[SECURITY] Integer overflow when jump_address greater than usize::MAX #909

Closed
pventuzelo opened this issue Oct 18, 2024 · 1 comment
Closed
Labels
levm Lambda EVM implementation

Comments

@pventuzelo
Copy link

pventuzelo commented Oct 18, 2024

Executive summary

Our team (@FuzzingLabs) discovered a vulnerability in LambdaClass's EVM implementation, specifically in the jump opcode and valid_jump function. In fact, we can provide a value equal to U256::MAX as a parameter to trigger this bug, causing the VM to crash.

Vulnerability details

  • Severity: Critical
  • Affected component : jump opcode in Lambdaclass EVM

Steps to reproduce

Create a new test using this payload :

fn add_op() {
    let mut vm = new_vm_with_ops(&[
        Operation::Push((32, U256::MAX)),
        Operation::Jump,
        Operation::Stop,
    ]);

    vm.execute();

    assert!(vm.current_call_frame_mut().stack.pop().unwrap() == U256::one());
    assert!(vm.current_call_frame_mut().pc() == 68);
}
thread 'tests::add_op' panicked at /home/.../.cargo/registry/src/index.crates.io-6f17d22bba15001f/primitive-types-0.12.2/src/lib.rs:38:1:
Integer overflow when casting to usize
stack backtrace:
   0: rust_begin_unwind
             at /rustc/c1a6199e9d92bb785c17a6d7ffd8b8b552f79c10/library/std/src/panicking.rs:665:5
   1: core::panicking::panic_fmt
             at /rustc/c1a6199e9d92bb785c17a6d7ffd8b8b552f79c10/library/core/src/panicking.rs:74:14
   2: primitive_types::U256::as_usize
             at /home/.../.cargo/registry/src/index.crates.io-6f17d22bba15001f/uint-0.9.5/src/uint.rs:661:6
   3: ethereum_rust_levm::call_frame::CallFrame::valid_jump
             at ./src/call_frame.rs:147:24
   4: ethereum_rust_levm::call_frame::CallFrame::jump
             at ./src/call_frame.rs:139:13
   5: ethereum_rust_levm::opcode_handlers::stack_memory_storage_flow::<impl ethereum_rust_levm::vm::VM>::op_jump
             at ./src/opcode_handlers/stack_memory_storage_flow.rs:278:13

Root cause

The opcode will call the function valid_jump :

    pub fn jump(&mut self, jump_address: U256) -> bool {
        if !self.valid_jump(jump_address) {
            return false;
        }
        self.pc = jump_address.as_usize();
        true
    }

Here is the function :

    fn valid_jump(&self, jump_address: U256) -> bool {
        self.opcode_at(jump_address.as_usize())
            .map(|opcode| opcode.eq(&Opcode::JUMPDEST))
            .is_some_and(|is_jumpdest| is_jumpdest)
    }

First of all, the function will cast jump_address using as_usize without checking for integer overflow. If we give jump_address a value greater than usize::MAX, we can trigger an integer overflow and then crash the VM.

@JereSalo JereSalo added the levm Lambda EVM implementation label Oct 21, 2024
@ilitteri
Copy link
Contributor

Thanks! Fixed in #1170.

github-merge-queue bot pushed a commit that referenced this issue Nov 15, 2024
**Motivation**

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

To add edge case tests suggested by [Fuzzing
Labs](#1085).

**Description**

- Adds test from
#1171
- Adds test from
#1156
- Adds test from
#1155
- Adds test from
#1154
- Adds test from
#1153
- Adds test from
#1152
- Adds test from
#1147
- Adds test from
#1146
- Adds test from
#1145
- Adds test from
#1144
- Adds test from
#1143
- Adds test from
#909
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
levm Lambda EVM implementation
Projects
Status: Done
Development

No branches or pull requests

3 participants