Forráskód Böngészése

API: make JITted program and `prog_exec_jit()` function unsafe

The JITted program could make the system crash if it contains errors,
and as a consequence should be marked as `unsafe`.

Reported-by: @CensoredUsername
Reported-at: https://www.reddit.com/r/rust/comments/5n4n1p/rust_virtual_machine_and_jit_compiler_for_ebpf/dc8os42/
Quentin Monnet 8 éve
szülő
commit
6124d65ae2
5 módosított fájl, 161 hozzáadás és 125 törlés
  1. 18 10
      README.md
  2. 1 1
      src/jit.rs
  3. 37 13
      src/lib.rs
  4. 10 6
      tests/misc.rs
  5. 95 95
      tests/ubpf_jit_x86_64.rs

+ 18 - 10
README.md

@@ -129,7 +129,9 @@ All these structs implement the same public functions:
 pub fn new(prog: &'a std::vec::Vec<u8>) -> EbpfVmMbuff<'a>
 
 // called with EbpfVmFixedMbuff:: prefix
-pub fn new(prog: &'a std::vec::Vec<u8>, data_offset: usize, data_end_offset: usize) -> EbpfVmFixedMbuff<'a>
+pub fn new(prog: &'a std::vec::Vec<u8>,
+           data_offset: usize,
+           data_end_offset: usize) -> EbpfVmFixedMbuff<'a>
 
 // called with EbpfVmRaw:: prefix
 pub fn new(prog: &'a std::vec::Vec<u8>) -> EbpfVmRaw<'a>
@@ -166,7 +168,9 @@ program after the VM instance creation. This program is checked with the
 verifier.
 
 ```rust
-pub fn register_helper(&mut self, key: u32, function: fn (u64, u64, u64, u64, u64) -> u64)
+pub fn register_helper(&mut self,
+                       key: u32,
+                       function: fn (u64, u64, u64, u64, u64) -> u64)
 ```
 
 This function is used to register a helper function. The VM stores its
@@ -176,10 +180,13 @@ therefore must use specific helper numbers.
 
 ```rust
 // for struct EbpfVmMbuff
-pub fn prog_exec(&self, mem: &'a mut std::vec::Vec<u8>, mbuff: &'a mut std::vec::Vec<u8>) -> u64
+pub fn prog_exec(&self,
+                 mem: &'a mut std::vec::Vec<u8>,
+                 mbuff: &'a mut std::vec::Vec<u8>) -> u64
 
 // for struct EbpfVmFixedMbuff and struct EbpfVmRaw
-pub fn prog_exec(&self, mem: &'a mut std::vec::Vec<u8>) -> u64
+pub fn prog_exec(&self,
+                 mem: &'a mut std::vec::Vec<u8>) -> u64
 
 // for struct EbpfVmNoData
 pub fn prog_exec(&self) -> u64
@@ -200,13 +207,14 @@ is called. The generated assembly function is internally stored in the VM.
 
 ```rust
 // for struct EbpfVmMbuff
-pub fn prog_exec_jit(&self, mem: &'a mut std::vec::Vec<u8>, mbuff: &'a mut std::vec::Vec<u8>) -> u64
+pub unsafe fn prog_exec_jit(&self, mem: &'a mut std::vec::Vec<u8>,
+                            mbuff: &'a mut std::vec::Vec<u8>) -> u64
 
 // for struct EbpfVmFixedMbuff and struct EbpfVmRaw
-pub fn prog_exec_jit(&self, mem: &'a mut std::vec::Vec<u8>) -> u64
+pub unsafe fn prog_exec_jit(&self, mem: &'a mut std::vec::Vec<u8>) -> u64
 
 // for struct EbpfVmNoData
-pub fn prog_exec_jit(&self) -> u64
+pub unsafe fn prog_exec_jit(&self) -> u64
 ```
 
 Calls the JIT-compiled program. The arguments to provide are the same as for
@@ -214,7 +222,7 @@ Calls the JIT-compiled program. The arguments to provide are the same as for
 the JIT-compiled program should be the same as with the interpreter, but it
 should run faster. Note that if errors occur during the program execution, the
 JIT-compiled version does not handle it as well as the interpreter, and the
-program may crash.
+program may crash. For this reason the functions are marked as `unsafe`.
 
 ## Example uses
 
@@ -273,7 +281,7 @@ fn main() {
 
     // Then we execute it. For this kind of VM, a reference to the packet data
     // must be passed to the function that executes the program.
-    assert_eq!(vm.prog_exec_jit(&mut mem), 0x11);
+    unsafe { assert_eq!(vm.prog_exec_jit(&mut mem), 0x11); }
 }
 ```
 ### Using a metadata buffer
@@ -314,7 +322,7 @@ fn main() {
 
     // Here we must provide both a reference to the packet data, and to the
     // metadata buffer we use.
-    assert_eq!(vm.prog_exec_jit(&mut mem, &mut mbuff), 0x2211);
+    unsafe { assert_eq!(vm.prog_exec_jit(&mut mem, &mut mbuff), 0x2211); }
 }
 ```
 

+ 1 - 1
src/jit.rs

@@ -835,7 +835,7 @@ impl<'a> std::fmt::Debug for JitMemory<'a> {
 pub fn compile(prog: &std::vec::Vec<u8>,
                helpers: &HashMap<u32, fn (u64, u64, u64, u64, u64) -> u64>,
                use_mbuff: bool, update_data_ptr: bool)
-    -> (fn(*mut u8, usize, *mut u8, usize, usize, usize) -> u64) {
+    -> (unsafe fn(*mut u8, usize, *mut u8, usize, usize, usize) -> u64) {
 
     // TODO: check how long the page must be to be sure to support an eBPF program of maximum
     // possible length

+ 37 - 13
src/lib.rs

@@ -69,7 +69,7 @@ struct MetaBuff {
 /// ```
 pub struct EbpfVmMbuff<'a> {
     prog:    &'a std::vec::Vec<u8>,
-    jit:     (fn (*mut u8, usize, *mut u8, usize, usize, usize) -> u64),
+    jit:     (unsafe fn (*mut u8, usize, *mut u8, usize, usize, usize) -> u64),
     helpers: HashMap<u32, fn (u64, u64, u64, u64, u64) -> u64>,
 }
 
@@ -524,11 +524,15 @@ impl<'a> EbpfVmMbuff<'a> {
     ///
     /// This function panics if an error occurs during the execution of the program.
     ///
+    /// # Safety
+    ///
     /// **WARNING:** JIT-compiled assembly code is not safe, in particular there is no runtime
     /// check for memory access; so if the eBPF program attempts erroneous accesses, this may end
     /// very bad (program may segfault). It may be wise to check that the program works with the
     /// interpreter before running the JIT-compiled version of it.
     ///
+    /// For this reason the function should be called from within an `unsafe` bloc.
+    ///
     /// # Examples
     ///
     /// ```
@@ -557,10 +561,12 @@ impl<'a> EbpfVmMbuff<'a> {
     /// vm.jit_compile();
     ///
     /// // Provide both a reference to the packet data, and to the metadata buffer.
-    /// let res = vm.prog_exec_jit(&mut mem, &mut mbuff);
-    /// assert_eq!(res, 0x2211);
+    /// unsafe {
+    ///     let res = vm.prog_exec_jit(&mut mem, &mut mbuff);
+    ///     assert_eq!(res, 0x2211);
+    /// }
     /// ```
-    pub fn prog_exec_jit(&self, mem: &mut std::vec::Vec<u8>, mbuff: &'a mut std::vec::Vec<u8>) -> u64 {
+    pub unsafe fn prog_exec_jit(&self, mem: &mut std::vec::Vec<u8>, mbuff: &'a mut std::vec::Vec<u8>) -> u64 {
         // If packet data is empty, do not send the address of an empty vector; send a null
         // pointer (zero value) as first argument instead, as this is uBPF's behavior (empty
         // packet should not happen in the kernel; anyway the verifier would prevent the use of
@@ -875,11 +881,15 @@ impl<'a> EbpfVmFixedMbuff<'a> {
     ///
     /// This function panics if an error occurs during the execution of the program.
     ///
+    /// # Safety
+    ///
     /// **WARNING:** JIT-compiled assembly code is not safe, in particular there is no runtime
     /// check for memory access; so if the eBPF program attempts erroneous accesses, this may end
     /// very bad (program may segfault). It may be wise to check that the program works with the
     /// interpreter before running the JIT-compiled version of it.
     ///
+    /// For this reason the function should be called from within an `unsafe` bloc.
+    ///
     /// # Examples
     ///
     /// ```
@@ -902,12 +912,14 @@ impl<'a> EbpfVmFixedMbuff<'a> {
     /// vm.jit_compile();
     ///
     /// // Provide only a reference to the packet data. We do not manage the metadata buffer.
-    /// let res = vm.prog_exec_jit(&mut mem);
-    /// assert_eq!(res, 0xdd);
+    /// unsafe {
+    ///     let res = vm.prog_exec_jit(&mut mem);
+    ///     assert_eq!(res, 0xdd);
+    /// }
     /// ```
     // This struct redefines the `prog_exec_jit()` function, in order to pass the offsets
     // associated with the fixed mbuff.
-    pub fn prog_exec_jit(&mut self, mem: &'a mut std::vec::Vec<u8>) -> u64 {
+    pub unsafe fn prog_exec_jit(&mut self, mem: &'a mut std::vec::Vec<u8>) -> u64 {
         // If packet data is empty, do not send the address of an empty vector; send a null
         // pointer (zero value) as first argument instead, as this is uBPF's behavior (empty
         // packet should not happen in the kernel; anyway the verifier would prevent the use of
@@ -1117,11 +1129,15 @@ impl<'a> EbpfVmRaw<'a> {
     ///
     /// This function panics if an error occurs during the execution of the program.
     ///
+    /// # Safety
+    ///
     /// **WARNING:** JIT-compiled assembly code is not safe, in particular there is no runtime
     /// check for memory access; so if the eBPF program attempts erroneous accesses, this may end
     /// very bad (program may segfault). It may be wise to check that the program works with the
     /// interpreter before running the JIT-compiled version of it.
     ///
+    /// For this reason the function should be called from within an `unsafe` bloc.
+    ///
     /// # Examples
     ///
     /// ```
@@ -1140,10 +1156,12 @@ impl<'a> EbpfVmRaw<'a> {
     ///
     /// vm.jit_compile();
     ///
-    /// let res = vm.prog_exec_jit(&mut mem);
-    /// assert_eq!(res, 0x22cc);
+    /// unsafe {
+    ///     let res = vm.prog_exec_jit(&mut mem);
+    ///     assert_eq!(res, 0x22cc);
+    /// }
     /// ```
-    pub fn prog_exec_jit(&self, mem: &'a mut std::vec::Vec<u8>) -> u64 {
+    pub unsafe fn prog_exec_jit(&self, mem: &'a mut std::vec::Vec<u8>) -> u64 {
         let mut mbuff = vec![];
         self.parent.prog_exec_jit(mem, &mut mbuff)
     }
@@ -1349,11 +1367,15 @@ impl<'a> EbpfVmNoData<'a> {
     ///
     /// This function panics if an error occurs during the execution of the program.
     ///
+    /// # Safety
+    ///
     /// **WARNING:** JIT-compiled assembly code is not safe, in particular there is no runtime
     /// check for memory access; so if the eBPF program attempts erroneous accesses, this may end
     /// very bad (program may segfault). It may be wise to check that the program works with the
     /// interpreter before running the JIT-compiled version of it.
     ///
+    /// For this reason the function should be called from within an `unsafe` bloc.
+    ///
     /// # Examples
     ///
     /// ```
@@ -1367,10 +1389,12 @@ impl<'a> EbpfVmNoData<'a> {
     ///
     /// vm.jit_compile();
     ///
-    /// let res = vm.prog_exec_jit();
-    /// assert_eq!(res, 0x1122);
+    /// unsafe {
+    ///     let res = vm.prog_exec_jit();
+    ///     assert_eq!(res, 0x1122);
+    /// }
     /// ```
-    pub fn prog_exec_jit(&self) -> u64 {
+    pub unsafe fn prog_exec_jit(&self) -> u64 {
         self.parent.prog_exec_jit(&mut vec![])
     }
 }

+ 10 - 6
tests/misc.rs

@@ -246,9 +246,11 @@ fn test_jit_block_port() {
     vm.register_helper(helpers::BPF_TRACE_PRINTK_IDX, helpers::bpf_trace_printf);
     vm.jit_compile();
 
-    let res = vm.prog_exec_jit(&mut packet);
-    println!("Program returned: {:?} ({:#x})", res, res);
-    assert_eq!(res, 0xffffffff);
+    unsafe {
+        let res = vm.prog_exec_jit(&mut packet);
+        println!("Program returned: {:?} ({:#x})", res, res);
+        assert_eq!(res, 0xffffffff);
+    }
 }
 
 // Program and memory come from uBPF test ldxh.
@@ -299,7 +301,9 @@ fn test_jit_mbuff() {
         *data_end = mem.as_ptr() as u64 + mem.len() as u64;
     }
 
-    let mut vm = rbpf::EbpfVmMbuff::new(&prog);
-    vm.jit_compile();
-    assert_eq!(vm.prog_exec_jit(&mut mem, &mut mbuff), 0x2211);
+    unsafe {
+        let mut vm = rbpf::EbpfVmMbuff::new(&prog);
+        vm.jit_compile();
+        assert_eq!(vm.prog_exec_jit(&mut mem, &mut mbuff), 0x2211);
+    }
 }

+ 95 - 95
tests/ubpf_jit_x86_64.rs

@@ -36,7 +36,7 @@ fn test_jit_add() {
     ];
     let mut vm = rbpf::EbpfVmNoData::new(&prog);
     vm.jit_compile();
-    assert_eq!(vm.prog_exec_jit(), 0x3);
+    unsafe { assert_eq!(vm.prog_exec_jit(), 0x3); }
 }
 
 #[test]
@@ -64,7 +64,7 @@ fn test_jit_alu64_arith() {
     ];
     let mut vm = rbpf::EbpfVmNoData::new(&prog);
     vm.jit_compile();
-    assert_eq!(vm.prog_exec_jit(), 0x2a);
+    unsafe { assert_eq!(vm.prog_exec_jit(), 0x2a); }
 }
 
 #[test]
@@ -96,7 +96,7 @@ fn test_jit_alu64_bit() {
     ];
     let mut vm = rbpf::EbpfVmNoData::new(&prog);
     vm.jit_compile();
-    assert_eq!(vm.prog_exec_jit(), 0x11);
+    unsafe { assert_eq!(vm.prog_exec_jit(), 0x11); }
 }
 
 #[test]
@@ -124,7 +124,7 @@ fn test_jit_alu_arith() {
     ];
     let mut vm = rbpf::EbpfVmNoData::new(&prog);
     vm.jit_compile();
-    assert_eq!(vm.prog_exec_jit(), 0x2a);
+    unsafe { assert_eq!(vm.prog_exec_jit(), 0x2a); }
 }
 
 #[test]
@@ -154,7 +154,7 @@ fn test_jit_alu_bit() {
     ];
     let mut vm = rbpf::EbpfVmNoData::new(&prog);
     vm.jit_compile();
-    assert_eq!(vm.prog_exec_jit(), 0x11);
+    unsafe { assert_eq!(vm.prog_exec_jit(), 0x11); }
 }
 
 #[test]
@@ -168,7 +168,7 @@ fn test_jit_arsh32_high_shift() {
     ];
     let mut vm = rbpf::EbpfVmNoData::new(&prog);
     vm.jit_compile();
-    assert_eq!(vm.prog_exec_jit(), 0x4);
+    unsafe { assert_eq!(vm.prog_exec_jit(), 0x4); }
 }
 
 #[test]
@@ -181,7 +181,7 @@ fn test_jit_arsh() {
     ];
     let mut vm = rbpf::EbpfVmNoData::new(&prog);
     vm.jit_compile();
-    assert_eq!(vm.prog_exec_jit(), 0xffff8000);
+    unsafe { assert_eq!(vm.prog_exec_jit(), 0xffff8000); }
 }
 
 #[test]
@@ -196,7 +196,7 @@ fn test_jit_arsh64() {
     ];
     let mut vm = rbpf::EbpfVmNoData::new(&prog);
     vm.jit_compile();
-    assert_eq!(vm.prog_exec_jit(), 0xfffffffffffffff8);
+    unsafe { assert_eq!(vm.prog_exec_jit(), 0xfffffffffffffff8); }
 }
 
 #[test]
@@ -210,7 +210,7 @@ fn test_jit_arsh_reg() {
     ];
     let mut vm = rbpf::EbpfVmNoData::new(&prog);
     vm.jit_compile();
-    assert_eq!(vm.prog_exec_jit(), 0xffff8000);
+    unsafe { assert_eq!(vm.prog_exec_jit(), 0xffff8000); }
 }
 
 #[test]
@@ -225,7 +225,7 @@ fn test_jit_be16() {
     ];
     let mut vm = rbpf::EbpfVmRaw::new(&prog);
     vm.jit_compile();
-    assert_eq!(vm.prog_exec_jit(&mut mem), 0x1122);
+    unsafe { assert_eq!(vm.prog_exec_jit(&mut mem), 0x1122); }
 }
 
 #[test]
@@ -240,7 +240,7 @@ fn test_jit_be16_high() {
     ];
     let mut vm = rbpf::EbpfVmRaw::new(&prog);
     vm.jit_compile();
-    assert_eq!(vm.prog_exec_jit(&mut mem), 0x1122);
+    unsafe { assert_eq!(vm.prog_exec_jit(&mut mem), 0x1122); }
 }
 
 #[test]
@@ -255,7 +255,7 @@ fn test_jit_be32() {
     ];
     let mut vm = rbpf::EbpfVmRaw::new(&prog);
     vm.jit_compile();
-    assert_eq!(vm.prog_exec_jit(&mut mem), 0x11223344);
+    unsafe { assert_eq!(vm.prog_exec_jit(&mut mem), 0x11223344); }
 }
 
 #[test]
@@ -270,7 +270,7 @@ fn test_jit_be32_high() {
     ];
     let mut vm = rbpf::EbpfVmRaw::new(&prog);
     vm.jit_compile();
-    assert_eq!(vm.prog_exec_jit(&mut mem), 0x11223344);
+    unsafe { assert_eq!(vm.prog_exec_jit(&mut mem), 0x11223344); }
 }
 
 #[test]
@@ -285,7 +285,7 @@ fn test_jit_be64() {
     ];
     let mut vm = rbpf::EbpfVmRaw::new(&prog);
     vm.jit_compile();
-    assert_eq!(vm.prog_exec_jit(&mut mem), 0x1122334455667788);
+    unsafe { assert_eq!(vm.prog_exec_jit(&mut mem), 0x1122334455667788); }
 }
 
 #[test]
@@ -302,7 +302,7 @@ fn test_jit_call() {
     let mut vm = rbpf::EbpfVmNoData::new(&prog);
     vm.register_helper(0, helpers::gather_bytes);
     vm.jit_compile();
-    assert_eq!(vm.prog_exec_jit(), 0x0102030405);
+    unsafe { assert_eq!(vm.prog_exec_jit(), 0x0102030405); }
 }
 
 #[test]
@@ -322,7 +322,7 @@ fn test_jit_call_memfrob() {
     let mut vm = rbpf::EbpfVmRaw::new(&prog);
     vm.register_helper(1, helpers::memfrob);
     vm.jit_compile();
-    assert_eq!(vm.prog_exec_jit(&mut mem), 0x102292e2f2c0708);
+    unsafe { assert_eq!(vm.prog_exec_jit(&mut mem), 0x102292e2f2c0708); }
 }
 
 // TODO: helpers::trash_registers needs asm!().
@@ -345,7 +345,7 @@ fn test_jit_call_memfrob() {
     //let mut vm = rbpf::EbpfVmNoData::new(&prog);
     //vm.register_helper(2, helpers::trash_registers);
     //vm.jit_compile();
-    //assert_eq!(vm.prog_exec_jit(), 0x4321);
+    //unsafe { assert_eq!(vm.prog_exec_jit(), 0x4321); }
 //}
 
 #[test]
@@ -359,7 +359,7 @@ fn test_jit_div32_high_divisor() {
     ];
     let mut vm = rbpf::EbpfVmNoData::new(&prog);
     vm.jit_compile();
-    assert_eq!(vm.prog_exec_jit(), 0x3);
+    unsafe { assert_eq!(vm.prog_exec_jit(), 0x3); }
 }
 
 #[test]
@@ -372,7 +372,7 @@ fn test_jit_div32_imm() {
     ];
     let mut vm = rbpf::EbpfVmNoData::new(&prog);
     vm.jit_compile();
-    assert_eq!(vm.prog_exec_jit(), 0x3);
+    unsafe { assert_eq!(vm.prog_exec_jit(), 0x3); }
 }
 
 #[test]
@@ -386,7 +386,7 @@ fn test_jit_div32_reg() {
     ];
     let mut vm = rbpf::EbpfVmNoData::new(&prog);
     vm.jit_compile();
-    assert_eq!(vm.prog_exec_jit(), 0x3);
+    unsafe { assert_eq!(vm.prog_exec_jit(), 0x3); }
 }
 
 #[test]
@@ -399,7 +399,7 @@ fn test_jit_div64_imm() {
     ];
     let mut vm = rbpf::EbpfVmNoData::new(&prog);
     vm.jit_compile();
-    assert_eq!(vm.prog_exec_jit(), 0x300000000);
+    unsafe { assert_eq!(vm.prog_exec_jit(), 0x300000000); }
 }
 
 #[test]
