qmonnet / rbpf

Rust virtual machine and JIT compiler for eBPF programs

Geek Repo:Geek Repo

Github PK Tool:Github PK Tool

Out-of-bound memory write in the interpreter

pcy190 opened this issue · comments

There exists several integer overflow in the mem_check check. The addition of 'addr' and 'len' variables may result in overflow towards a lower address, circumventing the checks on pointer addresses.

rbpf/src/interpreter.rs

Lines 15 to 23 in 4812c52

if mbuff.as_ptr() as u64 <= addr && addr + len as u64 <= mbuff.as_ptr() as u64 + mbuff.len() as u64 {
return Ok(())
}
if mem.as_ptr() as u64 <= addr && addr + len as u64 <= mem.as_ptr() as u64 + mem.len() as u64 {
return Ok(())
}
if stack.as_ptr() as u64 <= addr && addr + len as u64 <= stack.as_ptr() as u64 + stack.len() as u64 {
return Ok(())
}

Take addr + len as u64 <= mbuff.as_ptr() as u64 + mbuff.len() as u64 for an example, if addr is the mbuff pointer address and len is -1, the final result overflow towards mbuff.ptr() -1, causing the bad memory access.

The following PoC program will violate the safety check and broke the interpreter.

stdw [r2-0x1], 0x380affff
exit

With overflow-check enabled, we coud get the following panic:

thread '<unnamed>' panicked at src/interpreter.rs:15:41:
attempt to add with overflow
note: run with `RUST_BACKTRACE=1` environment variable to display a backtrace
...
    #14 0x10668d704 in core::panicking::panic::h28efa1d8b603254d panicking.rs:144
    #15 0x104fe6ed4 in rbpf::interpreter::check_mem::he501d64976cf2caa interpreter.rs:15
    #16 0x104fe858c in rbpf::interpreter::execute_program::he7cae8749900d08a interpreter.rs:176

Good catch, thanks! And thank you for the fix, too.

I wonder if uBPF might be affected as well (in bounds_check()), did you check by any chance?

uBPF have the similar issues in bounds_check, I will draft and report it. Many thanks.