|
@@ -8,6 +8,8 @@ mod common;
|
|
|
|
|
|
use rbpf::{assembler::assemble, helpers};
|
|
use rbpf::{assembler::assemble, helpers};
|
|
|
|
|
|
|
|
+use crate::common::{TCP_SACK_ASM, TCP_SACK_MATCH, TCP_SACK_NOMATCH};
|
|
|
|
+
|
|
macro_rules! test_cranelift {
|
|
macro_rules! test_cranelift {
|
|
($name:ident, $prog:expr, $expected:expr) => {
|
|
($name:ident, $prog:expr, $expected:expr) => {
|
|
#[test]
|
|
#[test]
|
|
@@ -446,6 +448,18 @@ test_cranelift!(
|
|
0x1
|
|
0x1
|
|
);
|
|
);
|
|
|
|
|
|
|
|
+#[test]
|
|
|
|
+// #[should_panic(expected = "Error: out of bounds memory store (insn #1)")]
|
|
|
|
+#[ignore = "We have stack OOB checks, but we don't yet catch the trap code and convert it into a panic"]
|
|
|
|
+fn test_cranelift_err_stack_out_of_bound() {
|
|
|
|
+ let prog = [
|
|
|
|
+ 0x72, 0x0a, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x95, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
|
|
|
|
+ 0x00,
|
|
|
|
+ ];
|
|
|
|
+ let vm = rbpf::EbpfVmNoData::new(Some(&prog)).unwrap();
|
|
|
|
+ vm.execute_cranelift().unwrap();
|
|
|
|
+}
|
|
|
|
+
|
|
test_cranelift!(
|
|
test_cranelift!(
|
|
test_cranelift_exit,
|
|
test_cranelift_exit,
|
|
"
|
|
"
|
|
@@ -846,6 +860,48 @@ test_cranelift!(
|
|
0x100000004
|
|
0x100000004
|
|
);
|
|
);
|
|
|
|
|
|
|
|
+test_cranelift!(
|
|
|
|
+ test_cranelift_neg64,
|
|
|
|
+ "
|
|
|
|
+ mov32 r0, 2
|
|
|
|
+ neg r0
|
|
|
|
+ exit
|
|
|
|
+ ",
|
|
|
|
+ 0xfffffffffffffffe
|
|
|
|
+);
|
|
|
|
+
|
|
|
|
+test_cranelift!(
|
|
|
|
+ test_cranelift_neg,
|
|
|
|
+ "
|
|
|
|
+ mov32 r0, 2
|
|
|
|
+ neg32 r0
|
|
|
|
+ exit
|
|
|
|
+ ",
|
|
|
|
+ 0xfffffffe
|
|
|
|
+);
|
|
|
|
+
|
|
|
|
+test_cranelift!(
|
|
|
|
+ test_cranelift_rhs32,
|
|
|
|
+ "
|
|
|
|
+ xor r0, r0
|
|
|
|
+ sub r0, 1
|
|
|
|
+ rsh32 r0, 8
|
|
|
|
+ exit
|
|
|
|
+ ",
|
|
|
|
+ 0x00ffffff
|
|
|
|
+);
|
|
|
|
+
|
|
|
|
+test_cranelift!(
|
|
|
|
+ test_cranelift_rsh_reg,
|
|
|
|
+ "
|
|
|
|
+ mov r0, 0x10
|
|
|
|
+ mov r7, 4
|
|
|
|
+ rsh r0, r7
|
|
|
|
+ exit
|
|
|
|
+ ",
|
|
|
|
+ 0x1
|
|
|
|
+);
|
|
|
|
+
|
|
test_cranelift!(
|
|
test_cranelift!(
|
|
test_cranelift_stack,
|
|
test_cranelift_stack,
|
|
"
|
|
"
|
|
@@ -924,6 +980,47 @@ test_cranelift!(
|
|
0x2211
|
|
0x2211
|
|
);
|
|
);
|
|
|
|
|
|
|
|
+#[test]
|
|
|
|
+#[ignore]
|
|
|
|
+fn test_cranelift_string_stack() {
|
|
|
|
+ let prog = assemble(
|
|
|
|
+ "
|
|
|
|
+ mov r1, 0x78636261
|
|
|
|
+ stxw [r10-8], r1
|
|
|
|
+ mov r6, 0x0
|
|
|
|
+ stxb [r10-4], r6
|
|
|
|
+ stxb [r10-12], r6
|
|
|
|
+ mov r1, 0x79636261
|
|
|
|
+ stxw [r10-16], r1
|
|
|
|
+ mov r1, r10
|
|
|
|
+ add r1, -8
|
|
|
|
+ mov r2, r1
|
|
|
|
+ call 0x4
|
|
|
|
+ mov r1, r0
|
|
|
|
+ mov r0, 0x1
|
|
|
|
+ lsh r1, 0x20
|
|
|
|
+ rsh r1, 0x20
|
|
|
|
+ jne r1, 0x0, +11
|
|
|
|
+ mov r1, r10
|
|
|
|
+ add r1, -8
|
|
|
|
+ mov r2, r10
|
|
|
|
+ add r2, -16
|
|
|
|
+ call 0x4
|
|
|
|
+ mov r1, r0
|
|
|
|
+ lsh r1, 0x20
|
|
|
|
+ rsh r1, 0x20
|
|
|
|
+ mov r0, 0x1
|
|
|
|
+ jeq r1, r6, +1
|
|
|
|
+ mov r0, 0x0
|
|
|
|
+ exit",
|
|
|
|
+ )
|
|
|
|
+ .unwrap();
|
|
|
|
+
|
|
|
|
+ let mut vm = rbpf::EbpfVmNoData::new(Some(&prog)).unwrap();
|
|
|
|
+ vm.register_helper(4, helpers::strcmp).unwrap();
|
|
|
|
+ assert_eq!(vm.execute_cranelift().unwrap(), 0x0);
|
|
|
|
+}
|
|
|
|
+
|
|
test_cranelift!(
|
|
test_cranelift!(
|
|
test_cranelift_stw,
|
|
test_cranelift_stw,
|
|
"
|
|
"
|
|
@@ -1056,3 +1153,102 @@ test_cranelift!(
|
|
[0xaa, 0xbb, 0xff, 0xff, 0xff, 0xff, 0xcc, 0xdd],
|
|
[0xaa, 0xbb, 0xff, 0xff, 0xff, 0xff, 0xcc, 0xdd],
|
|
0x44332211
|
|
0x44332211
|
|
);
|
|
);
|
|
|
|
+
|
|
|
|
+const PROG_TCP_PORT_80: [u8; 152] = [
|
|
|
|
+ 0x71, 0x12, 0x0c, 0x00, 0x00, 0x00, 0x00, 0x00, 0x71, 0x13, 0x0d, 0x00, 0x00, 0x00, 0x00, 0x00,
|
|
|
|
+ 0x67, 0x03, 0x00, 0x00, 0x08, 0x00, 0x00, 0x00, 0x4f, 0x23, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
|
|
|
|
+ 0xb7, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x55, 0x03, 0x0c, 0x00, 0x08, 0x00, 0x00, 0x00,
|
|
|
|
+ 0x71, 0x12, 0x17, 0x00, 0x00, 0x00, 0x00, 0x00, 0x55, 0x02, 0x0a, 0x00, 0x06, 0x00, 0x00, 0x00,
|
|
|
|
+ 0x71, 0x12, 0x0e, 0x00, 0x00, 0x00, 0x00, 0x00, 0x07, 0x01, 0x00, 0x00, 0x0e, 0x00, 0x00, 0x00,
|
|
|
|
+ 0x57, 0x02, 0x00, 0x00, 0x0f, 0x00, 0x00, 0x00, 0x67, 0x02, 0x00, 0x00, 0x02, 0x00, 0x00, 0x00,
|
|
|
|
+ 0x0f, 0x21, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x69, 0x12, 0x02, 0x00, 0x00, 0x00, 0x00, 0x00,
|
|
|
|
+ 0x15, 0x02, 0x02, 0x00, 0x00, 0x50, 0x00, 0x00, 0x69, 0x11, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
|
|
|
|
+ 0x55, 0x01, 0x01, 0x00, 0x00, 0x50, 0x00, 0x00, 0xb7, 0x00, 0x00, 0x00, 0x01, 0x00, 0x00, 0x00,
|
|
|
|
+ 0x95, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
|
|
|
|
+];
|
|
|
|
+
|
|
|
|
+#[test]
|
|
|
|
+#[ignore]
|
|
|
|
+fn test_cranelift_tcp_port80_match() {
|
|
|
|
+ let mem = &mut [
|
|
|
|
+ 0x00, 0x01, 0x02, 0x03, 0x04, 0x05, 0x00, 0x06, 0x07, 0x08, 0x09, 0x0a, 0x08, 0x00, 0x45,
|
|
|
|
+ 0x00, 0x00, 0x56, 0x00, 0x01, 0x00, 0x00, 0x40, 0x06, 0xf9, 0x4d, 0xc0, 0xa8, 0x00, 0x01,
|
|
|
|
+ 0xc0, 0xa8, 0x00, 0x02, 0x27, 0x10, 0x00, 0x50, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
|
|
|
|
+ 0x00, 0x50, 0x02, 0x20, 0x00, 0xc5, 0x18, 0x00, 0x00, 0x44, 0x44, 0x44, 0x44, 0x44, 0x44,
|
|
|
|
+ 0x44, 0x44, 0x44, 0x44, 0x44, 0x44, 0x44, 0x44, 0x44, 0x44, 0x44, 0x44, 0x44, 0x44, 0x44,
|
|
|
|
+ 0x44, 0x44, 0x44, 0x44, 0x44, 0x44, 0x44, 0x44, 0x44, 0x44, 0x44, 0x44, 0x44, 0x44, 0x44,
|
|
|
|
+ 0x44, 0x44, 0x44, 0x44, 0x44, 0x44, 0x44, 0x44, 0x44, 0x44,
|
|
|
|
+ ];
|
|
|
|
+ let prog = &PROG_TCP_PORT_80;
|
|
|
|
+ let vm = rbpf::EbpfVmRaw::new(Some(prog)).unwrap();
|
|
|
|
+ assert_eq!(vm.execute_cranelift(mem).unwrap(), 0x1);
|
|
|
|
+}
|
|
|
|
+
|
|
|
|
+#[test]
|
|
|
|
+#[ignore]
|
|
|
|
+fn test_cranelift_tcp_port80_nomatch() {
|
|
|
|
+ let mem = &mut [
|
|
|
|
+ 0x00, 0x01, 0x02, 0x03, 0x04, 0x05, 0x00, 0x06, 0x07, 0x08, 0x09, 0x0a, 0x08, 0x00, 0x45,
|
|
|
|
+ 0x00, 0x00, 0x56, 0x00, 0x01, 0x00, 0x00, 0x40, 0x06, 0xf9, 0x4d, 0xc0, 0xa8, 0x00, 0x01,
|
|
|
|
+ 0xc0, 0xa8, 0x00, 0x02, 0x00, 0x16, 0x27, 0x10, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
|
|
|
|
+ 0x00, 0x51, 0x02, 0x20, 0x00, 0xc5, 0x18, 0x00, 0x00, 0x44, 0x44, 0x44, 0x44, 0x44, 0x44,
|
|
|
|
+ 0x44, 0x44, 0x44, 0x44, 0x44, 0x44, 0x44, 0x44, 0x44, 0x44, 0x44, 0x44, 0x44, 0x44, 0x44,
|
|
|
|
+ 0x44, 0x44, 0x44, 0x44, 0x44, 0x44, 0x44, 0x44, 0x44, 0x44, 0x44, 0x44, 0x44, 0x44, 0x44,
|
|
|
|
+ 0x44, 0x44, 0x44, 0x44, 0x44, 0x44, 0x44, 0x44, 0x44, 0x44,
|
|
|
|
+ ];
|
|
|
|
+ let prog = &PROG_TCP_PORT_80;
|
|
|
|
+ let vm = rbpf::EbpfVmRaw::new(Some(prog)).unwrap();
|
|
|
|
+ assert_eq!(vm.execute_cranelift(mem).unwrap(), 0x0);
|
|
|
|
+}
|
|
|
|
+
|
|
|
|
+#[test]
|
|
|
|
+#[ignore]
|
|
|
|
+fn test_cranelift_tcp_port80_nomatch_ethertype() {
|
|
|
|
+ let mem = &mut [
|
|
|
|
+ 0x00, 0x01, 0x02, 0x03, 0x04, 0x05, 0x00, 0x06, 0x07, 0x08, 0x09, 0x0a, 0x08, 0x01, 0x45,
|
|
|
|
+ 0x00, 0x00, 0x56, 0x00, 0x01, 0x00, 0x00, 0x40, 0x06, 0xf9, 0x4d, 0xc0, 0xa8, 0x00, 0x01,
|
|
|
|
+ 0xc0, 0xa8, 0x00, 0x02, 0x27, 0x10, 0x00, 0x50, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
|
|
|
|
+ 0x00, 0x50, 0x02, 0x20, 0x00, 0xc5, 0x18, 0x00, 0x00, 0x44, 0x44, 0x44, 0x44, 0x44, 0x44,
|
|
|
|
+ 0x44, 0x44, 0x44, 0x44, 0x44, 0x44, 0x44, 0x44, 0x44, 0x44, 0x44, 0x44, 0x44, 0x44, 0x44,
|
|
|
|
+ 0x44, 0x44, 0x44, 0x44, 0x44, 0x44, 0x44, 0x44, 0x44, 0x44, 0x44, 0x44, 0x44, 0x44, 0x44,
|
|
|
|
+ 0x44, 0x44, 0x44, 0x44, 0x44, 0x44, 0x44, 0x44, 0x44, 0x44,
|
|
|
|
+ ];
|
|
|
|
+ let prog = &PROG_TCP_PORT_80;
|
|
|
|
+ let vm = rbpf::EbpfVmRaw::new(Some(prog)).unwrap();
|
|
|
|
+ assert_eq!(vm.execute_cranelift(mem).unwrap(), 0x0);
|
|
|
|
+}
|
|
|
|
+
|
|
|
|
+#[test]
|
|
|
|
+#[ignore]
|
|
|
|
+fn test_cranelift_tcp_port80_nomatch_proto() {
|
|
|
|
+ let mem = &mut [
|
|
|
|
+ 0x00, 0x01, 0x02, 0x03, 0x04, 0x05, 0x00, 0x06, 0x07, 0x08, 0x09, 0x0a, 0x08, 0x00, 0x45,
|
|
|
|
+ 0x00, 0x00, 0x56, 0x00, 0x01, 0x00, 0x00, 0x40, 0x11, 0xf9, 0x4d, 0xc0, 0xa8, 0x00, 0x01,
|
|
|
|
+ 0xc0, 0xa8, 0x00, 0x02, 0x27, 0x10, 0x00, 0x50, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
|
|
|
|
+ 0x00, 0x50, 0x02, 0x20, 0x00, 0xc5, 0x18, 0x00, 0x00, 0x44, 0x44, 0x44, 0x44, 0x44, 0x44,
|
|
|
|
+ 0x44, 0x44, 0x44, 0x44, 0x44, 0x44, 0x44, 0x44, 0x44, 0x44, 0x44, 0x44, 0x44, 0x44, 0x44,
|
|
|
|
+ 0x44, 0x44, 0x44, 0x44, 0x44, 0x44, 0x44, 0x44, 0x44, 0x44, 0x44, 0x44, 0x44, 0x44, 0x44,
|
|
|
|
+ 0x44, 0x44, 0x44, 0x44, 0x44, 0x44, 0x44, 0x44, 0x44, 0x44,
|
|
|
|
+ ];
|
|
|
|
+ let prog = &PROG_TCP_PORT_80;
|
|
|
|
+ let vm = rbpf::EbpfVmRaw::new(Some(prog)).unwrap();
|
|
|
|
+ assert_eq!(vm.execute_cranelift(mem).unwrap(), 0x0);
|
|
|
|
+}
|
|
|
|
+
|
|
|
|
+#[test]
|
|
|
|
+#[ignore]
|
|
|
|
+fn test_cranelift_tcp_sack_match() {
|
|
|
|
+ let mut mem = TCP_SACK_MATCH.to_vec();
|
|
|
|
+ let prog = assemble(TCP_SACK_ASM).unwrap();
|
|
|
|
+ let vm = rbpf::EbpfVmRaw::new(Some(&prog)).unwrap();
|
|
|
|
+ assert_eq!(vm.execute_cranelift(mem.as_mut_slice()).unwrap(), 0x1);
|
|
|
|
+}
|
|
|
|
+
|
|
|
|
+#[test]
|
|
|
|
+#[ignore]
|
|
|
|
+fn test_cranelift_tcp_sack_nomatch() {
|
|
|
|
+ let mut mem = TCP_SACK_NOMATCH.to_vec();
|
|
|
|
+ let prog = assemble(TCP_SACK_ASM).unwrap();
|
|
|
|
+ let vm = rbpf::EbpfVmRaw::new(Some(&prog)).unwrap();
|
|
|
|
+ assert_eq!(vm.execute_cranelift(mem.as_mut_slice()).unwrap(), 0x0);
|
|
|
|
+}
|