@@ -413,7 +413,7 @@ fn test_jit_div64_reg() {
     ];
     let mut vm = rbpf::EbpfVmNoData::new(&prog);
     vm.jit_compile();
-    assert_eq!(vm.prog_exec_jit(), 0x300000000);
+    unsafe { assert_eq!(vm.prog_exec_jit(), 0x300000000); }
 }
 
 #[test]
@@ -426,7 +426,7 @@ fn test_jit_early_exit() {
     ];
     let mut vm = rbpf::EbpfVmNoData::new(&prog);
     vm.jit_compile();
-    assert_eq!(vm.prog_exec_jit(), 0x3);
+    unsafe { assert_eq!(vm.prog_exec_jit(), 0x3); }
 }
 
 // uBPF limits the number of user functions at 64. We don't.
@@ -448,7 +448,7 @@ fn test_jit_err_call_unreg() {
     ];
     let mut vm = rbpf::EbpfVmNoData::new(&prog);
     vm.jit_compile();
-    vm.prog_exec_jit();
+    unsafe { vm.prog_exec_jit(); }
 }
 
 // TODO: Should panic!() instead, but I could not make it panic in JIT-compiled code, so the
@@ -464,7 +464,7 @@ fn test_jit_err_div64_by_zero_reg() {
     ];
     let mut vm = rbpf::EbpfVmNoData::new(&prog);
     vm.jit_compile();
