// Copyright © Alex Forster // SPDX-License-Identifier: MIT OR Apache-2.0 #[test] fn test() { let programs = [ [ r#" ldh [12] jne #0x806, drop ret #-1 drop: ret #0 "#, "4,40 0 0 12,21 0 1 2054,6 0 0 4294967295,6 0 0 0", ], [ r#" ldh [12] jne #0x800, drop ldb [23] jneq #6, drop ret #-1 drop: ret #0 "#, "6,40 0 0 12,21 0 3 2048,48 0 0 23,21 0 1 6,6 0 0 4294967295,6 0 0 0", ], [ r#" start: ldh [12] jne #0x800, drop ldb [23] jneq #6, drop ldh [20] jset #0x1fff, drop ldxb 4 * ([14] & 0xf) ldh [x + 14] jeq #0x16, pass ldh [x + 16] jne #0x16, drop pass: ret #-1 drop: ret #0 "#, "13,40 0 0 12,21 0 10 2048,48 0 0 23,21 0 8 6,40 0 0 20,69 6 0 8191,177 0 0 14,72 0 0 14,21 2 0 22,72 0 0 16,21 0 1 22,6 0 0 4294967295,6 0 0 0", ], [ r#" ld [4] /* offsetof(struct seccomp_data, arch) */ jne #0xc000003e, bad /* AUDIT_ARCH_X86_64 */ ld [0] /* offsetof(struct seccomp_data, nr) */ jeq #15, good /* __NR_rt_sigreturn */ jeq #231, good /* __NR_exit_group */ jeq #60, good /* __NR_exit */ jeq #0, good /* __NR_read */ jeq #1, good /* __NR_write */ jeq #5, good /* __NR_fstat */ jeq #9, good /* __NR_mmap */ jeq #14, good /* __NR_rt_sigprocmask */ jeq #13, good /* __NR_rt_sigaction */ jeq #35, good /* __NR_nanosleep */ bad: ret #0 /* SECCOMP_RET_KILL */ good: ret #0x7fff0000 /* SECCOMP_RET_ALLOW */ "#, "15,32 0 0 4,21 0 11 3221225534,32 0 0 0,21 10 0 15,21 9 0 231,21 8 0 60,21 7 0 0,21 6 0 1,21 5 0 5,21 4 0 9,21 3 0 14,21 2 0 13,21 1 0 35,6 0 0 0,6 0 0 2147418112", ], [ r#" ld poff ret a "#, "2,32 0 0 4294963252,22 0 0 0", ], [ r#" ld vlanp jeq #0, drop ret #-1 drop: ret #0 "#, "4,32 0 0 4294963248,21 1 0 0,6 0 0 4294967295,6 0 0 0", ], [ r#" ld #vlanp jeq #0, drop ld vlant jneq #10, drop ret #-1 drop: ret #0 "#, "6,32 0 0 4294963248,21 3 0 0,32 0 0 4294963244,21 0 1 10,6 0 0 4294967295,6 0 0 0", ], [ r#" ldh #proto /* A = skb->protocol */ jneq #0, skip /* check for NETLINK_ROUTE */ ldb [4] /* A = nlmsg_type */ jneq #0x10, skip /* check type == RTNL_NEWLINK */ ldx #16 /* X = offset(ifinfomsg) */ ldb [x + 4] /* offset(ifi_index) */ jneq #0x3, skip /* check ifindex == 3 */ ld #32 /* A = len(nlmsghdr) + len(ifinfomsg), payload offset */ ldx #16 /* X = IFLA_OPERSTATE */ ld #nla /* A = offset(IFLA_OPERSTATE) */ jeq #0, skip tax ld M[1] and x ldb [x + 4] /* A = value(IFLA_OPERSTATE) */ jneq #0x6, skip /* check oper state is UP */ ret #-1 skip: ret #0 "#, "18,40 0 0 4294963200,21 0 15 0,48 0 0 4,21 0 13 16,1 0 0 16,80 0 0 4,21 0 10 3,0 0 0 32,1 0 0 16,32 0 0 4294963212,21 6 0 0,7 0 0 0,96 0 0 1,92 0 0 0,80 0 0 4,21 0 1 6,6 0 0 4294967295,6 0 0 0", ], [ r#" ; icmp random packet sampling, 1 in 4 ldh [12] jne #0x800, drop ldb [23] jneq #1, drop ; get a random uint32 number ld rand mod #4 jneq #1, drop ret #-1 drop: ret #0 "#, "9,40 0 0 12,21 0 6 2048,48 0 0 23,21 0 4 1,32 0 0 4294963256,148 0 0 4,21 0 1 1,6 0 0 4294967295,6 0 0 0", ], [ r#" ld [4] ld [x + 4] ld M[4] ld #4 ld len ld proto ldi #4 ldh [4] ldh [x + 4] ldh proto ldb [4] ldb [x + 4] ldb proto ldx M[4] ldx 4 * ([4] & 0xF) ldx #4 ldx len ldxi #4 ldxb 4 * ([4] & 0xF) st M[4] stx M[4] jmp jump_target_1 ja jump_target_2 jeq x, jump_target_3, jump_target_1 jeq x, jump_target_2 jeq #4, jump_target_3, jump_target_1 jeq #4, jump_target_2 jneq x, jump_target_3 jne x, jump_target_1 jneq #4, jump_target_2 jne #4, jump_target_3 jlt x, jump_target_1 jlt #4, jump_target_2 jle x, jump_target_3 jle #4, jump_target_1 jgt x, jump_target_2 jgt #4, jump_target_3 jge x, jump_target_1 jge x, jump_target_2 jset x, jump_target_3, jump_target_1 jset x, jump_target_2 jset #4, jump_target_3, jump_target_1 jset #4, jump_target_2 add x add #4 sub x sub #4 mul x mul #4 div x div #4 mod x mod #4 neg and x and #4 or x or #4 xor x xor #4 lsh x lsh #4 rsh x rsh #4 tax txa jump_target_1: ret a jump_target_2: ret x jump_target_3: ret #4 "#, "69,32 0 0 4,64 0 0 4,96 0 0 4,0 0 0 4,128 0 0 0,32 0 0 4294963200,0 0 0 4,40 0 0 4,72 0 0 4,40 0 0 4294963200,48 0 0 4,80 0 0 4,48 0 0 4294963200,97 0 0 4,177 0 0 4,1 0 0 4,129 0 0 0,1 0 0 4,177 0 0 4,2 0 0 4,3 0 0 4,5 0 0 44,5 0 0 44,29 44 42 0,29 42 0 0,21 42 40 4,21 40 0 4,29 0 40 0,29 0 37 0,21 0 37 4,21 0 37 4,61 0 34 0,53 0 34 4,45 0 34 0,37 0 31 4,45 31 0 0,37 31 0 4,61 28 0 0,61 28 0 0,77 28 26 0,77 26 0 0,69 26 24 4,69 24 0 4,12 0 0 0,4 0 0 4,28 0 0 0,20 0 0 4,44 0 0 0,36 0 0 4,60 0 0 0,52 0 0 4,156 0 0 0,148 0 0 4,132 0 0 0,92 0 0 0,84 0 0 4,76 0 0 0,68 0 0 4,172 0 0 0,164 0 0 4,108 0 0 0,100 0 0 4,124 0 0 0,116 0 0 4,7 0 0 0,135 0 0 0,22 0 0 0,14 0 0 0,6 0 0 4", ] ]; let extensions = bpfasm::extensions::linux(); for [source, expected] in programs { let instructions = bpfasm::assemble(source, &extensions).expect("compiler error"); let actual = format!( "{},{}", instructions.len(), instructions.iter().map(|s| s.to_string()).collect::>().join(",") ); assert_eq!(actual, expected); } }