ソースを参照

fix: clarify signed & unsigned for jump insts

Signed-off-by: hsqStephenZhang <stephenzhang666666@gmail.com>
hsqStephenZhang 5 ヶ月 前
コミット
acc042b276
1 ファイル変更14 行追加6 行削除
  1. 14 6
      src/interpreter.rs

+ 14 - 6
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(); },