-    assert_eq!(vm.prog_exec_jit(), 0xffffffffffffffff);
+    unsafe { assert_eq!(vm.prog_exec_jit(), 0xffffffffffffffff); }
 }
 
 // TODO: Same remark as above
@@ -479,7 +479,7 @@ fn test_jit_err_div_by_zero_reg() {
     ];
     let mut vm = rbpf::EbpfVmNoData::new(&prog);
     vm.jit_compile();
-    assert_eq!(vm.prog_exec_jit(), 0xffffffffffffffff);
+    unsafe { assert_eq!(vm.prog_exec_jit(), 0xffffffffffffffff); }
 }
 
 // TODO: Same remark as above
@@ -494,7 +494,7 @@ fn test_jit_err_mod64_by_zero_reg() {
     ];
     let mut vm = rbpf::EbpfVmNoData::new(&prog);
     vm.jit_compile();
-    assert_eq!(vm.prog_exec_jit(), 0xffffffffffffffff);
+    unsafe { assert_eq!(vm.prog_exec_jit(), 0xffffffffffffffff); }
 }
 
 // TODO: Same remark as above
@@ -509,7 +509,7 @@ fn test_jit_err_mod_by_zero_reg() {
     ];
     let mut vm = rbpf::EbpfVmNoData::new(&prog);
     vm.jit_compile();
