From f7ad168586f117473f6f01715c57271a79db452c Mon Sep 17 00:00:00 2001 From: hsqStephenZhang Date: Sat, 11 Jan 2025 19:09:38 +0800 Subject: [PATCH] fix: clarify signed & unsigned for jump insts Signed-off-by: hsqStephenZhang --- src/interpreter.rs | 20 ++++++++++++++------ 1 file changed, 14 insertions(+), 6 deletions(-) diff --git a/src/interpreter.rs b/src/interpreter.rs index 1c79bf6a..8a21171d 100644 --- a/src/interpreter.rs +++ b/src/interpreter.rs @@ -90,6 +90,12 @@ pub fn execute_program( insn_ptr = (insn_ptr as i16 + insn.off) as usize; }; + macro_rules! unsigned_u64 { + ($imm:expr) => { + ($imm as u32) as u64 + }; + } + match insn.opc { // BPF_LD class @@ -298,20 +304,22 @@ pub fn execute_program( // BPF_JMP class // TODO: check this actually works as expected for signed / unsigned ops + // J-EQ, J-NE, J-GT, J-GE, J-LT, J-LE: unsigned + // JS-GT, JS-GE, JS-LT, JS-LE: signed ebpf::JA => do_jump(), - ebpf::JEQ_IMM => if reg[_dst] == insn.imm as u64 { do_jump(); }, + ebpf::JEQ_IMM => if reg[_dst] == unsigned_u64!(insn.imm) { do_jump(); }, ebpf::JEQ_REG => if reg[_dst] == reg[_src] { do_jump(); }, - ebpf::JGT_IMM => if reg[_dst] > insn.imm as u64 { do_jump(); }, + ebpf::JGT_IMM => if reg[_dst] > unsigned_u64!(insn.imm) { do_jump(); }, ebpf::JGT_REG => if reg[_dst] > reg[_src] { do_jump(); }, - ebpf::JGE_IMM => if reg[_dst] >= insn.imm as u64 { do_jump(); }, + ebpf::JGE_IMM => if reg[_dst] >= unsigned_u64!(insn.imm) { do_jump(); }, ebpf::JGE_REG => if reg[_dst] >= reg[_src] { do_jump(); }, - ebpf::JLT_IMM => if reg[_dst] < insn.imm as u64 { do_jump(); }, + ebpf::JLT_IMM => if reg[_dst] < unsigned_u64!(insn.imm) { do_jump(); }, ebpf::JLT_REG => if reg[_dst] < reg[_src] { do_jump(); }, - ebpf::JLE_IMM => if reg[_dst] <= insn.imm as u64 { do_jump(); }, + ebpf::JLE_IMM => if reg[_dst] <= unsigned_u64!(insn.imm) { do_jump(); }, ebpf::JLE_REG => if reg[_dst] <= reg[_src] { do_jump(); }, ebpf::JSET_IMM => if reg[_dst] & insn.imm as u64 != 0 { do_jump(); }, ebpf::JSET_REG => if reg[_dst] & reg[_src] != 0 { do_jump(); }, - ebpf::JNE_IMM => if reg[_dst] != insn.imm as u64 { do_jump(); }, + ebpf::JNE_IMM => if reg[_dst] != unsigned_u64!(insn.imm) { do_jump(); }, ebpf::JNE_REG => if reg[_dst] != reg[_src] { do_jump(); }, ebpf::JSGT_IMM => if reg[_dst] as i64 > insn.imm as i64 { do_jump(); }, ebpf::JSGT_REG => if reg[_dst] as i64 > reg[_src] as i64 { do_jump(); },