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_rlimit.h"
18 #include "cgroup_helpers.h"
20 #define CG_PATH "/foo"
22 #define FIXUP_SYSCTL_VALUE 0
24 char bpf_log_buf
[BPF_LOG_BUF_SIZE
];
28 size_t fixup_value_insn
;
29 struct bpf_insn insns
[MAX_INSNS
];
30 const char *prog_file
;
31 enum bpf_attach_type attach_type
;
44 static struct sysctl_test tests
[] = {
46 .descr
= "sysctl wrong attach_type",
48 BPF_MOV64_IMM(BPF_REG_0
, 1),
52 .sysctl
= "kernel/ostype",
53 .open_flags
= O_RDONLY
,
54 .result
= ATTACH_REJECT
,
57 .descr
= "sysctl:read allow all",
59 BPF_MOV64_IMM(BPF_REG_0
, 1),
62 .attach_type
= BPF_CGROUP_SYSCTL
,
63 .sysctl
= "kernel/ostype",
64 .open_flags
= O_RDONLY
,
68 .descr
= "sysctl:read deny all",
70 BPF_MOV64_IMM(BPF_REG_0
, 0),
73 .attach_type
= BPF_CGROUP_SYSCTL
,
74 .sysctl
= "kernel/ostype",
75 .open_flags
= O_RDONLY
,
79 .descr
= "ctx:write sysctl:read read ok",
82 BPF_LDX_MEM(BPF_W
, BPF_REG_7
, BPF_REG_1
,
83 offsetof(struct bpf_sysctl
, write
)),
84 BPF_JMP_IMM(BPF_JNE
, BPF_REG_7
, 1, 2),
87 BPF_MOV64_IMM(BPF_REG_0
, 0),
90 /* else return ALLOW; */
91 BPF_MOV64_IMM(BPF_REG_0
, 1),
94 .attach_type
= BPF_CGROUP_SYSCTL
,
95 .sysctl
= "kernel/ostype",
96 .open_flags
= O_RDONLY
,
100 .descr
= "ctx:write sysctl:write read ok",
103 BPF_LDX_MEM(BPF_B
, BPF_REG_7
, BPF_REG_1
,
104 offsetof(struct bpf_sysctl
, write
)),
105 BPF_JMP_IMM(BPF_JNE
, BPF_REG_7
, 1, 2),
108 BPF_MOV64_IMM(BPF_REG_0
, 0),
111 /* else return ALLOW; */
112 BPF_MOV64_IMM(BPF_REG_0
, 1),
115 .attach_type
= BPF_CGROUP_SYSCTL
,
116 .sysctl
= "kernel/domainname",
117 .open_flags
= O_WRONLY
,
118 .newval
= "(none)", /* same as default, should fail anyway */
122 .descr
= "ctx:write sysctl:read write reject",
125 BPF_MOV64_IMM(BPF_REG_0
, 0),
126 BPF_STX_MEM(BPF_W
, BPF_REG_1
, BPF_REG_0
,
127 offsetof(struct bpf_sysctl
, write
)),
128 BPF_MOV64_IMM(BPF_REG_0
, 1),
131 .attach_type
= BPF_CGROUP_SYSCTL
,
132 .sysctl
= "kernel/ostype",
133 .open_flags
= O_RDONLY
,
134 .result
= LOAD_REJECT
,
137 .descr
= "ctx:file_pos sysctl:read read ok",
139 /* If (file_pos == X) */
140 BPF_LDX_MEM(BPF_W
, BPF_REG_7
, BPF_REG_1
,
141 offsetof(struct bpf_sysctl
, file_pos
)),
142 BPF_JMP_IMM(BPF_JNE
, BPF_REG_7
, 0, 2),
145 BPF_MOV64_IMM(BPF_REG_0
, 1),
148 /* else return DENY; */
149 BPF_MOV64_IMM(BPF_REG_0
, 0),
152 .attach_type
= BPF_CGROUP_SYSCTL
,
153 .sysctl
= "kernel/ostype",
154 .open_flags
= O_RDONLY
,
158 .descr
= "ctx:file_pos sysctl:read read ok narrow",
160 /* If (file_pos == X) */
161 BPF_LDX_MEM(BPF_B
, BPF_REG_7
, BPF_REG_1
,
162 offsetof(struct bpf_sysctl
, file_pos
)),
163 BPF_JMP_IMM(BPF_JNE
, BPF_REG_7
, 0, 2),
166 BPF_MOV64_IMM(BPF_REG_0
, 1),
169 /* else return DENY; */
170 BPF_MOV64_IMM(BPF_REG_0
, 0),
173 .attach_type
= BPF_CGROUP_SYSCTL
,
174 .sysctl
= "kernel/ostype",
175 .open_flags
= O_RDONLY
,
179 .descr
= "ctx:file_pos sysctl:read write ok",
182 BPF_MOV64_IMM(BPF_REG_0
, 2),
183 BPF_STX_MEM(BPF_W
, BPF_REG_1
, BPF_REG_0
,
184 offsetof(struct bpf_sysctl
, file_pos
)),
185 BPF_MOV64_IMM(BPF_REG_0
, 1),
188 .attach_type
= BPF_CGROUP_SYSCTL
,
189 .sysctl
= "kernel/ostype",
190 .open_flags
= O_RDONLY
,
195 .descr
= "sysctl_get_name sysctl_value:base ok",
197 /* sysctl_get_name arg2 (buf) */
198 BPF_MOV64_REG(BPF_REG_7
, BPF_REG_10
),
199 BPF_ALU64_IMM(BPF_ADD
, BPF_REG_7
, -8),
200 BPF_MOV64_IMM(BPF_REG_0
, 0),
201 BPF_STX_MEM(BPF_DW
, BPF_REG_7
, BPF_REG_0
, 0),
203 BPF_MOV64_REG(BPF_REG_2
, BPF_REG_7
),
205 /* sysctl_get_name arg3 (buf_len) */
206 BPF_MOV64_IMM(BPF_REG_3
, 8),
208 /* sysctl_get_name arg4 (flags) */
209 BPF_MOV64_IMM(BPF_REG_4
, BPF_F_SYSCTL_BASE_NAME
),
211 /* sysctl_get_name(ctx, buf, buf_len, flags) */
212 BPF_EMIT_CALL(BPF_FUNC_sysctl_get_name
),
214 /* if (ret == expected && */
215 BPF_JMP_IMM(BPF_JNE
, BPF_REG_0
, sizeof("tcp_mem") - 1, 6),
216 /* buf == "tcp_mem\0") */
217 BPF_LD_IMM64(BPF_REG_8
, 0x006d656d5f706374ULL
),
218 BPF_LDX_MEM(BPF_DW
, BPF_REG_9
, BPF_REG_7
, 0),
219 BPF_JMP_REG(BPF_JNE
, BPF_REG_8
, BPF_REG_9
, 2),
222 BPF_MOV64_IMM(BPF_REG_0
, 1),
225 /* else return DENY; */
226 BPF_MOV64_IMM(BPF_REG_0
, 0),
229 .attach_type
= BPF_CGROUP_SYSCTL
,
230 .sysctl
= "net/ipv4/tcp_mem",
231 .open_flags
= O_RDONLY
,
235 .descr
= "sysctl_get_name sysctl_value:base E2BIG truncated",
237 /* sysctl_get_name arg2 (buf) */
238 BPF_MOV64_REG(BPF_REG_7
, BPF_REG_10
),
239 BPF_ALU64_IMM(BPF_ADD
, BPF_REG_7
, -8),
240 BPF_MOV64_IMM(BPF_REG_0
, 0),
241 BPF_STX_MEM(BPF_DW
, BPF_REG_7
, BPF_REG_0
, 0),
243 BPF_MOV64_REG(BPF_REG_2
, BPF_REG_7
),
245 /* sysctl_get_name arg3 (buf_len) too small */
246 BPF_MOV64_IMM(BPF_REG_3
, 7),
248 /* sysctl_get_name arg4 (flags) */
249 BPF_MOV64_IMM(BPF_REG_4
, BPF_F_SYSCTL_BASE_NAME
),
251 /* sysctl_get_name(ctx, buf, buf_len, flags) */
252 BPF_EMIT_CALL(BPF_FUNC_sysctl_get_name
),
254 /* if (ret == expected && */
255 BPF_JMP_IMM(BPF_JNE
, BPF_REG_0
, -E2BIG
, 6),
257 /* buf[0:7] == "tcp_me\0") */
258 BPF_LD_IMM64(BPF_REG_8
, 0x00656d5f706374ULL
),
259 BPF_LDX_MEM(BPF_DW
, BPF_REG_9
, BPF_REG_7
, 0),
260 BPF_JMP_REG(BPF_JNE
, BPF_REG_8
, BPF_REG_9
, 2),
263 BPF_MOV64_IMM(BPF_REG_0
, 1),
266 /* else return DENY; */
267 BPF_MOV64_IMM(BPF_REG_0
, 0),
270 .attach_type
= BPF_CGROUP_SYSCTL
,
271 .sysctl
= "net/ipv4/tcp_mem",
272 .open_flags
= O_RDONLY
,
276 .descr
= "sysctl_get_name sysctl:full ok",
278 /* sysctl_get_name arg2 (buf) */
279 BPF_MOV64_REG(BPF_REG_7
, BPF_REG_10
),
280 BPF_ALU64_IMM(BPF_ADD
, BPF_REG_7
, -24),
281 BPF_MOV64_IMM(BPF_REG_0
, 0),
282 BPF_STX_MEM(BPF_DW
, BPF_REG_7
, BPF_REG_0
, 0),
283 BPF_STX_MEM(BPF_DW
, BPF_REG_7
, BPF_REG_0
, 8),
284 BPF_STX_MEM(BPF_DW
, BPF_REG_7
, BPF_REG_0
, 16),
286 BPF_MOV64_REG(BPF_REG_2
, BPF_REG_7
),
288 /* sysctl_get_name arg3 (buf_len) */
289 BPF_MOV64_IMM(BPF_REG_3
, 17),
291 /* sysctl_get_name arg4 (flags) */
292 BPF_MOV64_IMM(BPF_REG_4
, 0),
294 /* sysctl_get_name(ctx, buf, buf_len, flags) */
295 BPF_EMIT_CALL(BPF_FUNC_sysctl_get_name
),
297 /* if (ret == expected && */
298 BPF_JMP_IMM(BPF_JNE
, BPF_REG_0
, 16, 14),
300 /* buf[0:8] == "net/ipv4" && */
301 BPF_LD_IMM64(BPF_REG_8
, 0x347670692f74656eULL
),
302 BPF_LDX_MEM(BPF_DW
, BPF_REG_9
, BPF_REG_7
, 0),
303 BPF_JMP_REG(BPF_JNE
, BPF_REG_8
, BPF_REG_9
, 10),
305 /* buf[8:16] == "/tcp_mem" && */
306 BPF_LD_IMM64(BPF_REG_8
, 0x6d656d5f7063742fULL
),
307 BPF_LDX_MEM(BPF_DW
, BPF_REG_9
, BPF_REG_7
, 8),
308 BPF_JMP_REG(BPF_JNE
, BPF_REG_8
, BPF_REG_9
, 6),
310 /* buf[16:24] == "\0") */
311 BPF_LD_IMM64(BPF_REG_8
, 0x0ULL
),
312 BPF_LDX_MEM(BPF_DW
, BPF_REG_9
, BPF_REG_7
, 16),
313 BPF_JMP_REG(BPF_JNE
, BPF_REG_8
, BPF_REG_9
, 2),
316 BPF_MOV64_IMM(BPF_REG_0
, 1),
319 /* else return DENY; */
320 BPF_MOV64_IMM(BPF_REG_0
, 0),
323 .attach_type
= BPF_CGROUP_SYSCTL
,
324 .sysctl
= "net/ipv4/tcp_mem",
325 .open_flags
= O_RDONLY
,
329 .descr
= "sysctl_get_name sysctl:full E2BIG truncated",
331 /* sysctl_get_name arg2 (buf) */
332 BPF_MOV64_REG(BPF_REG_7
, BPF_REG_10
),
333 BPF_ALU64_IMM(BPF_ADD
, BPF_REG_7
, -16),
334 BPF_MOV64_IMM(BPF_REG_0
, 0),
335 BPF_STX_MEM(BPF_DW
, BPF_REG_7
, BPF_REG_0
, 0),
336 BPF_STX_MEM(BPF_DW
, BPF_REG_7
, BPF_REG_0
, 8),
338 BPF_MOV64_REG(BPF_REG_2
, BPF_REG_7
),
340 /* sysctl_get_name arg3 (buf_len) */
341 BPF_MOV64_IMM(BPF_REG_3
, 16),
343 /* sysctl_get_name arg4 (flags) */
344 BPF_MOV64_IMM(BPF_REG_4
, 0),
346 /* sysctl_get_name(ctx, buf, buf_len, flags) */
347 BPF_EMIT_CALL(BPF_FUNC_sysctl_get_name
),
349 /* if (ret == expected && */
350 BPF_JMP_IMM(BPF_JNE
, BPF_REG_0
, -E2BIG
, 10),
352 /* buf[0:8] == "net/ipv4" && */
353 BPF_LD_IMM64(BPF_REG_8
, 0x347670692f74656eULL
),
354 BPF_LDX_MEM(BPF_DW
, BPF_REG_9
, BPF_REG_7
, 0),
355 BPF_JMP_REG(BPF_JNE
, BPF_REG_8
, BPF_REG_9
, 6),
357 /* buf[8:16] == "/tcp_me\0") */
358 BPF_LD_IMM64(BPF_REG_8
, 0x00656d5f7063742fULL
),
359 BPF_LDX_MEM(BPF_DW
, BPF_REG_9
, BPF_REG_7
, 8),
360 BPF_JMP_REG(BPF_JNE
, BPF_REG_8
, BPF_REG_9
, 2),
363 BPF_MOV64_IMM(BPF_REG_0
, 1),
366 /* else return DENY; */
367 BPF_MOV64_IMM(BPF_REG_0
, 0),
370 .attach_type
= BPF_CGROUP_SYSCTL
,
371 .sysctl
= "net/ipv4/tcp_mem",
372 .open_flags
= O_RDONLY
,
376 .descr
= "sysctl_get_name sysctl:full E2BIG truncated small",
378 /* sysctl_get_name arg2 (buf) */
379 BPF_MOV64_REG(BPF_REG_7
, BPF_REG_10
),
380 BPF_ALU64_IMM(BPF_ADD
, BPF_REG_7
, -8),
381 BPF_MOV64_IMM(BPF_REG_0
, 0),
382 BPF_STX_MEM(BPF_DW
, BPF_REG_7
, BPF_REG_0
, 0),
384 BPF_MOV64_REG(BPF_REG_2
, BPF_REG_7
),
386 /* sysctl_get_name arg3 (buf_len) */
387 BPF_MOV64_IMM(BPF_REG_3
, 7),
389 /* sysctl_get_name arg4 (flags) */
390 BPF_MOV64_IMM(BPF_REG_4
, 0),
392 /* sysctl_get_name(ctx, buf, buf_len, flags) */
393 BPF_EMIT_CALL(BPF_FUNC_sysctl_get_name
),
395 /* if (ret == expected && */
396 BPF_JMP_IMM(BPF_JNE
, BPF_REG_0
, -E2BIG
, 6),
398 /* buf[0:8] == "net/ip\0") */
399 BPF_LD_IMM64(BPF_REG_8
, 0x000070692f74656eULL
),
400 BPF_LDX_MEM(BPF_DW
, BPF_REG_9
, BPF_REG_7
, 0),
401 BPF_JMP_REG(BPF_JNE
, BPF_REG_8
, BPF_REG_9
, 2),
404 BPF_MOV64_IMM(BPF_REG_0
, 1),
407 /* else return DENY; */
408 BPF_MOV64_IMM(BPF_REG_0
, 0),
411 .attach_type
= BPF_CGROUP_SYSCTL
,
412 .sysctl
= "net/ipv4/tcp_mem",
413 .open_flags
= O_RDONLY
,
417 .descr
= "sysctl_get_current_value sysctl:read ok, gt",
419 /* sysctl_get_current_value arg2 (buf) */
420 BPF_MOV64_REG(BPF_REG_7
, BPF_REG_10
),
421 BPF_ALU64_IMM(BPF_ADD
, BPF_REG_7
, -8),
422 BPF_MOV64_REG(BPF_REG_2
, BPF_REG_7
),
424 /* sysctl_get_current_value arg3 (buf_len) */
425 BPF_MOV64_IMM(BPF_REG_3
, 8),
427 /* sysctl_get_current_value(ctx, buf, buf_len) */
428 BPF_EMIT_CALL(BPF_FUNC_sysctl_get_current_value
),
430 /* if (ret == expected && */
431 BPF_JMP_IMM(BPF_JNE
, BPF_REG_0
, 6, 6),
433 /* buf[0:6] == "Linux\n\0") */
434 BPF_LD_IMM64(BPF_REG_8
, 0x000a78756e694cULL
),
435 BPF_LDX_MEM(BPF_DW
, BPF_REG_9
, BPF_REG_7
, 0),
436 BPF_JMP_REG(BPF_JNE
, BPF_REG_8
, BPF_REG_9
, 2),
439 BPF_MOV64_IMM(BPF_REG_0
, 1),
442 /* else return DENY; */
443 BPF_MOV64_IMM(BPF_REG_0
, 0),
446 .attach_type
= BPF_CGROUP_SYSCTL
,
447 .sysctl
= "kernel/ostype",
448 .open_flags
= O_RDONLY
,
452 .descr
= "sysctl_get_current_value sysctl:read ok, eq",
454 /* sysctl_get_current_value arg2 (buf) */
455 BPF_MOV64_REG(BPF_REG_7
, BPF_REG_10
),
456 BPF_ALU64_IMM(BPF_ADD
, BPF_REG_7
, -8),
457 BPF_MOV64_IMM(BPF_REG_0
, 0),
458 BPF_STX_MEM(BPF_B
, BPF_REG_7
, BPF_REG_0
, 7),
460 BPF_MOV64_REG(BPF_REG_2
, BPF_REG_7
),
462 /* sysctl_get_current_value arg3 (buf_len) */
463 BPF_MOV64_IMM(BPF_REG_3
, 7),
465 /* sysctl_get_current_value(ctx, buf, buf_len) */
466 BPF_EMIT_CALL(BPF_FUNC_sysctl_get_current_value
),
468 /* if (ret == expected && */
469 BPF_JMP_IMM(BPF_JNE
, BPF_REG_0
, 6, 6),
471 /* buf[0:6] == "Linux\n\0") */
472 BPF_LD_IMM64(BPF_REG_8
, 0x000a78756e694cULL
),
473 BPF_LDX_MEM(BPF_DW
, BPF_REG_9
, BPF_REG_7
, 0),
474 BPF_JMP_REG(BPF_JNE
, BPF_REG_8
, BPF_REG_9
, 2),
477 BPF_MOV64_IMM(BPF_REG_0
, 1),
480 /* else return DENY; */
481 BPF_MOV64_IMM(BPF_REG_0
, 0),
484 .attach_type
= BPF_CGROUP_SYSCTL
,
485 .sysctl
= "kernel/ostype",
486 .open_flags
= O_RDONLY
,
490 .descr
= "sysctl_get_current_value sysctl:read E2BIG truncated",
492 /* sysctl_get_current_value arg2 (buf) */
493 BPF_MOV64_REG(BPF_REG_7
, BPF_REG_10
),
494 BPF_ALU64_IMM(BPF_ADD
, BPF_REG_7
, -8),
495 BPF_MOV64_IMM(BPF_REG_0
, 0),
496 BPF_STX_MEM(BPF_H
, BPF_REG_7
, BPF_REG_0
, 6),
498 BPF_MOV64_REG(BPF_REG_2
, BPF_REG_7
),
500 /* sysctl_get_current_value arg3 (buf_len) */
501 BPF_MOV64_IMM(BPF_REG_3
, 6),
503 /* sysctl_get_current_value(ctx, buf, buf_len) */
504 BPF_EMIT_CALL(BPF_FUNC_sysctl_get_current_value
),
506 /* if (ret == expected && */
507 BPF_JMP_IMM(BPF_JNE
, BPF_REG_0
, -E2BIG
, 6),
509 /* buf[0:6] == "Linux\0") */
510 BPF_LD_IMM64(BPF_REG_8
, 0x000078756e694cULL
),
511 BPF_LDX_MEM(BPF_DW
, BPF_REG_9
, BPF_REG_7
, 0),
512 BPF_JMP_REG(BPF_JNE
, BPF_REG_8
, BPF_REG_9
, 2),
515 BPF_MOV64_IMM(BPF_REG_0
, 1),
518 /* else return DENY; */
519 BPF_MOV64_IMM(BPF_REG_0
, 0),
522 .attach_type
= BPF_CGROUP_SYSCTL
,
523 .sysctl
= "kernel/ostype",
524 .open_flags
= O_RDONLY
,
528 .descr
= "sysctl_get_current_value sysctl:read EINVAL",
530 /* sysctl_get_current_value arg2 (buf) */
531 BPF_MOV64_REG(BPF_REG_7
, BPF_REG_10
),
532 BPF_ALU64_IMM(BPF_ADD
, BPF_REG_7
, -8),
534 BPF_MOV64_REG(BPF_REG_2
, BPF_REG_7
),
536 /* sysctl_get_current_value arg3 (buf_len) */
537 BPF_MOV64_IMM(BPF_REG_3
, 8),
539 /* sysctl_get_current_value(ctx, buf, buf_len) */
540 BPF_EMIT_CALL(BPF_FUNC_sysctl_get_current_value
),
542 /* if (ret == expected && */
543 BPF_JMP_IMM(BPF_JNE
, BPF_REG_0
, -EINVAL
, 4),
545 /* buf[0:8] is NUL-filled) */
546 BPF_LDX_MEM(BPF_DW
, BPF_REG_9
, BPF_REG_7
, 0),
547 BPF_JMP_IMM(BPF_JNE
, BPF_REG_9
, 0, 2),
550 BPF_MOV64_IMM(BPF_REG_0
, 0),
553 /* else return ALLOW; */
554 BPF_MOV64_IMM(BPF_REG_0
, 1),
557 .attach_type
= BPF_CGROUP_SYSCTL
,
558 .sysctl
= "net/ipv6/conf/lo/stable_secret", /* -EIO */
559 .open_flags
= O_RDONLY
,
563 .descr
= "sysctl_get_current_value sysctl:write ok",
564 .fixup_value_insn
= 6,
566 /* sysctl_get_current_value arg2 (buf) */
567 BPF_MOV64_REG(BPF_REG_7
, BPF_REG_10
),
568 BPF_ALU64_IMM(BPF_ADD
, BPF_REG_7
, -8),
570 BPF_MOV64_REG(BPF_REG_2
, BPF_REG_7
),
572 /* sysctl_get_current_value arg3 (buf_len) */
573 BPF_MOV64_IMM(BPF_REG_3
, 8),
575 /* sysctl_get_current_value(ctx, buf, buf_len) */
576 BPF_EMIT_CALL(BPF_FUNC_sysctl_get_current_value
),
578 /* if (ret == expected && */
579 BPF_JMP_IMM(BPF_JNE
, BPF_REG_0
, 4, 6),
581 /* buf[0:4] == expected) */
582 BPF_LD_IMM64(BPF_REG_8
, FIXUP_SYSCTL_VALUE
),
583 BPF_LDX_MEM(BPF_DW
, BPF_REG_9
, BPF_REG_7
, 0),
584 BPF_JMP_REG(BPF_JNE
, BPF_REG_8
, BPF_REG_9
, 2),
587 BPF_MOV64_IMM(BPF_REG_0
, 0),
590 /* else return ALLOW; */
591 BPF_MOV64_IMM(BPF_REG_0
, 1),
594 .attach_type
= BPF_CGROUP_SYSCTL
,
595 .sysctl
= "net/ipv4/route/mtu_expires",
596 .open_flags
= O_WRONLY
,
597 .newval
= "600", /* same as default, should fail anyway */
601 .descr
= "sysctl_get_new_value sysctl:read EINVAL",
603 /* sysctl_get_new_value arg2 (buf) */
604 BPF_MOV64_REG(BPF_REG_7
, BPF_REG_10
),
605 BPF_ALU64_IMM(BPF_ADD
, BPF_REG_7
, -8),
606 BPF_MOV64_IMM(BPF_REG_0
, 0),
607 BPF_STX_MEM(BPF_DW
, BPF_REG_7
, BPF_REG_0
, 0),
609 BPF_MOV64_REG(BPF_REG_2
, BPF_REG_7
),
611 /* sysctl_get_new_value arg3 (buf_len) */
612 BPF_MOV64_IMM(BPF_REG_3
, 8),
614 /* sysctl_get_new_value(ctx, buf, buf_len) */
615 BPF_EMIT_CALL(BPF_FUNC_sysctl_get_new_value
),
617 /* if (ret == expected) */
618 BPF_JMP_IMM(BPF_JNE
, BPF_REG_0
, -EINVAL
, 2),
621 BPF_MOV64_IMM(BPF_REG_0
, 1),
624 /* else return DENY; */
625 BPF_MOV64_IMM(BPF_REG_0
, 0),
628 .attach_type
= BPF_CGROUP_SYSCTL
,
629 .sysctl
= "net/ipv4/tcp_mem",
630 .open_flags
= O_RDONLY
,
634 .descr
= "sysctl_get_new_value sysctl:write ok",
636 /* sysctl_get_new_value arg2 (buf) */
637 BPF_MOV64_REG(BPF_REG_7
, BPF_REG_10
),
638 BPF_ALU64_IMM(BPF_ADD
, BPF_REG_7
, -8),
640 BPF_MOV64_REG(BPF_REG_2
, BPF_REG_7
),
642 /* sysctl_get_new_value arg3 (buf_len) */
643 BPF_MOV64_IMM(BPF_REG_3
, 4),
645 /* sysctl_get_new_value(ctx, buf, buf_len) */
646 BPF_EMIT_CALL(BPF_FUNC_sysctl_get_new_value
),
648 /* if (ret == expected && */
649 BPF_JMP_IMM(BPF_JNE
, BPF_REG_0
, 3, 4),
651 /* buf[0:4] == "606\0") */
652 BPF_LDX_MEM(BPF_W
, BPF_REG_9
, BPF_REG_7
, 0),
653 BPF_JMP_IMM(BPF_JNE
, BPF_REG_9
, 0x00363036, 2),
656 BPF_MOV64_IMM(BPF_REG_0
, 0),
659 /* else return ALLOW; */
660 BPF_MOV64_IMM(BPF_REG_0
, 1),
663 .attach_type
= BPF_CGROUP_SYSCTL
,
664 .sysctl
= "net/ipv4/route/mtu_expires",
665 .open_flags
= O_WRONLY
,
670 .descr
= "sysctl_get_new_value sysctl:write ok long",
672 /* sysctl_get_new_value arg2 (buf) */
673 BPF_MOV64_REG(BPF_REG_7
, BPF_REG_10
),
674 BPF_ALU64_IMM(BPF_ADD
, BPF_REG_7
, -24),
676 BPF_MOV64_REG(BPF_REG_2
, BPF_REG_7
),
678 /* sysctl_get_new_value arg3 (buf_len) */
679 BPF_MOV64_IMM(BPF_REG_3
, 24),
681 /* sysctl_get_new_value(ctx, buf, buf_len) */
682 BPF_EMIT_CALL(BPF_FUNC_sysctl_get_new_value
),
684 /* if (ret == expected && */
685 BPF_JMP_IMM(BPF_JNE
, BPF_REG_0
, 23, 14),
687 /* buf[0:8] == "3000000 " && */
688 BPF_LD_IMM64(BPF_REG_8
, 0x2030303030303033ULL
),
689 BPF_LDX_MEM(BPF_DW
, BPF_REG_9
, BPF_REG_7
, 0),
690 BPF_JMP_REG(BPF_JNE
, BPF_REG_8
, BPF_REG_9
, 10),
692 /* buf[8:16] == "4000000 " && */
693 BPF_LD_IMM64(BPF_REG_8
, 0x2030303030303034ULL
),
694 BPF_LDX_MEM(BPF_DW
, BPF_REG_9
, BPF_REG_7
, 8),
695 BPF_JMP_REG(BPF_JNE
, BPF_REG_8
, BPF_REG_9
, 6),
697 /* buf[16:24] == "6000000\0") */
698 BPF_LD_IMM64(BPF_REG_8
, 0x0030303030303036ULL
),
699 BPF_LDX_MEM(BPF_DW
, BPF_REG_9
, BPF_REG_7
, 16),
700 BPF_JMP_REG(BPF_JNE
, BPF_REG_8
, BPF_REG_9
, 2),
703 BPF_MOV64_IMM(BPF_REG_0
, 0),
706 /* else return ALLOW; */
707 BPF_MOV64_IMM(BPF_REG_0
, 1),
710 .attach_type
= BPF_CGROUP_SYSCTL
,
711 .sysctl
= "net/ipv4/tcp_mem",
712 .open_flags
= O_WRONLY
,
713 .newval
= "3000000 4000000 6000000",
717 .descr
= "sysctl_get_new_value sysctl:write E2BIG",
719 /* sysctl_get_new_value arg2 (buf) */
720 BPF_MOV64_REG(BPF_REG_7
, BPF_REG_10
),
721 BPF_ALU64_IMM(BPF_ADD
, BPF_REG_7
, -8),
722 BPF_MOV64_IMM(BPF_REG_0
, 0),
723 BPF_STX_MEM(BPF_B
, BPF_REG_7
, BPF_REG_0
, 3),
725 BPF_MOV64_REG(BPF_REG_2
, BPF_REG_7
),
727 /* sysctl_get_new_value arg3 (buf_len) */
728 BPF_MOV64_IMM(BPF_REG_3
, 3),
730 /* sysctl_get_new_value(ctx, buf, buf_len) */
731 BPF_EMIT_CALL(BPF_FUNC_sysctl_get_new_value
),
733 /* if (ret == expected && */
734 BPF_JMP_IMM(BPF_JNE
, BPF_REG_0
, -E2BIG
, 4),
736 /* buf[0:3] == "60\0") */
737 BPF_LDX_MEM(BPF_W
, BPF_REG_9
, BPF_REG_7
, 0),
738 BPF_JMP_IMM(BPF_JNE
, BPF_REG_9
, 0x003036, 2),
741 BPF_MOV64_IMM(BPF_REG_0
, 0),
744 /* else return ALLOW; */
745 BPF_MOV64_IMM(BPF_REG_0
, 1),
748 .attach_type
= BPF_CGROUP_SYSCTL
,
749 .sysctl
= "net/ipv4/route/mtu_expires",
750 .open_flags
= O_WRONLY
,
755 .descr
= "sysctl_set_new_value sysctl:read EINVAL",
757 /* sysctl_set_new_value arg2 (buf) */
758 BPF_MOV64_REG(BPF_REG_7
, BPF_REG_10
),
759 BPF_ALU64_IMM(BPF_ADD
, BPF_REG_7
, -8),
760 BPF_MOV64_IMM(BPF_REG_0
, 0x00303036),
761 BPF_STX_MEM(BPF_DW
, BPF_REG_7
, BPF_REG_0
, 0),
763 BPF_MOV64_REG(BPF_REG_2
, BPF_REG_7
),
765 /* sysctl_set_new_value arg3 (buf_len) */
766 BPF_MOV64_IMM(BPF_REG_3
, 3),
768 /* sysctl_set_new_value(ctx, buf, buf_len) */
769 BPF_EMIT_CALL(BPF_FUNC_sysctl_set_new_value
),
771 /* if (ret == expected) */
772 BPF_JMP_IMM(BPF_JNE
, BPF_REG_0
, -EINVAL
, 2),
775 BPF_MOV64_IMM(BPF_REG_0
, 1),
778 /* else return DENY; */
779 BPF_MOV64_IMM(BPF_REG_0
, 0),
782 .attach_type
= BPF_CGROUP_SYSCTL
,
783 .sysctl
= "net/ipv4/route/mtu_expires",
784 .open_flags
= O_RDONLY
,
788 .descr
= "sysctl_set_new_value sysctl:write ok",
789 .fixup_value_insn
= 2,
791 /* sysctl_set_new_value arg2 (buf) */
792 BPF_MOV64_REG(BPF_REG_7
, BPF_REG_10
),
793 BPF_ALU64_IMM(BPF_ADD
, BPF_REG_7
, -8),
794 BPF_MOV64_IMM(BPF_REG_0
, FIXUP_SYSCTL_VALUE
),
795 BPF_STX_MEM(BPF_DW
, BPF_REG_7
, BPF_REG_0
, 0),
797 BPF_MOV64_REG(BPF_REG_2
, BPF_REG_7
),
799 /* sysctl_set_new_value arg3 (buf_len) */
800 BPF_MOV64_IMM(BPF_REG_3
, 3),
802 /* sysctl_set_new_value(ctx, buf, buf_len) */
803 BPF_EMIT_CALL(BPF_FUNC_sysctl_set_new_value
),
805 /* if (ret == expected) */
806 BPF_JMP_IMM(BPF_JNE
, BPF_REG_0
, 0, 2),
809 BPF_MOV64_IMM(BPF_REG_0
, 1),
812 /* else return DENY; */
813 BPF_MOV64_IMM(BPF_REG_0
, 0),
816 .attach_type
= BPF_CGROUP_SYSCTL
,
817 .sysctl
= "net/ipv4/route/mtu_expires",
818 .open_flags
= O_WRONLY
,
823 "bpf_strtoul one number string",
826 BPF_MOV64_REG(BPF_REG_7
, BPF_REG_10
),
827 BPF_ALU64_IMM(BPF_ADD
, BPF_REG_7
, -8),
828 BPF_MOV64_IMM(BPF_REG_0
, 0x00303036),
829 BPF_STX_MEM(BPF_DW
, BPF_REG_7
, BPF_REG_0
, 0),
831 BPF_MOV64_REG(BPF_REG_1
, BPF_REG_7
),
834 BPF_MOV64_IMM(BPF_REG_2
, 4),
837 BPF_MOV64_IMM(BPF_REG_3
, 0),
840 BPF_ALU64_IMM(BPF_ADD
, BPF_REG_7
, -8),
841 BPF_STX_MEM(BPF_DW
, BPF_REG_7
, BPF_REG_0
, 0),
842 BPF_MOV64_REG(BPF_REG_4
, BPF_REG_7
),
844 BPF_EMIT_CALL(BPF_FUNC_strtoul
),
846 /* if (ret == expected && */
847 BPF_JMP_IMM(BPF_JNE
, BPF_REG_0
, 3, 4),
848 /* res == expected) */
849 BPF_LDX_MEM(BPF_DW
, BPF_REG_9
, BPF_REG_7
, 0),
850 BPF_JMP_IMM(BPF_JNE
, BPF_REG_9
, 600, 2),
853 BPF_MOV64_IMM(BPF_REG_0
, 1),
856 /* else return DENY; */
857 BPF_MOV64_IMM(BPF_REG_0
, 0),
860 .attach_type
= BPF_CGROUP_SYSCTL
,
861 .sysctl
= "net/ipv4/route/mtu_expires",
862 .open_flags
= O_RDONLY
,
866 "bpf_strtoul multi number string",
869 BPF_MOV64_REG(BPF_REG_7
, BPF_REG_10
),
870 BPF_ALU64_IMM(BPF_ADD
, BPF_REG_7
, -8),
872 BPF_LD_IMM64(BPF_REG_0
, 0x0032303620303036ULL
),
873 BPF_STX_MEM(BPF_DW
, BPF_REG_7
, BPF_REG_0
, 0),
874 BPF_MOV64_REG(BPF_REG_1
, BPF_REG_7
),
877 BPF_MOV64_IMM(BPF_REG_2
, 8),
880 BPF_MOV64_IMM(BPF_REG_3
, 0),
883 BPF_ALU64_IMM(BPF_ADD
, BPF_REG_7
, -8),
884 BPF_STX_MEM(BPF_DW
, BPF_REG_7
, BPF_REG_0
, 0),
885 BPF_MOV64_REG(BPF_REG_4
, BPF_REG_7
),
887 BPF_EMIT_CALL(BPF_FUNC_strtoul
),
889 /* if (ret == expected && */
890 BPF_JMP_IMM(BPF_JNE
, BPF_REG_0
, 3, 18),
891 /* res == expected) */
892 BPF_LDX_MEM(BPF_DW
, BPF_REG_9
, BPF_REG_7
, 0),
893 BPF_JMP_IMM(BPF_JNE
, BPF_REG_9
, 600, 16),
896 BPF_MOV64_REG(BPF_REG_7
, BPF_REG_10
),
897 BPF_ALU64_IMM(BPF_ADD
, BPF_REG_7
, -8),
898 BPF_ALU64_REG(BPF_ADD
, BPF_REG_7
, BPF_REG_0
),
899 BPF_MOV64_REG(BPF_REG_1
, BPF_REG_7
),
902 BPF_MOV64_IMM(BPF_REG_2
, 8),
903 BPF_ALU64_REG(BPF_SUB
, BPF_REG_2
, BPF_REG_0
),
906 BPF_MOV64_IMM(BPF_REG_3
, 0),
909 BPF_MOV64_REG(BPF_REG_7
, BPF_REG_10
),
910 BPF_ALU64_IMM(BPF_ADD
, BPF_REG_7
, -16),
911 BPF_MOV64_REG(BPF_REG_4
, BPF_REG_7
),
913 BPF_EMIT_CALL(BPF_FUNC_strtoul
),
915 /* if (ret == expected && */
916 BPF_JMP_IMM(BPF_JNE
, BPF_REG_0
, 4, 4),
917 /* res == expected) */
918 BPF_LDX_MEM(BPF_DW
, BPF_REG_9
, BPF_REG_7
, 0),
919 BPF_JMP_IMM(BPF_JNE
, BPF_REG_9
, 602, 2),
922 BPF_MOV64_IMM(BPF_REG_0
, 1),
925 /* else return DENY; */
926 BPF_MOV64_IMM(BPF_REG_0
, 0),
929 .attach_type
= BPF_CGROUP_SYSCTL
,
930 .sysctl
= "net/ipv4/tcp_mem",
931 .open_flags
= O_RDONLY
,
935 "bpf_strtoul buf_len = 0, reject",
938 BPF_MOV64_REG(BPF_REG_7
, BPF_REG_10
),
939 BPF_ALU64_IMM(BPF_ADD
, BPF_REG_7
, -8),
940 BPF_MOV64_IMM(BPF_REG_0
, 0x00303036),
941 BPF_STX_MEM(BPF_DW
, BPF_REG_7
, BPF_REG_0
, 0),
943 BPF_MOV64_REG(BPF_REG_1
, BPF_REG_7
),
946 BPF_MOV64_IMM(BPF_REG_2
, 0),
949 BPF_MOV64_IMM(BPF_REG_3
, 0),
952 BPF_ALU64_IMM(BPF_ADD
, BPF_REG_7
, -8),
953 BPF_STX_MEM(BPF_DW
, BPF_REG_7
, BPF_REG_0
, 0),
954 BPF_MOV64_REG(BPF_REG_4
, BPF_REG_7
),
956 BPF_EMIT_CALL(BPF_FUNC_strtoul
),
958 BPF_MOV64_IMM(BPF_REG_0
, 1),
961 .attach_type
= BPF_CGROUP_SYSCTL
,
962 .sysctl
= "net/ipv4/route/mtu_expires",
963 .open_flags
= O_RDONLY
,
964 .result
= LOAD_REJECT
,
967 "bpf_strtoul supported base, ok",
970 BPF_MOV64_REG(BPF_REG_7
, BPF_REG_10
),
971 BPF_ALU64_IMM(BPF_ADD
, BPF_REG_7
, -8),
972 BPF_MOV64_IMM(BPF_REG_0
, 0x00373730),
973 BPF_STX_MEM(BPF_DW
, BPF_REG_7
, BPF_REG_0
, 0),
975 BPF_MOV64_REG(BPF_REG_1
, BPF_REG_7
),
978 BPF_MOV64_IMM(BPF_REG_2
, 4),
981 BPF_MOV64_IMM(BPF_REG_3
, 8),
984 BPF_ALU64_IMM(BPF_ADD
, BPF_REG_7
, -8),
985 BPF_STX_MEM(BPF_DW
, BPF_REG_7
, BPF_REG_0
, 0),
986 BPF_MOV64_REG(BPF_REG_4
, BPF_REG_7
),
988 BPF_EMIT_CALL(BPF_FUNC_strtoul
),
990 /* if (ret == expected && */
991 BPF_JMP_IMM(BPF_JNE
, BPF_REG_0
, 3, 4),
992 /* res == expected) */
993 BPF_LDX_MEM(BPF_DW
, BPF_REG_9
, BPF_REG_7
, 0),
994 BPF_JMP_IMM(BPF_JNE
, BPF_REG_9
, 63, 2),
997 BPF_MOV64_IMM(BPF_REG_0
, 1),
1000 /* else return DENY; */
1001 BPF_MOV64_IMM(BPF_REG_0
, 0),
1004 .attach_type
= BPF_CGROUP_SYSCTL
,
1005 .sysctl
= "net/ipv4/route/mtu_expires",
1006 .open_flags
= O_RDONLY
,
1010 "bpf_strtoul unsupported base, EINVAL",
1013 BPF_MOV64_REG(BPF_REG_7
, BPF_REG_10
),
1014 BPF_ALU64_IMM(BPF_ADD
, BPF_REG_7
, -8),
1015 BPF_MOV64_IMM(BPF_REG_0
, 0x00303036),
1016 BPF_STX_MEM(BPF_DW
, BPF_REG_7
, BPF_REG_0
, 0),
1018 BPF_MOV64_REG(BPF_REG_1
, BPF_REG_7
),
1020 /* arg2 (buf_len) */
1021 BPF_MOV64_IMM(BPF_REG_2
, 4),
1024 BPF_MOV64_IMM(BPF_REG_3
, 3),
1027 BPF_ALU64_IMM(BPF_ADD
, BPF_REG_7
, -8),
1028 BPF_STX_MEM(BPF_DW
, BPF_REG_7
, BPF_REG_0
, 0),
1029 BPF_MOV64_REG(BPF_REG_4
, BPF_REG_7
),
1031 BPF_EMIT_CALL(BPF_FUNC_strtoul
),
1033 /* if (ret == expected) */
1034 BPF_JMP_IMM(BPF_JNE
, BPF_REG_0
, -EINVAL
, 2),
1037 BPF_MOV64_IMM(BPF_REG_0
, 1),
1040 /* else return DENY; */
1041 BPF_MOV64_IMM(BPF_REG_0
, 0),
1044 .attach_type
= BPF_CGROUP_SYSCTL
,
1045 .sysctl
= "net/ipv4/route/mtu_expires",
1046 .open_flags
= O_RDONLY
,
1050 "bpf_strtoul buf with spaces only, EINVAL",
1053 BPF_MOV64_REG(BPF_REG_7
, BPF_REG_10
),
1054 BPF_ALU64_IMM(BPF_ADD
, BPF_REG_7
, -8),
1055 BPF_MOV64_IMM(BPF_REG_0
, 0x090a0c0d),
1056 BPF_STX_MEM(BPF_DW
, BPF_REG_7
, BPF_REG_0
, 0),
1058 BPF_MOV64_REG(BPF_REG_1
, BPF_REG_7
),
1060 /* arg2 (buf_len) */
1061 BPF_MOV64_IMM(BPF_REG_2
, 4),
1064 BPF_MOV64_IMM(BPF_REG_3
, 0),
1067 BPF_ALU64_IMM(BPF_ADD
, BPF_REG_7
, -8),
1068 BPF_STX_MEM(BPF_DW
, BPF_REG_7
, BPF_REG_0
, 0),
1069 BPF_MOV64_REG(BPF_REG_4
, BPF_REG_7
),
1071 BPF_EMIT_CALL(BPF_FUNC_strtoul
),
1073 /* if (ret == expected) */
1074 BPF_JMP_IMM(BPF_JNE
, BPF_REG_0
, -EINVAL
, 2),
1077 BPF_MOV64_IMM(BPF_REG_0
, 1),
1080 /* else return DENY; */
1081 BPF_MOV64_IMM(BPF_REG_0
, 0),
1084 .attach_type
= BPF_CGROUP_SYSCTL
,
1085 .sysctl
= "net/ipv4/route/mtu_expires",
1086 .open_flags
= O_RDONLY
,
1090 "bpf_strtoul negative number, EINVAL",
1093 BPF_MOV64_REG(BPF_REG_7
, BPF_REG_10
),
1094 BPF_ALU64_IMM(BPF_ADD
, BPF_REG_7
, -8),
1095 BPF_MOV64_IMM(BPF_REG_0
, 0x00362d0a), /* " -6\0" */
1096 BPF_STX_MEM(BPF_DW
, BPF_REG_7
, BPF_REG_0
, 0),
1098 BPF_MOV64_REG(BPF_REG_1
, BPF_REG_7
),
1100 /* arg2 (buf_len) */
1101 BPF_MOV64_IMM(BPF_REG_2
, 4),
1104 BPF_MOV64_IMM(BPF_REG_3
, 0),
1107 BPF_ALU64_IMM(BPF_ADD
, BPF_REG_7
, -8),
1108 BPF_STX_MEM(BPF_DW
, BPF_REG_7
, BPF_REG_0
, 0),
1109 BPF_MOV64_REG(BPF_REG_4
, BPF_REG_7
),
1111 BPF_EMIT_CALL(BPF_FUNC_strtoul
),
1113 /* if (ret == expected) */
1114 BPF_JMP_IMM(BPF_JNE
, BPF_REG_0
, -EINVAL
, 2),
1117 BPF_MOV64_IMM(BPF_REG_0
, 1),
1120 /* else return DENY; */
1121 BPF_MOV64_IMM(BPF_REG_0
, 0),
1124 .attach_type
= BPF_CGROUP_SYSCTL
,
1125 .sysctl
= "net/ipv4/route/mtu_expires",
1126 .open_flags
= O_RDONLY
,
1130 "bpf_strtol negative number, ok",
1133 BPF_MOV64_REG(BPF_REG_7
, BPF_REG_10
),
1134 BPF_ALU64_IMM(BPF_ADD
, BPF_REG_7
, -8),
1135 BPF_MOV64_IMM(BPF_REG_0
, 0x00362d0a), /* " -6\0" */
1136 BPF_STX_MEM(BPF_DW
, BPF_REG_7
, BPF_REG_0
, 0),
1138 BPF_MOV64_REG(BPF_REG_1
, BPF_REG_7
),
1140 /* arg2 (buf_len) */
1141 BPF_MOV64_IMM(BPF_REG_2
, 4),
1144 BPF_MOV64_IMM(BPF_REG_3
, 10),
1147 BPF_ALU64_IMM(BPF_ADD
, BPF_REG_7
, -8),
1148 BPF_STX_MEM(BPF_DW
, BPF_REG_7
, BPF_REG_0
, 0),
1149 BPF_MOV64_REG(BPF_REG_4
, BPF_REG_7
),
1151 BPF_EMIT_CALL(BPF_FUNC_strtol
),
1153 /* if (ret == expected && */
1154 BPF_JMP_IMM(BPF_JNE
, BPF_REG_0
, 3, 4),
1155 /* res == expected) */
1156 BPF_LDX_MEM(BPF_DW
, BPF_REG_9
, BPF_REG_7
, 0),
1157 BPF_JMP_IMM(BPF_JNE
, BPF_REG_9
, -6, 2),
1160 BPF_MOV64_IMM(BPF_REG_0
, 1),
1163 /* else return DENY; */
1164 BPF_MOV64_IMM(BPF_REG_0
, 0),
1167 .attach_type
= BPF_CGROUP_SYSCTL
,
1168 .sysctl
= "net/ipv4/route/mtu_expires",
1169 .open_flags
= O_RDONLY
,
1173 "bpf_strtol hex number, ok",
1176 BPF_MOV64_REG(BPF_REG_7
, BPF_REG_10
),
1177 BPF_ALU64_IMM(BPF_ADD
, BPF_REG_7
, -8),
1178 BPF_MOV64_IMM(BPF_REG_0
, 0x65667830), /* "0xfe" */
1179 BPF_STX_MEM(BPF_DW
, BPF_REG_7
, BPF_REG_0
, 0),
1181 BPF_MOV64_REG(BPF_REG_1
, BPF_REG_7
),
1183 /* arg2 (buf_len) */
1184 BPF_MOV64_IMM(BPF_REG_2
, 4),
1187 BPF_MOV64_IMM(BPF_REG_3
, 0),
1190 BPF_ALU64_IMM(BPF_ADD
, BPF_REG_7
, -8),
1191 BPF_STX_MEM(BPF_DW
, BPF_REG_7
, BPF_REG_0
, 0),
1192 BPF_MOV64_REG(BPF_REG_4
, BPF_REG_7
),
1194 BPF_EMIT_CALL(BPF_FUNC_strtol
),
1196 /* if (ret == expected && */
1197 BPF_JMP_IMM(BPF_JNE
, BPF_REG_0
, 4, 4),
1198 /* res == expected) */
1199 BPF_LDX_MEM(BPF_DW
, BPF_REG_9
, BPF_REG_7
, 0),
1200 BPF_JMP_IMM(BPF_JNE
, BPF_REG_9
, 254, 2),
1203 BPF_MOV64_IMM(BPF_REG_0
, 1),
1206 /* else return DENY; */
1207 BPF_MOV64_IMM(BPF_REG_0
, 0),
1210 .attach_type
= BPF_CGROUP_SYSCTL
,
1211 .sysctl
= "net/ipv4/route/mtu_expires",
1212 .open_flags
= O_RDONLY
,
1216 "bpf_strtol max long",
1218 /* arg1 (buf) 9223372036854775807 */
1219 BPF_MOV64_REG(BPF_REG_7
, BPF_REG_10
),
1220 BPF_ALU64_IMM(BPF_ADD
, BPF_REG_7
, -24),
1221 BPF_LD_IMM64(BPF_REG_0
, 0x3032373333323239ULL
),
1222 BPF_STX_MEM(BPF_DW
, BPF_REG_7
, BPF_REG_0
, 0),
1223 BPF_LD_IMM64(BPF_REG_0
, 0x3537373435383633ULL
),
1224 BPF_STX_MEM(BPF_DW
, BPF_REG_7
, BPF_REG_0
, 8),
1225 BPF_LD_IMM64(BPF_REG_0
, 0x0000000000373038ULL
),
1226 BPF_STX_MEM(BPF_DW
, BPF_REG_7
, BPF_REG_0
, 16),
1228 BPF_MOV64_REG(BPF_REG_1
, BPF_REG_7
),
1230 /* arg2 (buf_len) */
1231 BPF_MOV64_IMM(BPF_REG_2
, 19),
1234 BPF_MOV64_IMM(BPF_REG_3
, 0),
1237 BPF_ALU64_IMM(BPF_ADD
, BPF_REG_7
, -8),
1238 BPF_STX_MEM(BPF_DW
, BPF_REG_7
, BPF_REG_0
, 0),
1239 BPF_MOV64_REG(BPF_REG_4
, BPF_REG_7
),
1241 BPF_EMIT_CALL(BPF_FUNC_strtol
),
1243 /* if (ret == expected && */
1244 BPF_JMP_IMM(BPF_JNE
, BPF_REG_0
, 19, 6),
1245 /* res == expected) */
1246 BPF_LD_IMM64(BPF_REG_8
, 0x7fffffffffffffffULL
),
1247 BPF_LDX_MEM(BPF_DW
, BPF_REG_9
, BPF_REG_7
, 0),
1248 BPF_JMP_REG(BPF_JNE
, BPF_REG_8
, BPF_REG_9
, 2),
1251 BPF_MOV64_IMM(BPF_REG_0
, 1),
1254 /* else return DENY; */
1255 BPF_MOV64_IMM(BPF_REG_0
, 0),
1258 .attach_type
= BPF_CGROUP_SYSCTL
,
1259 .sysctl
= "net/ipv4/route/mtu_expires",
1260 .open_flags
= O_RDONLY
,
1264 "bpf_strtol overflow, ERANGE",
1266 /* arg1 (buf) 9223372036854775808 */
1267 BPF_MOV64_REG(BPF_REG_7
, BPF_REG_10
),
1268 BPF_ALU64_IMM(BPF_ADD
, BPF_REG_7
, -24),
1269 BPF_LD_IMM64(BPF_REG_0
, 0x3032373333323239ULL
),
1270 BPF_STX_MEM(BPF_DW
, BPF_REG_7
, BPF_REG_0
, 0),
1271 BPF_LD_IMM64(BPF_REG_0
, 0x3537373435383633ULL
),
1272 BPF_STX_MEM(BPF_DW
, BPF_REG_7
, BPF_REG_0
, 8),
1273 BPF_LD_IMM64(BPF_REG_0
, 0x0000000000383038ULL
),
1274 BPF_STX_MEM(BPF_DW
, BPF_REG_7
, BPF_REG_0
, 16),
1276 BPF_MOV64_REG(BPF_REG_1
, BPF_REG_7
),
1278 /* arg2 (buf_len) */
1279 BPF_MOV64_IMM(BPF_REG_2
, 19),
1282 BPF_MOV64_IMM(BPF_REG_3
, 0),
1285 BPF_ALU64_IMM(BPF_ADD
, BPF_REG_7
, -8),
1286 BPF_STX_MEM(BPF_DW
, BPF_REG_7
, BPF_REG_0
, 0),
1287 BPF_MOV64_REG(BPF_REG_4
, BPF_REG_7
),
1289 BPF_EMIT_CALL(BPF_FUNC_strtol
),
1291 /* if (ret == expected) */
1292 BPF_JMP_IMM(BPF_JNE
, BPF_REG_0
, -ERANGE
, 2),
1295 BPF_MOV64_IMM(BPF_REG_0
, 1),
1298 /* else return DENY; */
1299 BPF_MOV64_IMM(BPF_REG_0
, 0),
1302 .attach_type
= BPF_CGROUP_SYSCTL
,
1303 .sysctl
= "net/ipv4/route/mtu_expires",
1304 .open_flags
= O_RDONLY
,
1308 "C prog: deny all writes",
1309 .prog_file
= "./test_sysctl_prog.o",
1310 .attach_type
= BPF_CGROUP_SYSCTL
,
1311 .sysctl
= "net/ipv4/tcp_mem",
1312 .open_flags
= O_WRONLY
,
1313 .newval
= "123 456 789",
1317 "C prog: deny access by name",
1318 .prog_file
= "./test_sysctl_prog.o",
1319 .attach_type
= BPF_CGROUP_SYSCTL
,
1320 .sysctl
= "net/ipv4/route/mtu_expires",
1321 .open_flags
= O_RDONLY
,
1325 "C prog: read tcp_mem",
1326 .prog_file
= "./test_sysctl_prog.o",
1327 .attach_type
= BPF_CGROUP_SYSCTL
,
1328 .sysctl
= "net/ipv4/tcp_mem",
1329 .open_flags
= O_RDONLY
,
1334 static size_t probe_prog_length(const struct bpf_insn
*fp
)
1338 for (len
= MAX_INSNS
- 1; len
> 0; --len
)
1339 if (fp
[len
].code
!= 0 || fp
[len
].imm
!= 0)
1344 static int fixup_sysctl_value(const char *buf
, size_t buf_len
,
1345 struct bpf_insn
*prog
, size_t insn_num
)
1347 uint32_t value_num
= 0;
1350 if (buf_len
> sizeof(value_num
)) {
1351 log_err("Value is too big (%zd) to use in fixup", buf_len
);
1355 for (i
= 0; i
< buf_len
; ++i
) {
1357 value_num
|= (c
<< i
* 8);
1360 prog
[insn_num
].imm
= value_num
;
1365 static int load_sysctl_prog_insns(struct sysctl_test
*test
,
1366 const char *sysctl_path
)
1368 struct bpf_insn
*prog
= test
->insns
;
1369 struct bpf_load_program_attr attr
;
1372 memset(&attr
, 0, sizeof(struct bpf_load_program_attr
));
1373 attr
.prog_type
= BPF_PROG_TYPE_CGROUP_SYSCTL
;
1375 attr
.insns_cnt
= probe_prog_length(attr
.insns
);
1376 attr
.license
= "GPL";
1378 if (test
->fixup_value_insn
) {
1383 fd
= open(sysctl_path
, O_RDONLY
| O_CLOEXEC
);
1385 log_err("open(%s) failed", sysctl_path
);
1388 len
= read(fd
, buf
, sizeof(buf
));
1390 log_err("read(%s) failed", sysctl_path
);
1395 if (fixup_sysctl_value(buf
, len
, prog
, test
->fixup_value_insn
))
1399 ret
= bpf_load_program_xattr(&attr
, bpf_log_buf
, BPF_LOG_BUF_SIZE
);
1400 if (ret
< 0 && test
->result
!= LOAD_REJECT
) {
1401 log_err(">>> Loading program error.\n"
1402 ">>> Verifier output:\n%s\n-------\n", bpf_log_buf
);
1408 static int load_sysctl_prog_file(struct sysctl_test
*test
)
1410 struct bpf_prog_load_attr attr
;
1411 struct bpf_object
*obj
;
1414 memset(&attr
, 0, sizeof(struct bpf_prog_load_attr
));
1415 attr
.file
= test
->prog_file
;
1416 attr
.prog_type
= BPF_PROG_TYPE_CGROUP_SYSCTL
;
1418 if (bpf_prog_load_xattr(&attr
, &obj
, &prog_fd
)) {
1419 if (test
->result
!= LOAD_REJECT
)
1420 log_err(">>> Loading program (%s) error.\n",
1428 static int load_sysctl_prog(struct sysctl_test
*test
, const char *sysctl_path
)
1430 return test
->prog_file
1431 ? load_sysctl_prog_file(test
)
1432 : load_sysctl_prog_insns(test
, sysctl_path
);
1435 static int access_sysctl(const char *sysctl_path
,
1436 const struct sysctl_test
*test
)
1441 fd
= open(sysctl_path
, test
->open_flags
| O_CLOEXEC
);
1445 if (test
->open_flags
== O_RDONLY
) {
1448 if (read(fd
, buf
, sizeof(buf
)) == -1)
1451 strncmp(buf
, test
->oldval
, strlen(test
->oldval
))) {
1452 log_err("Read value %s != %s", buf
, test
->oldval
);
1455 } else if (test
->open_flags
== O_WRONLY
) {
1456 if (!test
->newval
) {
1457 log_err("New value for sysctl is not set");
1460 if (write(fd
, test
->newval
, strlen(test
->newval
)) == -1)
1463 log_err("Unexpected sysctl access: neither read nor write");
1475 static int run_test_case(int cgfd
, struct sysctl_test
*test
)
1477 enum bpf_attach_type atype
= test
->attach_type
;
1478 char sysctl_path
[128];
1482 printf("Test case: %s .. ", test
->descr
);
1484 snprintf(sysctl_path
, sizeof(sysctl_path
), "/proc/sys/%s",
1487 progfd
= load_sysctl_prog(test
, sysctl_path
);
1489 if (test
->result
== LOAD_REJECT
)
1495 if (bpf_prog_attach(progfd
, cgfd
, atype
, BPF_F_ALLOW_OVERRIDE
) == -1) {
1496 if (test
->result
== ATTACH_REJECT
)
1502 if (access_sysctl(sysctl_path
, test
) == -1) {
1503 if (test
->result
== OP_EPERM
&& errno
== EPERM
)
1509 if (test
->result
!= SUCCESS
) {
1510 log_err("Unexpected failure");
1518 /* Detaching w/o checking return code: best effort attempt. */
1520 bpf_prog_detach(cgfd
, atype
);
1522 printf("[%s]\n", err
? "FAIL" : "PASS");
1526 static int run_tests(int cgfd
)
1532 for (i
= 0; i
< ARRAY_SIZE(tests
); ++i
) {
1533 if (run_test_case(cgfd
, &tests
[i
]))
1538 printf("Summary: %d PASSED, %d FAILED\n", passes
, fails
);
1539 return fails
? -1 : 0;
1542 int main(int argc
, char **argv
)
1547 if (setup_cgroup_environment())
1550 cgfd
= create_and_get_cgroup(CG_PATH
);
1554 if (join_cgroup(CG_PATH
))
1557 if (run_tests(cgfd
))
1565 cleanup_cgroup_environment();