-    assert_eq!(vm.prog_exec_jit(), 0xffffffffffffffff);
+    unsafe { assert_eq!(vm.prog_exec_jit(), 0xffffffffffffffff); }
 }
 
 // TODO SKIP: JIT disabled for this testcase (stack oob check not implemented)
@@ -522,7 +522,7 @@ fn test_jit_err_mod_by_zero_reg() {
 //     ];
 //     let mut vm = rbpf::EbpfVmNoData::new(&prog);
 //     vm.jit_compile();
-//     vm.prog_exec_jit();
+//     unsafe { vm.prog_exec_jit(); }
 // }
 
 #[test]
@@ -533,7 +533,7 @@ fn test_jit_exit() {
     ];
     let mut vm = rbpf::EbpfVmNoData::new(&prog);
     vm.jit_compile();
-    assert_eq!(vm.prog_exec_jit(), 0x0);
+    unsafe { assert_eq!(vm.prog_exec_jit(), 0x0); }
 }
 
 #[test]
@@ -546,7 +546,7 @@ fn test_jit_ja() {
     ];
     let mut vm = rbpf::EbpfVmNoData::new(&prog);
     vm.jit_compile();
-    assert_eq!(vm.prog_exec_jit(), 0x1);
+    unsafe { assert_eq!(vm.prog_exec_jit(), 0x1); }
 }
 
 #[test]
