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 BPF_LDX_MEM(BPF_B, BPF_REG_7, BPF_REG_1,
165 offsetof(struct bpf_sysctl, file_pos)),
166 BPF_JMP_IMM(BPF_JNE, BPF_REG_7, 0, 2),
169 BPF_MOV64_IMM(BPF_REG_0, 1),
172 /* else return DENY; */
173 BPF_MOV64_IMM(BPF_REG_0, 0),
176 .attach_type = BPF_CGROUP_SYSCTL,
177 .sysctl = "kernel/ostype",
178 .open_flags = O_RDONLY,
182 .descr = "ctx:file_pos sysctl:read write ok",
185 BPF_MOV64_IMM(BPF_REG_0, 2),
186 BPF_STX_MEM(BPF_W, BPF_REG_1, BPF_REG_0,
187 offsetof(struct bpf_sysctl, file_pos)),
188 BPF_MOV64_IMM(BPF_REG_0, 1),
191 .attach_type = BPF_CGROUP_SYSCTL,
192 .sysctl = "kernel/ostype",
193 .open_flags = O_RDONLY,
198 .descr = "sysctl_get_name sysctl_value:base ok",
200 /* sysctl_get_name arg2 (buf) */
201 BPF_MOV64_REG(BPF_REG_7, BPF_REG_10),
202 BPF_ALU64_IMM(BPF_ADD, BPF_REG_7, -8),
203 BPF_MOV64_IMM(BPF_REG_0, 0),
204 BPF_STX_MEM(BPF_DW, BPF_REG_7, BPF_REG_0, 0),
206 BPF_MOV64_REG(BPF_REG_2, BPF_REG_7),
208 /* sysctl_get_name arg3 (buf_len) */
209 BPF_MOV64_IMM(BPF_REG_3, 8),
211 /* sysctl_get_name arg4 (flags) */
212 BPF_MOV64_IMM(BPF_REG_4, BPF_F_SYSCTL_BASE_NAME),
214 /* sysctl_get_name(ctx, buf, buf_len, flags) */
215 BPF_EMIT_CALL(BPF_FUNC_sysctl_get_name),
217 /* if (ret == expected && */
218 BPF_JMP_IMM(BPF_JNE, BPF_REG_0, sizeof("tcp_mem") - 1, 6),
219 /* buf == "tcp_mem\0") */
220 BPF_LD_IMM64(BPF_REG_8,
221 bpf_be64_to_cpu(0x7463705f6d656d00ULL)),
222 BPF_LDX_MEM(BPF_DW, BPF_REG_9, BPF_REG_7, 0),
223 BPF_JMP_REG(BPF_JNE, BPF_REG_8, BPF_REG_9, 2),
226 BPF_MOV64_IMM(BPF_REG_0, 1),
229 /* else return DENY; */
230 BPF_MOV64_IMM(BPF_REG_0, 0),
233 .attach_type = BPF_CGROUP_SYSCTL,
234 .sysctl = "net/ipv4/tcp_mem",
235 .open_flags = O_RDONLY,
239 .descr = "sysctl_get_name sysctl_value:base E2BIG truncated",
241 /* sysctl_get_name arg2 (buf) */
242 BPF_MOV64_REG(BPF_REG_7, BPF_REG_10),
243 BPF_ALU64_IMM(BPF_ADD, BPF_REG_7, -8),
244 BPF_MOV64_IMM(BPF_REG_0, 0),
245 BPF_STX_MEM(BPF_DW, BPF_REG_7, BPF_REG_0, 0),
247 BPF_MOV64_REG(BPF_REG_2, BPF_REG_7),
249 /* sysctl_get_name arg3 (buf_len) too small */
250 BPF_MOV64_IMM(BPF_REG_3, 7),
252 /* sysctl_get_name arg4 (flags) */
253 BPF_MOV64_IMM(BPF_REG_4, BPF_F_SYSCTL_BASE_NAME),
255 /* sysctl_get_name(ctx, buf, buf_len, flags) */
256 BPF_EMIT_CALL(BPF_FUNC_sysctl_get_name),
258 /* if (ret == expected && */
259 BPF_JMP_IMM(BPF_JNE, BPF_REG_0, -E2BIG, 6),
261 /* buf[0:7] == "tcp_me\0") */
262 BPF_LD_IMM64(BPF_REG_8,
263 bpf_be64_to_cpu(0x7463705f6d650000ULL)),
264 BPF_LDX_MEM(BPF_DW, BPF_REG_9, BPF_REG_7, 0),
265 BPF_JMP_REG(BPF_JNE, BPF_REG_8, BPF_REG_9, 2),
268 BPF_MOV64_IMM(BPF_REG_0, 1),
271 /* else return DENY; */
272 BPF_MOV64_IMM(BPF_REG_0, 0),
275 .attach_type = BPF_CGROUP_SYSCTL,
276 .sysctl = "net/ipv4/tcp_mem",
277 .open_flags = O_RDONLY,
281 .descr = "sysctl_get_name sysctl:full ok",
283 /* sysctl_get_name arg2 (buf) */
284 BPF_MOV64_REG(BPF_REG_7, BPF_REG_10),
285 BPF_ALU64_IMM(BPF_ADD, BPF_REG_7, -24),
286 BPF_MOV64_IMM(BPF_REG_0, 0),
287 BPF_STX_MEM(BPF_DW, BPF_REG_7, BPF_REG_0, 0),
288 BPF_STX_MEM(BPF_DW, BPF_REG_7, BPF_REG_0, 8),
289 BPF_STX_MEM(BPF_DW, BPF_REG_7, BPF_REG_0, 16),
291 BPF_MOV64_REG(BPF_REG_2, BPF_REG_7),
293 /* sysctl_get_name arg3 (buf_len) */
294 BPF_MOV64_IMM(BPF_REG_3, 17),
296 /* sysctl_get_name arg4 (flags) */
297 BPF_MOV64_IMM(BPF_REG_4, 0),
299 /* sysctl_get_name(ctx, buf, buf_len, flags) */
300 BPF_EMIT_CALL(BPF_FUNC_sysctl_get_name),
302 /* if (ret == expected && */
303 BPF_JMP_IMM(BPF_JNE, BPF_REG_0, 16, 14),
305 /* buf[0:8] == "net/ipv4" && */
306 BPF_LD_IMM64(BPF_REG_8,
307 bpf_be64_to_cpu(0x6e65742f69707634ULL)),
308 BPF_LDX_MEM(BPF_DW, BPF_REG_9, BPF_REG_7, 0),
309 BPF_JMP_REG(BPF_JNE, BPF_REG_8, BPF_REG_9, 10),
311 /* buf[8:16] == "/tcp_mem" && */
312 BPF_LD_IMM64(BPF_REG_8,
313 bpf_be64_to_cpu(0x2f7463705f6d656dULL)),
314 BPF_LDX_MEM(BPF_DW, BPF_REG_9, BPF_REG_7, 8),
315 BPF_JMP_REG(BPF_JNE, BPF_REG_8, BPF_REG_9, 6),
317 /* buf[16:24] == "\0") */
318 BPF_LD_IMM64(BPF_REG_8, 0x0ULL),
319 BPF_LDX_MEM(BPF_DW, BPF_REG_9, BPF_REG_7, 16),
320 BPF_JMP_REG(BPF_JNE, BPF_REG_8, BPF_REG_9, 2),
323 BPF_MOV64_IMM(BPF_REG_0, 1),
326 /* else return DENY; */
327 BPF_MOV64_IMM(BPF_REG_0, 0),
330 .attach_type = BPF_CGROUP_SYSCTL,
331 .sysctl = "net/ipv4/tcp_mem",
332 .open_flags = O_RDONLY,
336 .descr = "sysctl_get_name sysctl:full E2BIG truncated",
338 /* sysctl_get_name arg2 (buf) */
339 BPF_MOV64_REG(BPF_REG_7, BPF_REG_10),
340 BPF_ALU64_IMM(BPF_ADD, BPF_REG_7, -16),
341 BPF_MOV64_IMM(BPF_REG_0, 0),
342 BPF_STX_MEM(BPF_DW, BPF_REG_7, BPF_REG_0, 0),
343 BPF_STX_MEM(BPF_DW, BPF_REG_7, BPF_REG_0, 8),
345 BPF_MOV64_REG(BPF_REG_2, BPF_REG_7),
347 /* sysctl_get_name arg3 (buf_len) */
348 BPF_MOV64_IMM(BPF_REG_3, 16),
350 /* sysctl_get_name arg4 (flags) */
351 BPF_MOV64_IMM(BPF_REG_4, 0),
353 /* sysctl_get_name(ctx, buf, buf_len, flags) */
354 BPF_EMIT_CALL(BPF_FUNC_sysctl_get_name),
356 /* if (ret == expected && */
357 BPF_JMP_IMM(BPF_JNE, BPF_REG_0, -E2BIG, 10),
359 /* buf[0:8] == "net/ipv4" && */
360 BPF_LD_IMM64(BPF_REG_8,
361 bpf_be64_to_cpu(0x6e65742f69707634ULL)),
362 BPF_LDX_MEM(BPF_DW, BPF_REG_9, BPF_REG_7, 0),
363 BPF_JMP_REG(BPF_JNE, BPF_REG_8, BPF_REG_9, 6),
365 /* buf[8:16] == "/tcp_me\0") */
366 BPF_LD_IMM64(BPF_REG_8,
367 bpf_be64_to_cpu(0x2f7463705f6d6500ULL)),
368 BPF_LDX_MEM(BPF_DW, BPF_REG_9, BPF_REG_7, 8),
369 BPF_JMP_REG(BPF_JNE, BPF_REG_8, BPF_REG_9, 2),
372 BPF_MOV64_IMM(BPF_REG_0, 1),
375 /* else return DENY; */
376 BPF_MOV64_IMM(BPF_REG_0, 0),
379 .attach_type = BPF_CGROUP_SYSCTL,
380 .sysctl = "net/ipv4/tcp_mem",
381 .open_flags = O_RDONLY,
385 .descr = "sysctl_get_name sysctl:full E2BIG truncated small",
387 /* sysctl_get_name arg2 (buf) */
388 BPF_MOV64_REG(BPF_REG_7, BPF_REG_10),
389 BPF_ALU64_IMM(BPF_ADD, BPF_REG_7, -8),
390 BPF_MOV64_IMM(BPF_REG_0, 0),
391 BPF_STX_MEM(BPF_DW, BPF_REG_7, BPF_REG_0, 0),
393 BPF_MOV64_REG(BPF_REG_2, BPF_REG_7),
395 /* sysctl_get_name arg3 (buf_len) */
396 BPF_MOV64_IMM(BPF_REG_3, 7),
398 /* sysctl_get_name arg4 (flags) */
399 BPF_MOV64_IMM(BPF_REG_4, 0),
401 /* sysctl_get_name(ctx, buf, buf_len, flags) */
402 BPF_EMIT_CALL(BPF_FUNC_sysctl_get_name),
404 /* if (ret == expected && */
405 BPF_JMP_IMM(BPF_JNE, BPF_REG_0, -E2BIG, 6),
407 /* buf[0:8] == "net/ip\0") */
408 BPF_LD_IMM64(BPF_REG_8,
409 bpf_be64_to_cpu(0x6e65742f69700000ULL)),
410 BPF_LDX_MEM(BPF_DW, BPF_REG_9, BPF_REG_7, 0),
411 BPF_JMP_REG(BPF_JNE, BPF_REG_8, BPF_REG_9, 2),
414 BPF_MOV64_IMM(BPF_REG_0, 1),
417 /* else return DENY; */
418 BPF_MOV64_IMM(BPF_REG_0, 0),
421 .attach_type = BPF_CGROUP_SYSCTL,
422 .sysctl = "net/ipv4/tcp_mem",
423 .open_flags = O_RDONLY,
427 .descr = "sysctl_get_current_value sysctl:read ok, gt",
429 /* sysctl_get_current_value arg2 (buf) */
430 BPF_MOV64_REG(BPF_REG_7, BPF_REG_10),
431 BPF_ALU64_IMM(BPF_ADD, BPF_REG_7, -8),
432 BPF_MOV64_REG(BPF_REG_2, BPF_REG_7),
434 /* sysctl_get_current_value arg3 (buf_len) */
435 BPF_MOV64_IMM(BPF_REG_3, 8),
437 /* sysctl_get_current_value(ctx, buf, buf_len) */
438 BPF_EMIT_CALL(BPF_FUNC_sysctl_get_current_value),
440 /* if (ret == expected && */
441 BPF_JMP_IMM(BPF_JNE, BPF_REG_0, 6, 6),
443 /* buf[0:6] == "Linux\n\0") */
444 BPF_LD_IMM64(BPF_REG_8,
445 bpf_be64_to_cpu(0x4c696e75780a0000ULL)),
446 BPF_LDX_MEM(BPF_DW, BPF_REG_9, BPF_REG_7, 0),
447 BPF_JMP_REG(BPF_JNE, BPF_REG_8, BPF_REG_9, 2),
450 BPF_MOV64_IMM(BPF_REG_0, 1),
453 /* else return DENY; */
454 BPF_MOV64_IMM(BPF_REG_0, 0),
457 .attach_type = BPF_CGROUP_SYSCTL,
458 .sysctl = "kernel/ostype",
459 .open_flags = O_RDONLY,
463 .descr = "sysctl_get_current_value sysctl:read ok, eq",
465 /* sysctl_get_current_value arg2 (buf) */
466 BPF_MOV64_REG(BPF_REG_7, BPF_REG_10),
467 BPF_ALU64_IMM(BPF_ADD, BPF_REG_7, -8),
468 BPF_MOV64_IMM(BPF_REG_0, 0),
469 BPF_STX_MEM(BPF_B, BPF_REG_7, BPF_REG_0, 7),
471 BPF_MOV64_REG(BPF_REG_2, BPF_REG_7),
473 /* sysctl_get_current_value arg3 (buf_len) */
474 BPF_MOV64_IMM(BPF_REG_3, 7),
476 /* sysctl_get_current_value(ctx, buf, buf_len) */
477 BPF_EMIT_CALL(BPF_FUNC_sysctl_get_current_value),
479 /* if (ret == expected && */
480 BPF_JMP_IMM(BPF_JNE, BPF_REG_0, 6, 6),
482 /* buf[0:6] == "Linux\n\0") */
483 BPF_LD_IMM64(BPF_REG_8,
484 bpf_be64_to_cpu(0x4c696e75780a0000ULL)),
485 BPF_LDX_MEM(BPF_DW, BPF_REG_9, BPF_REG_7, 0),
486 BPF_JMP_REG(BPF_JNE, BPF_REG_8, BPF_REG_9, 2),
489 BPF_MOV64_IMM(BPF_REG_0, 1),
492 /* else return DENY; */
493 BPF_MOV64_IMM(BPF_REG_0, 0),
496 .attach_type = BPF_CGROUP_SYSCTL,
497 .sysctl = "kernel/ostype",
498 .open_flags = O_RDONLY,
502 .descr = "sysctl_get_current_value sysctl:read E2BIG truncated",
504 /* sysctl_get_current_value arg2 (buf) */
505 BPF_MOV64_REG(BPF_REG_7, BPF_REG_10),
506 BPF_ALU64_IMM(BPF_ADD, BPF_REG_7, -8),
507 BPF_MOV64_IMM(BPF_REG_0, 0),
508 BPF_STX_MEM(BPF_H, BPF_REG_7, BPF_REG_0, 6),
510 BPF_MOV64_REG(BPF_REG_2, BPF_REG_7),
512 /* sysctl_get_current_value arg3 (buf_len) */
513 BPF_MOV64_IMM(BPF_REG_3, 6),
515 /* sysctl_get_current_value(ctx, buf, buf_len) */
516 BPF_EMIT_CALL(BPF_FUNC_sysctl_get_current_value),
518 /* if (ret == expected && */
519 BPF_JMP_IMM(BPF_JNE, BPF_REG_0, -E2BIG, 6),
521 /* buf[0:6] == "Linux\0") */
522 BPF_LD_IMM64(BPF_REG_8,
523 bpf_be64_to_cpu(0x4c696e7578000000ULL)),
524 BPF_LDX_MEM(BPF_DW, BPF_REG_9, BPF_REG_7, 0),
525 BPF_JMP_REG(BPF_JNE, BPF_REG_8, BPF_REG_9, 2),
528 BPF_MOV64_IMM(BPF_REG_0, 1),
531 /* else return DENY; */
532 BPF_MOV64_IMM(BPF_REG_0, 0),
535 .attach_type = BPF_CGROUP_SYSCTL,
536 .sysctl = "kernel/ostype",
537 .open_flags = O_RDONLY,
541 .descr = "sysctl_get_current_value sysctl:read EINVAL",
543 /* sysctl_get_current_value arg2 (buf) */
544 BPF_MOV64_REG(BPF_REG_7, BPF_REG_10),
545 BPF_ALU64_IMM(BPF_ADD, BPF_REG_7, -8),
547 BPF_MOV64_REG(BPF_REG_2, BPF_REG_7),
549 /* sysctl_get_current_value arg3 (buf_len) */
550 BPF_MOV64_IMM(BPF_REG_3, 8),
552 /* sysctl_get_current_value(ctx, buf, buf_len) */
553 BPF_EMIT_CALL(BPF_FUNC_sysctl_get_current_value),
555 /* if (ret == expected && */
556 BPF_JMP_IMM(BPF_JNE, BPF_REG_0, -EINVAL, 4),
558 /* buf[0:8] is NUL-filled) */
559 BPF_LDX_MEM(BPF_DW, BPF_REG_9, BPF_REG_7, 0),
560 BPF_JMP_IMM(BPF_JNE, BPF_REG_9, 0, 2),
563 BPF_MOV64_IMM(BPF_REG_0, 0),
566 /* else return ALLOW; */
567 BPF_MOV64_IMM(BPF_REG_0, 1),
570 .attach_type = BPF_CGROUP_SYSCTL,
571 .sysctl = "net/ipv6/conf/lo/stable_secret", /* -EIO */
572 .open_flags = O_RDONLY,
576 .descr = "sysctl_get_current_value sysctl:write ok",
577 .fixup_value_insn = 6,
579 /* sysctl_get_current_value arg2 (buf) */
580 BPF_MOV64_REG(BPF_REG_7, BPF_REG_10),
581 BPF_ALU64_IMM(BPF_ADD, BPF_REG_7, -8),
583 BPF_MOV64_REG(BPF_REG_2, BPF_REG_7),
585 /* sysctl_get_current_value arg3 (buf_len) */
586 BPF_MOV64_IMM(BPF_REG_3, 8),
588 /* sysctl_get_current_value(ctx, buf, buf_len) */
589 BPF_EMIT_CALL(BPF_FUNC_sysctl_get_current_value),
591 /* if (ret == expected && */
592 BPF_JMP_IMM(BPF_JNE, BPF_REG_0, 4, 6),
594 /* buf[0:4] == expected) */
595 BPF_LD_IMM64(BPF_REG_8, FIXUP_SYSCTL_VALUE),
596 BPF_LDX_MEM(BPF_DW, BPF_REG_9, BPF_REG_7, 0),
597 BPF_JMP_REG(BPF_JNE, BPF_REG_8, BPF_REG_9, 2),
600 BPF_MOV64_IMM(BPF_REG_0, 0),
603 /* else return ALLOW; */
604 BPF_MOV64_IMM(BPF_REG_0, 1),
607 .attach_type = BPF_CGROUP_SYSCTL,
608 .sysctl = "net/ipv4/route/mtu_expires",
609 .open_flags = O_WRONLY,
610 .newval = "600", /* same as default, should fail anyway */
614 .descr = "sysctl_get_new_value sysctl:read EINVAL",
616 /* sysctl_get_new_value arg2 (buf) */
617 BPF_MOV64_REG(BPF_REG_7, BPF_REG_10),
618 BPF_ALU64_IMM(BPF_ADD, BPF_REG_7, -8),
619 BPF_MOV64_IMM(BPF_REG_0, 0),
620 BPF_STX_MEM(BPF_DW, BPF_REG_7, BPF_REG_0, 0),
622 BPF_MOV64_REG(BPF_REG_2, BPF_REG_7),
624 /* sysctl_get_new_value arg3 (buf_len) */
625 BPF_MOV64_IMM(BPF_REG_3, 8),
627 /* sysctl_get_new_value(ctx, buf, buf_len) */
628 BPF_EMIT_CALL(BPF_FUNC_sysctl_get_new_value),
630 /* if (ret == expected) */
631 BPF_JMP_IMM(BPF_JNE, BPF_REG_0, -EINVAL, 2),
634 BPF_MOV64_IMM(BPF_REG_0, 1),
637 /* else return DENY; */
638 BPF_MOV64_IMM(BPF_REG_0, 0),
641 .attach_type = BPF_CGROUP_SYSCTL,
642 .sysctl = "net/ipv4/tcp_mem",
643 .open_flags = O_RDONLY,
647 .descr = "sysctl_get_new_value sysctl:write ok",
649 /* sysctl_get_new_value arg2 (buf) */
650 BPF_MOV64_REG(BPF_REG_7, BPF_REG_10),
651 BPF_ALU64_IMM(BPF_ADD, BPF_REG_7, -8),
653 BPF_MOV64_REG(BPF_REG_2, BPF_REG_7),
655 /* sysctl_get_new_value arg3 (buf_len) */
656 BPF_MOV64_IMM(BPF_REG_3, 4),
658 /* sysctl_get_new_value(ctx, buf, buf_len) */
659 BPF_EMIT_CALL(BPF_FUNC_sysctl_get_new_value),
661 /* if (ret == expected && */
662 BPF_JMP_IMM(BPF_JNE, BPF_REG_0, 3, 4),
664 /* buf[0:4] == "606\0") */
665 BPF_LDX_MEM(BPF_W, BPF_REG_9, BPF_REG_7, 0),
666 BPF_JMP_IMM(BPF_JNE, BPF_REG_9,
667 bpf_ntohl(0x36303600), 2),
670 BPF_MOV64_IMM(BPF_REG_0, 0),
673 /* else return ALLOW; */
674 BPF_MOV64_IMM(BPF_REG_0, 1),
677 .attach_type = BPF_CGROUP_SYSCTL,
678 .sysctl = "net/ipv4/route/mtu_expires",
679 .open_flags = O_WRONLY,
684 .descr = "sysctl_get_new_value sysctl:write ok long",
686 /* sysctl_get_new_value arg2 (buf) */
687 BPF_MOV64_REG(BPF_REG_7, BPF_REG_10),
688 BPF_ALU64_IMM(BPF_ADD, BPF_REG_7, -24),
690 BPF_MOV64_REG(BPF_REG_2, BPF_REG_7),
692 /* sysctl_get_new_value arg3 (buf_len) */
693 BPF_MOV64_IMM(BPF_REG_3, 24),
695 /* sysctl_get_new_value(ctx, buf, buf_len) */
696 BPF_EMIT_CALL(BPF_FUNC_sysctl_get_new_value),
698 /* if (ret == expected && */
699 BPF_JMP_IMM(BPF_JNE, BPF_REG_0, 23, 14),
701 /* buf[0:8] == "3000000 " && */
702 BPF_LD_IMM64(BPF_REG_8,
703 bpf_be64_to_cpu(0x3330303030303020ULL)),
704 BPF_LDX_MEM(BPF_DW, BPF_REG_9, BPF_REG_7, 0),
705 BPF_JMP_REG(BPF_JNE, BPF_REG_8, BPF_REG_9, 10),
707 /* buf[8:16] == "4000000 " && */
708 BPF_LD_IMM64(BPF_REG_8,
709 bpf_be64_to_cpu(0x3430303030303020ULL)),
710 BPF_LDX_MEM(BPF_DW, BPF_REG_9, BPF_REG_7, 8),
711 BPF_JMP_REG(BPF_JNE, BPF_REG_8, BPF_REG_9, 6),
713 /* buf[16:24] == "6000000\0") */
714 BPF_LD_IMM64(BPF_REG_8,
715 bpf_be64_to_cpu(0x3630303030303000ULL)),
716 BPF_LDX_MEM(BPF_DW, BPF_REG_9, BPF_REG_7, 16),
717 BPF_JMP_REG(BPF_JNE, BPF_REG_8, BPF_REG_9, 2),
720 BPF_MOV64_IMM(BPF_REG_0, 0),
723 /* else return ALLOW; */
724 BPF_MOV64_IMM(BPF_REG_0, 1),
727 .attach_type = BPF_CGROUP_SYSCTL,
728 .sysctl = "net/ipv4/tcp_mem",
729 .open_flags = O_WRONLY,
730 .newval = "3000000 4000000 6000000",
734 .descr = "sysctl_get_new_value sysctl:write E2BIG",
736 /* sysctl_get_new_value arg2 (buf) */
737 BPF_MOV64_REG(BPF_REG_7, BPF_REG_10),
738 BPF_ALU64_IMM(BPF_ADD, BPF_REG_7, -8),
739 BPF_MOV64_IMM(BPF_REG_0, 0),
740 BPF_STX_MEM(BPF_B, BPF_REG_7, BPF_REG_0, 3),
742 BPF_MOV64_REG(BPF_REG_2, BPF_REG_7),
744 /* sysctl_get_new_value arg3 (buf_len) */
745 BPF_MOV64_IMM(BPF_REG_3, 3),
747 /* sysctl_get_new_value(ctx, buf, buf_len) */
748 BPF_EMIT_CALL(BPF_FUNC_sysctl_get_new_value),
750 /* if (ret == expected && */
751 BPF_JMP_IMM(BPF_JNE, BPF_REG_0, -E2BIG, 4),
753 /* buf[0:3] == "60\0") */
754 BPF_LDX_MEM(BPF_W, BPF_REG_9, BPF_REG_7, 0),
755 BPF_JMP_IMM(BPF_JNE, BPF_REG_9,
756 bpf_ntohl(0x36300000), 2),
759 BPF_MOV64_IMM(BPF_REG_0, 0),
762 /* else return ALLOW; */
763 BPF_MOV64_IMM(BPF_REG_0, 1),
766 .attach_type = BPF_CGROUP_SYSCTL,
767 .sysctl = "net/ipv4/route/mtu_expires",
768 .open_flags = O_WRONLY,
773 .descr = "sysctl_set_new_value sysctl:read EINVAL",
775 /* sysctl_set_new_value arg2 (buf) */
776 BPF_MOV64_REG(BPF_REG_7, BPF_REG_10),
777 BPF_ALU64_IMM(BPF_ADD, BPF_REG_7, -8),
778 BPF_MOV64_IMM(BPF_REG_0,
779 bpf_ntohl(0x36303000)),
780 BPF_STX_MEM(BPF_DW, BPF_REG_7, BPF_REG_0, 0),
782 BPF_MOV64_REG(BPF_REG_2, BPF_REG_7),
784 /* sysctl_set_new_value arg3 (buf_len) */
785 BPF_MOV64_IMM(BPF_REG_3, 3),
787 /* sysctl_set_new_value(ctx, buf, buf_len) */
788 BPF_EMIT_CALL(BPF_FUNC_sysctl_set_new_value),
790 /* if (ret == expected) */
791 BPF_JMP_IMM(BPF_JNE, BPF_REG_0, -EINVAL, 2),
794 BPF_MOV64_IMM(BPF_REG_0, 1),
797 /* else return DENY; */
798 BPF_MOV64_IMM(BPF_REG_0, 0),
801 .attach_type = BPF_CGROUP_SYSCTL,
802 .sysctl = "net/ipv4/route/mtu_expires",
803 .open_flags = O_RDONLY,
807 .descr = "sysctl_set_new_value sysctl:write ok",
808 .fixup_value_insn = 2,
810 /* sysctl_set_new_value arg2 (buf) */
811 BPF_MOV64_REG(BPF_REG_7, BPF_REG_10),
812 BPF_ALU64_IMM(BPF_ADD, BPF_REG_7, -8),
813 BPF_LD_IMM64(BPF_REG_0, FIXUP_SYSCTL_VALUE),
814 BPF_STX_MEM(BPF_DW, BPF_REG_7, BPF_REG_0, 0),
816 BPF_MOV64_REG(BPF_REG_2, BPF_REG_7),
818 /* sysctl_set_new_value arg3 (buf_len) */
819 BPF_MOV64_IMM(BPF_REG_3, 3),
821 /* sysctl_set_new_value(ctx, buf, buf_len) */
822 BPF_EMIT_CALL(BPF_FUNC_sysctl_set_new_value),
824 /* if (ret == expected) */
825 BPF_JMP_IMM(BPF_JNE, BPF_REG_0, 0, 2),
828 BPF_MOV64_IMM(BPF_REG_0, 1),
831 /* else return DENY; */
832 BPF_MOV64_IMM(BPF_REG_0, 0),
835 .attach_type = BPF_CGROUP_SYSCTL,
836 .sysctl = "net/ipv4/route/mtu_expires",
837 .open_flags = O_WRONLY,
842 "bpf_strtoul one number string",
845 BPF_MOV64_REG(BPF_REG_7, BPF_REG_10),
846 BPF_ALU64_IMM(BPF_ADD, BPF_REG_7, -8),
847 BPF_MOV64_IMM(BPF_REG_0,
848 bpf_ntohl(0x36303000)),
849 BPF_STX_MEM(BPF_W, BPF_REG_7, BPF_REG_0, 0),
851 BPF_MOV64_REG(BPF_REG_1, BPF_REG_7),
854 BPF_MOV64_IMM(BPF_REG_2, 4),
857 BPF_MOV64_IMM(BPF_REG_3, 0),
860 BPF_ALU64_IMM(BPF_ADD, BPF_REG_7, -8),
861 BPF_STX_MEM(BPF_DW, BPF_REG_7, BPF_REG_0, 0),
862 BPF_MOV64_REG(BPF_REG_4, BPF_REG_7),
864 BPF_EMIT_CALL(BPF_FUNC_strtoul),
866 /* if (ret == expected && */
867 BPF_JMP_IMM(BPF_JNE, BPF_REG_0, 3, 4),
868 /* res == expected) */
869 BPF_LDX_MEM(BPF_DW, BPF_REG_9, BPF_REG_7, 0),
870 BPF_JMP_IMM(BPF_JNE, BPF_REG_9, 600, 2),
873 BPF_MOV64_IMM(BPF_REG_0, 1),
876 /* else return DENY; */
877 BPF_MOV64_IMM(BPF_REG_0, 0),
880 .attach_type = BPF_CGROUP_SYSCTL,
881 .sysctl = "net/ipv4/route/mtu_expires",
882 .open_flags = O_RDONLY,
886 "bpf_strtoul multi number string",
889 BPF_MOV64_REG(BPF_REG_7, BPF_REG_10),
890 BPF_ALU64_IMM(BPF_ADD, BPF_REG_7, -8),
892 BPF_LD_IMM64(BPF_REG_0,
893 bpf_be64_to_cpu(0x3630302036303200ULL)),
894 BPF_STX_MEM(BPF_DW, BPF_REG_7, BPF_REG_0, 0),
895 BPF_MOV64_REG(BPF_REG_1, BPF_REG_7),
898 BPF_MOV64_IMM(BPF_REG_2, 8),
901 BPF_MOV64_IMM(BPF_REG_3, 0),
904 BPF_ALU64_IMM(BPF_ADD, BPF_REG_7, -8),
905 BPF_STX_MEM(BPF_DW, BPF_REG_7, BPF_REG_0, 0),
906 BPF_MOV64_REG(BPF_REG_4, BPF_REG_7),
908 BPF_EMIT_CALL(BPF_FUNC_strtoul),
910 /* if (ret == expected && */
911 BPF_JMP_IMM(BPF_JNE, BPF_REG_0, 3, 18),
912 /* res == expected) */
913 BPF_LDX_MEM(BPF_DW, BPF_REG_9, BPF_REG_7, 0),
914 BPF_JMP_IMM(BPF_JNE, BPF_REG_9, 600, 16),
917 BPF_MOV64_REG(BPF_REG_7, BPF_REG_10),
918 BPF_ALU64_IMM(BPF_ADD, BPF_REG_7, -8),
919 BPF_ALU64_REG(BPF_ADD, BPF_REG_7, BPF_REG_0),
920 BPF_MOV64_REG(BPF_REG_1, BPF_REG_7),
923 BPF_MOV64_IMM(BPF_REG_2, 8),
924 BPF_ALU64_REG(BPF_SUB, BPF_REG_2, BPF_REG_0),
927 BPF_MOV64_IMM(BPF_REG_3, 0),
930 BPF_MOV64_REG(BPF_REG_7, BPF_REG_10),
931 BPF_ALU64_IMM(BPF_ADD, BPF_REG_7, -16),
932 BPF_MOV64_REG(BPF_REG_4, BPF_REG_7),
934 BPF_EMIT_CALL(BPF_FUNC_strtoul),
936 /* if (ret == expected && */
937 BPF_JMP_IMM(BPF_JNE, BPF_REG_0, 4, 4),
938 /* res == expected) */
939 BPF_LDX_MEM(BPF_DW, BPF_REG_9, BPF_REG_7, 0),
940 BPF_JMP_IMM(BPF_JNE, BPF_REG_9, 602, 2),
943 BPF_MOV64_IMM(BPF_REG_0, 1),
946 /* else return DENY; */
947 BPF_MOV64_IMM(BPF_REG_0, 0),
950 .attach_type = BPF_CGROUP_SYSCTL,
951 .sysctl = "net/ipv4/tcp_mem",
952 .open_flags = O_RDONLY,
956 "bpf_strtoul buf_len = 0, reject",
959 BPF_MOV64_REG(BPF_REG_7, BPF_REG_10),
960 BPF_ALU64_IMM(BPF_ADD, BPF_REG_7, -8),
961 BPF_MOV64_IMM(BPF_REG_0,
962 bpf_ntohl(0x36303000)),
963 BPF_STX_MEM(BPF_DW, BPF_REG_7, BPF_REG_0, 0),
965 BPF_MOV64_REG(BPF_REG_1, BPF_REG_7),
968 BPF_MOV64_IMM(BPF_REG_2, 0),
971 BPF_MOV64_IMM(BPF_REG_3, 0),
974 BPF_ALU64_IMM(BPF_ADD, BPF_REG_7, -8),
975 BPF_STX_MEM(BPF_DW, BPF_REG_7, BPF_REG_0, 0),
976 BPF_MOV64_REG(BPF_REG_4, BPF_REG_7),
978 BPF_EMIT_CALL(BPF_FUNC_strtoul),
980 BPF_MOV64_IMM(BPF_REG_0, 1),
983 .attach_type = BPF_CGROUP_SYSCTL,
984 .sysctl = "net/ipv4/route/mtu_expires",
985 .open_flags = O_RDONLY,
986 .result = LOAD_REJECT,
989 "bpf_strtoul supported base, ok",
992 BPF_MOV64_REG(BPF_REG_7, BPF_REG_10),
993 BPF_ALU64_IMM(BPF_ADD, BPF_REG_7, -8),
994 BPF_MOV64_IMM(BPF_REG_0,
995 bpf_ntohl(0x30373700)),
996 BPF_STX_MEM(BPF_W, BPF_REG_7, BPF_REG_0, 0),
998 BPF_MOV64_REG(BPF_REG_1, BPF_REG_7),
1000 /* arg2 (buf_len) */
1001 BPF_MOV64_IMM(BPF_REG_2, 4),
1004 BPF_MOV64_IMM(BPF_REG_3, 8),
1007 BPF_ALU64_IMM(BPF_ADD, BPF_REG_7, -8),
1008 BPF_STX_MEM(BPF_DW, BPF_REG_7, BPF_REG_0, 0),
1009 BPF_MOV64_REG(BPF_REG_4, BPF_REG_7),
1011 BPF_EMIT_CALL(BPF_FUNC_strtoul),
1013 /* if (ret == expected && */
1014 BPF_JMP_IMM(BPF_JNE, BPF_REG_0, 3, 4),
1015 /* res == expected) */
1016 BPF_LDX_MEM(BPF_DW, BPF_REG_9, BPF_REG_7, 0),
1017 BPF_JMP_IMM(BPF_JNE, BPF_REG_9, 63, 2),
1020 BPF_MOV64_IMM(BPF_REG_0, 1),
1023 /* else return DENY; */
1024 BPF_MOV64_IMM(BPF_REG_0, 0),
1027 .attach_type = BPF_CGROUP_SYSCTL,
1028 .sysctl = "net/ipv4/route/mtu_expires",
1029 .open_flags = O_RDONLY,
1033 "bpf_strtoul unsupported base, EINVAL",
1036 BPF_MOV64_REG(BPF_REG_7, BPF_REG_10),
1037 BPF_ALU64_IMM(BPF_ADD, BPF_REG_7, -8),
1038 BPF_MOV64_IMM(BPF_REG_0,
1039 bpf_ntohl(0x36303000)),
1040 BPF_STX_MEM(BPF_DW, BPF_REG_7, BPF_REG_0, 0),
1042 BPF_MOV64_REG(BPF_REG_1, BPF_REG_7),
1044 /* arg2 (buf_len) */
1045 BPF_MOV64_IMM(BPF_REG_2, 4),
1048 BPF_MOV64_IMM(BPF_REG_3, 3),
1051 BPF_ALU64_IMM(BPF_ADD, BPF_REG_7, -8),
1052 BPF_STX_MEM(BPF_DW, BPF_REG_7, BPF_REG_0, 0),
1053 BPF_MOV64_REG(BPF_REG_4, BPF_REG_7),
1055 BPF_EMIT_CALL(BPF_FUNC_strtoul),
1057 /* if (ret == expected) */
1058 BPF_JMP_IMM(BPF_JNE, BPF_REG_0, -EINVAL, 2),
1061 BPF_MOV64_IMM(BPF_REG_0, 1),
1064 /* else return DENY; */
1065 BPF_MOV64_IMM(BPF_REG_0, 0),
1068 .attach_type = BPF_CGROUP_SYSCTL,
1069 .sysctl = "net/ipv4/route/mtu_expires",
1070 .open_flags = O_RDONLY,
1074 "bpf_strtoul buf with spaces only, EINVAL",
1077 BPF_MOV64_REG(BPF_REG_7, BPF_REG_10),
1078 BPF_ALU64_IMM(BPF_ADD, BPF_REG_7, -8),
1079 BPF_MOV64_IMM(BPF_REG_0,
1080 bpf_ntohl(0x0d0c0a09)),
1081 BPF_STX_MEM(BPF_DW, BPF_REG_7, BPF_REG_0, 0),
1083 BPF_MOV64_REG(BPF_REG_1, BPF_REG_7),
1085 /* arg2 (buf_len) */
1086 BPF_MOV64_IMM(BPF_REG_2, 4),
1089 BPF_MOV64_IMM(BPF_REG_3, 0),
1092 BPF_ALU64_IMM(BPF_ADD, BPF_REG_7, -8),
1093 BPF_STX_MEM(BPF_DW, BPF_REG_7, BPF_REG_0, 0),
1094 BPF_MOV64_REG(BPF_REG_4, BPF_REG_7),
1096 BPF_EMIT_CALL(BPF_FUNC_strtoul),
1098 /* if (ret == expected) */
1099 BPF_JMP_IMM(BPF_JNE, BPF_REG_0, -EINVAL, 2),
1102 BPF_MOV64_IMM(BPF_REG_0, 1),
1105 /* else return DENY; */
1106 BPF_MOV64_IMM(BPF_REG_0, 0),
1109 .attach_type = BPF_CGROUP_SYSCTL,
1110 .sysctl = "net/ipv4/route/mtu_expires",
1111 .open_flags = O_RDONLY,
1115 "bpf_strtoul negative number, EINVAL",
1118 BPF_MOV64_REG(BPF_REG_7, BPF_REG_10),
1119 BPF_ALU64_IMM(BPF_ADD, BPF_REG_7, -8),
1121 BPF_MOV64_IMM(BPF_REG_0,
1122 bpf_ntohl(0x0a2d3600)),
1123 BPF_STX_MEM(BPF_DW, BPF_REG_7, BPF_REG_0, 0),
1125 BPF_MOV64_REG(BPF_REG_1, BPF_REG_7),
1127 /* arg2 (buf_len) */
1128 BPF_MOV64_IMM(BPF_REG_2, 4),
1131 BPF_MOV64_IMM(BPF_REG_3, 0),
1134 BPF_ALU64_IMM(BPF_ADD, BPF_REG_7, -8),
1135 BPF_STX_MEM(BPF_DW, BPF_REG_7, BPF_REG_0, 0),
1136 BPF_MOV64_REG(BPF_REG_4, BPF_REG_7),
1138 BPF_EMIT_CALL(BPF_FUNC_strtoul),
1140 /* if (ret == expected) */
1141 BPF_JMP_IMM(BPF_JNE, BPF_REG_0, -EINVAL, 2),
1144 BPF_MOV64_IMM(BPF_REG_0, 1),
1147 /* else return DENY; */
1148 BPF_MOV64_IMM(BPF_REG_0, 0),
1151 .attach_type = BPF_CGROUP_SYSCTL,
1152 .sysctl = "net/ipv4/route/mtu_expires",
1153 .open_flags = O_RDONLY,
1157 "bpf_strtol negative number, ok",
1160 BPF_MOV64_REG(BPF_REG_7, BPF_REG_10),
1161 BPF_ALU64_IMM(BPF_ADD, BPF_REG_7, -8),
1163 BPF_MOV64_IMM(BPF_REG_0,
1164 bpf_ntohl(0x0a2d3600)),
1165 BPF_STX_MEM(BPF_W, BPF_REG_7, BPF_REG_0, 0),
1167 BPF_MOV64_REG(BPF_REG_1, BPF_REG_7),
1169 /* arg2 (buf_len) */
1170 BPF_MOV64_IMM(BPF_REG_2, 4),
1173 BPF_MOV64_IMM(BPF_REG_3, 10),
1176 BPF_ALU64_IMM(BPF_ADD, BPF_REG_7, -8),
1177 BPF_STX_MEM(BPF_DW, BPF_REG_7, BPF_REG_0, 0),
1178 BPF_MOV64_REG(BPF_REG_4, BPF_REG_7),
1180 BPF_EMIT_CALL(BPF_FUNC_strtol),
1182 /* if (ret == expected && */
1183 BPF_JMP_IMM(BPF_JNE, BPF_REG_0, 3, 4),
1184 /* res == expected) */
1185 BPF_LDX_MEM(BPF_DW, BPF_REG_9, BPF_REG_7, 0),
1186 BPF_JMP_IMM(BPF_JNE, BPF_REG_9, -6, 2),
1189 BPF_MOV64_IMM(BPF_REG_0, 1),
1192 /* else return DENY; */
1193 BPF_MOV64_IMM(BPF_REG_0, 0),
1196 .attach_type = BPF_CGROUP_SYSCTL,
1197 .sysctl = "net/ipv4/route/mtu_expires",
1198 .open_flags = O_RDONLY,
1202 "bpf_strtol hex number, ok",
1205 BPF_MOV64_REG(BPF_REG_7, BPF_REG_10),
1206 BPF_ALU64_IMM(BPF_ADD, BPF_REG_7, -8),
1208 BPF_MOV64_IMM(BPF_REG_0,
1209 bpf_ntohl(0x30786665)),
1210 BPF_STX_MEM(BPF_W, BPF_REG_7, BPF_REG_0, 0),
1212 BPF_MOV64_REG(BPF_REG_1, BPF_REG_7),
1214 /* arg2 (buf_len) */
1215 BPF_MOV64_IMM(BPF_REG_2, 4),
1218 BPF_MOV64_IMM(BPF_REG_3, 0),
1221 BPF_ALU64_IMM(BPF_ADD, BPF_REG_7, -8),
1222 BPF_STX_MEM(BPF_DW, BPF_REG_7, BPF_REG_0, 0),
1223 BPF_MOV64_REG(BPF_REG_4, BPF_REG_7),
1225 BPF_EMIT_CALL(BPF_FUNC_strtol),
1227 /* if (ret == expected && */
1228 BPF_JMP_IMM(BPF_JNE, BPF_REG_0, 4, 4),
1229 /* res == expected) */
1230 BPF_LDX_MEM(BPF_DW, BPF_REG_9, BPF_REG_7, 0),
1231 BPF_JMP_IMM(BPF_JNE, BPF_REG_9, 254, 2),
1234 BPF_MOV64_IMM(BPF_REG_0, 1),
1237 /* else return DENY; */
1238 BPF_MOV64_IMM(BPF_REG_0, 0),
1241 .attach_type = BPF_CGROUP_SYSCTL,
1242 .sysctl = "net/ipv4/route/mtu_expires",
1243 .open_flags = O_RDONLY,
1247 "bpf_strtol max long",
1249 /* arg1 (buf) 9223372036854775807 */
1250 BPF_MOV64_REG(BPF_REG_7, BPF_REG_10),
1251 BPF_ALU64_IMM(BPF_ADD, BPF_REG_7, -24),
1252 BPF_LD_IMM64(BPF_REG_0,
1253 bpf_be64_to_cpu(0x3932323333373230ULL)),
1254 BPF_STX_MEM(BPF_DW, BPF_REG_7, BPF_REG_0, 0),
1255 BPF_LD_IMM64(BPF_REG_0,
1256 bpf_be64_to_cpu(0x3336383534373735ULL)),
1257 BPF_STX_MEM(BPF_DW, BPF_REG_7, BPF_REG_0, 8),
1258 BPF_LD_IMM64(BPF_REG_0,
1259 bpf_be64_to_cpu(0x3830370000000000ULL)),
1260 BPF_STX_MEM(BPF_DW, BPF_REG_7, BPF_REG_0, 16),
1262 BPF_MOV64_REG(BPF_REG_1, BPF_REG_7),
1264 /* arg2 (buf_len) */
1265 BPF_MOV64_IMM(BPF_REG_2, 19),
1268 BPF_MOV64_IMM(BPF_REG_3, 0),
1271 BPF_ALU64_IMM(BPF_ADD, BPF_REG_7, -8),
1272 BPF_STX_MEM(BPF_DW, BPF_REG_7, BPF_REG_0, 0),
1273 BPF_MOV64_REG(BPF_REG_4, BPF_REG_7),
1275 BPF_EMIT_CALL(BPF_FUNC_strtol),
1277 /* if (ret == expected && */
1278 BPF_JMP_IMM(BPF_JNE, BPF_REG_0, 19, 6),
1279 /* res == expected) */
1280 BPF_LD_IMM64(BPF_REG_8, 0x7fffffffffffffffULL),
1281 BPF_LDX_MEM(BPF_DW, BPF_REG_9, BPF_REG_7, 0),
1282 BPF_JMP_REG(BPF_JNE, BPF_REG_8, BPF_REG_9, 2),
1285 BPF_MOV64_IMM(BPF_REG_0, 1),
1288 /* else return DENY; */
1289 BPF_MOV64_IMM(BPF_REG_0, 0),
1292 .attach_type = BPF_CGROUP_SYSCTL,
1293 .sysctl = "net/ipv4/route/mtu_expires",
1294 .open_flags = O_RDONLY,
1298 "bpf_strtol overflow, ERANGE",
1300 /* arg1 (buf) 9223372036854775808 */
1301 BPF_MOV64_REG(BPF_REG_7, BPF_REG_10),
1302 BPF_ALU64_IMM(BPF_ADD, BPF_REG_7, -24),
1303 BPF_LD_IMM64(BPF_REG_0,
1304 bpf_be64_to_cpu(0x3932323333373230ULL)),
1305 BPF_STX_MEM(BPF_DW, BPF_REG_7, BPF_REG_0, 0),
1306 BPF_LD_IMM64(BPF_REG_0,
1307 bpf_be64_to_cpu(0x3336383534373735ULL)),
1308 BPF_STX_MEM(BPF_DW, BPF_REG_7, BPF_REG_0, 8),
1309 BPF_LD_IMM64(BPF_REG_0,
1310 bpf_be64_to_cpu(0x3830380000000000ULL)),
1311 BPF_STX_MEM(BPF_DW, BPF_REG_7, BPF_REG_0, 16),
1313 BPF_MOV64_REG(BPF_REG_1, BPF_REG_7),
1315 /* arg2 (buf_len) */
1316 BPF_MOV64_IMM(BPF_REG_2, 19),
1319 BPF_MOV64_IMM(BPF_REG_3, 0),
1322 BPF_ALU64_IMM(BPF_ADD, BPF_REG_7, -8),
1323 BPF_STX_MEM(BPF_DW, BPF_REG_7, BPF_REG_0, 0),
1324 BPF_MOV64_REG(BPF_REG_4, BPF_REG_7),
1326 BPF_EMIT_CALL(BPF_FUNC_strtol),
1328 /* if (ret == expected) */
1329 BPF_JMP_IMM(BPF_JNE, BPF_REG_0, -ERANGE, 2),
1332 BPF_MOV64_IMM(BPF_REG_0, 1),
1335 /* else return DENY; */
1336 BPF_MOV64_IMM(BPF_REG_0, 0),
1339 .attach_type = BPF_CGROUP_SYSCTL,
1340 .sysctl = "net/ipv4/route/mtu_expires",
1341 .open_flags = O_RDONLY,
1345 "C prog: deny all writes",
1346 .prog_file = "./test_sysctl_prog.o",
1347 .attach_type = BPF_CGROUP_SYSCTL,
1348 .sysctl = "net/ipv4/tcp_mem",
1349 .open_flags = O_WRONLY,
1350 .newval = "123 456 789",
1354 "C prog: deny access by name",
1355 .prog_file = "./test_sysctl_prog.o",
1356 .attach_type = BPF_CGROUP_SYSCTL,
1357 .sysctl = "net/ipv4/route/mtu_expires",
1358 .open_flags = O_RDONLY,
1362 "C prog: read tcp_mem",
1363 .prog_file = "./test_sysctl_prog.o",
1364 .attach_type = BPF_CGROUP_SYSCTL,
1365 .sysctl = "net/ipv4/tcp_mem",
1366 .open_flags = O_RDONLY,
1371 static size_t probe_prog_length(const struct bpf_insn *fp)
1375 for (len = MAX_INSNS - 1; len > 0; --len)
1376 if (fp[len].code != 0 || fp[len].imm != 0)
1381 static int fixup_sysctl_value(const char *buf, size_t buf_len,
1382 struct bpf_insn *prog, size_t insn_num)
1385 uint8_t raw[sizeof(uint64_t)];
1390 if (buf_len > sizeof(value)) {
1391 log_err("Value is too big (%zd) to use in fixup", buf_len);
1394 if (prog[insn_num].code != (BPF_LD | BPF_DW | BPF_IMM)) {
1395 log_err("Can fixup only BPF_LD_IMM64 insns");
1399 memcpy(value.raw, buf, buf_len);
1400 prog[insn_num].imm = (uint32_t)value.num;
1401 prog[insn_num + 1].imm = (uint32_t)(value.num >> 32);
1406 static int load_sysctl_prog_insns(struct sysctl_test *test,
1407 const char *sysctl_path)
1409 struct bpf_insn *prog = test->insns;
1410 struct bpf_load_program_attr attr;
1413 memset(&attr, 0, sizeof(struct bpf_load_program_attr));
1414 attr.prog_type = BPF_PROG_TYPE_CGROUP_SYSCTL;
1416 attr.insns_cnt = probe_prog_length(attr.insns);
1417 attr.license = "GPL";
1419 if (test->fixup_value_insn) {
1424 fd = open(sysctl_path, O_RDONLY | O_CLOEXEC);
1426 log_err("open(%s) failed", sysctl_path);
1429 len = read(fd, buf, sizeof(buf));
1431 log_err("read(%s) failed", sysctl_path);
1436 if (fixup_sysctl_value(buf, len, prog, test->fixup_value_insn))
1440 ret = bpf_load_program_xattr(&attr, bpf_log_buf, BPF_LOG_BUF_SIZE);
1441 if (ret < 0 && test->result != LOAD_REJECT) {
1442 log_err(">>> Loading program error.\n"
1443 ">>> Verifier output:\n%s\n-------\n", bpf_log_buf);
1449 static int load_sysctl_prog_file(struct sysctl_test *test)
1451 struct bpf_prog_load_attr attr;
1452 struct bpf_object *obj;
1455 memset(&attr, 0, sizeof(struct bpf_prog_load_attr));
1456 attr.file = test->prog_file;
1457 attr.prog_type = BPF_PROG_TYPE_CGROUP_SYSCTL;
1459 if (bpf_prog_load_xattr(&attr, &obj, &prog_fd)) {
1460 if (test->result != LOAD_REJECT)
1461 log_err(">>> Loading program (%s) error.\n",
1469 static int load_sysctl_prog(struct sysctl_test *test, const char *sysctl_path)
1471 return test->prog_file
1472 ? load_sysctl_prog_file(test)
1473 : load_sysctl_prog_insns(test, sysctl_path);
1476 static int access_sysctl(const char *sysctl_path,
1477 const struct sysctl_test *test)
1482 fd = open(sysctl_path, test->open_flags | O_CLOEXEC);
1486 if (test->seek && lseek(fd, test->seek, SEEK_SET) == -1) {
1487 log_err("lseek(%d) failed", test->seek);
1491 if (test->open_flags == O_RDONLY) {
1494 if (read(fd, buf, sizeof(buf)) == -1)
1497 strncmp(buf, test->oldval, strlen(test->oldval))) {
1498 log_err("Read value %s != %s", buf, test->oldval);
1501 } else if (test->open_flags == O_WRONLY) {
1502 if (!test->newval) {
1503 log_err("New value for sysctl is not set");
1506 if (write(fd, test->newval, strlen(test->newval)) == -1)
1509 log_err("Unexpected sysctl access: neither read nor write");
1521 static int run_test_case(int cgfd, struct sysctl_test *test)
1523 enum bpf_attach_type atype = test->attach_type;
1524 char sysctl_path[128];
1528 printf("Test case: %s .. ", test->descr);
1530 snprintf(sysctl_path, sizeof(sysctl_path), "/proc/sys/%s",
1533 progfd = load_sysctl_prog(test, sysctl_path);
1535 if (test->result == LOAD_REJECT)
1541 if (bpf_prog_attach(progfd, cgfd, atype, BPF_F_ALLOW_OVERRIDE) == -1) {
1542 if (test->result == ATTACH_REJECT)
1549 if (access_sysctl(sysctl_path, test) == -1) {
1550 if (test->result == OP_EPERM && errno == EPERM)
1556 if (test->result != SUCCESS) {
1557 log_err("Unexpected success");
1565 /* Detaching w/o checking return code: best effort attempt. */
1567 bpf_prog_detach(cgfd, atype);
1569 printf("[%s]\n", err ? "FAIL" : "PASS");
1573 static int run_tests(int cgfd)
1579 for (i = 0; i < ARRAY_SIZE(tests); ++i) {
1580 if (run_test_case(cgfd, &tests[i]))
1585 printf("Summary: %d PASSED, %d FAILED\n", passes, fails);
1586 return fails ? -1 : 0;
1589 int main(int argc, char **argv)
1594 if (setup_cgroup_environment())
1597 cgfd = create_and_get_cgroup(CG_PATH);
1601 if (join_cgroup(CG_PATH))
1604 if (run_tests(cgfd))
1612 cleanup_cgroup_environment();