Skip to content

Commit 2f99865

Browse files
hsqStephenZhangqmonnet
authored andcommitted
fix: cast i32 to u32 first for zero ext
Signed-off-by: hsqStephenZhang <stephenzhang666666@gmail.com>
1 parent a54b100 commit 2f99865

2 files changed

Lines changed: 41 additions & 6 deletions

File tree

src/interpreter.rs

Lines changed: 6 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -261,12 +261,12 @@ pub fn execute_program(
261261
// TODO Check how overflow works in kernel. Should we &= U32MAX all src register value
262262
// before we do the operation?
263263
// Cf ((0x11 << 32) - (0x1 << 32)) as u32 VS ((0x11 << 32) as u32 - (0x1 << 32) as u32
264-
ebpf::ADD32_IMM => reg[_dst] = (reg[_dst] as i32).wrapping_add(insn.imm) as u64, //((reg[_dst] & U32MAX) + insn.imm as u64) & U32MAX,
265-
ebpf::ADD32_REG => reg[_dst] = (reg[_dst] as i32).wrapping_add(reg[_src] as i32) as u64, //((reg[_dst] & U32MAX) + (reg[_src] & U32MAX)) & U32MAX,
266-
ebpf::SUB32_IMM => reg[_dst] = (reg[_dst] as i32).wrapping_sub(insn.imm) as u64,
267-
ebpf::SUB32_REG => reg[_dst] = (reg[_dst] as i32).wrapping_sub(reg[_src] as i32) as u64,
268-
ebpf::MUL32_IMM => reg[_dst] = (reg[_dst] as i32).wrapping_mul(insn.imm) as u64,
269-
ebpf::MUL32_REG => reg[_dst] = (reg[_dst] as i32).wrapping_mul(reg[_src] as i32) as u64,
264+
ebpf::ADD32_IMM => reg[_dst] = (reg[_dst] as i32).wrapping_add(insn.imm) as u32 as u64,
265+
ebpf::ADD32_REG => reg[_dst] = (reg[_dst] as i32).wrapping_add(reg[_src] as i32) as u32 as u64,
266+
ebpf::SUB32_IMM => reg[_dst] = (reg[_dst] as i32).wrapping_sub(insn.imm) as u32 as u64,
267+
ebpf::SUB32_REG => reg[_dst] = (reg[_dst] as i32).wrapping_sub(reg[_src] as i32) as u32 as u64,
268+
ebpf::MUL32_IMM => reg[_dst] = (reg[_dst] as i32).wrapping_mul(insn.imm) as u32 as u64,
269+
ebpf::MUL32_REG => reg[_dst] = (reg[_dst] as i32).wrapping_mul(reg[_src] as i32) as u32 as u64,
270270
ebpf::DIV32_IMM if insn.imm as u32 == 0 => reg[_dst] = 0,
271271
ebpf::DIV32_IMM => reg[_dst] = (reg[_dst] as u32 / insn.imm as u32) as u64,
272272
ebpf::DIV32_REG if reg[_src] as u32 == 0 => reg[_dst] = 0,

tests/ubpf_vm.rs

Lines changed: 35 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -2902,3 +2902,38 @@ fn test_vm_tcp_sack_nomatch() {
29022902
let vm = rbpf::EbpfVmRaw::new(Some(&prog)).unwrap();
29032903
assert_eq!(vm.execute_program(mem.as_mut_slice()).unwrap(), 0x0);
29042904
}
2905+
2906+
// Tests for 32-bit arithmetic with sign extension handling
2907+
// These tests verify that negative results are zero-extended, not sign-extended
2908+
#[test]
2909+
fn test_vm_sub32_imm_negative_result() {
2910+
// 1 - 2 = -1 (0xFFFFFFFF in u32)
2911+
// Should be zero-extended to 0x00000000FFFFFFFF, not sign-extended to 0xFFFFFFFFFFFFFFFF
2912+
let prog = assemble(
2913+
"
2914+
mov32 r0, 1
2915+
sub32 r0, 2
2916+
exit
2917+
",
2918+
)
2919+
.unwrap();
2920+
let vm = rbpf::EbpfVmNoData::new(Some(&prog)).unwrap();
2921+
assert_eq!(vm.execute_program().unwrap(), 0x00000000FFFFFFFF);
2922+
}
2923+
2924+
#[test]
2925+
fn test_vm_sub32_reg_negative_result() {
2926+
// 5 - 10 = -5 (0xFFFFFFFB in u32)
2927+
// Should be zero-extended to 0x00000000FFFFFFFB
2928+
let prog = assemble(
2929+
"
2930+
mov32 r0, 5
2931+
mov32 r1, 10
2932+
sub32 r0, r1
2933+
exit
2934+
",
2935+
)
2936+
.unwrap();
2937+
let vm = rbpf::EbpfVmNoData::new(Some(&prog)).unwrap();
2938+
assert_eq!(vm.execute_program().unwrap(), 0x00000000FFFFFFFB);
2939+
}

0 commit comments

Comments
 (0)