@@ -563,7 +563,7 @@ fn test_jit_jeq_imm() {
     ];
     let mut vm = rbpf::EbpfVmNoData::new(&prog);
     vm.jit_compile();
-    assert_eq!(vm.prog_exec_jit(), 0x1);
+    unsafe { assert_eq!(vm.prog_exec_jit(), 0x1); }
 }
 
 #[test]
@@ -581,7 +581,7 @@ fn test_jit_jeq_reg() {
     ];
     let mut vm = rbpf::EbpfVmNoData::new(&prog);
     vm.jit_compile();
-    assert_eq!(vm.prog_exec_jit(), 0x1);
+    unsafe { assert_eq!(vm.prog_exec_jit(), 0x1); }
 }
 
 #[test]
@@ -598,7 +598,7 @@ fn test_jit_jge_imm() {
     ];
     let mut vm = rbpf::EbpfVmNoData::new(&prog);
     vm.jit_compile();
-    assert_eq!(vm.prog_exec_jit(), 0x1);
+    unsafe { assert_eq!(vm.prog_exec_jit(), 0x1); }
 }
 
 #[test]
@@ -615,7 +615,7 @@ fn test_jit_jgt_imm() {
     ];
     let mut vm = rbpf::EbpfVmNoData::new(&prog);
     vm.jit_compile();
-    assert_eq!(vm.prog_exec_jit(), 0x1);
+    unsafe { assert_eq!(vm.prog_exec_jit(), 0x1); }
 }
 
 #[test]
@@ -634,7 +634,7 @@ fn test_jit_jgt_reg() {
     ];
     let mut vm = rbpf::EbpfVmNoData::new(&prog);
     vm.jit_compile();
-    assert_eq!(vm.prog_exec_jit(), 0x1);
+    unsafe { assert_eq!(vm.prog_exec_jit(), 0x1); }
 }
 
 #[test]
@@ -650,7 +650,7 @@ fn test_jit_jit_bounce() {
     ];
     let mut vm = rbpf::EbpfVmNoData::new(&prog);
     vm.jit_compile();
-    assert_eq!(vm.prog_exec_jit(), 0x1);
+    unsafe { assert_eq!(vm.prog_exec_jit(), 0x1); }
 }
 
 #[test]
@@ -668,7 +668,7 @@ fn test_jit_jne_reg() {
     ];
     let mut vm = rbpf::EbpfVmNoData::new(&prog);
     vm.jit_compile();
-    assert_eq!(vm.prog_exec_jit(), 0x1);
+    unsafe { assert_eq!(vm.prog_exec_jit(), 0x1); }
 }
 
 #[test]
@@ -685,7 +685,7 @@ fn test_jit_jset_imm() {
     ];
     let mut vm = rbpf::EbpfVmNoData::new(&prog);
     vm.jit_compile();
-    assert_eq!(vm.prog_exec_jit(), 0x1);
+    unsafe { assert_eq!(vm.prog_exec_jit(), 0x1); }
 }
 
 #[test]
@@ -703,7 +703,7 @@ fn test_jit_jset_reg() {
     ];
     let mut vm = rbpf::EbpfVmNoData::new(&prog);
     vm.jit_compile();
-    assert_eq!(vm.prog_exec_jit(), 0x1);
+    unsafe { assert_eq!(vm.prog_exec_jit(), 0x1); }
 }
 
 #[test]
@@ -721,7 +721,7 @@ fn test_jit_jsge_imm() {
     ];
     let mut vm = rbpf::EbpfVmNoData::new(&prog);
     vm.jit_compile();
-    assert_eq!(vm.prog_exec_jit(), 0x1);
+    unsafe { assert_eq!(vm.prog_exec_jit(), 0x1); }
 }
 
 #[test]
@@ -741,7 +741,7 @@ fn test_jit_jsge_reg() {
     ];
     let mut vm = rbpf::EbpfVmNoData::new(&prog);
     vm.jit_compile();
-    assert_eq!(vm.prog_exec_jit(), 0x1);
+    unsafe { assert_eq!(vm.prog_exec_jit(), 0x1); }
 }
 
 #[test]
@@ -758,7 +758,7 @@ fn test_jit_jsgt_imm() {
     ];
     let mut vm = rbpf::EbpfVmNoData::new(&prog);
     vm.jit_compile();
-    assert_eq!(vm.prog_exec_jit(), 0x1);
+    unsafe { assert_eq!(vm.prog_exec_jit(), 0x1); }
 }
 
 #[test]
@@ -776,7 +776,7 @@ fn test_jit_jsgt_reg() {
     ];
     let mut vm = rbpf::EbpfVmNoData::new(&prog);
     vm.jit_compile();
-    assert_eq!(vm.prog_exec_jit(), 0x1);
+    unsafe { assert_eq!(vm.prog_exec_jit(), 0x1); }
 }
 
 #[test]
@@ -788,7 +788,7 @@ fn test_jit_lddw() {
     ];
     let mut vm = rbpf::EbpfVmNoData::new(&prog);
     vm.jit_compile();
-    assert_eq!(vm.prog_exec_jit(), 0x1122334455667788);
+    unsafe { assert_eq!(vm.prog_exec_jit(), 0x1122334455667788); }
 }
 
 #[test]
@@ -800,7 +800,7 @@ fn test_jit_lddw2() {
     ];
     let mut vm = rbpf::EbpfVmNoData::new(&prog);
     vm.jit_compile();
-    assert_eq!(vm.prog_exec_jit(), 0x80000000);
+    unsafe { assert_eq!(vm.prog_exec_jit(), 0x80000000); }
 }
 
 #[test]
@@ -844,7 +844,7 @@ fn test_jit_ldxb_all() {
     ];
     let mut vm = rbpf::EbpfVmRaw::new(&prog);
     vm.jit_compile();
-    assert_eq!(vm.prog_exec_jit(&mut mem), 0x9876543210);
+    unsafe { assert_eq!(vm.prog_exec_jit(&mut mem), 0x9876543210); }
 }
 
 #[test]
@@ -858,7 +858,7 @@ fn test_jit_ldxb() {
     ];
     let mut vm = rbpf::EbpfVmRaw::new(&prog);
     vm.jit_compile();
