xref: /aosp_15_r20/external/sandboxed-api/sandboxed_api/sandbox2/bpfdisassembler_test.cc (revision ec63e07ab9515d95e79c211197c445ef84cefa6a)
1 #include "sandboxed_api/sandbox2/bpfdisassembler.h"
2 
3 #include <linux/bpf_common.h>
4 #include <linux/filter.h>
5 #include <linux/seccomp.h>
6 
7 #include "gmock/gmock.h"
8 #include "gtest/gtest.h"
9 #include "sandboxed_api/sandbox2/util/bpf_helper.h"
10 
11 namespace sandbox2 {
12 namespace bpf {
13 namespace {
14 
15 using ::testing::Eq;
16 using ::testing::StartsWith;
17 
18 #ifndef SECCOMP_RET_USER_NOTIF
19 #define SECCOMP_RET_USER_NOTIF 0x7fc00000U /* notifies userspace */
20 #endif
21 
22 #ifndef SECCOMP_RET_KILL_PROCESS
23 #define SECCOMP_RET_KILL_PROCESS 0x80000000U /* kill the process */
24 #endif
25 
26 #ifndef SECCOMP_RET_LOG
27 #define SECCOMP_RET_LOG 0x7ffc0000U /* allow after logging */
28 #endif
29 
TEST(DecodeInstructionTest,Loads)30 TEST(DecodeInstructionTest, Loads) {
31   EXPECT_THAT(DecodeInstruction(LOAD_ARCH, 1), Eq("A := architecture"));
32   EXPECT_THAT(DecodeInstruction(LOAD_SYSCALL_NR, 1), Eq("A := syscall number"));
33   EXPECT_THAT(DecodeInstruction(ARG_32(0), 1), Eq("A := arg 0 low"));
34   EXPECT_THAT(
35       DecodeInstruction(BPF_STMT(BPF_LD | BPF_W | BPF_ABS, HI_ARG(0)), 1),
36       Eq("A := arg 0 high"));
37   EXPECT_THAT(DecodeInstruction(BPF_STMT(BPF_LD | BPF_W | BPF_LEN, 0), 1),
38               Eq("A := sizeof(seccomp_data)"));
39   EXPECT_THAT(DecodeInstruction(BPF_STMT(BPF_LDX | BPF_W | BPF_LEN, 0), 1),
40               Eq("X := sizeof(seccomp_data)"));
41   EXPECT_THAT(DecodeInstruction(BPF_STMT(BPF_LD | BPF_IMM, 0x1234), 1),
42               Eq("A := 0x1234"));
43   EXPECT_THAT(DecodeInstruction(BPF_STMT(BPF_LDX | BPF_IMM, 0x1234), 1),
44               Eq("X := 0x1234"));
45   EXPECT_THAT(DecodeInstruction(BPF_STMT(BPF_MISC | BPF_TAX, 0), 1),
46               Eq("X := A"));
47   EXPECT_THAT(DecodeInstruction(BPF_STMT(BPF_MISC | BPF_TXA, 0), 1),
48               Eq("A := X"));
49   EXPECT_THAT(DecodeInstruction(BPF_STMT(BPF_LD | BPF_W | BPF_ABS, 0x1), 1),
50               Eq("A := data[0x1] (misaligned load)"));
51   EXPECT_THAT(DecodeInstruction(BPF_STMT(BPF_LD | BPF_W | BPF_ABS, 0x1234), 1),
52               Eq("A := data[0x1234] (invalid load)"));
53 }
54 
TEST(DecodeInstructionTest,Memory)55 TEST(DecodeInstructionTest, Memory) {
56   EXPECT_THAT(DecodeInstruction(BPF_STMT(BPF_ST, 1), 1), Eq("M[1] := A"));
57   EXPECT_THAT(DecodeInstruction(BPF_STMT(BPF_STX, 1), 1), Eq("M[1] := X"));
58   EXPECT_THAT(DecodeInstruction(BPF_STMT(BPF_LD | BPF_MEM, 1), 1),
59               Eq("A := M[1]"));
60   EXPECT_THAT(DecodeInstruction(BPF_STMT(BPF_LDX | BPF_MEM, 1), 1),
61               Eq("X := M[1]"));
62 }
63 
TEST(DecodeInstructionTest,Returns)64 TEST(DecodeInstructionTest, Returns) {
65   EXPECT_THAT(DecodeInstruction(KILL, 1), Eq("KILL"));
66   EXPECT_THAT(DecodeInstruction(ALLOW, 1), Eq("ALLOW"));
67   EXPECT_THAT(DecodeInstruction(TRAP(0x12), 1), Eq("TRAP 0x12"));
68   EXPECT_THAT(DecodeInstruction(ERRNO(0x23), 1), Eq("ERRNO 0x23"));
69   EXPECT_THAT(DecodeInstruction(TRACE(0x34), 1), Eq("TRACE 0x34"));
70   EXPECT_THAT(
71       DecodeInstruction(BPF_STMT(BPF_RET + BPF_K, SECCOMP_RET_USER_NOTIF), 1),
72       Eq("USER_NOTIF"));
73   EXPECT_THAT(DecodeInstruction(BPF_STMT(BPF_RET + BPF_K, SECCOMP_RET_LOG), 1),
74               Eq("LOG"));
75   EXPECT_THAT(
76       DecodeInstruction(BPF_STMT(BPF_RET + BPF_K, SECCOMP_RET_KILL_PROCESS), 1),
77       Eq("KILL_PROCESS"));
78   EXPECT_THAT(DecodeInstruction(BPF_STMT(BPF_RET + BPF_A, 0), 1),
79               Eq("return A"));
80 }
81 
TEST(DecodeInstructionTest,Alu)82 TEST(DecodeInstructionTest, Alu) {
83   EXPECT_THAT(DecodeInstruction(BPF_STMT(BPF_ALU | BPF_NEG, 0), 1),
84               Eq("A := -A"));
85   EXPECT_THAT(DecodeInstruction(BPF_STMT(BPF_ALU | BPF_ADD | BPF_K, 5), 1),
86               Eq("A := A + 0x5"));
87   EXPECT_THAT(DecodeInstruction(BPF_STMT(BPF_ALU | BPF_SUB | BPF_K, 5), 1),
88               Eq("A := A - 0x5"));
89   EXPECT_THAT(DecodeInstruction(BPF_STMT(BPF_ALU | BPF_DIV | BPF_X, 0), 1),
90               Eq("A := A / X"));
91   EXPECT_THAT(DecodeInstruction(BPF_STMT(BPF_ALU | BPF_MUL | BPF_X, 0), 1),
92               Eq("A := A * X"));
93   EXPECT_THAT(DecodeInstruction(BPF_STMT(BPF_ALU | BPF_AND | BPF_K, 6), 1),
94               Eq("A := A & 0x6"));
95   EXPECT_THAT(DecodeInstruction(BPF_STMT(BPF_ALU | BPF_OR | BPF_K, 7), 1),
96               Eq("A := A | 0x7"));
97   EXPECT_THAT(DecodeInstruction(BPF_STMT(BPF_ALU | BPF_XOR | BPF_K, 8), 1),
98               Eq("A := A ^ 0x8"));
99   EXPECT_THAT(DecodeInstruction(BPF_STMT(BPF_ALU | BPF_RSH | BPF_K, 9), 1),
100               Eq("A := A >> 0x9"));
101   EXPECT_THAT(DecodeInstruction(BPF_STMT(BPF_ALU | BPF_LSH | BPF_K, 1), 1),
102               Eq("A := A << 0x1"));
103 }
104 
TEST(DecodeInstructionTest,Jump)105 TEST(DecodeInstructionTest, Jump) {
106   EXPECT_THAT(
107       DecodeInstruction(BPF_JUMP(BPF_JMP | BPF_JEQ | BPF_K, 0x1234, 1, 0), 1),
108       Eq("if A == 0x1234 goto 3"));
109   EXPECT_THAT(
110       DecodeInstruction(BPF_JUMP(BPF_JMP | BPF_JGT | BPF_K, 0x1234, 0, 1), 1),
111       Eq("if A <= 0x1234 goto 3"));
112   EXPECT_THAT(
113       DecodeInstruction(BPF_JUMP(BPF_JMP | BPF_JGT | BPF_K, 0x1234, 1, 2), 1),
114       Eq("if A > 0x1234 then 3 else 4"));
115   EXPECT_THAT(
116       DecodeInstruction(BPF_JUMP(BPF_JMP | BPF_JSET | BPF_X, 1, 1, 0), 1),
117       Eq("if A & X goto 3"));
118   EXPECT_THAT(
119       DecodeInstruction(BPF_JUMP(BPF_JMP | BPF_JGE | BPF_X, 0, 0, 1), 1),
120       Eq("if A < X goto 3"));
121   EXPECT_THAT(
122       DecodeInstruction(BPF_JUMP(BPF_JMP | BPF_JGE | BPF_X, 0, 1, 2), 1),
123       Eq("if A >= X then 3 else 4"));
124   EXPECT_THAT(DecodeInstruction(BPF_STMT(BPF_JMP | BPF_K, 3), 1),
125               Eq("jump to 5"));
126 }
127 
TEST(DecodeInstructionTest,Invalid)128 TEST(DecodeInstructionTest, Invalid) {
129   EXPECT_THAT(DecodeInstruction(BPF_STMT(BPF_LDX | BPF_W | BPF_ABS, 0), 1),
130               StartsWith("Invalid instruction"));
131 }
132 
TEST(DisasmTest,Simple)133 TEST(DisasmTest, Simple) {
134   EXPECT_THAT(Disasm({ALLOW}), Eq("000: ALLOW\n"));
135   EXPECT_THAT(Disasm({KILL}), Eq("000: KILL\n"));
136 }
137 
TEST(DisasmTest,Complex)138 TEST(DisasmTest, Complex) {
139   EXPECT_THAT(Disasm({LOAD_ARCH, JNE32(0x1, KILL), LOAD_SYSCALL_NR,
140                       JEQ32(0x1234, ERRNO(0x33)), TRACE(0x22)}),
141               Eq(R"(000: A := architecture
142 001: if A == 0x1 goto 3
143 002: KILL
144 003: A := syscall number
145 004: if A != 0x1234 goto 6
146 005: ERRNO 0x33
147 006: TRACE 0x22
148 )"));
149 }
150 
151 }  // namespace
152 }  // namespace bpf
153 }  // namespace sandbox2
154