Linux kernel mirror (for testing)
git.kernel.org/pub/scm/linux/kernel/git/torvalds/linux.git
kernel
os
linux
1{
2 "pointer/scalar confusion in state equality check (way 1)",
3 .insns = {
4 BPF_ST_MEM(BPF_DW, BPF_REG_10, -8, 0),
5 BPF_MOV64_REG(BPF_REG_2, BPF_REG_10),
6 BPF_ALU64_IMM(BPF_ADD, BPF_REG_2, -8),
7 BPF_LD_MAP_FD(BPF_REG_1, 0),
8 BPF_RAW_INSN(BPF_JMP | BPF_CALL, 0, 0, 0, BPF_FUNC_map_lookup_elem),
9 BPF_JMP_IMM(BPF_JEQ, BPF_REG_0, 0, 2),
10 BPF_LDX_MEM(BPF_DW, BPF_REG_0, BPF_REG_0, 0),
11 BPF_JMP_A(1),
12 BPF_MOV64_REG(BPF_REG_0, BPF_REG_10),
13 BPF_JMP_A(0),
14 BPF_EXIT_INSN(),
15 },
16 .fixup_map_hash_8b = { 3 },
17 .result = ACCEPT,
18 .retval = POINTER_VALUE,
19 .result_unpriv = REJECT,
20 .errstr_unpriv = "R0 leaks addr as return value"
21},
22{
23 "pointer/scalar confusion in state equality check (way 2)",
24 .insns = {
25 BPF_ST_MEM(BPF_DW, BPF_REG_10, -8, 0),
26 BPF_MOV64_REG(BPF_REG_2, BPF_REG_10),
27 BPF_ALU64_IMM(BPF_ADD, BPF_REG_2, -8),
28 BPF_LD_MAP_FD(BPF_REG_1, 0),
29 BPF_RAW_INSN(BPF_JMP | BPF_CALL, 0, 0, 0, BPF_FUNC_map_lookup_elem),
30 BPF_JMP_IMM(BPF_JNE, BPF_REG_0, 0, 2),
31 BPF_MOV64_REG(BPF_REG_0, BPF_REG_10),
32 BPF_JMP_A(1),
33 BPF_LDX_MEM(BPF_DW, BPF_REG_0, BPF_REG_0, 0),
34 BPF_EXIT_INSN(),
35 },
36 .fixup_map_hash_8b = { 3 },
37 .result = ACCEPT,
38 .retval = POINTER_VALUE,
39 .result_unpriv = REJECT,
40 .errstr_unpriv = "R0 leaks addr as return value"
41},
42{
43 "liveness pruning and write screening",
44 .insns = {
45 /* Get an unknown value */
46 BPF_LDX_MEM(BPF_W, BPF_REG_2, BPF_REG_1, 0),
47 /* branch conditions teach us nothing about R2 */
48 BPF_JMP_IMM(BPF_JGE, BPF_REG_2, 0, 1),
49 BPF_MOV64_IMM(BPF_REG_0, 0),
50 BPF_JMP_IMM(BPF_JGE, BPF_REG_2, 0, 1),
51 BPF_MOV64_IMM(BPF_REG_0, 0),
52 BPF_EXIT_INSN(),
53 },
54 .errstr = "R0 !read_ok",
55 .result = REJECT,
56 .prog_type = BPF_PROG_TYPE_LWT_IN,
57},
58{
59 "varlen_map_value_access pruning",
60 .insns = {
61 BPF_ST_MEM(BPF_DW, BPF_REG_10, -8, 0),
62 BPF_MOV64_REG(BPF_REG_2, BPF_REG_10),
63 BPF_ALU64_IMM(BPF_ADD, BPF_REG_2, -8),
64 BPF_LD_MAP_FD(BPF_REG_1, 0),
65 BPF_RAW_INSN(BPF_JMP | BPF_CALL, 0, 0, 0, BPF_FUNC_map_lookup_elem),
66 BPF_JMP_IMM(BPF_JEQ, BPF_REG_0, 0, 8),
67 BPF_LDX_MEM(BPF_DW, BPF_REG_1, BPF_REG_0, 0),
68 BPF_MOV32_IMM(BPF_REG_2, MAX_ENTRIES),
69 BPF_JMP_REG(BPF_JSGT, BPF_REG_2, BPF_REG_1, 1),
70 BPF_MOV32_IMM(BPF_REG_1, 0),
71 BPF_ALU32_IMM(BPF_LSH, BPF_REG_1, 2),
72 BPF_ALU64_REG(BPF_ADD, BPF_REG_0, BPF_REG_1),
73 BPF_JMP_IMM(BPF_JA, 0, 0, 0),
74 BPF_ST_MEM(BPF_DW, BPF_REG_0, 0, offsetof(struct test_val, foo)),
75 BPF_EXIT_INSN(),
76 },
77 .fixup_map_hash_48b = { 3 },
78 .errstr_unpriv = "R0 leaks addr",
79 .errstr = "R0 unbounded memory access",
80 .result_unpriv = REJECT,
81 .result = REJECT,
82 .flags = F_NEEDS_EFFICIENT_UNALIGNED_ACCESS,
83},
84{
85 "search pruning: all branches should be verified (nop operation)",
86 .insns = {
87 BPF_MOV64_REG(BPF_REG_2, BPF_REG_10),
88 BPF_ALU64_IMM(BPF_ADD, BPF_REG_2, -8),
89 BPF_ST_MEM(BPF_DW, BPF_REG_2, 0, 0),
90 BPF_LD_MAP_FD(BPF_REG_1, 0),
91 BPF_EMIT_CALL(BPF_FUNC_map_lookup_elem),
92 BPF_JMP_IMM(BPF_JEQ, BPF_REG_0, 0, 11),
93 BPF_LDX_MEM(BPF_DW, BPF_REG_3, BPF_REG_0, 0),
94 BPF_JMP_IMM(BPF_JEQ, BPF_REG_3, 0xbeef, 2),
95 BPF_MOV64_IMM(BPF_REG_4, 0),
96 BPF_JMP_A(1),
97 BPF_MOV64_IMM(BPF_REG_4, 1),
98 BPF_STX_MEM(BPF_DW, BPF_REG_10, BPF_REG_4, -16),
99 BPF_EMIT_CALL(BPF_FUNC_ktime_get_ns),
100 BPF_LDX_MEM(BPF_DW, BPF_REG_5, BPF_REG_10, -16),
101 BPF_JMP_IMM(BPF_JEQ, BPF_REG_5, 0, 2),
102 BPF_MOV64_IMM(BPF_REG_6, 0),
103 BPF_ST_MEM(BPF_DW, BPF_REG_6, 0, 0xdead),
104 BPF_EXIT_INSN(),
105 },
106 .fixup_map_hash_8b = { 3 },
107 .errstr = "R6 invalid mem access 'scalar'",
108 .result = REJECT,
109 .prog_type = BPF_PROG_TYPE_TRACEPOINT,
110},
111{
112 "search pruning: all branches should be verified (invalid stack access)",
113 .insns = {
114 BPF_MOV64_REG(BPF_REG_2, BPF_REG_10),
115 BPF_ALU64_IMM(BPF_ADD, BPF_REG_2, -8),
116 BPF_ST_MEM(BPF_DW, BPF_REG_2, 0, 0),
117 BPF_LD_MAP_FD(BPF_REG_1, 0),
118 BPF_EMIT_CALL(BPF_FUNC_map_lookup_elem),
119 BPF_JMP_IMM(BPF_JEQ, BPF_REG_0, 0, 8),
120 BPF_LDX_MEM(BPF_DW, BPF_REG_3, BPF_REG_0, 0),
121 BPF_MOV64_IMM(BPF_REG_4, 0),
122 BPF_JMP_IMM(BPF_JEQ, BPF_REG_3, 0xbeef, 2),
123 BPF_STX_MEM(BPF_DW, BPF_REG_10, BPF_REG_4, -16),
124 BPF_JMP_A(1),
125 BPF_STX_MEM(BPF_DW, BPF_REG_10, BPF_REG_4, -24),
126 BPF_EMIT_CALL(BPF_FUNC_ktime_get_ns),
127 BPF_LDX_MEM(BPF_DW, BPF_REG_5, BPF_REG_10, -16),
128 BPF_EXIT_INSN(),
129 },
130 .fixup_map_hash_8b = { 3 },
131 .errstr = "invalid read from stack off -16+0 size 8",
132 .result = REJECT,
133 .prog_type = BPF_PROG_TYPE_TRACEPOINT,
134},
135{
136 "precision tracking for u32 spill/fill",
137 .insns = {
138 BPF_MOV64_REG(BPF_REG_7, BPF_REG_1),
139 BPF_EMIT_CALL(BPF_FUNC_get_prandom_u32),
140 BPF_MOV32_IMM(BPF_REG_6, 32),
141 BPF_JMP_IMM(BPF_JEQ, BPF_REG_0, 0, 1),
142 BPF_MOV32_IMM(BPF_REG_6, 4),
143 /* Additional insns to introduce a pruning point. */
144 BPF_EMIT_CALL(BPF_FUNC_get_prandom_u32),
145 BPF_MOV64_IMM(BPF_REG_3, 0),
146 BPF_MOV64_IMM(BPF_REG_3, 0),
147 BPF_JMP_IMM(BPF_JEQ, BPF_REG_0, 0, 1),
148 BPF_MOV64_IMM(BPF_REG_3, 0),
149 /* u32 spill/fill */
150 BPF_STX_MEM(BPF_W, BPF_REG_10, BPF_REG_6, -8),
151 BPF_LDX_MEM(BPF_W, BPF_REG_8, BPF_REG_10, -8),
152 /* out-of-bound map value access for r6=32 */
153 BPF_ST_MEM(BPF_DW, BPF_REG_10, -16, 0),
154 BPF_MOV64_REG(BPF_REG_2, BPF_REG_10),
155 BPF_ALU64_IMM(BPF_ADD, BPF_REG_2, -16),
156 BPF_LD_MAP_FD(BPF_REG_1, 0),
157 BPF_RAW_INSN(BPF_JMP | BPF_CALL, 0, 0, 0, BPF_FUNC_map_lookup_elem),
158 BPF_JMP_IMM(BPF_JEQ, BPF_REG_0, 0, 2),
159 BPF_ALU64_REG(BPF_ADD, BPF_REG_0, BPF_REG_8),
160 BPF_LDX_MEM(BPF_W, BPF_REG_1, BPF_REG_0, 0),
161 BPF_MOV64_IMM(BPF_REG_0, 0),
162 BPF_EXIT_INSN(),
163 },
164 .fixup_map_hash_8b = { 15 },
165 .result = REJECT,
166 .errstr = "R0 min value is outside of the allowed memory range",
167 .prog_type = BPF_PROG_TYPE_TRACEPOINT,
168},
169{
170 "precision tracking for u32 spills, u64 fill",
171 .insns = {
172 BPF_EMIT_CALL(BPF_FUNC_get_prandom_u32),
173 BPF_MOV64_REG(BPF_REG_6, BPF_REG_0),
174 BPF_MOV32_IMM(BPF_REG_7, 0xffffffff),
175 /* Additional insns to introduce a pruning point. */
176 BPF_MOV64_IMM(BPF_REG_3, 1),
177 BPF_MOV64_IMM(BPF_REG_3, 1),
178 BPF_MOV64_IMM(BPF_REG_3, 1),
179 BPF_MOV64_IMM(BPF_REG_3, 1),
180 BPF_EMIT_CALL(BPF_FUNC_get_prandom_u32),
181 BPF_JMP_IMM(BPF_JEQ, BPF_REG_0, 0, 1),
182 BPF_MOV64_IMM(BPF_REG_3, 1),
183 BPF_ALU32_IMM(BPF_DIV, BPF_REG_3, 0),
184 /* u32 spills, u64 fill */
185 BPF_STX_MEM(BPF_W, BPF_REG_10, BPF_REG_6, -4),
186 BPF_STX_MEM(BPF_W, BPF_REG_10, BPF_REG_7, -8),
187 BPF_LDX_MEM(BPF_DW, BPF_REG_8, BPF_REG_10, -8),
188 /* if r8 != X goto pc+1 r8 known in fallthrough branch */
189 BPF_JMP_IMM(BPF_JNE, BPF_REG_8, 0xffffffff, 1),
190 BPF_MOV64_IMM(BPF_REG_3, 1),
191 /* if r8 == X goto pc+1 condition always true on first
192 * traversal, so starts backtracking to mark r8 as requiring
193 * precision. r7 marked as needing precision. r6 not marked
194 * since it's not tracked.
195 */
196 BPF_JMP_IMM(BPF_JEQ, BPF_REG_8, 0xffffffff, 1),
197 /* fails if r8 correctly marked unknown after fill. */
198 BPF_ALU32_IMM(BPF_DIV, BPF_REG_3, 0),
199 BPF_MOV64_IMM(BPF_REG_0, 0),
200 BPF_EXIT_INSN(),
201 },
202 .result = REJECT,
203 .errstr = "div by zero",
204 .prog_type = BPF_PROG_TYPE_TRACEPOINT,
205},
206{
207 "allocated_stack",
208 .insns = {
209 BPF_ALU64_REG(BPF_MOV, BPF_REG_6, BPF_REG_1),
210 BPF_RAW_INSN(BPF_JMP | BPF_CALL, 0, 0, 0, BPF_FUNC_get_prandom_u32),
211 BPF_ALU64_REG(BPF_MOV, BPF_REG_7, BPF_REG_0),
212 BPF_JMP_IMM(BPF_JEQ, BPF_REG_0, 0, 5),
213 BPF_MOV64_IMM(BPF_REG_0, 0),
214 BPF_STX_MEM(BPF_DW, BPF_REG_10, BPF_REG_6, -8),
215 BPF_LDX_MEM(BPF_DW, BPF_REG_6, BPF_REG_10, -8),
216 BPF_STX_MEM(BPF_B, BPF_REG_10, BPF_REG_7, -9),
217 BPF_LDX_MEM(BPF_B, BPF_REG_7, BPF_REG_10, -9),
218 BPF_JMP_IMM(BPF_JNE, BPF_REG_0, 0, 0),
219 BPF_JMP_IMM(BPF_JNE, BPF_REG_0, 0, 0),
220 BPF_JMP_IMM(BPF_JNE, BPF_REG_0, 0, 0),
221 BPF_JMP_IMM(BPF_JNE, BPF_REG_0, 0, 0),
222 BPF_EXIT_INSN(),
223 },
224 .result = ACCEPT,
225 .result_unpriv = ACCEPT,
226 .insn_processed = 15,
227},