-    assert_eq!(vm.prog_exec_jit(&mut mem), 0x11);
+    unsafe { assert_eq!(vm.prog_exec_jit(&mut mem), 0x11); }
 }
 
 #[test]
@@ -873,7 +873,7 @@ fn test_jit_ldxdw() {
     ];
     let mut vm = rbpf::EbpfVmRaw::new(&prog);
     vm.jit_compile();
-    assert_eq!(vm.prog_exec_jit(&mut mem), 0x8877665544332211);
+    unsafe { assert_eq!(vm.prog_exec_jit(&mut mem), 0x8877665544332211); }
 }
 
 #[test]
@@ -928,7 +928,7 @@ fn test_jit_ldxh_all() {
     ];
     let mut vm = rbpf::EbpfVmRaw::new(&prog);
     vm.jit_compile();
-    assert_eq!(vm.prog_exec_jit(&mut mem), 0x9876543210);
+    unsafe { assert_eq!(vm.prog_exec_jit(&mut mem), 0x9876543210); }
 }
 
 #[test]
@@ -973,7 +973,7 @@ fn test_jit_ldxh_all2() {
     ];
     let mut vm = rbpf::EbpfVmRaw::new(&prog);
     vm.jit_compile();
-    assert_eq!(vm.prog_exec_jit(&mut mem), 0x3ff);
+    unsafe { assert_eq!(vm.prog_exec_jit(&mut mem), 0x3ff); }
 }
 
 #[test]
@@ -987,7 +987,7 @@ fn test_jit_ldxh() {
     ];
     let mut vm = rbpf::EbpfVmRaw::new(&prog);
     vm.jit_compile();
-    assert_eq!(vm.prog_exec_jit(&mut mem), 0x2211);
+    unsafe { assert_eq!(vm.prog_exec_jit(&mut mem), 0x2211); }
 }
 
 #[test]
@@ -1003,7 +1003,7 @@ fn test_jit_ldxh_same_reg() {
     ];
     let mut vm = rbpf::EbpfVmRaw::new(&prog);
     vm.jit_compile();
-    assert_eq!(vm.prog_exec_jit(&mut mem), 0x1234);
+    unsafe { assert_eq!(vm.prog_exec_jit(&mut mem), 0x1234); }
 }
 
 #[test]
@@ -1050,7 +1050,7 @@ fn test_jit_ldxw_all() {
     ];
     let mut vm = rbpf::EbpfVmRaw::new(&prog);
     vm.jit_compile();
-    assert_eq!(vm.prog_exec_jit(&mut mem), 0x030f0f);
+    unsafe { assert_eq!(vm.prog_exec_jit(&mut mem), 0x030f0f); }
 }
 
 #[test]
@@ -1064,7 +1064,7 @@ fn test_jit_ldxw() {
     ];
     let mut vm = rbpf::EbpfVmRaw::new(&prog);
     vm.jit_compile();
-    assert_eq!(vm.prog_exec_jit(&mut mem), 0x44332211);
+    unsafe { assert_eq!(vm.prog_exec_jit(&mut mem), 0x44332211); }
 }
 
 #[test]
@@ -1079,7 +1079,7 @@ fn test_jit_le16() {
     ];
     let mut vm = rbpf::EbpfVmRaw::new(&prog);
     vm.jit_compile();
-    assert_eq!(vm.prog_exec_jit(&mut mem), 0x1122);
+    unsafe { assert_eq!(vm.prog_exec_jit(&mut mem), 0x1122); }
 }
 
 #[test]
@@ -1094,7 +1094,7 @@ fn test_jit_le32() {
     ];
     let mut vm = rbpf::EbpfVmRaw::new(&prog);
     vm.jit_compile();
-    assert_eq!(vm.prog_exec_jit(&mut mem), 0x11223344);
+    unsafe { assert_eq!(vm.prog_exec_jit(&mut mem), 0x11223344); }
 }
 
 #[test]
@@ -1109,7 +1109,7 @@ fn test_jit_le64() {
     ];
     let mut vm = rbpf::EbpfVmRaw::new(&prog);
     vm.jit_compile();
-    assert_eq!(vm.prog_exec_jit(&mut mem), 0x1122334455667788);
+    unsafe { assert_eq!(vm.prog_exec_jit(&mut mem), 0x1122334455667788); }
 }
 
 #[test]
@@ -1122,7 +1122,7 @@ fn test_jit_lsh_reg() {
     ];
     let mut vm = rbpf::EbpfVmNoData::new(&prog);
     vm.jit_compile();
-    assert_eq!(vm.prog_exec_jit(), 0x10);
+    unsafe { assert_eq!(vm.prog_exec_jit(), 0x10); }
 }
 
 #[test]
@@ -1136,7 +1136,7 @@ fn test_jit_mod() {
     ];
     let mut vm = rbpf::EbpfVmNoData::new(&prog);
     vm.jit_compile();
-    assert_eq!(vm.prog_exec_jit(), 0x5);
+    unsafe { assert_eq!(vm.prog_exec_jit(), 0x5); }
 }
 
 #[test]
@@ -1149,7 +1149,7 @@ fn test_jit_mod32() {
     ];
     let mut vm = rbpf::EbpfVmNoData::new(&prog);
     vm.jit_compile();
-    assert_eq!(vm.prog_exec_jit(), 0x0);
+    unsafe { assert_eq!(vm.prog_exec_jit(), 0x0); }
 }
 
 #[test]
@@ -1167,7 +1167,7 @@ fn test_jit_mod64() {
     ];
     let mut vm = rbpf::EbpfVmNoData::new(&prog);
     vm.jit_compile();
-    assert_eq!(vm.prog_exec_jit(), 0x30ba5a04);
+    unsafe { assert_eq!(vm.prog_exec_jit(), 0x30ba5a04); }
 }
 
 #[test]
@@ -1179,7 +1179,7 @@ fn test_jit_mov() {
     ];
     let mut vm = rbpf::EbpfVmNoData::new(&prog);
     vm.jit_compile();
-    assert_eq!(vm.prog_exec_jit(), 0x1);
+    unsafe { assert_eq!(vm.prog_exec_jit(), 0x1); }
 }
 
 #[test]
@@ -1191,7 +1191,7 @@ fn test_jit_mul32_imm() {
     ];
     let mut vm = rbpf::EbpfVmNoData::new(&prog);
     vm.jit_compile();
