1 {
2 	"spin_lock: test1 success",
3 	.insns = {
4 	BPF_ST_MEM(BPF_W, BPF_REG_10, -4, 0),
5 	BPF_MOV64_REG(BPF_REG_2, BPF_REG_10),
6 	BPF_ALU64_IMM(BPF_ADD, BPF_REG_2, -4),
7 	BPF_LD_MAP_FD(BPF_REG_1,
8 		      0),
9 	BPF_RAW_INSN(BPF_JMP | BPF_CALL, 0, 0, 0, BPF_FUNC_map_lookup_elem),
10 	BPF_JMP_IMM(BPF_JNE, BPF_REG_0, 0, 1),
11 	BPF_EXIT_INSN(),
12 	BPF_MOV64_REG(BPF_REG_6, BPF_REG_0),
13 	BPF_MOV64_REG(BPF_REG_1, BPF_REG_0),
14 	BPF_ALU64_IMM(BPF_ADD, BPF_REG_1, 4),
15 	BPF_RAW_INSN(BPF_JMP | BPF_CALL, 0, 0, 0, BPF_FUNC_spin_lock),
16 	BPF_MOV64_REG(BPF_REG_1, BPF_REG_6),
17 	BPF_ALU64_IMM(BPF_ADD, BPF_REG_1, 4),
18 	BPF_LDX_MEM(BPF_W, BPF_REG_0, BPF_REG_6, 0),
19 	BPF_RAW_INSN(BPF_JMP | BPF_CALL, 0, 0, 0, BPF_FUNC_spin_unlock),
20 	BPF_MOV64_IMM(BPF_REG_0, 0),
21 	BPF_EXIT_INSN(),
22 	},
23 	.fixup_map_spin_lock = { 3 },
24 	.result = ACCEPT,
25 	.result_unpriv = REJECT,
26 	.errstr_unpriv = "",
27 	.prog_type = BPF_PROG_TYPE_CGROUP_SKB,
28 },
29 {
30 	"spin_lock: test2 direct ld/st",
31 	.insns = {
32 	BPF_ST_MEM(BPF_W, BPF_REG_10, -4, 0),
33 	BPF_MOV64_REG(BPF_REG_2, BPF_REG_10),
34 	BPF_ALU64_IMM(BPF_ADD, BPF_REG_2, -4),
35 	BPF_LD_MAP_FD(BPF_REG_1,
36 		      0),
37 	BPF_RAW_INSN(BPF_JMP | BPF_CALL, 0, 0, 0, BPF_FUNC_map_lookup_elem),
38 	BPF_JMP_IMM(BPF_JNE, BPF_REG_0, 0, 1),
39 	BPF_EXIT_INSN(),
40 	BPF_MOV64_REG(BPF_REG_6, BPF_REG_0),
41 	BPF_MOV64_REG(BPF_REG_1, BPF_REG_0),
42 	BPF_ALU64_IMM(BPF_ADD, BPF_REG_1, 4),
43 	BPF_RAW_INSN(BPF_JMP | BPF_CALL, 0, 0, 0, BPF_FUNC_spin_lock),
44 	BPF_MOV64_REG(BPF_REG_1, BPF_REG_6),
45 	BPF_ALU64_IMM(BPF_ADD, BPF_REG_1, 4),
46 	BPF_LDX_MEM(BPF_W, BPF_REG_0, BPF_REG_1, 0),
47 	BPF_RAW_INSN(BPF_JMP | BPF_CALL, 0, 0, 0, BPF_FUNC_spin_unlock),
48 	BPF_MOV64_IMM(BPF_REG_0, 0),
49 	BPF_EXIT_INSN(),
50 	},
51 	.fixup_map_spin_lock = { 3 },
52 	.result = REJECT,
53 	.errstr = "cannot be accessed directly",
54 	.result_unpriv = REJECT,
55 	.errstr_unpriv = "",
56 	.prog_type = BPF_PROG_TYPE_CGROUP_SKB,
57 },
58 {
59 	"spin_lock: test3 direct ld/st",
60 	.insns = {
61 	BPF_ST_MEM(BPF_W, BPF_REG_10, -4, 0),
62 	BPF_MOV64_REG(BPF_REG_2, BPF_REG_10),
63 	BPF_ALU64_IMM(BPF_ADD, BPF_REG_2, -4),
64 	BPF_LD_MAP_FD(BPF_REG_1,
65 		      0),
66 	BPF_RAW_INSN(BPF_JMP | BPF_CALL, 0, 0, 0, BPF_FUNC_map_lookup_elem),
67 	BPF_JMP_IMM(BPF_JNE, BPF_REG_0, 0, 1),
68 	BPF_EXIT_INSN(),
69 	BPF_MOV64_REG(BPF_REG_6, BPF_REG_0),
70 	BPF_MOV64_REG(BPF_REG_1, BPF_REG_0),
71 	BPF_ALU64_IMM(BPF_ADD, BPF_REG_1, 4),
72 	BPF_RAW_INSN(BPF_JMP | BPF_CALL, 0, 0, 0, BPF_FUNC_spin_lock),
73 	BPF_MOV64_REG(BPF_REG_1, BPF_REG_6),
74 	BPF_ALU64_IMM(BPF_ADD, BPF_REG_1, 4),
75 	BPF_LDX_MEM(BPF_W, BPF_REG_0, BPF_REG_6, 1),
76 	BPF_RAW_INSN(BPF_JMP | BPF_CALL, 0, 0, 0, BPF_FUNC_spin_unlock),
77 	BPF_MOV64_IMM(BPF_REG_0, 0),
78 	BPF_EXIT_INSN(),
79 	},
80 	.fixup_map_spin_lock = { 3 },
81 	.result = REJECT,
82 	.errstr = "cannot be accessed directly",
83 	.result_unpriv = REJECT,
84 	.errstr_unpriv = "",
85 	.prog_type = BPF_PROG_TYPE_CGROUP_SKB,
86 	.flags = F_NEEDS_EFFICIENT_UNALIGNED_ACCESS,
87 },
88 {
89 	"spin_lock: test4 direct ld/st",
90 	.insns = {
91 	BPF_ST_MEM(BPF_W, BPF_REG_10, -4, 0),
92 	BPF_MOV64_REG(BPF_REG_2, BPF_REG_10),
93 	BPF_ALU64_IMM(BPF_ADD, BPF_REG_2, -4),
94 	BPF_LD_MAP_FD(BPF_REG_1,
95 		      0),
96 	BPF_RAW_INSN(BPF_JMP | BPF_CALL, 0, 0, 0, BPF_FUNC_map_lookup_elem),
97 	BPF_JMP_IMM(BPF_JNE, BPF_REG_0, 0, 1),
98 	BPF_EXIT_INSN(),
99 	BPF_MOV64_REG(BPF_REG_6, BPF_REG_0),
100 	BPF_MOV64_REG(BPF_REG_1, BPF_REG_0),
101 	BPF_ALU64_IMM(BPF_ADD, BPF_REG_1, 4),
102 	BPF_RAW_INSN(BPF_JMP | BPF_CALL, 0, 0, 0, BPF_FUNC_spin_lock),
103 	BPF_MOV64_REG(BPF_REG_1, BPF_REG_6),
104 	BPF_ALU64_IMM(BPF_ADD, BPF_REG_1, 4),
105 	BPF_LDX_MEM(BPF_H, BPF_REG_0, BPF_REG_6, 3),
106 	BPF_RAW_INSN(BPF_JMP | BPF_CALL, 0, 0, 0, BPF_FUNC_spin_unlock),
107 	BPF_MOV64_IMM(BPF_REG_0, 0),
108 	BPF_EXIT_INSN(),
109 	},
110 	.fixup_map_spin_lock = { 3 },
111 	.result = REJECT,
112 	.errstr = "cannot be accessed directly",
113 	.result_unpriv = REJECT,
114 	.errstr_unpriv = "",
115 	.prog_type = BPF_PROG_TYPE_CGROUP_SKB,
116 	.flags = F_NEEDS_EFFICIENT_UNALIGNED_ACCESS,
117 },
118 {
119 	"spin_lock: test5 call within a locked region",
120 	.insns = {
121 	BPF_ST_MEM(BPF_W, BPF_REG_10, -4, 0),
122 	BPF_MOV64_REG(BPF_REG_2, BPF_REG_10),
123 	BPF_ALU64_IMM(BPF_ADD, BPF_REG_2, -4),
124 	BPF_LD_MAP_FD(BPF_REG_1,
125 		      0),
126 	BPF_RAW_INSN(BPF_JMP | BPF_CALL, 0, 0, 0, BPF_FUNC_map_lookup_elem),
127 	BPF_JMP_IMM(BPF_JNE, BPF_REG_0, 0, 1),
128 	BPF_EXIT_INSN(),
129 	BPF_MOV64_REG(BPF_REG_6, BPF_REG_0),
130 	BPF_MOV64_REG(BPF_REG_1, BPF_REG_0),
131 	BPF_ALU64_IMM(BPF_ADD, BPF_REG_1, 4),
132 	BPF_RAW_INSN(BPF_JMP | BPF_CALL, 0, 0, 0, BPF_FUNC_spin_lock),
133 	BPF_RAW_INSN(BPF_JMP | BPF_CALL, 0, 0, 0, BPF_FUNC_get_prandom_u32),
134 	BPF_MOV64_REG(BPF_REG_1, BPF_REG_6),
135 	BPF_ALU64_IMM(BPF_ADD, BPF_REG_1, 4),
136 	BPF_RAW_INSN(BPF_JMP | BPF_CALL, 0, 0, 0, BPF_FUNC_spin_unlock),
137 	BPF_MOV64_IMM(BPF_REG_0, 0),
138 	BPF_EXIT_INSN(),
139 	},
140 	.fixup_map_spin_lock = { 3 },
141 	.result = REJECT,
142 	.errstr = "calls are not allowed",
143 	.result_unpriv = REJECT,
144 	.errstr_unpriv = "",
145 	.prog_type = BPF_PROG_TYPE_CGROUP_SKB,
146 },
147 {
148 	"spin_lock: test6 missing unlock",
149 	.insns = {
150 	BPF_ST_MEM(BPF_W, BPF_REG_10, -4, 0),
151 	BPF_MOV64_REG(BPF_REG_2, BPF_REG_10),
152 	BPF_ALU64_IMM(BPF_ADD, BPF_REG_2, -4),
153 	BPF_LD_MAP_FD(BPF_REG_1,
154 		      0),
155 	BPF_RAW_INSN(BPF_JMP | BPF_CALL, 0, 0, 0, BPF_FUNC_map_lookup_elem),
156 	BPF_JMP_IMM(BPF_JNE, BPF_REG_0, 0, 1),
157 	BPF_EXIT_INSN(),
158 	BPF_MOV64_REG(BPF_REG_6, BPF_REG_0),
159 	BPF_MOV64_REG(BPF_REG_1, BPF_REG_0),
160 	BPF_ALU64_IMM(BPF_ADD, BPF_REG_1, 4),
161 	BPF_RAW_INSN(BPF_JMP | BPF_CALL, 0, 0, 0, BPF_FUNC_spin_lock),
162 	BPF_MOV64_REG(BPF_REG_1, BPF_REG_6),
163 	BPF_ALU64_IMM(BPF_ADD, BPF_REG_1, 4),
164 	BPF_LDX_MEM(BPF_W, BPF_REG_0, BPF_REG_6, 0),
165 	BPF_JMP_IMM(BPF_JNE, BPF_REG_0, 0, 1),
166 	BPF_RAW_INSN(BPF_JMP | BPF_CALL, 0, 0, 0, BPF_FUNC_spin_unlock),
167 	BPF_MOV64_IMM(BPF_REG_0, 0),
168 	BPF_EXIT_INSN(),
169 	},
170 	.fixup_map_spin_lock = { 3 },
171 	.result = REJECT,
172 	.errstr = "unlock is missing",
173 	.result_unpriv = REJECT,
174 	.errstr_unpriv = "",
175 	.prog_type = BPF_PROG_TYPE_CGROUP_SKB,
176 },
177 {
178 	"spin_lock: test7 unlock without lock",
179 	.insns = {
180 	BPF_ST_MEM(BPF_W, BPF_REG_10, -4, 0),
181 	BPF_MOV64_REG(BPF_REG_2, BPF_REG_10),
182 	BPF_ALU64_IMM(BPF_ADD, BPF_REG_2, -4),
183 	BPF_LD_MAP_FD(BPF_REG_1,
184 		      0),
185 	BPF_RAW_INSN(BPF_JMP | BPF_CALL, 0, 0, 0, BPF_FUNC_map_lookup_elem),
186 	BPF_JMP_IMM(BPF_JNE, BPF_REG_0, 0, 1),
187 	BPF_EXIT_INSN(),
188 	BPF_MOV64_REG(BPF_REG_6, BPF_REG_0),
189 	BPF_MOV64_REG(BPF_REG_1, BPF_REG_0),
190 	BPF_ALU64_IMM(BPF_ADD, BPF_REG_1, 4),
191 	BPF_JMP_IMM(BPF_JNE, BPF_REG_1, 0, 1),
192 	BPF_RAW_INSN(BPF_JMP | BPF_CALL, 0, 0, 0, BPF_FUNC_spin_lock),
193 	BPF_MOV64_REG(BPF_REG_1, BPF_REG_6),
194 	BPF_ALU64_IMM(BPF_ADD, BPF_REG_1, 4),
195 	BPF_LDX_MEM(BPF_W, BPF_REG_0, BPF_REG_6, 0),
196 	BPF_RAW_INSN(BPF_JMP | BPF_CALL, 0, 0, 0, BPF_FUNC_spin_unlock),
197 	BPF_MOV64_IMM(BPF_REG_0, 0),
198 	BPF_EXIT_INSN(),
199 	},
200 	.fixup_map_spin_lock = { 3 },
201 	.result = REJECT,
202 	.errstr = "without taking a lock",
203 	.result_unpriv = REJECT,
204 	.errstr_unpriv = "",
205 	.prog_type = BPF_PROG_TYPE_CGROUP_SKB,
206 },
207 {
208 	"spin_lock: test8 double lock",
209 	.insns = {
210 	BPF_ST_MEM(BPF_W, BPF_REG_10, -4, 0),
211 	BPF_MOV64_REG(BPF_REG_2, BPF_REG_10),
212 	BPF_ALU64_IMM(BPF_ADD, BPF_REG_2, -4),
213 	BPF_LD_MAP_FD(BPF_REG_1,
214 		      0),
215 	BPF_RAW_INSN(BPF_JMP | BPF_CALL, 0, 0, 0, BPF_FUNC_map_lookup_elem),
216 	BPF_JMP_IMM(BPF_JNE, BPF_REG_0, 0, 1),
217 	BPF_EXIT_INSN(),
218 	BPF_MOV64_REG(BPF_REG_6, BPF_REG_0),
219 	BPF_MOV64_REG(BPF_REG_1, BPF_REG_0),
220 	BPF_ALU64_IMM(BPF_ADD, BPF_REG_1, 4),
221 	BPF_RAW_INSN(BPF_JMP | BPF_CALL, 0, 0, 0, BPF_FUNC_spin_lock),
222 	BPF_MOV64_REG(BPF_REG_1, BPF_REG_6),
223 	BPF_ALU64_IMM(BPF_ADD, BPF_REG_1, 4),
224 	BPF_RAW_INSN(BPF_JMP | BPF_CALL, 0, 0, 0, BPF_FUNC_spin_lock),
225 	BPF_MOV64_REG(BPF_REG_1, BPF_REG_6),
226 	BPF_ALU64_IMM(BPF_ADD, BPF_REG_1, 4),
227 	BPF_LDX_MEM(BPF_W, BPF_REG_0, BPF_REG_6, 0),
228 	BPF_RAW_INSN(BPF_JMP | BPF_CALL, 0, 0, 0, BPF_FUNC_spin_unlock),
229 	BPF_MOV64_IMM(BPF_REG_0, 0),
230 	BPF_EXIT_INSN(),
231 	},
232 	.fixup_map_spin_lock = { 3 },
233 	.result = REJECT,
234 	.errstr = "calls are not allowed",
235 	.result_unpriv = REJECT,
236 	.errstr_unpriv = "",
237 	.prog_type = BPF_PROG_TYPE_CGROUP_SKB,
238 },
239 {
240 	"spin_lock: test9 different lock",
241 	.insns = {
242 	BPF_ST_MEM(BPF_W, BPF_REG_10, -4, 0),
243 	BPF_MOV64_REG(BPF_REG_2, BPF_REG_10),
244 	BPF_ALU64_IMM(BPF_ADD, BPF_REG_2, -4),
245 	BPF_LD_MAP_FD(BPF_REG_1,
246 		      0),
247 	BPF_RAW_INSN(BPF_JMP | BPF_CALL, 0, 0, 0, BPF_FUNC_map_lookup_elem),
248 	BPF_JMP_IMM(BPF_JNE, BPF_REG_0, 0, 1),
249 	BPF_EXIT_INSN(),
250 	BPF_MOV64_REG(BPF_REG_6, BPF_REG_0),
251 	BPF_MOV64_REG(BPF_REG_2, BPF_REG_10),
252 	BPF_ALU64_IMM(BPF_ADD, BPF_REG_2, -4),
253 	BPF_LD_MAP_FD(BPF_REG_1,
254 		      0),
255 	BPF_RAW_INSN(BPF_JMP | BPF_CALL, 0, 0, 0, BPF_FUNC_map_lookup_elem),
256 	BPF_JMP_IMM(BPF_JNE, BPF_REG_0, 0, 1),
257 	BPF_EXIT_INSN(),
258 	BPF_MOV64_REG(BPF_REG_7, BPF_REG_0),
259 	BPF_MOV64_REG(BPF_REG_1, BPF_REG_6),
260 	BPF_ALU64_IMM(BPF_ADD, BPF_REG_1, 4),
261 	BPF_RAW_INSN(BPF_JMP | BPF_CALL, 0, 0, 0, BPF_FUNC_spin_lock),
262 	BPF_MOV64_REG(BPF_REG_1, BPF_REG_7),
263 	BPF_ALU64_IMM(BPF_ADD, BPF_REG_1, 4),
264 	BPF_RAW_INSN(BPF_JMP | BPF_CALL, 0, 0, 0, BPF_FUNC_spin_unlock),
265 	BPF_MOV64_IMM(BPF_REG_0, 0),
266 	BPF_EXIT_INSN(),
267 	},
268 	.fixup_map_spin_lock = { 3, 11 },
269 	.result = REJECT,
270 	.errstr = "unlock of different lock",
271 	.result_unpriv = REJECT,
272 	.errstr_unpriv = "",
273 	.prog_type = BPF_PROG_TYPE_CGROUP_SKB,
274 },
275 {
276 	"spin_lock: test10 lock in subprog without unlock",
277 	.insns = {
278 	BPF_ST_MEM(BPF_W, BPF_REG_10, -4, 0),
279 	BPF_MOV64_REG(BPF_REG_2, BPF_REG_10),
280 	BPF_ALU64_IMM(BPF_ADD, BPF_REG_2, -4),
281 	BPF_LD_MAP_FD(BPF_REG_1,
282 		      0),
283 	BPF_RAW_INSN(BPF_JMP | BPF_CALL, 0, 0, 0, BPF_FUNC_map_lookup_elem),
284 	BPF_JMP_IMM(BPF_JNE, BPF_REG_0, 0, 1),
285 	BPF_EXIT_INSN(),
286 	BPF_MOV64_REG(BPF_REG_6, BPF_REG_0),
287 	BPF_MOV64_REG(BPF_REG_1, BPF_REG_0),
288 	BPF_ALU64_IMM(BPF_ADD, BPF_REG_1, 4),
289 	BPF_RAW_INSN(BPF_JMP | BPF_CALL, 0, 1, 0, 5),
290 	BPF_MOV64_REG(BPF_REG_1, BPF_REG_6),
291 	BPF_ALU64_IMM(BPF_ADD, BPF_REG_1, 4),
292 	BPF_RAW_INSN(BPF_JMP | BPF_CALL, 0, 0, 0, BPF_FUNC_spin_unlock),
293 	BPF_MOV64_IMM(BPF_REG_0, 1),
294 	BPF_EXIT_INSN(),
295 	BPF_RAW_INSN(BPF_JMP | BPF_CALL, 0, 0, 0, BPF_FUNC_spin_lock),
296 	BPF_MOV64_IMM(BPF_REG_0, 0),
297 	BPF_EXIT_INSN(),
298 	},
299 	.fixup_map_spin_lock = { 3 },
300 	.result = REJECT,
301 	.errstr = "unlock is missing",
302 	.result_unpriv = REJECT,
303 	.errstr_unpriv = "",
304 	.prog_type = BPF_PROG_TYPE_CGROUP_SKB,
305 },
306 {
307 	"spin_lock: test11 ld_abs under lock",
308 	.insns = {
309 	BPF_MOV64_REG(BPF_REG_6, BPF_REG_1),
310 	BPF_ST_MEM(BPF_W, BPF_REG_10, -4, 0),
311 	BPF_MOV64_REG(BPF_REG_2, BPF_REG_10),
312 	BPF_ALU64_IMM(BPF_ADD, BPF_REG_2, -4),
313 	BPF_LD_MAP_FD(BPF_REG_1,
314 		      0),
315 	BPF_RAW_INSN(BPF_JMP | BPF_CALL, 0, 0, 0, BPF_FUNC_map_lookup_elem),
316 	BPF_JMP_IMM(BPF_JNE, BPF_REG_0, 0, 1),
317 	BPF_EXIT_INSN(),
318 	BPF_MOV64_REG(BPF_REG_7, BPF_REG_0),
319 	BPF_MOV64_REG(BPF_REG_1, BPF_REG_0),
320 	BPF_ALU64_IMM(BPF_ADD, BPF_REG_1, 4),
321 	BPF_RAW_INSN(BPF_JMP | BPF_CALL, 0, 0, 0, BPF_FUNC_spin_lock),
322 	BPF_LD_ABS(BPF_B, 0),
323 	BPF_MOV64_REG(BPF_REG_1, BPF_REG_7),
324 	BPF_ALU64_IMM(BPF_ADD, BPF_REG_1, 4),
325 	BPF_RAW_INSN(BPF_JMP | BPF_CALL, 0, 0, 0, BPF_FUNC_spin_unlock),
326 	BPF_MOV64_IMM(BPF_REG_0, 0),
327 	BPF_EXIT_INSN(),
328 	},
329 	.fixup_map_spin_lock = { 4 },
330 	.result = REJECT,
331 	.errstr = "inside bpf_spin_lock",
332 	.prog_type = BPF_PROG_TYPE_SCHED_CLS,
333 },
334 {
335 	"spin_lock: regsafe compare reg->id for map value",
336 	.insns = {
337 	BPF_MOV64_REG(BPF_REG_6, BPF_REG_1),
338 	BPF_LDX_MEM(BPF_W, BPF_REG_6, BPF_REG_6, offsetof(struct __sk_buff, mark)),
339 	BPF_LD_MAP_FD(BPF_REG_1, 0),
340 	BPF_MOV64_REG(BPF_REG_9, BPF_REG_1),
341 	BPF_ST_MEM(BPF_W, BPF_REG_10, -4, 0),
342 	BPF_MOV64_REG(BPF_REG_2, BPF_REG_10),
343 	BPF_ALU64_IMM(BPF_ADD, BPF_REG_2, -4),
344 	BPF_RAW_INSN(BPF_JMP | BPF_CALL, 0, 0, 0, BPF_FUNC_map_lookup_elem),
345 	BPF_JMP_IMM(BPF_JNE, BPF_REG_0, 0, 1),
346 	BPF_EXIT_INSN(),
347 	BPF_MOV64_REG(BPF_REG_7, BPF_REG_0),
348 	BPF_MOV64_REG(BPF_REG_1, BPF_REG_9),
349 	BPF_MOV64_REG(BPF_REG_2, BPF_REG_10),
350 	BPF_ALU64_IMM(BPF_ADD, BPF_REG_2, -4),
351 	BPF_RAW_INSN(BPF_JMP | BPF_CALL, 0, 0, 0, BPF_FUNC_map_lookup_elem),
352 	BPF_JMP_IMM(BPF_JNE, BPF_REG_0, 0, 1),
353 	BPF_EXIT_INSN(),
354 	BPF_MOV64_REG(BPF_REG_8, BPF_REG_0),
355 	BPF_MOV64_REG(BPF_REG_1, BPF_REG_7),
356 	BPF_ALU64_IMM(BPF_ADD, BPF_REG_1, 4),
357 	BPF_RAW_INSN(BPF_JMP | BPF_CALL, 0, 0, 0, BPF_FUNC_spin_lock),
358 	BPF_JMP_IMM(BPF_JEQ, BPF_REG_6, 0, 1),
359 	BPF_JMP_IMM(BPF_JA, 0, 0, 1),
360 	BPF_MOV64_REG(BPF_REG_7, BPF_REG_8),
361 	BPF_MOV64_REG(BPF_REG_1, BPF_REG_7),
362 	BPF_ALU64_IMM(BPF_ADD, BPF_REG_1, 4),
363 	BPF_RAW_INSN(BPF_JMP | BPF_CALL, 0, 0, 0, BPF_FUNC_spin_unlock),
364 	BPF_MOV64_IMM(BPF_REG_0, 0),
365 	BPF_EXIT_INSN(),
366 	},
367 	.fixup_map_spin_lock = { 2 },
368 	.result = REJECT,
369 	.errstr = "bpf_spin_unlock of different lock",
370 	.prog_type = BPF_PROG_TYPE_SCHED_CLS,
371 	.flags = BPF_F_TEST_STATE_FREQ,
372 },
373 /* Make sure that regsafe() compares ids for spin lock records using
374  * check_ids():
375  *  1: r9 = map_lookup_elem(...)  ; r9.id == 1
376  *  2: r8 = map_lookup_elem(...)  ; r8.id == 2
377  *  3: r7 = ktime_get_ns()
378  *  4: r6 = ktime_get_ns()
379  *  5: if r6 > r7 goto <9>
380  *  6: spin_lock(r8)
381  *  7: r9 = r8
382  *  8: goto <10>
383  *  9: spin_lock(r9)
384  * 10: spin_unlock(r9)             ; r9.id == 1 || r9.id == 2 and lock is active,
385  *                                 ; second visit to (10) should be considered safe
386  *                                 ; if check_ids() is used.
387  * 11: exit(0)
388  */
389 {
390 	"spin_lock: regsafe() check_ids() similar id mappings",
391 	.insns = {
392 	BPF_ST_MEM(BPF_W, BPF_REG_10, -4, 0),
393 	/* r9 = map_lookup_elem(...) */
394 	BPF_MOV64_REG(BPF_REG_2, BPF_REG_10),
395 	BPF_ALU64_IMM(BPF_ADD, BPF_REG_2, -4),
396 	BPF_LD_MAP_FD(BPF_REG_1,
397 		      0),
398 	BPF_EMIT_CALL(BPF_FUNC_map_lookup_elem),
399 	BPF_JMP_IMM(BPF_JEQ, BPF_REG_0, 0, 24),
400 	BPF_MOV64_REG(BPF_REG_9, BPF_REG_0),
401 	/* r8 = map_lookup_elem(...) */
402 	BPF_MOV64_REG(BPF_REG_2, BPF_REG_10),
403 	BPF_ALU64_IMM(BPF_ADD, BPF_REG_2, -4),
404 	BPF_LD_MAP_FD(BPF_REG_1,
405 		      0),
406 	BPF_EMIT_CALL(BPF_FUNC_map_lookup_elem),
407 	BPF_JMP_IMM(BPF_JEQ, BPF_REG_0, 0, 18),
408 	BPF_MOV64_REG(BPF_REG_8, BPF_REG_0),
409 	/* r7 = ktime_get_ns() */
410 	BPF_EMIT_CALL(BPF_FUNC_ktime_get_ns),
411 	BPF_MOV64_REG(BPF_REG_7, BPF_REG_0),
412 	/* r6 = ktime_get_ns() */
413 	BPF_EMIT_CALL(BPF_FUNC_ktime_get_ns),
414 	BPF_MOV64_REG(BPF_REG_6, BPF_REG_0),
415 	/* if r6 > r7 goto +5      ; no new information about the state is derived from
416 	 *                         ; this check, thus produced verifier states differ
417 	 *                         ; only in 'insn_idx'
418 	 * spin_lock(r8)
419 	 * r9 = r8
420 	 * goto unlock
421 	 */
422 	BPF_JMP_REG(BPF_JGT, BPF_REG_6, BPF_REG_7, 5),
423 	BPF_MOV64_REG(BPF_REG_1, BPF_REG_8),
424 	BPF_ALU64_IMM(BPF_ADD, BPF_REG_1, 4),
425 	BPF_EMIT_CALL(BPF_FUNC_spin_lock),
426 	BPF_MOV64_REG(BPF_REG_9, BPF_REG_8),
427 	BPF_JMP_A(3),
428 	/* spin_lock(r9) */
429 	BPF_MOV64_REG(BPF_REG_1, BPF_REG_9),
430 	BPF_ALU64_IMM(BPF_ADD, BPF_REG_1, 4),
431 	BPF_EMIT_CALL(BPF_FUNC_spin_lock),
432 	/* spin_unlock(r9) */
433 	BPF_MOV64_REG(BPF_REG_1, BPF_REG_9),
434 	BPF_ALU64_IMM(BPF_ADD, BPF_REG_1, 4),
435 	BPF_EMIT_CALL(BPF_FUNC_spin_unlock),
436 	/* exit(0) */
437 	BPF_MOV64_IMM(BPF_REG_0, 0),
438 	BPF_EXIT_INSN(),
439 	},
440 	.fixup_map_spin_lock = { 3, 10 },
441 	.result = VERBOSE_ACCEPT,
442 	.errstr = "28: safe",
443 	.result_unpriv = REJECT,
444 	.errstr_unpriv = "",
445 	.prog_type = BPF_PROG_TYPE_CGROUP_SKB,
446 	.flags = BPF_F_TEST_STATE_FREQ,
447 },
448