1 // SPDX-License-Identifier: GPL-2.0
2 // Copyright (c) 2019 Facebook
11 #include <linux/filter.h>
14 #include <bpf/libbpf.h>
16 #include "bpf_endian.h"
17 #include "bpf_rlimit.h"
19 #include "cgroup_helpers.h"
21 #define CG_PATH "/foo"
23 #define FIXUP_SYSCTL_VALUE 0
25 char bpf_log_buf[BPF_LOG_BUF_SIZE];
29 size_t fixup_value_insn;
30 struct bpf_insn insns[MAX_INSNS];
31 const char *prog_file;
32 enum bpf_attach_type attach_type;
46 static struct sysctl_test tests[] = {
48 .descr = "sysctl wrong attach_type",
50 BPF_MOV64_IMM(BPF_REG_0, 1),
54 .sysctl = "kernel/ostype",
55 .open_flags = O_RDONLY,
56 .result = ATTACH_REJECT,
59 .descr = "sysctl:read allow all",
61 BPF_MOV64_IMM(BPF_REG_0, 1),
64 .attach_type = BPF_CGROUP_SYSCTL,
65 .sysctl = "kernel/ostype",
66 .open_flags = O_RDONLY,
70 .descr = "sysctl:read deny all",
72 BPF_MOV64_IMM(BPF_REG_0, 0),
75 .attach_type = BPF_CGROUP_SYSCTL,
76 .sysctl = "kernel/ostype",
77 .open_flags = O_RDONLY,
81 .descr = "ctx:write sysctl:read read ok",
84 BPF_LDX_MEM(BPF_W, BPF_REG_7, BPF_REG_1,
85 offsetof(struct bpf_sysctl, write)),
86 BPF_JMP_IMM(BPF_JNE, BPF_REG_7, 1, 2),
89 BPF_MOV64_IMM(BPF_REG_0, 0),
92 /* else return ALLOW; */
93 BPF_MOV64_IMM(BPF_REG_0, 1),
96 .attach_type = BPF_CGROUP_SYSCTL,
97 .sysctl = "kernel/ostype",
98 .open_flags = O_RDONLY,
102 .descr = "ctx:write sysctl:write read ok",
105 BPF_LDX_MEM(BPF_W, BPF_REG_7, BPF_REG_1,
106 offsetof(struct bpf_sysctl, write)),
107 BPF_JMP_IMM(BPF_JNE, BPF_REG_7, 1, 2),
110 BPF_MOV64_IMM(BPF_REG_0, 0),
113 /* else return ALLOW; */
114 BPF_MOV64_IMM(BPF_REG_0, 1),
117 .attach_type = BPF_CGROUP_SYSCTL,
118 .sysctl = "kernel/domainname",
119 .open_flags = O_WRONLY,
120 .newval = "(none)", /* same as default, should fail anyway */
124 .descr = "ctx:write sysctl:read write reject",
127 BPF_MOV64_IMM(BPF_REG_0, 0),
128 BPF_STX_MEM(BPF_W, BPF_REG_1, BPF_REG_0,
129 offsetof(struct bpf_sysctl, write)),
130 BPF_MOV64_IMM(BPF_REG_0, 1),
133 .attach_type = BPF_CGROUP_SYSCTL,
134 .sysctl = "kernel/ostype",
135 .open_flags = O_RDONLY,
136 .result = LOAD_REJECT,
139 .descr = "ctx:file_pos sysctl:read read ok",
141 /* If (file_pos == X) */
142 BPF_LDX_MEM(BPF_W, BPF_REG_7, BPF_REG_1,
143 offsetof(struct bpf_sysctl, file_pos)),
144 BPF_JMP_IMM(BPF_JNE, BPF_REG_7, 3, 2),
147 BPF_MOV64_IMM(BPF_REG_0, 1),
150 /* else return DENY; */
151 BPF_MOV64_IMM(BPF_REG_0, 0),
154 .attach_type = BPF_CGROUP_SYSCTL,
155 .sysctl = "kernel/ostype",
156 .open_flags = O_RDONLY,
161 .descr = "ctx:file_pos sysctl:read read ok narrow",
163 /* If (file_pos == X) */
164 #if __BYTE_ORDER == __LITTLE_ENDIAN
165 BPF_LDX_MEM(BPF_B, BPF_REG_7, BPF_REG_1,
166 offsetof(struct bpf_sysctl, file_pos)),
168 BPF_LDX_MEM(BPF_B, BPF_REG_7, BPF_REG_1,
169 offsetof(struct bpf_sysctl, file_pos) + 3),
171 BPF_JMP_IMM(BPF_JNE, BPF_REG_7, 4, 2),
174 BPF_MOV64_IMM(BPF_REG_0, 1),
177 /* else return DENY; */
178 BPF_MOV64_IMM(BPF_REG_0, 0),
181 .attach_type = BPF_CGROUP_SYSCTL,
182 .sysctl = "kernel/ostype",
183 .open_flags = O_RDONLY,
188 .descr = "ctx:file_pos sysctl:read write ok",
191 BPF_MOV64_IMM(BPF_REG_0, 2),
192 BPF_STX_MEM(BPF_W, BPF_REG_1, BPF_REG_0,
193 offsetof(struct bpf_sysctl, file_pos)),
194 BPF_MOV64_IMM(BPF_REG_0, 1),
197 .attach_type = BPF_CGROUP_SYSCTL,
198 .sysctl = "kernel/ostype",
199 .open_flags = O_RDONLY,
204 .descr = "sysctl_get_name sysctl_value:base ok",
206 /* sysctl_get_name arg2 (buf) */
207 BPF_MOV64_REG(BPF_REG_7, BPF_REG_10),
208 BPF_ALU64_IMM(BPF_ADD, BPF_REG_7, -8),
209 BPF_MOV64_IMM(BPF_REG_0, 0),
210 BPF_STX_MEM(BPF_DW, BPF_REG_7, BPF_REG_0, 0),
212 BPF_MOV64_REG(BPF_REG_2, BPF_REG_7),
214 /* sysctl_get_name arg3 (buf_len) */
215 BPF_MOV64_IMM(BPF_REG_3, 8),
217 /* sysctl_get_name arg4 (flags) */
218 BPF_MOV64_IMM(BPF_REG_4, BPF_F_SYSCTL_BASE_NAME),
220 /* sysctl_get_name(ctx, buf, buf_len, flags) */
221 BPF_EMIT_CALL(BPF_FUNC_sysctl_get_name),
223 /* if (ret == expected && */
224 BPF_JMP_IMM(BPF_JNE, BPF_REG_0, sizeof("tcp_mem") - 1, 6),
225 /* buf == "tcp_mem\0") */
226 BPF_LD_IMM64(BPF_REG_8,
227 bpf_be64_to_cpu(0x7463705f6d656d00ULL)),
228 BPF_LDX_MEM(BPF_DW, BPF_REG_9, BPF_REG_7, 0),
229 BPF_JMP_REG(BPF_JNE, BPF_REG_8, BPF_REG_9, 2),
232 BPF_MOV64_IMM(BPF_REG_0, 1),
235 /* else return DENY; */
236 BPF_MOV64_IMM(BPF_REG_0, 0),
239 .attach_type = BPF_CGROUP_SYSCTL,
240 .sysctl = "net/ipv4/tcp_mem",
241 .open_flags = O_RDONLY,
245 .descr = "sysctl_get_name sysctl_value:base E2BIG truncated",
247 /* sysctl_get_name arg2 (buf) */
248 BPF_MOV64_REG(BPF_REG_7, BPF_REG_10),
249 BPF_ALU64_IMM(BPF_ADD, BPF_REG_7, -8),
250 BPF_MOV64_IMM(BPF_REG_0, 0),
251 BPF_STX_MEM(BPF_DW, BPF_REG_7, BPF_REG_0, 0),
253 BPF_MOV64_REG(BPF_REG_2, BPF_REG_7),
255 /* sysctl_get_name arg3 (buf_len) too small */
256 BPF_MOV64_IMM(BPF_REG_3, 7),
258 /* sysctl_get_name arg4 (flags) */
259 BPF_MOV64_IMM(BPF_REG_4, BPF_F_SYSCTL_BASE_NAME),
261 /* sysctl_get_name(ctx, buf, buf_len, flags) */
262 BPF_EMIT_CALL(BPF_FUNC_sysctl_get_name),
264 /* if (ret == expected && */
265 BPF_JMP_IMM(BPF_JNE, BPF_REG_0, -E2BIG, 6),
267 /* buf[0:7] == "tcp_me\0") */
268 BPF_LD_IMM64(BPF_REG_8,
269 bpf_be64_to_cpu(0x7463705f6d650000ULL)),
270 BPF_LDX_MEM(BPF_DW, BPF_REG_9, BPF_REG_7, 0),
271 BPF_JMP_REG(BPF_JNE, BPF_REG_8, BPF_REG_9, 2),
274 BPF_MOV64_IMM(BPF_REG_0, 1),
277 /* else return DENY; */
278 BPF_MOV64_IMM(BPF_REG_0, 0),
281 .attach_type = BPF_CGROUP_SYSCTL,
282 .sysctl = "net/ipv4/tcp_mem",
283 .open_flags = O_RDONLY,
287 .descr = "sysctl_get_name sysctl:full ok",
289 /* sysctl_get_name arg2 (buf) */
290 BPF_MOV64_REG(BPF_REG_7, BPF_REG_10),
291 BPF_ALU64_IMM(BPF_ADD, BPF_REG_7, -24),
292 BPF_MOV64_IMM(BPF_REG_0, 0),
293 BPF_STX_MEM(BPF_DW, BPF_REG_7, BPF_REG_0, 0),
294 BPF_STX_MEM(BPF_DW, BPF_REG_7, BPF_REG_0, 8),
295 BPF_STX_MEM(BPF_DW, BPF_REG_7, BPF_REG_0, 16),
297 BPF_MOV64_REG(BPF_REG_2, BPF_REG_7),
299 /* sysctl_get_name arg3 (buf_len) */
300 BPF_MOV64_IMM(BPF_REG_3, 17),
302 /* sysctl_get_name arg4 (flags) */
303 BPF_MOV64_IMM(BPF_REG_4, 0),
305 /* sysctl_get_name(ctx, buf, buf_len, flags) */
306 BPF_EMIT_CALL(BPF_FUNC_sysctl_get_name),
308 /* if (ret == expected && */
309 BPF_JMP_IMM(BPF_JNE, BPF_REG_0, 16, 14),
311 /* buf[0:8] == "net/ipv4" && */
312 BPF_LD_IMM64(BPF_REG_8,
313 bpf_be64_to_cpu(0x6e65742f69707634ULL)),
314 BPF_LDX_MEM(BPF_DW, BPF_REG_9, BPF_REG_7, 0),
315 BPF_JMP_REG(BPF_JNE, BPF_REG_8, BPF_REG_9, 10),
317 /* buf[8:16] == "/tcp_mem" && */
318 BPF_LD_IMM64(BPF_REG_8,
319 bpf_be64_to_cpu(0x2f7463705f6d656dULL)),
320 BPF_LDX_MEM(BPF_DW, BPF_REG_9, BPF_REG_7, 8),
321 BPF_JMP_REG(BPF_JNE, BPF_REG_8, BPF_REG_9, 6),
323 /* buf[16:24] == "\0") */
324 BPF_LD_IMM64(BPF_REG_8, 0x0ULL),
325 BPF_LDX_MEM(BPF_DW, BPF_REG_9, BPF_REG_7, 16),
326 BPF_JMP_REG(BPF_JNE, BPF_REG_8, BPF_REG_9, 2),
329 BPF_MOV64_IMM(BPF_REG_0, 1),
332 /* else return DENY; */
333 BPF_MOV64_IMM(BPF_REG_0, 0),
336 .attach_type = BPF_CGROUP_SYSCTL,
337 .sysctl = "net/ipv4/tcp_mem",
338 .open_flags = O_RDONLY,
342 .descr = "sysctl_get_name sysctl:full E2BIG truncated",
344 /* sysctl_get_name arg2 (buf) */
345 BPF_MOV64_REG(BPF_REG_7, BPF_REG_10),
346 BPF_ALU64_IMM(BPF_ADD, BPF_REG_7, -16),
347 BPF_MOV64_IMM(BPF_REG_0, 0),
348 BPF_STX_MEM(BPF_DW, BPF_REG_7, BPF_REG_0, 0),
349 BPF_STX_MEM(BPF_DW, BPF_REG_7, BPF_REG_0, 8),
351 BPF_MOV64_REG(BPF_REG_2, BPF_REG_7),
353 /* sysctl_get_name arg3 (buf_len) */
354 BPF_MOV64_IMM(BPF_REG_3, 16),
356 /* sysctl_get_name arg4 (flags) */
357 BPF_MOV64_IMM(BPF_REG_4, 0),
359 /* sysctl_get_name(ctx, buf, buf_len, flags) */
360 BPF_EMIT_CALL(BPF_FUNC_sysctl_get_name),
362 /* if (ret == expected && */
363 BPF_JMP_IMM(BPF_JNE, BPF_REG_0, -E2BIG, 10),
365 /* buf[0:8] == "net/ipv4" && */
366 BPF_LD_IMM64(BPF_REG_8,
367 bpf_be64_to_cpu(0x6e65742f69707634ULL)),
368 BPF_LDX_MEM(BPF_DW, BPF_REG_9, BPF_REG_7, 0),
369 BPF_JMP_REG(BPF_JNE, BPF_REG_8, BPF_REG_9, 6),
371 /* buf[8:16] == "/tcp_me\0") */
372 BPF_LD_IMM64(BPF_REG_8,
373 bpf_be64_to_cpu(0x2f7463705f6d6500ULL)),
374 BPF_LDX_MEM(BPF_DW, BPF_REG_9, BPF_REG_7, 8),
375 BPF_JMP_REG(BPF_JNE, BPF_REG_8, BPF_REG_9, 2),
378 BPF_MOV64_IMM(BPF_REG_0, 1),
381 /* else return DENY; */
382 BPF_MOV64_IMM(BPF_REG_0, 0),
385 .attach_type = BPF_CGROUP_SYSCTL,
386 .sysctl = "net/ipv4/tcp_mem",
387 .open_flags = O_RDONLY,
391 .descr = "sysctl_get_name sysctl:full E2BIG truncated small",
393 /* sysctl_get_name arg2 (buf) */
394 BPF_MOV64_REG(BPF_REG_7, BPF_REG_10),
395 BPF_ALU64_IMM(BPF_ADD, BPF_REG_7, -8),
396 BPF_MOV64_IMM(BPF_REG_0, 0),
397 BPF_STX_MEM(BPF_DW, BPF_REG_7, BPF_REG_0, 0),
399 BPF_MOV64_REG(BPF_REG_2, BPF_REG_7),
401 /* sysctl_get_name arg3 (buf_len) */
402 BPF_MOV64_IMM(BPF_REG_3, 7),
404 /* sysctl_get_name arg4 (flags) */
405 BPF_MOV64_IMM(BPF_REG_4, 0),
407 /* sysctl_get_name(ctx, buf, buf_len, flags) */
408 BPF_EMIT_CALL(BPF_FUNC_sysctl_get_name),
410 /* if (ret == expected && */
411 BPF_JMP_IMM(BPF_JNE, BPF_REG_0, -E2BIG, 6),
413 /* buf[0:8] == "net/ip\0") */
414 BPF_LD_IMM64(BPF_REG_8,
415 bpf_be64_to_cpu(0x6e65742f69700000ULL)),
416 BPF_LDX_MEM(BPF_DW, BPF_REG_9, BPF_REG_7, 0),
417 BPF_JMP_REG(BPF_JNE, BPF_REG_8, BPF_REG_9, 2),
420 BPF_MOV64_IMM(BPF_REG_0, 1),
423 /* else return DENY; */
424 BPF_MOV64_IMM(BPF_REG_0, 0),
427 .attach_type = BPF_CGROUP_SYSCTL,
428 .sysctl = "net/ipv4/tcp_mem",
429 .open_flags = O_RDONLY,
433 .descr = "sysctl_get_current_value sysctl:read ok, gt",
435 /* sysctl_get_current_value arg2 (buf) */
436 BPF_MOV64_REG(BPF_REG_7, BPF_REG_10),
437 BPF_ALU64_IMM(BPF_ADD, BPF_REG_7, -8),
438 BPF_MOV64_REG(BPF_REG_2, BPF_REG_7),
440 /* sysctl_get_current_value arg3 (buf_len) */
441 BPF_MOV64_IMM(BPF_REG_3, 8),
443 /* sysctl_get_current_value(ctx, buf, buf_len) */
444 BPF_EMIT_CALL(BPF_FUNC_sysctl_get_current_value),
446 /* if (ret == expected && */
447 BPF_JMP_IMM(BPF_JNE, BPF_REG_0, 6, 6),
449 /* buf[0:6] == "Linux\n\0") */
450 BPF_LD_IMM64(BPF_REG_8,
451 bpf_be64_to_cpu(0x4c696e75780a0000ULL)),
452 BPF_LDX_MEM(BPF_DW, BPF_REG_9, BPF_REG_7, 0),
453 BPF_JMP_REG(BPF_JNE, BPF_REG_8, BPF_REG_9, 2),
456 BPF_MOV64_IMM(BPF_REG_0, 1),
459 /* else return DENY; */
460 BPF_MOV64_IMM(BPF_REG_0, 0),
463 .attach_type = BPF_CGROUP_SYSCTL,
464 .sysctl = "kernel/ostype",
465 .open_flags = O_RDONLY,
469 .descr = "sysctl_get_current_value sysctl:read ok, eq",
471 /* sysctl_get_current_value arg2 (buf) */
472 BPF_MOV64_REG(BPF_REG_7, BPF_REG_10),
473 BPF_ALU64_IMM(BPF_ADD, BPF_REG_7, -8),
474 BPF_MOV64_IMM(BPF_REG_0, 0),
475 BPF_STX_MEM(BPF_B, BPF_REG_7, BPF_REG_0, 7),
477 BPF_MOV64_REG(BPF_REG_2, BPF_REG_7),
479 /* sysctl_get_current_value arg3 (buf_len) */
480 BPF_MOV64_IMM(BPF_REG_3, 7),
482 /* sysctl_get_current_value(ctx, buf, buf_len) */
483 BPF_EMIT_CALL(BPF_FUNC_sysctl_get_current_value),
485 /* if (ret == expected && */
486 BPF_JMP_IMM(BPF_JNE, BPF_REG_0, 6, 6),
488 /* buf[0:6] == "Linux\n\0") */
489 BPF_LD_IMM64(BPF_REG_8,
490 bpf_be64_to_cpu(0x4c696e75780a0000ULL)),
491 BPF_LDX_MEM(BPF_DW, BPF_REG_9, BPF_REG_7, 0),
492 BPF_JMP_REG(BPF_JNE, BPF_REG_8, BPF_REG_9, 2),
495 BPF_MOV64_IMM(BPF_REG_0, 1),
498 /* else return DENY; */
499 BPF_MOV64_IMM(BPF_REG_0, 0),
502 .attach_type = BPF_CGROUP_SYSCTL,
503 .sysctl = "kernel/ostype",
504 .open_flags = O_RDONLY,
508 .descr = "sysctl_get_current_value sysctl:read E2BIG truncated",
510 /* sysctl_get_current_value arg2 (buf) */
511 BPF_MOV64_REG(BPF_REG_7, BPF_REG_10),
512 BPF_ALU64_IMM(BPF_ADD, BPF_REG_7, -8),
513 BPF_MOV64_IMM(BPF_REG_0, 0),
514 BPF_STX_MEM(BPF_H, BPF_REG_7, BPF_REG_0, 6),
516 BPF_MOV64_REG(BPF_REG_2, BPF_REG_7),
518 /* sysctl_get_current_value arg3 (buf_len) */
519 BPF_MOV64_IMM(BPF_REG_3, 6),
521 /* sysctl_get_current_value(ctx, buf, buf_len) */
522 BPF_EMIT_CALL(BPF_FUNC_sysctl_get_current_value),
524 /* if (ret == expected && */
525 BPF_JMP_IMM(BPF_JNE, BPF_REG_0, -E2BIG, 6),
527 /* buf[0:6] == "Linux\0") */
528 BPF_LD_IMM64(BPF_REG_8,
529 bpf_be64_to_cpu(0x4c696e7578000000ULL)),
530 BPF_LDX_MEM(BPF_DW, BPF_REG_9, BPF_REG_7, 0),
531 BPF_JMP_REG(BPF_JNE, BPF_REG_8, BPF_REG_9, 2),
534 BPF_MOV64_IMM(BPF_REG_0, 1),
537 /* else return DENY; */
538 BPF_MOV64_IMM(BPF_REG_0, 0),
541 .attach_type = BPF_CGROUP_SYSCTL,
542 .sysctl = "kernel/ostype",
543 .open_flags = O_RDONLY,
547 .descr = "sysctl_get_current_value sysctl:read EINVAL",
549 /* sysctl_get_current_value arg2 (buf) */
550 BPF_MOV64_REG(BPF_REG_7, BPF_REG_10),
551 BPF_ALU64_IMM(BPF_ADD, BPF_REG_7, -8),
553 BPF_MOV64_REG(BPF_REG_2, BPF_REG_7),
555 /* sysctl_get_current_value arg3 (buf_len) */
556 BPF_MOV64_IMM(BPF_REG_3, 8),
558 /* sysctl_get_current_value(ctx, buf, buf_len) */
559 BPF_EMIT_CALL(BPF_FUNC_sysctl_get_current_value),
561 /* if (ret == expected && */
562 BPF_JMP_IMM(BPF_JNE, BPF_REG_0, -EINVAL, 4),
564 /* buf[0:8] is NUL-filled) */
565 BPF_LDX_MEM(BPF_DW, BPF_REG_9, BPF_REG_7, 0),
566 BPF_JMP_IMM(BPF_JNE, BPF_REG_9, 0, 2),
569 BPF_MOV64_IMM(BPF_REG_0, 0),
572 /* else return ALLOW; */
573 BPF_MOV64_IMM(BPF_REG_0, 1),
576 .attach_type = BPF_CGROUP_SYSCTL,
577 .sysctl = "net/ipv6/conf/lo/stable_secret", /* -EIO */
578 .open_flags = O_RDONLY,
582 .descr = "sysctl_get_current_value sysctl:write ok",
583 .fixup_value_insn = 6,
585 /* sysctl_get_current_value arg2 (buf) */
586 BPF_MOV64_REG(BPF_REG_7, BPF_REG_10),
587 BPF_ALU64_IMM(BPF_ADD, BPF_REG_7, -8),
589 BPF_MOV64_REG(BPF_REG_2, BPF_REG_7),
591 /* sysctl_get_current_value arg3 (buf_len) */
592 BPF_MOV64_IMM(BPF_REG_3, 8),
594 /* sysctl_get_current_value(ctx, buf, buf_len) */
595 BPF_EMIT_CALL(BPF_FUNC_sysctl_get_current_value),
597 /* if (ret == expected && */
598 BPF_JMP_IMM(BPF_JNE, BPF_REG_0, 4, 6),
600 /* buf[0:4] == expected) */
601 BPF_LD_IMM64(BPF_REG_8, FIXUP_SYSCTL_VALUE),
602 BPF_LDX_MEM(BPF_DW, BPF_REG_9, BPF_REG_7, 0),
603 BPF_JMP_REG(BPF_JNE, BPF_REG_8, BPF_REG_9, 2),
606 BPF_MOV64_IMM(BPF_REG_0, 0),
609 /* else return ALLOW; */
610 BPF_MOV64_IMM(BPF_REG_0, 1),
613 .attach_type = BPF_CGROUP_SYSCTL,
614 .sysctl = "net/ipv4/route/mtu_expires",
615 .open_flags = O_WRONLY,
616 .newval = "600", /* same as default, should fail anyway */
620 .descr = "sysctl_get_new_value sysctl:read EINVAL",
622 /* sysctl_get_new_value arg2 (buf) */
623 BPF_MOV64_REG(BPF_REG_7, BPF_REG_10),
624 BPF_ALU64_IMM(BPF_ADD, BPF_REG_7, -8),
625 BPF_MOV64_IMM(BPF_REG_0, 0),
626 BPF_STX_MEM(BPF_DW, BPF_REG_7, BPF_REG_0, 0),
628 BPF_MOV64_REG(BPF_REG_2, BPF_REG_7),
630 /* sysctl_get_new_value arg3 (buf_len) */
631 BPF_MOV64_IMM(BPF_REG_3, 8),
633 /* sysctl_get_new_value(ctx, buf, buf_len) */
634 BPF_EMIT_CALL(BPF_FUNC_sysctl_get_new_value),
636 /* if (ret == expected) */
637 BPF_JMP_IMM(BPF_JNE, BPF_REG_0, -EINVAL, 2),
640 BPF_MOV64_IMM(BPF_REG_0, 1),
643 /* else return DENY; */
644 BPF_MOV64_IMM(BPF_REG_0, 0),
647 .attach_type = BPF_CGROUP_SYSCTL,
648 .sysctl = "net/ipv4/tcp_mem",
649 .open_flags = O_RDONLY,
653 .descr = "sysctl_get_new_value sysctl:write ok",
655 /* sysctl_get_new_value arg2 (buf) */
656 BPF_MOV64_REG(BPF_REG_7, BPF_REG_10),
657 BPF_ALU64_IMM(BPF_ADD, BPF_REG_7, -8),
659 BPF_MOV64_REG(BPF_REG_2, BPF_REG_7),
661 /* sysctl_get_new_value arg3 (buf_len) */
662 BPF_MOV64_IMM(BPF_REG_3, 4),
664 /* sysctl_get_new_value(ctx, buf, buf_len) */
665 BPF_EMIT_CALL(BPF_FUNC_sysctl_get_new_value),
667 /* if (ret == expected && */
668 BPF_JMP_IMM(BPF_JNE, BPF_REG_0, 3, 4),
670 /* buf[0:4] == "606\0") */
671 BPF_LDX_MEM(BPF_W, BPF_REG_9, BPF_REG_7, 0),
672 BPF_JMP_IMM(BPF_JNE, BPF_REG_9,
673 bpf_ntohl(0x36303600), 2),
676 BPF_MOV64_IMM(BPF_REG_0, 0),
679 /* else return ALLOW; */
680 BPF_MOV64_IMM(BPF_REG_0, 1),
683 .attach_type = BPF_CGROUP_SYSCTL,
684 .sysctl = "net/ipv4/route/mtu_expires",
685 .open_flags = O_WRONLY,
690 .descr = "sysctl_get_new_value sysctl:write ok long",
692 /* sysctl_get_new_value arg2 (buf) */
693 BPF_MOV64_REG(BPF_REG_7, BPF_REG_10),
694 BPF_ALU64_IMM(BPF_ADD, BPF_REG_7, -24),
696 BPF_MOV64_REG(BPF_REG_2, BPF_REG_7),
698 /* sysctl_get_new_value arg3 (buf_len) */
699 BPF_MOV64_IMM(BPF_REG_3, 24),
701 /* sysctl_get_new_value(ctx, buf, buf_len) */
702 BPF_EMIT_CALL(BPF_FUNC_sysctl_get_new_value),
704 /* if (ret == expected && */
705 BPF_JMP_IMM(BPF_JNE, BPF_REG_0, 23, 14),
707 /* buf[0:8] == "3000000 " && */
708 BPF_LD_IMM64(BPF_REG_8,
709 bpf_be64_to_cpu(0x3330303030303020ULL)),
710 BPF_LDX_MEM(BPF_DW, BPF_REG_9, BPF_REG_7, 0),
711 BPF_JMP_REG(BPF_JNE, BPF_REG_8, BPF_REG_9, 10),
713 /* buf[8:16] == "4000000 " && */
714 BPF_LD_IMM64(BPF_REG_8,
715 bpf_be64_to_cpu(0x3430303030303020ULL)),
716 BPF_LDX_MEM(BPF_DW, BPF_REG_9, BPF_REG_7, 8),
717 BPF_JMP_REG(BPF_JNE, BPF_REG_8, BPF_REG_9, 6),
719 /* buf[16:24] == "6000000\0") */
720 BPF_LD_IMM64(BPF_REG_8,
721 bpf_be64_to_cpu(0x3630303030303000ULL)),
722 BPF_LDX_MEM(BPF_DW, BPF_REG_9, BPF_REG_7, 16),
723 BPF_JMP_REG(BPF_JNE, BPF_REG_8, BPF_REG_9, 2),
726 BPF_MOV64_IMM(BPF_REG_0, 0),
729 /* else return ALLOW; */
730 BPF_MOV64_IMM(BPF_REG_0, 1),
733 .attach_type = BPF_CGROUP_SYSCTL,
734 .sysctl = "net/ipv4/tcp_mem",
735 .open_flags = O_WRONLY,
736 .newval = "3000000 4000000 6000000",
740 .descr = "sysctl_get_new_value sysctl:write E2BIG",
742 /* sysctl_get_new_value arg2 (buf) */
743 BPF_MOV64_REG(BPF_REG_7, BPF_REG_10),
744 BPF_ALU64_IMM(BPF_ADD, BPF_REG_7, -8),
745 BPF_MOV64_IMM(BPF_REG_0, 0),
746 BPF_STX_MEM(BPF_B, BPF_REG_7, BPF_REG_0, 3),
748 BPF_MOV64_REG(BPF_REG_2, BPF_REG_7),
750 /* sysctl_get_new_value arg3 (buf_len) */
751 BPF_MOV64_IMM(BPF_REG_3, 3),
753 /* sysctl_get_new_value(ctx, buf, buf_len) */
754 BPF_EMIT_CALL(BPF_FUNC_sysctl_get_new_value),
756 /* if (ret == expected && */
757 BPF_JMP_IMM(BPF_JNE, BPF_REG_0, -E2BIG, 4),
759 /* buf[0:3] == "60\0") */
760 BPF_LDX_MEM(BPF_W, BPF_REG_9, BPF_REG_7, 0),
761 BPF_JMP_IMM(BPF_JNE, BPF_REG_9,
762 bpf_ntohl(0x36300000), 2),
765 BPF_MOV64_IMM(BPF_REG_0, 0),
768 /* else return ALLOW; */
769 BPF_MOV64_IMM(BPF_REG_0, 1),
772 .attach_type = BPF_CGROUP_SYSCTL,
773 .sysctl = "net/ipv4/route/mtu_expires",
774 .open_flags = O_WRONLY,
779 .descr = "sysctl_set_new_value sysctl:read EINVAL",
781 /* sysctl_set_new_value arg2 (buf) */
782 BPF_MOV64_REG(BPF_REG_7, BPF_REG_10),
783 BPF_ALU64_IMM(BPF_ADD, BPF_REG_7, -8),
784 BPF_MOV64_IMM(BPF_REG_0,
785 bpf_ntohl(0x36303000)),
786 BPF_STX_MEM(BPF_DW, BPF_REG_7, BPF_REG_0, 0),
788 BPF_MOV64_REG(BPF_REG_2, BPF_REG_7),
790 /* sysctl_set_new_value arg3 (buf_len) */
791 BPF_MOV64_IMM(BPF_REG_3, 3),
793 /* sysctl_set_new_value(ctx, buf, buf_len) */
794 BPF_EMIT_CALL(BPF_FUNC_sysctl_set_new_value),
796 /* if (ret == expected) */
797 BPF_JMP_IMM(BPF_JNE, BPF_REG_0, -EINVAL, 2),
800 BPF_MOV64_IMM(BPF_REG_0, 1),
803 /* else return DENY; */
804 BPF_MOV64_IMM(BPF_REG_0, 0),
807 .attach_type = BPF_CGROUP_SYSCTL,
808 .sysctl = "net/ipv4/route/mtu_expires",
809 .open_flags = O_RDONLY,
813 .descr = "sysctl_set_new_value sysctl:write ok",
814 .fixup_value_insn = 2,
816 /* sysctl_set_new_value arg2 (buf) */
817 BPF_MOV64_REG(BPF_REG_7, BPF_REG_10),
818 BPF_ALU64_IMM(BPF_ADD, BPF_REG_7, -8),
819 BPF_LD_IMM64(BPF_REG_0, FIXUP_SYSCTL_VALUE),
820 BPF_STX_MEM(BPF_DW, BPF_REG_7, BPF_REG_0, 0),
822 BPF_MOV64_REG(BPF_REG_2, BPF_REG_7),
824 /* sysctl_set_new_value arg3 (buf_len) */
825 BPF_MOV64_IMM(BPF_REG_3, 3),
827 /* sysctl_set_new_value(ctx, buf, buf_len) */
828 BPF_EMIT_CALL(BPF_FUNC_sysctl_set_new_value),
830 /* if (ret == expected) */
831 BPF_JMP_IMM(BPF_JNE, BPF_REG_0, 0, 2),
834 BPF_MOV64_IMM(BPF_REG_0, 1),
837 /* else return DENY; */
838 BPF_MOV64_IMM(BPF_REG_0, 0),
841 .attach_type = BPF_CGROUP_SYSCTL,
842 .sysctl = "net/ipv4/route/mtu_expires",
843 .open_flags = O_WRONLY,
848 "bpf_strtoul one number string",
851 BPF_MOV64_REG(BPF_REG_7, BPF_REG_10),
852 BPF_ALU64_IMM(BPF_ADD, BPF_REG_7, -8),
853 BPF_MOV64_IMM(BPF_REG_0,
854 bpf_ntohl(0x36303000)),
855 BPF_STX_MEM(BPF_W, BPF_REG_7, BPF_REG_0, 0),
857 BPF_MOV64_REG(BPF_REG_1, BPF_REG_7),
860 BPF_MOV64_IMM(BPF_REG_2, 4),
863 BPF_MOV64_IMM(BPF_REG_3, 0),
866 BPF_ALU64_IMM(BPF_ADD, BPF_REG_7, -8),
867 BPF_STX_MEM(BPF_DW, BPF_REG_7, BPF_REG_0, 0),
868 BPF_MOV64_REG(BPF_REG_4, BPF_REG_7),
870 BPF_EMIT_CALL(BPF_FUNC_strtoul),
872 /* if (ret == expected && */
873 BPF_JMP_IMM(BPF_JNE, BPF_REG_0, 3, 4),
874 /* res == expected) */
875 BPF_LDX_MEM(BPF_DW, BPF_REG_9, BPF_REG_7, 0),
876 BPF_JMP_IMM(BPF_JNE, BPF_REG_9, 600, 2),
879 BPF_MOV64_IMM(BPF_REG_0, 1),
882 /* else return DENY; */
883 BPF_MOV64_IMM(BPF_REG_0, 0),
886 .attach_type = BPF_CGROUP_SYSCTL,
887 .sysctl = "net/ipv4/route/mtu_expires",
888 .open_flags = O_RDONLY,
892 "bpf_strtoul multi number string",
895 BPF_MOV64_REG(BPF_REG_7, BPF_REG_10),
896 BPF_ALU64_IMM(BPF_ADD, BPF_REG_7, -8),
898 BPF_LD_IMM64(BPF_REG_0,
899 bpf_be64_to_cpu(0x3630302036303200ULL)),
900 BPF_STX_MEM(BPF_DW, BPF_REG_7, BPF_REG_0, 0),
901 BPF_MOV64_REG(BPF_REG_1, BPF_REG_7),
904 BPF_MOV64_IMM(BPF_REG_2, 8),
907 BPF_MOV64_IMM(BPF_REG_3, 0),
910 BPF_ALU64_IMM(BPF_ADD, BPF_REG_7, -8),
911 BPF_STX_MEM(BPF_DW, BPF_REG_7, BPF_REG_0, 0),
912 BPF_MOV64_REG(BPF_REG_4, BPF_REG_7),
914 BPF_EMIT_CALL(BPF_FUNC_strtoul),
916 /* if (ret == expected && */
917 BPF_JMP_IMM(BPF_JNE, BPF_REG_0, 3, 18),
918 /* res == expected) */
919 BPF_LDX_MEM(BPF_DW, BPF_REG_9, BPF_REG_7, 0),
920 BPF_JMP_IMM(BPF_JNE, BPF_REG_9, 600, 16),
923 BPF_MOV64_REG(BPF_REG_7, BPF_REG_10),
924 BPF_ALU64_IMM(BPF_ADD, BPF_REG_7, -8),
925 BPF_ALU64_REG(BPF_ADD, BPF_REG_7, BPF_REG_0),
926 BPF_MOV64_REG(BPF_REG_1, BPF_REG_7),
929 BPF_MOV64_IMM(BPF_REG_2, 8),
930 BPF_ALU64_REG(BPF_SUB, BPF_REG_2, BPF_REG_0),
933 BPF_MOV64_IMM(BPF_REG_3, 0),
936 BPF_MOV64_REG(BPF_REG_7, BPF_REG_10),
937 BPF_ALU64_IMM(BPF_ADD, BPF_REG_7, -16),
938 BPF_MOV64_REG(BPF_REG_4, BPF_REG_7),
940 BPF_EMIT_CALL(BPF_FUNC_strtoul),
942 /* if (ret == expected && */
943 BPF_JMP_IMM(BPF_JNE, BPF_REG_0, 4, 4),
944 /* res == expected) */
945 BPF_LDX_MEM(BPF_DW, BPF_REG_9, BPF_REG_7, 0),
946 BPF_JMP_IMM(BPF_JNE, BPF_REG_9, 602, 2),
949 BPF_MOV64_IMM(BPF_REG_0, 1),
952 /* else return DENY; */
953 BPF_MOV64_IMM(BPF_REG_0, 0),
956 .attach_type = BPF_CGROUP_SYSCTL,
957 .sysctl = "net/ipv4/tcp_mem",
958 .open_flags = O_RDONLY,
962 "bpf_strtoul buf_len = 0, reject",
965 BPF_MOV64_REG(BPF_REG_7, BPF_REG_10),
966 BPF_ALU64_IMM(BPF_ADD, BPF_REG_7, -8),
967 BPF_MOV64_IMM(BPF_REG_0,
968 bpf_ntohl(0x36303000)),
969 BPF_STX_MEM(BPF_DW, BPF_REG_7, BPF_REG_0, 0),
971 BPF_MOV64_REG(BPF_REG_1, BPF_REG_7),
974 BPF_MOV64_IMM(BPF_REG_2, 0),
977 BPF_MOV64_IMM(BPF_REG_3, 0),
980 BPF_ALU64_IMM(BPF_ADD, BPF_REG_7, -8),
981 BPF_STX_MEM(BPF_DW, BPF_REG_7, BPF_REG_0, 0),
982 BPF_MOV64_REG(BPF_REG_4, BPF_REG_7),
984 BPF_EMIT_CALL(BPF_FUNC_strtoul),
986 BPF_MOV64_IMM(BPF_REG_0, 1),
989 .attach_type = BPF_CGROUP_SYSCTL,
990 .sysctl = "net/ipv4/route/mtu_expires",
991 .open_flags = O_RDONLY,
992 .result = LOAD_REJECT,
995 "bpf_strtoul supported base, ok",
998 BPF_MOV64_REG(BPF_REG_7, BPF_REG_10),
999 BPF_ALU64_IMM(BPF_ADD, BPF_REG_7, -8),
1000 BPF_MOV64_IMM(BPF_REG_0,
1001 bpf_ntohl(0x30373700)),
1002 BPF_STX_MEM(BPF_W, BPF_REG_7, BPF_REG_0, 0),
1004 BPF_MOV64_REG(BPF_REG_1, BPF_REG_7),
1006 /* arg2 (buf_len) */
1007 BPF_MOV64_IMM(BPF_REG_2, 4),
1010 BPF_MOV64_IMM(BPF_REG_3, 8),
1013 BPF_ALU64_IMM(BPF_ADD, BPF_REG_7, -8),
1014 BPF_STX_MEM(BPF_DW, BPF_REG_7, BPF_REG_0, 0),
1015 BPF_MOV64_REG(BPF_REG_4, BPF_REG_7),
1017 BPF_EMIT_CALL(BPF_FUNC_strtoul),
1019 /* if (ret == expected && */
1020 BPF_JMP_IMM(BPF_JNE, BPF_REG_0, 3, 4),
1021 /* res == expected) */
1022 BPF_LDX_MEM(BPF_DW, BPF_REG_9, BPF_REG_7, 0),
1023 BPF_JMP_IMM(BPF_JNE, BPF_REG_9, 63, 2),
1026 BPF_MOV64_IMM(BPF_REG_0, 1),
1029 /* else return DENY; */
1030 BPF_MOV64_IMM(BPF_REG_0, 0),
1033 .attach_type = BPF_CGROUP_SYSCTL,
1034 .sysctl = "net/ipv4/route/mtu_expires",
1035 .open_flags = O_RDONLY,
1039 "bpf_strtoul unsupported base, EINVAL",
1042 BPF_MOV64_REG(BPF_REG_7, BPF_REG_10),
1043 BPF_ALU64_IMM(BPF_ADD, BPF_REG_7, -8),
1044 BPF_MOV64_IMM(BPF_REG_0,
1045 bpf_ntohl(0x36303000)),
1046 BPF_STX_MEM(BPF_DW, BPF_REG_7, BPF_REG_0, 0),
1048 BPF_MOV64_REG(BPF_REG_1, BPF_REG_7),
1050 /* arg2 (buf_len) */
1051 BPF_MOV64_IMM(BPF_REG_2, 4),
1054 BPF_MOV64_IMM(BPF_REG_3, 3),
1057 BPF_ALU64_IMM(BPF_ADD, BPF_REG_7, -8),
1058 BPF_STX_MEM(BPF_DW, BPF_REG_7, BPF_REG_0, 0),
1059 BPF_MOV64_REG(BPF_REG_4, BPF_REG_7),
1061 BPF_EMIT_CALL(BPF_FUNC_strtoul),
1063 /* if (ret == expected) */
1064 BPF_JMP_IMM(BPF_JNE, BPF_REG_0, -EINVAL, 2),
1067 BPF_MOV64_IMM(BPF_REG_0, 1),
1070 /* else return DENY; */
1071 BPF_MOV64_IMM(BPF_REG_0, 0),
1074 .attach_type = BPF_CGROUP_SYSCTL,
1075 .sysctl = "net/ipv4/route/mtu_expires",
1076 .open_flags = O_RDONLY,
1080 "bpf_strtoul buf with spaces only, EINVAL",
1083 BPF_MOV64_REG(BPF_REG_7, BPF_REG_10),
1084 BPF_ALU64_IMM(BPF_ADD, BPF_REG_7, -8),
1085 BPF_MOV64_IMM(BPF_REG_0,
1086 bpf_ntohl(0x0d0c0a09)),
1087 BPF_STX_MEM(BPF_DW, BPF_REG_7, BPF_REG_0, 0),
1089 BPF_MOV64_REG(BPF_REG_1, BPF_REG_7),
1091 /* arg2 (buf_len) */
1092 BPF_MOV64_IMM(BPF_REG_2, 4),
1095 BPF_MOV64_IMM(BPF_REG_3, 0),
1098 BPF_ALU64_IMM(BPF_ADD, BPF_REG_7, -8),
1099 BPF_STX_MEM(BPF_DW, BPF_REG_7, BPF_REG_0, 0),
1100 BPF_MOV64_REG(BPF_REG_4, BPF_REG_7),
1102 BPF_EMIT_CALL(BPF_FUNC_strtoul),
1104 /* if (ret == expected) */
1105 BPF_JMP_IMM(BPF_JNE, BPF_REG_0, -EINVAL, 2),
1108 BPF_MOV64_IMM(BPF_REG_0, 1),
1111 /* else return DENY; */
1112 BPF_MOV64_IMM(BPF_REG_0, 0),
1115 .attach_type = BPF_CGROUP_SYSCTL,
1116 .sysctl = "net/ipv4/route/mtu_expires",
1117 .open_flags = O_RDONLY,
1121 "bpf_strtoul negative number, EINVAL",
1124 BPF_MOV64_REG(BPF_REG_7, BPF_REG_10),
1125 BPF_ALU64_IMM(BPF_ADD, BPF_REG_7, -8),
1127 BPF_MOV64_IMM(BPF_REG_0,
1128 bpf_ntohl(0x0a2d3600)),
1129 BPF_STX_MEM(BPF_DW, BPF_REG_7, BPF_REG_0, 0),
1131 BPF_MOV64_REG(BPF_REG_1, BPF_REG_7),
1133 /* arg2 (buf_len) */
1134 BPF_MOV64_IMM(BPF_REG_2, 4),
1137 BPF_MOV64_IMM(BPF_REG_3, 0),
1140 BPF_ALU64_IMM(BPF_ADD, BPF_REG_7, -8),
1141 BPF_STX_MEM(BPF_DW, BPF_REG_7, BPF_REG_0, 0),
1142 BPF_MOV64_REG(BPF_REG_4, BPF_REG_7),
1144 BPF_EMIT_CALL(BPF_FUNC_strtoul),
1146 /* if (ret == expected) */
1147 BPF_JMP_IMM(BPF_JNE, BPF_REG_0, -EINVAL, 2),
1150 BPF_MOV64_IMM(BPF_REG_0, 1),
1153 /* else return DENY; */
1154 BPF_MOV64_IMM(BPF_REG_0, 0),
1157 .attach_type = BPF_CGROUP_SYSCTL,
1158 .sysctl = "net/ipv4/route/mtu_expires",
1159 .open_flags = O_RDONLY,
1163 "bpf_strtol negative number, ok",
1166 BPF_MOV64_REG(BPF_REG_7, BPF_REG_10),
1167 BPF_ALU64_IMM(BPF_ADD, BPF_REG_7, -8),
1169 BPF_MOV64_IMM(BPF_REG_0,
1170 bpf_ntohl(0x0a2d3600)),
1171 BPF_STX_MEM(BPF_W, BPF_REG_7, BPF_REG_0, 0),
1173 BPF_MOV64_REG(BPF_REG_1, BPF_REG_7),
1175 /* arg2 (buf_len) */
1176 BPF_MOV64_IMM(BPF_REG_2, 4),
1179 BPF_MOV64_IMM(BPF_REG_3, 10),
1182 BPF_ALU64_IMM(BPF_ADD, BPF_REG_7, -8),
1183 BPF_STX_MEM(BPF_DW, BPF_REG_7, BPF_REG_0, 0),
1184 BPF_MOV64_REG(BPF_REG_4, BPF_REG_7),
1186 BPF_EMIT_CALL(BPF_FUNC_strtol),
1188 /* if (ret == expected && */
1189 BPF_JMP_IMM(BPF_JNE, BPF_REG_0, 3, 4),
1190 /* res == expected) */
1191 BPF_LDX_MEM(BPF_DW, BPF_REG_9, BPF_REG_7, 0),
1192 BPF_JMP_IMM(BPF_JNE, BPF_REG_9, -6, 2),
1195 BPF_MOV64_IMM(BPF_REG_0, 1),
1198 /* else return DENY; */
1199 BPF_MOV64_IMM(BPF_REG_0, 0),
1202 .attach_type = BPF_CGROUP_SYSCTL,
1203 .sysctl = "net/ipv4/route/mtu_expires",
1204 .open_flags = O_RDONLY,
1208 "bpf_strtol hex number, ok",
1211 BPF_MOV64_REG(BPF_REG_7, BPF_REG_10),
1212 BPF_ALU64_IMM(BPF_ADD, BPF_REG_7, -8),
1214 BPF_MOV64_IMM(BPF_REG_0,
1215 bpf_ntohl(0x30786665)),
1216 BPF_STX_MEM(BPF_W, BPF_REG_7, BPF_REG_0, 0),
1218 BPF_MOV64_REG(BPF_REG_1, BPF_REG_7),
1220 /* arg2 (buf_len) */
1221 BPF_MOV64_IMM(BPF_REG_2, 4),
1224 BPF_MOV64_IMM(BPF_REG_3, 0),
1227 BPF_ALU64_IMM(BPF_ADD, BPF_REG_7, -8),
1228 BPF_STX_MEM(BPF_DW, BPF_REG_7, BPF_REG_0, 0),
1229 BPF_MOV64_REG(BPF_REG_4, BPF_REG_7),
1231 BPF_EMIT_CALL(BPF_FUNC_strtol),
1233 /* if (ret == expected && */
1234 BPF_JMP_IMM(BPF_JNE, BPF_REG_0, 4, 4),
1235 /* res == expected) */
1236 BPF_LDX_MEM(BPF_DW, BPF_REG_9, BPF_REG_7, 0),
1237 BPF_JMP_IMM(BPF_JNE, BPF_REG_9, 254, 2),
1240 BPF_MOV64_IMM(BPF_REG_0, 1),
1243 /* else return DENY; */
1244 BPF_MOV64_IMM(BPF_REG_0, 0),
1247 .attach_type = BPF_CGROUP_SYSCTL,
1248 .sysctl = "net/ipv4/route/mtu_expires",
1249 .open_flags = O_RDONLY,
1253 "bpf_strtol max long",
1255 /* arg1 (buf) 9223372036854775807 */
1256 BPF_MOV64_REG(BPF_REG_7, BPF_REG_10),
1257 BPF_ALU64_IMM(BPF_ADD, BPF_REG_7, -24),
1258 BPF_LD_IMM64(BPF_REG_0,
1259 bpf_be64_to_cpu(0x3932323333373230ULL)),
1260 BPF_STX_MEM(BPF_DW, BPF_REG_7, BPF_REG_0, 0),
1261 BPF_LD_IMM64(BPF_REG_0,
1262 bpf_be64_to_cpu(0x3336383534373735ULL)),
1263 BPF_STX_MEM(BPF_DW, BPF_REG_7, BPF_REG_0, 8),
1264 BPF_LD_IMM64(BPF_REG_0,
1265 bpf_be64_to_cpu(0x3830370000000000ULL)),
1266 BPF_STX_MEM(BPF_DW, BPF_REG_7, BPF_REG_0, 16),
1268 BPF_MOV64_REG(BPF_REG_1, BPF_REG_7),
1270 /* arg2 (buf_len) */
1271 BPF_MOV64_IMM(BPF_REG_2, 19),
1274 BPF_MOV64_IMM(BPF_REG_3, 0),
1277 BPF_ALU64_IMM(BPF_ADD, BPF_REG_7, -8),
1278 BPF_STX_MEM(BPF_DW, BPF_REG_7, BPF_REG_0, 0),
1279 BPF_MOV64_REG(BPF_REG_4, BPF_REG_7),
1281 BPF_EMIT_CALL(BPF_FUNC_strtol),
1283 /* if (ret == expected && */
1284 BPF_JMP_IMM(BPF_JNE, BPF_REG_0, 19, 6),
1285 /* res == expected) */
1286 BPF_LD_IMM64(BPF_REG_8, 0x7fffffffffffffffULL),
1287 BPF_LDX_MEM(BPF_DW, BPF_REG_9, BPF_REG_7, 0),
1288 BPF_JMP_REG(BPF_JNE, BPF_REG_8, BPF_REG_9, 2),
1291 BPF_MOV64_IMM(BPF_REG_0, 1),
1294 /* else return DENY; */
1295 BPF_MOV64_IMM(BPF_REG_0, 0),
1298 .attach_type = BPF_CGROUP_SYSCTL,
1299 .sysctl = "net/ipv4/route/mtu_expires",
1300 .open_flags = O_RDONLY,
1304 "bpf_strtol overflow, ERANGE",
1306 /* arg1 (buf) 9223372036854775808 */
1307 BPF_MOV64_REG(BPF_REG_7, BPF_REG_10),
1308 BPF_ALU64_IMM(BPF_ADD, BPF_REG_7, -24),
1309 BPF_LD_IMM64(BPF_REG_0,
1310 bpf_be64_to_cpu(0x3932323333373230ULL)),
1311 BPF_STX_MEM(BPF_DW, BPF_REG_7, BPF_REG_0, 0),
1312 BPF_LD_IMM64(BPF_REG_0,
1313 bpf_be64_to_cpu(0x3336383534373735ULL)),
1314 BPF_STX_MEM(BPF_DW, BPF_REG_7, BPF_REG_0, 8),
1315 BPF_LD_IMM64(BPF_REG_0,
1316 bpf_be64_to_cpu(0x3830380000000000ULL)),
1317 BPF_STX_MEM(BPF_DW, BPF_REG_7, BPF_REG_0, 16),
1319 BPF_MOV64_REG(BPF_REG_1, BPF_REG_7),
1321 /* arg2 (buf_len) */
1322 BPF_MOV64_IMM(BPF_REG_2, 19),
1325 BPF_MOV64_IMM(BPF_REG_3, 0),
1328 BPF_ALU64_IMM(BPF_ADD, BPF_REG_7, -8),
1329 BPF_STX_MEM(BPF_DW, BPF_REG_7, BPF_REG_0, 0),
1330 BPF_MOV64_REG(BPF_REG_4, BPF_REG_7),
1332 BPF_EMIT_CALL(BPF_FUNC_strtol),
1334 /* if (ret == expected) */
1335 BPF_JMP_IMM(BPF_JNE, BPF_REG_0, -ERANGE, 2),
1338 BPF_MOV64_IMM(BPF_REG_0, 1),
1341 /* else return DENY; */
1342 BPF_MOV64_IMM(BPF_REG_0, 0),
1345 .attach_type = BPF_CGROUP_SYSCTL,
1346 .sysctl = "net/ipv4/route/mtu_expires",
1347 .open_flags = O_RDONLY,
1351 "C prog: deny all writes",
1352 .prog_file = "./test_sysctl_prog.o",
1353 .attach_type = BPF_CGROUP_SYSCTL,
1354 .sysctl = "net/ipv4/tcp_mem",
1355 .open_flags = O_WRONLY,
1356 .newval = "123 456 789",
1360 "C prog: deny access by name",
1361 .prog_file = "./test_sysctl_prog.o",
1362 .attach_type = BPF_CGROUP_SYSCTL,
1363 .sysctl = "net/ipv4/route/mtu_expires",
1364 .open_flags = O_RDONLY,
1368 "C prog: read tcp_mem",
1369 .prog_file = "./test_sysctl_prog.o",
1370 .attach_type = BPF_CGROUP_SYSCTL,
1371 .sysctl = "net/ipv4/tcp_mem",
1372 .open_flags = O_RDONLY,
1377 static size_t probe_prog_length(const struct bpf_insn *fp)
1381 for (len = MAX_INSNS - 1; len > 0; --len)
1382 if (fp[len].code != 0 || fp[len].imm != 0)
1387 static int fixup_sysctl_value(const char *buf, size_t buf_len,
1388 struct bpf_insn *prog, size_t insn_num)
1391 uint8_t raw[sizeof(uint64_t)];
1395 if (buf_len > sizeof(value)) {
1396 log_err("Value is too big (%zd) to use in fixup", buf_len);
1399 if (prog[insn_num].code != (BPF_LD | BPF_DW | BPF_IMM)) {
1400 log_err("Can fixup only BPF_LD_IMM64 insns");
1404 memcpy(value.raw, buf, buf_len);
1405 prog[insn_num].imm = (uint32_t)value.num;
1406 prog[insn_num + 1].imm = (uint32_t)(value.num >> 32);
1411 static int load_sysctl_prog_insns(struct sysctl_test *test,
1412 const char *sysctl_path)
1414 struct bpf_insn *prog = test->insns;
1415 struct bpf_load_program_attr attr;
1418 memset(&attr, 0, sizeof(struct bpf_load_program_attr));
1419 attr.prog_type = BPF_PROG_TYPE_CGROUP_SYSCTL;
1421 attr.insns_cnt = probe_prog_length(attr.insns);
1422 attr.license = "GPL";
1424 if (test->fixup_value_insn) {
1429 fd = open(sysctl_path, O_RDONLY | O_CLOEXEC);
1431 log_err("open(%s) failed", sysctl_path);
1434 len = read(fd, buf, sizeof(buf));
1436 log_err("read(%s) failed", sysctl_path);
1441 if (fixup_sysctl_value(buf, len, prog, test->fixup_value_insn))
1445 ret = bpf_load_program_xattr(&attr, bpf_log_buf, BPF_LOG_BUF_SIZE);
1446 if (ret < 0 && test->result != LOAD_REJECT) {
1447 log_err(">>> Loading program error.\n"
1448 ">>> Verifier output:\n%s\n-------\n", bpf_log_buf);
1454 static int load_sysctl_prog_file(struct sysctl_test *test)
1456 struct bpf_prog_load_attr attr;
1457 struct bpf_object *obj;
1460 memset(&attr, 0, sizeof(struct bpf_prog_load_attr));
1461 attr.file = test->prog_file;
1462 attr.prog_type = BPF_PROG_TYPE_CGROUP_SYSCTL;
1464 if (bpf_prog_load_xattr(&attr, &obj, &prog_fd)) {
1465 if (test->result != LOAD_REJECT)
1466 log_err(">>> Loading program (%s) error.\n",
1474 static int load_sysctl_prog(struct sysctl_test *test, const char *sysctl_path)
1476 return test->prog_file
1477 ? load_sysctl_prog_file(test)
1478 : load_sysctl_prog_insns(test, sysctl_path);
1481 static int access_sysctl(const char *sysctl_path,
1482 const struct sysctl_test *test)
1487 fd = open(sysctl_path, test->open_flags | O_CLOEXEC);
1491 if (test->seek && lseek(fd, test->seek, SEEK_SET) == -1) {
1492 log_err("lseek(%d) failed", test->seek);
1496 if (test->open_flags == O_RDONLY) {
1499 if (read(fd, buf, sizeof(buf)) == -1)
1502 strncmp(buf, test->oldval, strlen(test->oldval))) {
1503 log_err("Read value %s != %s", buf, test->oldval);
1506 } else if (test->open_flags == O_WRONLY) {
1507 if (!test->newval) {
1508 log_err("New value for sysctl is not set");
1511 if (write(fd, test->newval, strlen(test->newval)) == -1)
1514 log_err("Unexpected sysctl access: neither read nor write");
1526 static int run_test_case(int cgfd, struct sysctl_test *test)
1528 enum bpf_attach_type atype = test->attach_type;
1529 char sysctl_path[128];
1533 printf("Test case: %s .. ", test->descr);
1535 snprintf(sysctl_path, sizeof(sysctl_path), "/proc/sys/%s",
1538 progfd = load_sysctl_prog(test, sysctl_path);
1540 if (test->result == LOAD_REJECT)
1546 if (bpf_prog_attach(progfd, cgfd, atype, BPF_F_ALLOW_OVERRIDE) == -1) {
1547 if (test->result == ATTACH_REJECT)
1554 if (access_sysctl(sysctl_path, test) == -1) {
1555 if (test->result == OP_EPERM && errno == EPERM)
1561 if (test->result != SUCCESS) {
1562 log_err("Unexpected success");
1570 /* Detaching w/o checking return code: best effort attempt. */
1572 bpf_prog_detach(cgfd, atype);
1574 printf("[%s]\n", err ? "FAIL" : "PASS");
1578 static int run_tests(int cgfd)
1584 for (i = 0; i < ARRAY_SIZE(tests); ++i) {
1585 if (run_test_case(cgfd, &tests[i]))
1590 printf("Summary: %d PASSED, %d FAILED\n", passes, fails);
1591 return fails ? -1 : 0;
1594 int main(int argc, char **argv)
1599 if (setup_cgroup_environment())
1602 cgfd = create_and_get_cgroup(CG_PATH);
1606 if (join_cgroup(CG_PATH))
1609 if (run_tests(cgfd))
1617 cleanup_cgroup_environment();