-    assert_eq!(vm.prog_exec_jit(), 0xc);
+    unsafe { assert_eq!(vm.prog_exec_jit(), 0xc); }
 }
 
 #[test]
@@ -1204,7 +1204,7 @@ fn test_jit_mul32_reg() {
     ];
     let mut vm = rbpf::EbpfVmNoData::new(&prog);
     vm.jit_compile();
-    assert_eq!(vm.prog_exec_jit(), 0xc);
+    unsafe { assert_eq!(vm.prog_exec_jit(), 0xc); }
 }
 
 #[test]
@@ -1217,7 +1217,7 @@ fn test_jit_mul32_reg_overflow() {
     ];
     let mut vm = rbpf::EbpfVmNoData::new(&prog);
     vm.jit_compile();
-    assert_eq!(vm.prog_exec_jit(), 0x4);
+    unsafe { assert_eq!(vm.prog_exec_jit(), 0x4); }
 }
 
 #[test]
@@ -1229,7 +1229,7 @@ fn test_jit_mul64_imm() {
     ];
     let mut vm = rbpf::EbpfVmNoData::new(&prog);
     vm.jit_compile();
-    assert_eq!(vm.prog_exec_jit(), 0x100000004);
+    unsafe { assert_eq!(vm.prog_exec_jit(), 0x100000004); }
 }
 
 #[test]
@@ -1242,7 +1242,7 @@ fn test_jit_mul64_reg() {
     ];
     let mut vm = rbpf::EbpfVmNoData::new(&prog);
     vm.jit_compile();
-    assert_eq!(vm.prog_exec_jit(), 0x100000004);
+    unsafe { assert_eq!(vm.prog_exec_jit(), 0x100000004); }
 }
 
 #[test]
@@ -1261,7 +1261,7 @@ fn test_jit_mul_loop() {
     ];
     let mut vm = rbpf::EbpfVmNoData::new(&prog);
     vm.jit_compile();
-    assert_eq!(vm.prog_exec_jit(), 0x75db9c97);
+    unsafe { assert_eq!(vm.prog_exec_jit(), 0x75db9c97); }
 }
 
 #[test]
@@ -1273,7 +1273,7 @@ fn test_jit_neg64() {
     ];
     let mut vm = rbpf::EbpfVmNoData::new(&prog);
     vm.jit_compile();
-    assert_eq!(vm.prog_exec_jit(), 0xfffffffffffffffe);
+    unsafe { assert_eq!(vm.prog_exec_jit(), 0xfffffffffffffffe); }
 }
 
 #[test]
@@ -1285,7 +1285,7 @@ fn test_jit_neg() {
     ];
     let mut vm = rbpf::EbpfVmNoData::new(&prog);
     vm.jit_compile();
-    assert_eq!(vm.prog_exec_jit(), 0xfffffffe);
+    unsafe { assert_eq!(vm.prog_exec_jit(), 0xfffffffe); }
 }
 
 #[test]
@@ -1310,7 +1310,7 @@ fn test_jit_prime() {
     ];
     let mut vm = rbpf::EbpfVmNoData::new(&prog);
     vm.jit_compile();
-    assert_eq!(vm.prog_exec_jit(), 0x1);
+    unsafe { assert_eq!(vm.prog_exec_jit(), 0x1); }
 }
 
 #[test]
@@ -1323,7 +1323,7 @@ fn test_jit_rhs32() {
     ];
     let mut vm = rbpf::EbpfVmNoData::new(&prog);
     vm.jit_compile();
-    assert_eq!(vm.prog_exec_jit(), 0x00ffffff);
+    unsafe { assert_eq!(vm.prog_exec_jit(), 0x00ffffff); }
 }
 
 #[test]
@@ -1336,7 +1336,7 @@ fn test_jit_rsh_reg() {
     ];
     let mut vm = rbpf::EbpfVmNoData::new(&prog);
     vm.jit_compile();
-    assert_eq!(vm.prog_exec_jit(), 0x1);
+    unsafe { assert_eq!(vm.prog_exec_jit(), 0x1); }
 }
 
 #[test]
@@ -1354,7 +1354,7 @@ fn test_jit_stack() {
     ];
     let mut vm = rbpf::EbpfVmNoData::new(&prog);
     vm.jit_compile();
-    assert_eq!(vm.prog_exec_jit(), 0xcd);
+    unsafe { assert_eq!(vm.prog_exec_jit(), 0xcd); }
 }
 
 #[test]
@@ -1381,7 +1381,7 @@ fn test_jit_stack2() {
     vm.register_helper(0, helpers::gather_bytes);
     vm.register_helper(1, helpers::memfrob);
     vm.jit_compile();
-    assert_eq!(vm.prog_exec_jit(), 0x01020304);
+    unsafe { assert_eq!(vm.prog_exec_jit(), 0x01020304); }
 }
 
 #[test]
@@ -1396,7 +1396,7 @@ fn test_jit_stb() {
     ];
     let mut vm = rbpf::EbpfVmRaw::new(&prog);
     vm.jit_compile();
-    assert_eq!(vm.prog_exec_jit(&mut mem), 0x11);
+    unsafe { assert_eq!(vm.prog_exec_jit(&mut mem), 0x11); }
 }
 
 #[test]
@@ -1412,7 +1412,7 @@ fn test_jit_stdw() {
     ];
     let mut vm = rbpf::EbpfVmRaw::new(&prog);
     vm.jit_compile();
-    assert_eq!(vm.prog_exec_jit(&mut mem), 0x44332211);
+    unsafe { assert_eq!(vm.prog_exec_jit(&mut mem), 0x44332211); }
 }
 
 #[test]
@@ -1427,7 +1427,7 @@ fn test_jit_sth() {
     ];
     let mut vm = rbpf::EbpfVmRaw::new(&prog);
     vm.jit_compile();
-    assert_eq!(vm.prog_exec_jit(&mut mem), 0x2211);
+    unsafe { assert_eq!(vm.prog_exec_jit(&mut mem), 0x2211); }
 }
 
 #[test]
@@ -1465,7 +1465,7 @@ fn test_jit_string_stack() {
     let mut vm = rbpf::EbpfVmNoData::new(&prog);
     vm.register_helper(4, helpers::strcmp);
     vm.jit_compile();
-    assert_eq!(vm.prog_exec_jit(), 0x0);
+    unsafe { assert_eq!(vm.prog_exec_jit(), 0x0); }
 }
 
 #[test]
