Kaynağa Gözat

src/interpreter.rs: Use wrapping_offset() for load/store operations

Rust 1.83 introduces some additional out-of-bound checks [0], making it
illegal to attempt to load at an out-of-bound access when trying to
load/store values from/to register in rbpf's interpreter, and causing
the program to panick even before we reach the safety checks from
check_mem().

I understand we need to use wrapping_offset() rather than offset() in
that case, which causes the operation itself (but not the resulting
poitner) to be safe, and the checked to be deferred. See also the
related GitHub issue [1].

[0] https://github.com/rust-lang/rust/pull/130251
[1] https://github.com/qmonnet/rbpf/issues/115

Reported-by: Ben Kimock <kimockb@gmail.com>
Signed-off-by: Quentin Monnet <qmo@qmon.net>
Quentin Monnet 8 ay önce
ebeveyn
işleme
cfb363c156
1 değiştirilmiş dosya ile 12 ekleme ve 12 silme
  1. 12 12
      src/interpreter.rs

+ 12 - 12
src/interpreter.rs

@@ -139,75 +139,75 @@ pub fn execute_program(
             // BPF_LDX class
             ebpf::LD_B_REG   => reg[_dst] = unsafe {
                 #[allow(clippy::cast_ptr_alignment)]
-                let x = (reg[_src] as *const u8).offset(insn.off as isize) as *const u8;
+                let x = (reg[_src] as *const u8).wrapping_offset(insn.off as isize) as *const u8;
                 check_mem_load(x as u64, 1, insn_ptr)?;
                 x.read_unaligned() as u64
             },
             ebpf::LD_H_REG   => reg[_dst] = unsafe {
                 #[allow(clippy::cast_ptr_alignment)]
-                let x = (reg[_src] as *const u8).offset(insn.off as isize) as *const u16;
+                let x = (reg[_src] as *const u8).wrapping_offset(insn.off as isize) as *const u16;
                 check_mem_load(x as u64, 2, insn_ptr)?;
                 x.read_unaligned() as u64
             },
             ebpf::LD_W_REG   => reg[_dst] = unsafe {
                 #[allow(clippy::cast_ptr_alignment)]
-                let x = (reg[_src] as *const u8).offset(insn.off as isize) as *const u32;
+                let x = (reg[_src] as *const u8).wrapping_offset(insn.off as isize) as *const u32;
                 check_mem_load(x as u64, 4, insn_ptr)?;
                 x.read_unaligned() as u64
             },
             ebpf::LD_DW_REG  => reg[_dst] = unsafe {
                 #[allow(clippy::cast_ptr_alignment)]
-                let x = (reg[_src] as *const u8).offset(insn.off as isize) as *const u64;
+                let x = (reg[_src] as *const u8).wrapping_offset(insn.off as isize) as *const u64;
                 check_mem_load(x as u64, 8, insn_ptr)?;
                 x.read_unaligned()
             },
 
             // BPF_ST class
             ebpf::ST_B_IMM   => unsafe {
-                let x = (reg[_dst] as *const u8).offset(insn.off as isize) as *mut u8;
+                let x = (reg[_dst] as *const u8).wrapping_offset(insn.off as isize) as *mut u8;
                 check_mem_store(x as u64, 1, insn_ptr)?;
                 x.write_unaligned(insn.imm as u8);
             },
             ebpf::ST_H_IMM   => unsafe {
                 #[allow(clippy::cast_ptr_alignment)]
-                let x = (reg[_dst] as *const u8).offset(insn.off as isize) as *mut u16;
+                let x = (reg[_dst] as *const u8).wrapping_offset(insn.off as isize) as *mut u16;
                 check_mem_store(x as u64, 2, insn_ptr)?;
                 x.write_unaligned(insn.imm as u16);
             },
             ebpf::ST_W_IMM   => unsafe {
                 #[allow(clippy::cast_ptr_alignment)]
-                let x = (reg[_dst] as *const u8).offset(insn.off as isize) as *mut u32;
+                let x = (reg[_dst] as *const u8).wrapping_offset(insn.off as isize) as *mut u32;
                 check_mem_store(x as u64, 4, insn_ptr)?;
                 x.write_unaligned(insn.imm as u32);
             },
             ebpf::ST_DW_IMM  => unsafe {
                 #[allow(clippy::cast_ptr_alignment)]
-                let x = (reg[_dst] as *const u8).offset(insn.off as isize) as *mut u64;
+                let x = (reg[_dst] as *const u8).wrapping_offset(insn.off as isize) as *mut u64;
                 check_mem_store(x as u64, 8, insn_ptr)?;
                 x.write_unaligned(insn.imm as u64);
             },
 
             // BPF_STX class
             ebpf::ST_B_REG   => unsafe {
-                let x = (reg[_dst] as *const u8).offset(insn.off as isize) as *mut u8;
+                let x = (reg[_dst] as *const u8).wrapping_offset(insn.off as isize) as *mut u8;
                 check_mem_store(x as u64, 1, insn_ptr)?;
                 x.write_unaligned(reg[_src] as u8);
             },
             ebpf::ST_H_REG   => unsafe {
                 #[allow(clippy::cast_ptr_alignment)]
-                let x = (reg[_dst] as *const u8).offset(insn.off as isize) as *mut u16;
+                let x = (reg[_dst] as *const u8).wrapping_offset(insn.off as isize) as *mut u16;
                 check_mem_store(x as u64, 2, insn_ptr)?;
                 x.write_unaligned(reg[_src] as u16);
             },
             ebpf::ST_W_REG   => unsafe {
                 #[allow(clippy::cast_ptr_alignment)]
-                let x = (reg[_dst] as *const u8).offset(insn.off as isize) as *mut u32;
+                let x = (reg[_dst] as *const u8).wrapping_offset(insn.off as isize) as *mut u32;
                 check_mem_store(x as u64, 4, insn_ptr)?;
                 x.write_unaligned(reg[_src] as u32);
             },
             ebpf::ST_DW_REG  => unsafe {
                 #[allow(clippy::cast_ptr_alignment)]
-                let x = (reg[_dst] as *const u8).offset(insn.off as isize) as *mut u64;
+                let x = (reg[_dst] as *const u8).wrapping_offset(insn.off as isize) as *mut u64;
                 check_mem_store(x as u64, 8, insn_ptr)?;
                 x.write_unaligned(reg[_src]);
             },