@@ -1480,7 +1480,7 @@ fn test_jit_stw() {
     ];
     let mut vm = rbpf::EbpfVmRaw::new(&prog);
     vm.jit_compile();
-    assert_eq!(vm.prog_exec_jit(&mut mem), 0x44332211);
+    unsafe { assert_eq!(vm.prog_exec_jit(&mut mem), 0x44332211); }
 }
 
 #[test]
@@ -1496,7 +1496,7 @@ fn test_jit_stxb() {
     ];
     let mut vm = rbpf::EbpfVmRaw::new(&prog);
     vm.jit_compile();
-    assert_eq!(vm.prog_exec_jit(&mut mem), 0x11);
+    unsafe { assert_eq!(vm.prog_exec_jit(&mut mem), 0x11); }
 }
 
 #[test]
@@ -1527,7 +1527,7 @@ fn test_jit_stxb_all() {
     ];
     let mut vm = rbpf::EbpfVmRaw::new(&prog);
     vm.jit_compile();
-    assert_eq!(vm.prog_exec_jit(&mut mem), 0xf0f2f3f4f5f6f7f8);
+    unsafe { assert_eq!(vm.prog_exec_jit(&mut mem), 0xf0f2f3f4f5f6f7f8); }
 }
 
 #[test]
@@ -1547,7 +1547,7 @@ fn test_jit_stxb_all2() {
     ];
     let mut vm = rbpf::EbpfVmRaw::new(&prog);
     vm.jit_compile();
-    assert_eq!(vm.prog_exec_jit(&mut mem), 0xf1f9);
+    unsafe { assert_eq!(vm.prog_exec_jit(&mut mem), 0xf1f9); }
 }
 
 #[test]
@@ -1581,7 +1581,7 @@ fn test_jit_stxb_chain() {
     ];
     let mut vm = rbpf::EbpfVmRaw::new(&prog);
     vm.jit_compile();
-    assert_eq!(vm.prog_exec_jit(&mut mem), 0x2a);
+    unsafe { assert_eq!(vm.prog_exec_jit(&mut mem), 0x2a); }
 }
 
 #[test]
@@ -1600,7 +1600,7 @@ fn test_jit_stxdw() {
     ];
     let mut vm = rbpf::EbpfVmRaw::new(&prog);
     vm.jit_compile();
-    assert_eq!(vm.prog_exec_jit(&mut mem), 0x8877665544332211);
+    unsafe { assert_eq!(vm.prog_exec_jit(&mut mem), 0x8877665544332211); }
 }
 
 #[test]
@@ -1616,7 +1616,7 @@ fn test_jit_stxh() {
     ];
     let mut vm = rbpf::EbpfVmRaw::new(&prog);
     vm.jit_compile();
-    assert_eq!(vm.prog_exec_jit(&mut mem), 0x2211);
+    unsafe { assert_eq!(vm.prog_exec_jit(&mut mem), 0x2211); }
 }
 
 #[test]
@@ -1632,7 +1632,7 @@ fn test_jit_stxw() {
     ];
     let mut vm = rbpf::EbpfVmRaw::new(&prog);
     vm.jit_compile();
-    assert_eq!(vm.prog_exec_jit(&mut mem), 0x44332211);
+    unsafe { assert_eq!(vm.prog_exec_jit(&mut mem), 0x44332211); }
 }
 
 #[test]
@@ -1667,7 +1667,7 @@ fn test_jit_subnet() {
     ];
     let mut vm = rbpf::EbpfVmRaw::new(&prog);
     vm.jit_compile();
-    assert_eq!(vm.prog_exec_jit(&mut mem), 0x1);
+    unsafe { assert_eq!(vm.prog_exec_jit(&mut mem), 0x1); }
 }
 
 
@@ -1713,7 +1713,7 @@ fn test_jit_tcp_port80_match() {
     let prog = &PROG_TCP_PORT_80.to_vec();
     let mut vm = rbpf::EbpfVmRaw::new(prog);
     vm.jit_compile();
-    assert_eq!(vm.prog_exec_jit(&mut mem), 0x1);
+    unsafe { assert_eq!(vm.prog_exec_jit(&mut mem), 0x1); }
 }
 
 #[test]
@@ -1736,7 +1736,7 @@ fn test_jit_tcp_port80_nomatch() {
     let prog = &PROG_TCP_PORT_80.to_vec();
     let mut vm = rbpf::EbpfVmRaw::new(prog);
     vm.jit_compile();
-    assert_eq!(vm.prog_exec_jit(&mut mem), 0x0);
+    unsafe { assert_eq!(vm.prog_exec_jit(&mut mem), 0x0); }
 }
 
 #[test]
@@ -1759,7 +1759,7 @@ fn test_jit_tcp_port80_nomatch_ethertype() {
     let prog = &PROG_TCP_PORT_80.to_vec();
     let mut vm = rbpf::EbpfVmRaw::new(prog);
     vm.jit_compile();
-    assert_eq!(vm.prog_exec_jit(&mut mem), 0x0);
+    unsafe { assert_eq!(vm.prog_exec_jit(&mut mem), 0x0); }
 }
 
 #[test]
@@ -1782,7 +1782,7 @@ fn test_jit_tcp_port80_nomatch_proto() {
     let prog = &PROG_TCP_PORT_80.to_vec();
     let mut vm = rbpf::EbpfVmRaw::new(prog);
     vm.jit_compile();
-    assert_eq!(vm.prog_exec_jit(&mut mem), 0x0);
+    unsafe { assert_eq!(vm.prog_exec_jit(&mut mem), 0x0); }
 }
 
 const PROG_TCP_SACK: [u8;352] = [
@@ -1849,7 +1849,7 @@ fn test_jit_tcp_sack_match() {
     let prog = &PROG_TCP_SACK.to_vec();
     let mut vm = rbpf::EbpfVmRaw::new(prog);
     vm.jit_compile();
-    assert_eq!(vm.prog_exec_jit(&mut mem), 0x1);
+    unsafe { assert_eq!(vm.prog_exec_jit(&mut mem), 0x1); }
 }
 
 #[test]
@@ -1868,5 +1868,5 @@ fn test_jit_tcp_sack_nomatch() {
     let prog = &PROG_TCP_SACK.to_vec();
     let mut vm = rbpf::EbpfVmRaw::new(prog);
     vm.jit_compile();
-    assert_eq!(vm.prog_exec_jit(&mut mem), 0x0);
+    unsafe { assert_eq!(vm.prog_exec_jit(&mut mem), 0x0); }
 }