xref: /linux/tools/testing/selftests/bpf/test_sysctl.c (revision 3ec2a0ed3fec4ec8b27d9b71fdcbc1c30d1542d3)
11f5fa9abSAndrey Ignatov // SPDX-License-Identifier: GPL-2.0
21f5fa9abSAndrey Ignatov // Copyright (c) 2019 Facebook
31f5fa9abSAndrey Ignatov 
41f5fa9abSAndrey Ignatov #include <fcntl.h>
51f5fa9abSAndrey Ignatov #include <stdint.h>
61f5fa9abSAndrey Ignatov #include <stdio.h>
71f5fa9abSAndrey Ignatov #include <stdlib.h>
81f5fa9abSAndrey Ignatov #include <string.h>
91f5fa9abSAndrey Ignatov #include <unistd.h>
101f5fa9abSAndrey Ignatov 
111f5fa9abSAndrey Ignatov #include <linux/filter.h>
121f5fa9abSAndrey Ignatov 
131f5fa9abSAndrey Ignatov #include <bpf/bpf.h>
147568f4cbSAndrey Ignatov #include <bpf/libbpf.h>
151f5fa9abSAndrey Ignatov 
16*3ec2a0edSIlya Leoshkevich #include "bpf_endian.h"
171f5fa9abSAndrey Ignatov #include "bpf_rlimit.h"
181f5fa9abSAndrey Ignatov #include "bpf_util.h"
191f5fa9abSAndrey Ignatov #include "cgroup_helpers.h"
201f5fa9abSAndrey Ignatov 
211f5fa9abSAndrey Ignatov #define CG_PATH			"/foo"
221f5fa9abSAndrey Ignatov #define MAX_INSNS		512
2311ff34f7SAndrey Ignatov #define FIXUP_SYSCTL_VALUE	0
241f5fa9abSAndrey Ignatov 
251f5fa9abSAndrey Ignatov char bpf_log_buf[BPF_LOG_BUF_SIZE];
261f5fa9abSAndrey Ignatov 
271f5fa9abSAndrey Ignatov struct sysctl_test {
281f5fa9abSAndrey Ignatov 	const char *descr;
2911ff34f7SAndrey Ignatov 	size_t fixup_value_insn;
301f5fa9abSAndrey Ignatov 	struct bpf_insn	insns[MAX_INSNS];
317568f4cbSAndrey Ignatov 	const char *prog_file;
321f5fa9abSAndrey Ignatov 	enum bpf_attach_type attach_type;
331f5fa9abSAndrey Ignatov 	const char *sysctl;
341f5fa9abSAndrey Ignatov 	int open_flags;
351f5fa9abSAndrey Ignatov 	const char *newval;
369a1027e5SAndrey Ignatov 	const char *oldval;
371f5fa9abSAndrey Ignatov 	enum {
381f5fa9abSAndrey Ignatov 		LOAD_REJECT,
391f5fa9abSAndrey Ignatov 		ATTACH_REJECT,
401f5fa9abSAndrey Ignatov 		OP_EPERM,
411f5fa9abSAndrey Ignatov 		SUCCESS,
421f5fa9abSAndrey Ignatov 	} result;
431f5fa9abSAndrey Ignatov };
441f5fa9abSAndrey Ignatov 
451f5fa9abSAndrey Ignatov static struct sysctl_test tests[] = {
461f5fa9abSAndrey Ignatov 	{
471f5fa9abSAndrey Ignatov 		.descr = "sysctl wrong attach_type",
481f5fa9abSAndrey Ignatov 		.insns = {
491f5fa9abSAndrey Ignatov 			BPF_MOV64_IMM(BPF_REG_0, 1),
501f5fa9abSAndrey Ignatov 			BPF_EXIT_INSN(),
511f5fa9abSAndrey Ignatov 		},
521f5fa9abSAndrey Ignatov 		.attach_type = 0,
531f5fa9abSAndrey Ignatov 		.sysctl = "kernel/ostype",
541f5fa9abSAndrey Ignatov 		.open_flags = O_RDONLY,
551f5fa9abSAndrey Ignatov 		.result = ATTACH_REJECT,
561f5fa9abSAndrey Ignatov 	},
571f5fa9abSAndrey Ignatov 	{
581f5fa9abSAndrey Ignatov 		.descr = "sysctl:read allow all",
591f5fa9abSAndrey Ignatov 		.insns = {
601f5fa9abSAndrey Ignatov 			BPF_MOV64_IMM(BPF_REG_0, 1),
611f5fa9abSAndrey Ignatov 			BPF_EXIT_INSN(),
621f5fa9abSAndrey Ignatov 		},
631f5fa9abSAndrey Ignatov 		.attach_type = BPF_CGROUP_SYSCTL,
641f5fa9abSAndrey Ignatov 		.sysctl = "kernel/ostype",
651f5fa9abSAndrey Ignatov 		.open_flags = O_RDONLY,
661f5fa9abSAndrey Ignatov 		.result = SUCCESS,
671f5fa9abSAndrey Ignatov 	},
681f5fa9abSAndrey Ignatov 	{
691f5fa9abSAndrey Ignatov 		.descr = "sysctl:read deny all",
701f5fa9abSAndrey Ignatov 		.insns = {
711f5fa9abSAndrey Ignatov 			BPF_MOV64_IMM(BPF_REG_0, 0),
721f5fa9abSAndrey Ignatov 			BPF_EXIT_INSN(),
731f5fa9abSAndrey Ignatov 		},
741f5fa9abSAndrey Ignatov 		.attach_type = BPF_CGROUP_SYSCTL,
751f5fa9abSAndrey Ignatov 		.sysctl = "kernel/ostype",
761f5fa9abSAndrey Ignatov 		.open_flags = O_RDONLY,
771f5fa9abSAndrey Ignatov 		.result = OP_EPERM,
781f5fa9abSAndrey Ignatov 	},
791f5fa9abSAndrey Ignatov 	{
801f5fa9abSAndrey Ignatov 		.descr = "ctx:write sysctl:read read ok",
811f5fa9abSAndrey Ignatov 		.insns = {
821f5fa9abSAndrey Ignatov 			/* If (write) */
831f5fa9abSAndrey Ignatov 			BPF_LDX_MEM(BPF_W, BPF_REG_7, BPF_REG_1,
841f5fa9abSAndrey Ignatov 				    offsetof(struct bpf_sysctl, write)),
851f5fa9abSAndrey Ignatov 			BPF_JMP_IMM(BPF_JNE, BPF_REG_7, 1, 2),
861f5fa9abSAndrey Ignatov 
871f5fa9abSAndrey Ignatov 			/* return DENY; */
881f5fa9abSAndrey Ignatov 			BPF_MOV64_IMM(BPF_REG_0, 0),
891f5fa9abSAndrey Ignatov 			BPF_JMP_A(1),
901f5fa9abSAndrey Ignatov 
911f5fa9abSAndrey Ignatov 			/* else return ALLOW; */
921f5fa9abSAndrey Ignatov 			BPF_MOV64_IMM(BPF_REG_0, 1),
931f5fa9abSAndrey Ignatov 			BPF_EXIT_INSN(),
941f5fa9abSAndrey Ignatov 		},
951f5fa9abSAndrey Ignatov 		.attach_type = BPF_CGROUP_SYSCTL,
961f5fa9abSAndrey Ignatov 		.sysctl = "kernel/ostype",
971f5fa9abSAndrey Ignatov 		.open_flags = O_RDONLY,
981f5fa9abSAndrey Ignatov 		.result = SUCCESS,
991f5fa9abSAndrey Ignatov 	},
1001f5fa9abSAndrey Ignatov 	{
1011f5fa9abSAndrey Ignatov 		.descr = "ctx:write sysctl:write read ok",
1021f5fa9abSAndrey Ignatov 		.insns = {
1031f5fa9abSAndrey Ignatov 			/* If (write) */
1043404ddf2SIlya Leoshkevich 			BPF_LDX_MEM(BPF_W, BPF_REG_7, BPF_REG_1,
1051f5fa9abSAndrey Ignatov 				    offsetof(struct bpf_sysctl, write)),
1061f5fa9abSAndrey Ignatov 			BPF_JMP_IMM(BPF_JNE, BPF_REG_7, 1, 2),
1071f5fa9abSAndrey Ignatov 
1081f5fa9abSAndrey Ignatov 			/* return DENY; */
1091f5fa9abSAndrey Ignatov 			BPF_MOV64_IMM(BPF_REG_0, 0),
1101f5fa9abSAndrey Ignatov 			BPF_JMP_A(1),
1111f5fa9abSAndrey Ignatov 
1121f5fa9abSAndrey Ignatov 			/* else return ALLOW; */
1131f5fa9abSAndrey Ignatov 			BPF_MOV64_IMM(BPF_REG_0, 1),
1141f5fa9abSAndrey Ignatov 			BPF_EXIT_INSN(),
1151f5fa9abSAndrey Ignatov 		},
1161f5fa9abSAndrey Ignatov 		.attach_type = BPF_CGROUP_SYSCTL,
1171f5fa9abSAndrey Ignatov 		.sysctl = "kernel/domainname",
1181f5fa9abSAndrey Ignatov 		.open_flags = O_WRONLY,
1191f5fa9abSAndrey Ignatov 		.newval = "(none)", /* same as default, should fail anyway */
1201f5fa9abSAndrey Ignatov 		.result = OP_EPERM,
1211f5fa9abSAndrey Ignatov 	},
1221f5fa9abSAndrey Ignatov 	{
1231f5fa9abSAndrey Ignatov 		.descr = "ctx:write sysctl:read write reject",
1241f5fa9abSAndrey Ignatov 		.insns = {
1251f5fa9abSAndrey Ignatov 			/* write = X */
1261f5fa9abSAndrey Ignatov 			BPF_MOV64_IMM(BPF_REG_0, 0),
1271f5fa9abSAndrey Ignatov 			BPF_STX_MEM(BPF_W, BPF_REG_1, BPF_REG_0,
1281f5fa9abSAndrey Ignatov 				    offsetof(struct bpf_sysctl, write)),
1291f5fa9abSAndrey Ignatov 			BPF_MOV64_IMM(BPF_REG_0, 1),
1301f5fa9abSAndrey Ignatov 			BPF_EXIT_INSN(),
1311f5fa9abSAndrey Ignatov 		},
1321f5fa9abSAndrey Ignatov 		.attach_type = BPF_CGROUP_SYSCTL,
1331f5fa9abSAndrey Ignatov 		.sysctl = "kernel/ostype",
1341f5fa9abSAndrey Ignatov 		.open_flags = O_RDONLY,
1351f5fa9abSAndrey Ignatov 		.result = LOAD_REJECT,
1361f5fa9abSAndrey Ignatov 	},
1376041c67fSAndrey Ignatov 	{
1389a1027e5SAndrey Ignatov 		.descr = "ctx:file_pos sysctl:read read ok",
1399a1027e5SAndrey Ignatov 		.insns = {
1409a1027e5SAndrey Ignatov 			/* If (file_pos == X) */
1419a1027e5SAndrey Ignatov 			BPF_LDX_MEM(BPF_W, BPF_REG_7, BPF_REG_1,
1429a1027e5SAndrey Ignatov 				    offsetof(struct bpf_sysctl, file_pos)),
1439a1027e5SAndrey Ignatov 			BPF_JMP_IMM(BPF_JNE, BPF_REG_7, 0, 2),
1449a1027e5SAndrey Ignatov 
1459a1027e5SAndrey Ignatov 			/* return ALLOW; */
1469a1027e5SAndrey Ignatov 			BPF_MOV64_IMM(BPF_REG_0, 1),
1479a1027e5SAndrey Ignatov 			BPF_JMP_A(1),
1489a1027e5SAndrey Ignatov 
1499a1027e5SAndrey Ignatov 			/* else return DENY; */
1509a1027e5SAndrey Ignatov 			BPF_MOV64_IMM(BPF_REG_0, 0),
1519a1027e5SAndrey Ignatov 			BPF_EXIT_INSN(),
1529a1027e5SAndrey Ignatov 		},
1539a1027e5SAndrey Ignatov 		.attach_type = BPF_CGROUP_SYSCTL,
1549a1027e5SAndrey Ignatov 		.sysctl = "kernel/ostype",
1559a1027e5SAndrey Ignatov 		.open_flags = O_RDONLY,
1569a1027e5SAndrey Ignatov 		.result = SUCCESS,
1579a1027e5SAndrey Ignatov 	},
1589a1027e5SAndrey Ignatov 	{
1599a1027e5SAndrey Ignatov 		.descr = "ctx:file_pos sysctl:read read ok narrow",
1609a1027e5SAndrey Ignatov 		.insns = {
1619a1027e5SAndrey Ignatov 			/* If (file_pos == X) */
1629a1027e5SAndrey Ignatov 			BPF_LDX_MEM(BPF_B, BPF_REG_7, BPF_REG_1,
1639a1027e5SAndrey Ignatov 				    offsetof(struct bpf_sysctl, file_pos)),
1649a1027e5SAndrey Ignatov 			BPF_JMP_IMM(BPF_JNE, BPF_REG_7, 0, 2),
1659a1027e5SAndrey Ignatov 
1669a1027e5SAndrey Ignatov 			/* return ALLOW; */
1679a1027e5SAndrey Ignatov 			BPF_MOV64_IMM(BPF_REG_0, 1),
1689a1027e5SAndrey Ignatov 			BPF_JMP_A(1),
1699a1027e5SAndrey Ignatov 
1709a1027e5SAndrey Ignatov 			/* else return DENY; */
1719a1027e5SAndrey Ignatov 			BPF_MOV64_IMM(BPF_REG_0, 0),
1729a1027e5SAndrey Ignatov 			BPF_EXIT_INSN(),
1739a1027e5SAndrey Ignatov 		},
1749a1027e5SAndrey Ignatov 		.attach_type = BPF_CGROUP_SYSCTL,
1759a1027e5SAndrey Ignatov 		.sysctl = "kernel/ostype",
1769a1027e5SAndrey Ignatov 		.open_flags = O_RDONLY,
1779a1027e5SAndrey Ignatov 		.result = SUCCESS,
1789a1027e5SAndrey Ignatov 	},
1799a1027e5SAndrey Ignatov 	{
1809a1027e5SAndrey Ignatov 		.descr = "ctx:file_pos sysctl:read write ok",
1819a1027e5SAndrey Ignatov 		.insns = {
1829a1027e5SAndrey Ignatov 			/* file_pos = X */
1839a1027e5SAndrey Ignatov 			BPF_MOV64_IMM(BPF_REG_0, 2),
1849a1027e5SAndrey Ignatov 			BPF_STX_MEM(BPF_W, BPF_REG_1, BPF_REG_0,
1859a1027e5SAndrey Ignatov 				    offsetof(struct bpf_sysctl, file_pos)),
1869a1027e5SAndrey Ignatov 			BPF_MOV64_IMM(BPF_REG_0, 1),
1879a1027e5SAndrey Ignatov 			BPF_EXIT_INSN(),
1889a1027e5SAndrey Ignatov 		},
1899a1027e5SAndrey Ignatov 		.attach_type = BPF_CGROUP_SYSCTL,
1909a1027e5SAndrey Ignatov 		.sysctl = "kernel/ostype",
1919a1027e5SAndrey Ignatov 		.open_flags = O_RDONLY,
1929a1027e5SAndrey Ignatov 		.oldval = "nux\n",
1939a1027e5SAndrey Ignatov 		.result = SUCCESS,
1949a1027e5SAndrey Ignatov 	},
1959a1027e5SAndrey Ignatov 	{
1966041c67fSAndrey Ignatov 		.descr = "sysctl_get_name sysctl_value:base ok",
1976041c67fSAndrey Ignatov 		.insns = {
1986041c67fSAndrey Ignatov 			/* sysctl_get_name arg2 (buf) */
1996041c67fSAndrey Ignatov 			BPF_MOV64_REG(BPF_REG_7, BPF_REG_10),
2006041c67fSAndrey Ignatov 			BPF_ALU64_IMM(BPF_ADD, BPF_REG_7, -8),
2016041c67fSAndrey Ignatov 			BPF_MOV64_IMM(BPF_REG_0, 0),
2026041c67fSAndrey Ignatov 			BPF_STX_MEM(BPF_DW, BPF_REG_7, BPF_REG_0, 0),
2036041c67fSAndrey Ignatov 
2046041c67fSAndrey Ignatov 			BPF_MOV64_REG(BPF_REG_2, BPF_REG_7),
2056041c67fSAndrey Ignatov 
2066041c67fSAndrey Ignatov 			/* sysctl_get_name arg3 (buf_len) */
2076041c67fSAndrey Ignatov 			BPF_MOV64_IMM(BPF_REG_3, 8),
2086041c67fSAndrey Ignatov 
2096041c67fSAndrey Ignatov 			/* sysctl_get_name arg4 (flags) */
2106041c67fSAndrey Ignatov 			BPF_MOV64_IMM(BPF_REG_4, BPF_F_SYSCTL_BASE_NAME),
2116041c67fSAndrey Ignatov 
2126041c67fSAndrey Ignatov 			/* sysctl_get_name(ctx, buf, buf_len, flags) */
2136041c67fSAndrey Ignatov 			BPF_EMIT_CALL(BPF_FUNC_sysctl_get_name),
2146041c67fSAndrey Ignatov 
2156041c67fSAndrey Ignatov 			/* if (ret == expected && */
2166041c67fSAndrey Ignatov 			BPF_JMP_IMM(BPF_JNE, BPF_REG_0, sizeof("tcp_mem") - 1, 6),
2176041c67fSAndrey Ignatov 			/*     buf == "tcp_mem\0") */
218*3ec2a0edSIlya Leoshkevich 			BPF_LD_IMM64(BPF_REG_8,
219*3ec2a0edSIlya Leoshkevich 				     bpf_be64_to_cpu(0x7463705f6d656d00ULL)),
2206041c67fSAndrey Ignatov 			BPF_LDX_MEM(BPF_DW, BPF_REG_9, BPF_REG_7, 0),
2216041c67fSAndrey Ignatov 			BPF_JMP_REG(BPF_JNE, BPF_REG_8, BPF_REG_9, 2),
2226041c67fSAndrey Ignatov 
2236041c67fSAndrey Ignatov 			/* return ALLOW; */
2246041c67fSAndrey Ignatov 			BPF_MOV64_IMM(BPF_REG_0, 1),
2256041c67fSAndrey Ignatov 			BPF_JMP_A(1),
2266041c67fSAndrey Ignatov 
2276041c67fSAndrey Ignatov 			/* else return DENY; */
2286041c67fSAndrey Ignatov 			BPF_MOV64_IMM(BPF_REG_0, 0),
2296041c67fSAndrey Ignatov 			BPF_EXIT_INSN(),
2306041c67fSAndrey Ignatov 		},
2316041c67fSAndrey Ignatov 		.attach_type = BPF_CGROUP_SYSCTL,
2326041c67fSAndrey Ignatov 		.sysctl = "net/ipv4/tcp_mem",
2336041c67fSAndrey Ignatov 		.open_flags = O_RDONLY,
2346041c67fSAndrey Ignatov 		.result = SUCCESS,
2356041c67fSAndrey Ignatov 	},
2366041c67fSAndrey Ignatov 	{
2376041c67fSAndrey Ignatov 		.descr = "sysctl_get_name sysctl_value:base E2BIG truncated",
2386041c67fSAndrey Ignatov 		.insns = {
2396041c67fSAndrey Ignatov 			/* sysctl_get_name arg2 (buf) */
2406041c67fSAndrey Ignatov 			BPF_MOV64_REG(BPF_REG_7, BPF_REG_10),
2416041c67fSAndrey Ignatov 			BPF_ALU64_IMM(BPF_ADD, BPF_REG_7, -8),
2426041c67fSAndrey Ignatov 			BPF_MOV64_IMM(BPF_REG_0, 0),
2436041c67fSAndrey Ignatov 			BPF_STX_MEM(BPF_DW, BPF_REG_7, BPF_REG_0, 0),
2446041c67fSAndrey Ignatov 
2456041c67fSAndrey Ignatov 			BPF_MOV64_REG(BPF_REG_2, BPF_REG_7),
2466041c67fSAndrey Ignatov 
2476041c67fSAndrey Ignatov 			/* sysctl_get_name arg3 (buf_len) too small */
2486041c67fSAndrey Ignatov 			BPF_MOV64_IMM(BPF_REG_3, 7),
2496041c67fSAndrey Ignatov 
2506041c67fSAndrey Ignatov 			/* sysctl_get_name arg4 (flags) */
2516041c67fSAndrey Ignatov 			BPF_MOV64_IMM(BPF_REG_4, BPF_F_SYSCTL_BASE_NAME),
2526041c67fSAndrey Ignatov 
2536041c67fSAndrey Ignatov 			/* sysctl_get_name(ctx, buf, buf_len, flags) */
2546041c67fSAndrey Ignatov 			BPF_EMIT_CALL(BPF_FUNC_sysctl_get_name),
2556041c67fSAndrey Ignatov 
2566041c67fSAndrey Ignatov 			/* if (ret == expected && */
2576041c67fSAndrey Ignatov 			BPF_JMP_IMM(BPF_JNE, BPF_REG_0, -E2BIG, 6),
2586041c67fSAndrey Ignatov 
2596041c67fSAndrey Ignatov 			/*     buf[0:7] == "tcp_me\0") */
260*3ec2a0edSIlya Leoshkevich 			BPF_LD_IMM64(BPF_REG_8,
261*3ec2a0edSIlya Leoshkevich 				     bpf_be64_to_cpu(0x7463705f6d650000ULL)),
2626041c67fSAndrey Ignatov 			BPF_LDX_MEM(BPF_DW, BPF_REG_9, BPF_REG_7, 0),
2636041c67fSAndrey Ignatov 			BPF_JMP_REG(BPF_JNE, BPF_REG_8, BPF_REG_9, 2),
2646041c67fSAndrey Ignatov 
2656041c67fSAndrey Ignatov 			/* return ALLOW; */
2666041c67fSAndrey Ignatov 			BPF_MOV64_IMM(BPF_REG_0, 1),
2676041c67fSAndrey Ignatov 			BPF_JMP_A(1),
2686041c67fSAndrey Ignatov 
2696041c67fSAndrey Ignatov 			/* else return DENY; */
2706041c67fSAndrey Ignatov 			BPF_MOV64_IMM(BPF_REG_0, 0),
2716041c67fSAndrey Ignatov 			BPF_EXIT_INSN(),
2726041c67fSAndrey Ignatov 		},
2736041c67fSAndrey Ignatov 		.attach_type = BPF_CGROUP_SYSCTL,
2746041c67fSAndrey Ignatov 		.sysctl = "net/ipv4/tcp_mem",
2756041c67fSAndrey Ignatov 		.open_flags = O_RDONLY,
2766041c67fSAndrey Ignatov 		.result = SUCCESS,
2776041c67fSAndrey Ignatov 	},
2786041c67fSAndrey Ignatov 	{
2796041c67fSAndrey Ignatov 		.descr = "sysctl_get_name sysctl:full ok",
2806041c67fSAndrey Ignatov 		.insns = {
2816041c67fSAndrey Ignatov 			/* sysctl_get_name arg2 (buf) */
2826041c67fSAndrey Ignatov 			BPF_MOV64_REG(BPF_REG_7, BPF_REG_10),
2836041c67fSAndrey Ignatov 			BPF_ALU64_IMM(BPF_ADD, BPF_REG_7, -24),
2846041c67fSAndrey Ignatov 			BPF_MOV64_IMM(BPF_REG_0, 0),
2856041c67fSAndrey Ignatov 			BPF_STX_MEM(BPF_DW, BPF_REG_7, BPF_REG_0, 0),
2866041c67fSAndrey Ignatov 			BPF_STX_MEM(BPF_DW, BPF_REG_7, BPF_REG_0, 8),
2876041c67fSAndrey Ignatov 			BPF_STX_MEM(BPF_DW, BPF_REG_7, BPF_REG_0, 16),
2886041c67fSAndrey Ignatov 
2896041c67fSAndrey Ignatov 			BPF_MOV64_REG(BPF_REG_2, BPF_REG_7),
2906041c67fSAndrey Ignatov 
2916041c67fSAndrey Ignatov 			/* sysctl_get_name arg3 (buf_len) */
2926041c67fSAndrey Ignatov 			BPF_MOV64_IMM(BPF_REG_3, 17),
2936041c67fSAndrey Ignatov 
2946041c67fSAndrey Ignatov 			/* sysctl_get_name arg4 (flags) */
2956041c67fSAndrey Ignatov 			BPF_MOV64_IMM(BPF_REG_4, 0),
2966041c67fSAndrey Ignatov 
2976041c67fSAndrey Ignatov 			/* sysctl_get_name(ctx, buf, buf_len, flags) */
2986041c67fSAndrey Ignatov 			BPF_EMIT_CALL(BPF_FUNC_sysctl_get_name),
2996041c67fSAndrey Ignatov 
3006041c67fSAndrey Ignatov 			/* if (ret == expected && */
3016041c67fSAndrey Ignatov 			BPF_JMP_IMM(BPF_JNE, BPF_REG_0, 16, 14),
3026041c67fSAndrey Ignatov 
3036041c67fSAndrey Ignatov 			/*     buf[0:8] == "net/ipv4" && */
304*3ec2a0edSIlya Leoshkevich 			BPF_LD_IMM64(BPF_REG_8,
305*3ec2a0edSIlya Leoshkevich 				     bpf_be64_to_cpu(0x6e65742f69707634ULL)),
3066041c67fSAndrey Ignatov 			BPF_LDX_MEM(BPF_DW, BPF_REG_9, BPF_REG_7, 0),
3076041c67fSAndrey Ignatov 			BPF_JMP_REG(BPF_JNE, BPF_REG_8, BPF_REG_9, 10),
3086041c67fSAndrey Ignatov 
3096041c67fSAndrey Ignatov 			/*     buf[8:16] == "/tcp_mem" && */
310*3ec2a0edSIlya Leoshkevich 			BPF_LD_IMM64(BPF_REG_8,
311*3ec2a0edSIlya Leoshkevich 				     bpf_be64_to_cpu(0x2f7463705f6d656dULL)),
3126041c67fSAndrey Ignatov 			BPF_LDX_MEM(BPF_DW, BPF_REG_9, BPF_REG_7, 8),
3136041c67fSAndrey Ignatov 			BPF_JMP_REG(BPF_JNE, BPF_REG_8, BPF_REG_9, 6),
3146041c67fSAndrey Ignatov 
3156041c67fSAndrey Ignatov 			/*     buf[16:24] == "\0") */
3166041c67fSAndrey Ignatov 			BPF_LD_IMM64(BPF_REG_8, 0x0ULL),
3176041c67fSAndrey Ignatov 			BPF_LDX_MEM(BPF_DW, BPF_REG_9, BPF_REG_7, 16),
3186041c67fSAndrey Ignatov 			BPF_JMP_REG(BPF_JNE, BPF_REG_8, BPF_REG_9, 2),
3196041c67fSAndrey Ignatov 
3206041c67fSAndrey Ignatov 			/* return ALLOW; */
3216041c67fSAndrey Ignatov 			BPF_MOV64_IMM(BPF_REG_0, 1),
3226041c67fSAndrey Ignatov 			BPF_JMP_A(1),
3236041c67fSAndrey Ignatov 
3246041c67fSAndrey Ignatov 			/* else return DENY; */
3256041c67fSAndrey Ignatov 			BPF_MOV64_IMM(BPF_REG_0, 0),
3266041c67fSAndrey Ignatov 			BPF_EXIT_INSN(),
3276041c67fSAndrey Ignatov 		},
3286041c67fSAndrey Ignatov 		.attach_type = BPF_CGROUP_SYSCTL,
3296041c67fSAndrey Ignatov 		.sysctl = "net/ipv4/tcp_mem",
3306041c67fSAndrey Ignatov 		.open_flags = O_RDONLY,
3316041c67fSAndrey Ignatov 		.result = SUCCESS,
3326041c67fSAndrey Ignatov 	},
3336041c67fSAndrey Ignatov 	{
3346041c67fSAndrey Ignatov 		.descr = "sysctl_get_name sysctl:full E2BIG truncated",
3356041c67fSAndrey Ignatov 		.insns = {
3366041c67fSAndrey Ignatov 			/* sysctl_get_name arg2 (buf) */
3376041c67fSAndrey Ignatov 			BPF_MOV64_REG(BPF_REG_7, BPF_REG_10),
3386041c67fSAndrey Ignatov 			BPF_ALU64_IMM(BPF_ADD, BPF_REG_7, -16),
3396041c67fSAndrey Ignatov 			BPF_MOV64_IMM(BPF_REG_0, 0),
3406041c67fSAndrey Ignatov 			BPF_STX_MEM(BPF_DW, BPF_REG_7, BPF_REG_0, 0),
3416041c67fSAndrey Ignatov 			BPF_STX_MEM(BPF_DW, BPF_REG_7, BPF_REG_0, 8),
3426041c67fSAndrey Ignatov 
3436041c67fSAndrey Ignatov 			BPF_MOV64_REG(BPF_REG_2, BPF_REG_7),
3446041c67fSAndrey Ignatov 
3456041c67fSAndrey Ignatov 			/* sysctl_get_name arg3 (buf_len) */
3466041c67fSAndrey Ignatov 			BPF_MOV64_IMM(BPF_REG_3, 16),
3476041c67fSAndrey Ignatov 
3486041c67fSAndrey Ignatov 			/* sysctl_get_name arg4 (flags) */
3496041c67fSAndrey Ignatov 			BPF_MOV64_IMM(BPF_REG_4, 0),
3506041c67fSAndrey Ignatov 
3516041c67fSAndrey Ignatov 			/* sysctl_get_name(ctx, buf, buf_len, flags) */
3526041c67fSAndrey Ignatov 			BPF_EMIT_CALL(BPF_FUNC_sysctl_get_name),
3536041c67fSAndrey Ignatov 
3546041c67fSAndrey Ignatov 			/* if (ret == expected && */
3556041c67fSAndrey Ignatov 			BPF_JMP_IMM(BPF_JNE, BPF_REG_0, -E2BIG, 10),
3566041c67fSAndrey Ignatov 
3576041c67fSAndrey Ignatov 			/*     buf[0:8] == "net/ipv4" && */
358*3ec2a0edSIlya Leoshkevich 			BPF_LD_IMM64(BPF_REG_8,
359*3ec2a0edSIlya Leoshkevich 				     bpf_be64_to_cpu(0x6e65742f69707634ULL)),
3606041c67fSAndrey Ignatov 			BPF_LDX_MEM(BPF_DW, BPF_REG_9, BPF_REG_7, 0),
3616041c67fSAndrey Ignatov 			BPF_JMP_REG(BPF_JNE, BPF_REG_8, BPF_REG_9, 6),
3626041c67fSAndrey Ignatov 
3636041c67fSAndrey Ignatov 			/*     buf[8:16] == "/tcp_me\0") */
364*3ec2a0edSIlya Leoshkevich 			BPF_LD_IMM64(BPF_REG_8,
365*3ec2a0edSIlya Leoshkevich 				     bpf_be64_to_cpu(0x2f7463705f6d6500ULL)),
3666041c67fSAndrey Ignatov 			BPF_LDX_MEM(BPF_DW, BPF_REG_9, BPF_REG_7, 8),
3676041c67fSAndrey Ignatov 			BPF_JMP_REG(BPF_JNE, BPF_REG_8, BPF_REG_9, 2),
3686041c67fSAndrey Ignatov 
3696041c67fSAndrey Ignatov 			/* return ALLOW; */
3706041c67fSAndrey Ignatov 			BPF_MOV64_IMM(BPF_REG_0, 1),
3716041c67fSAndrey Ignatov 			BPF_JMP_A(1),
3726041c67fSAndrey Ignatov 
3736041c67fSAndrey Ignatov 			/* else return DENY; */
3746041c67fSAndrey Ignatov 			BPF_MOV64_IMM(BPF_REG_0, 0),
3756041c67fSAndrey Ignatov 			BPF_EXIT_INSN(),
3766041c67fSAndrey Ignatov 		},
3776041c67fSAndrey Ignatov 		.attach_type = BPF_CGROUP_SYSCTL,
3786041c67fSAndrey Ignatov 		.sysctl = "net/ipv4/tcp_mem",
3796041c67fSAndrey Ignatov 		.open_flags = O_RDONLY,
3806041c67fSAndrey Ignatov 		.result = SUCCESS,
3816041c67fSAndrey Ignatov 	},
3826041c67fSAndrey Ignatov 	{
3836041c67fSAndrey Ignatov 		.descr = "sysctl_get_name sysctl:full E2BIG truncated small",
3846041c67fSAndrey Ignatov 		.insns = {
3856041c67fSAndrey Ignatov 			/* sysctl_get_name arg2 (buf) */
3866041c67fSAndrey Ignatov 			BPF_MOV64_REG(BPF_REG_7, BPF_REG_10),
3876041c67fSAndrey Ignatov 			BPF_ALU64_IMM(BPF_ADD, BPF_REG_7, -8),
3886041c67fSAndrey Ignatov 			BPF_MOV64_IMM(BPF_REG_0, 0),
3896041c67fSAndrey Ignatov 			BPF_STX_MEM(BPF_DW, BPF_REG_7, BPF_REG_0, 0),
3906041c67fSAndrey Ignatov 
3916041c67fSAndrey Ignatov 			BPF_MOV64_REG(BPF_REG_2, BPF_REG_7),
3926041c67fSAndrey Ignatov 
3936041c67fSAndrey Ignatov 			/* sysctl_get_name arg3 (buf_len) */
3946041c67fSAndrey Ignatov 			BPF_MOV64_IMM(BPF_REG_3, 7),
3956041c67fSAndrey Ignatov 
3966041c67fSAndrey Ignatov 			/* sysctl_get_name arg4 (flags) */
3976041c67fSAndrey Ignatov 			BPF_MOV64_IMM(BPF_REG_4, 0),
3986041c67fSAndrey Ignatov 
3996041c67fSAndrey Ignatov 			/* sysctl_get_name(ctx, buf, buf_len, flags) */
4006041c67fSAndrey Ignatov 			BPF_EMIT_CALL(BPF_FUNC_sysctl_get_name),
4016041c67fSAndrey Ignatov 
4026041c67fSAndrey Ignatov 			/* if (ret == expected && */
4036041c67fSAndrey Ignatov 			BPF_JMP_IMM(BPF_JNE, BPF_REG_0, -E2BIG, 6),
4046041c67fSAndrey Ignatov 
4056041c67fSAndrey Ignatov 			/*     buf[0:8] == "net/ip\0") */
406*3ec2a0edSIlya Leoshkevich 			BPF_LD_IMM64(BPF_REG_8,
407*3ec2a0edSIlya Leoshkevich 				     bpf_be64_to_cpu(0x6e65742f69700000ULL)),
4086041c67fSAndrey Ignatov 			BPF_LDX_MEM(BPF_DW, BPF_REG_9, BPF_REG_7, 0),
4096041c67fSAndrey Ignatov 			BPF_JMP_REG(BPF_JNE, BPF_REG_8, BPF_REG_9, 2),
4106041c67fSAndrey Ignatov 
4116041c67fSAndrey Ignatov 			/* return ALLOW; */
4126041c67fSAndrey Ignatov 			BPF_MOV64_IMM(BPF_REG_0, 1),
4136041c67fSAndrey Ignatov 			BPF_JMP_A(1),
4146041c67fSAndrey Ignatov 
4156041c67fSAndrey Ignatov 			/* else return DENY; */
4166041c67fSAndrey Ignatov 			BPF_MOV64_IMM(BPF_REG_0, 0),
4176041c67fSAndrey Ignatov 			BPF_EXIT_INSN(),
4186041c67fSAndrey Ignatov 		},
4196041c67fSAndrey Ignatov 		.attach_type = BPF_CGROUP_SYSCTL,
4206041c67fSAndrey Ignatov 		.sysctl = "net/ipv4/tcp_mem",
4216041c67fSAndrey Ignatov 		.open_flags = O_RDONLY,
4226041c67fSAndrey Ignatov 		.result = SUCCESS,
4236041c67fSAndrey Ignatov 	},
42411ff34f7SAndrey Ignatov 	{
42511ff34f7SAndrey Ignatov 		.descr = "sysctl_get_current_value sysctl:read ok, gt",
42611ff34f7SAndrey Ignatov 		.insns = {
42711ff34f7SAndrey Ignatov 			/* sysctl_get_current_value arg2 (buf) */
42811ff34f7SAndrey Ignatov 			BPF_MOV64_REG(BPF_REG_7, BPF_REG_10),
42911ff34f7SAndrey Ignatov 			BPF_ALU64_IMM(BPF_ADD, BPF_REG_7, -8),
43011ff34f7SAndrey Ignatov 			BPF_MOV64_REG(BPF_REG_2, BPF_REG_7),
43111ff34f7SAndrey Ignatov 
43211ff34f7SAndrey Ignatov 			/* sysctl_get_current_value arg3 (buf_len) */
43311ff34f7SAndrey Ignatov 			BPF_MOV64_IMM(BPF_REG_3, 8),
43411ff34f7SAndrey Ignatov 
43511ff34f7SAndrey Ignatov 			/* sysctl_get_current_value(ctx, buf, buf_len) */
43611ff34f7SAndrey Ignatov 			BPF_EMIT_CALL(BPF_FUNC_sysctl_get_current_value),
43711ff34f7SAndrey Ignatov 
43811ff34f7SAndrey Ignatov 			/* if (ret == expected && */
43911ff34f7SAndrey Ignatov 			BPF_JMP_IMM(BPF_JNE, BPF_REG_0, 6, 6),
44011ff34f7SAndrey Ignatov 
44111ff34f7SAndrey Ignatov 			/*     buf[0:6] == "Linux\n\0") */
442*3ec2a0edSIlya Leoshkevich 			BPF_LD_IMM64(BPF_REG_8,
443*3ec2a0edSIlya Leoshkevich 				     bpf_be64_to_cpu(0x4c696e75780a0000ULL)),
44411ff34f7SAndrey Ignatov 			BPF_LDX_MEM(BPF_DW, BPF_REG_9, BPF_REG_7, 0),
44511ff34f7SAndrey Ignatov 			BPF_JMP_REG(BPF_JNE, BPF_REG_8, BPF_REG_9, 2),
44611ff34f7SAndrey Ignatov 
44711ff34f7SAndrey Ignatov 			/* return ALLOW; */
44811ff34f7SAndrey Ignatov 			BPF_MOV64_IMM(BPF_REG_0, 1),
44911ff34f7SAndrey Ignatov 			BPF_JMP_A(1),
45011ff34f7SAndrey Ignatov 
45111ff34f7SAndrey Ignatov 			/* else return DENY; */
45211ff34f7SAndrey Ignatov 			BPF_MOV64_IMM(BPF_REG_0, 0),
45311ff34f7SAndrey Ignatov 			BPF_EXIT_INSN(),
45411ff34f7SAndrey Ignatov 		},
45511ff34f7SAndrey Ignatov 		.attach_type = BPF_CGROUP_SYSCTL,
45611ff34f7SAndrey Ignatov 		.sysctl = "kernel/ostype",
45711ff34f7SAndrey Ignatov 		.open_flags = O_RDONLY,
45811ff34f7SAndrey Ignatov 		.result = SUCCESS,
45911ff34f7SAndrey Ignatov 	},
46011ff34f7SAndrey Ignatov 	{
46111ff34f7SAndrey Ignatov 		.descr = "sysctl_get_current_value sysctl:read ok, eq",
46211ff34f7SAndrey Ignatov 		.insns = {
46311ff34f7SAndrey Ignatov 			/* sysctl_get_current_value arg2 (buf) */
46411ff34f7SAndrey Ignatov 			BPF_MOV64_REG(BPF_REG_7, BPF_REG_10),
46511ff34f7SAndrey Ignatov 			BPF_ALU64_IMM(BPF_ADD, BPF_REG_7, -8),
46611ff34f7SAndrey Ignatov 			BPF_MOV64_IMM(BPF_REG_0, 0),
46711ff34f7SAndrey Ignatov 			BPF_STX_MEM(BPF_B, BPF_REG_7, BPF_REG_0, 7),
46811ff34f7SAndrey Ignatov 
46911ff34f7SAndrey Ignatov 			BPF_MOV64_REG(BPF_REG_2, BPF_REG_7),
47011ff34f7SAndrey Ignatov 
47111ff34f7SAndrey Ignatov 			/* sysctl_get_current_value arg3 (buf_len) */
47211ff34f7SAndrey Ignatov 			BPF_MOV64_IMM(BPF_REG_3, 7),
47311ff34f7SAndrey Ignatov 
47411ff34f7SAndrey Ignatov 			/* sysctl_get_current_value(ctx, buf, buf_len) */
47511ff34f7SAndrey Ignatov 			BPF_EMIT_CALL(BPF_FUNC_sysctl_get_current_value),
47611ff34f7SAndrey Ignatov 
47711ff34f7SAndrey Ignatov 			/* if (ret == expected && */
47811ff34f7SAndrey Ignatov 			BPF_JMP_IMM(BPF_JNE, BPF_REG_0, 6, 6),
47911ff34f7SAndrey Ignatov 
48011ff34f7SAndrey Ignatov 			/*     buf[0:6] == "Linux\n\0") */
481*3ec2a0edSIlya Leoshkevich 			BPF_LD_IMM64(BPF_REG_8,
482*3ec2a0edSIlya Leoshkevich 				     bpf_be64_to_cpu(0x4c696e75780a0000ULL)),
48311ff34f7SAndrey Ignatov 			BPF_LDX_MEM(BPF_DW, BPF_REG_9, BPF_REG_7, 0),
48411ff34f7SAndrey Ignatov 			BPF_JMP_REG(BPF_JNE, BPF_REG_8, BPF_REG_9, 2),
48511ff34f7SAndrey Ignatov 
48611ff34f7SAndrey Ignatov 			/* return ALLOW; */
48711ff34f7SAndrey Ignatov 			BPF_MOV64_IMM(BPF_REG_0, 1),
48811ff34f7SAndrey Ignatov 			BPF_JMP_A(1),
48911ff34f7SAndrey Ignatov 
49011ff34f7SAndrey Ignatov 			/* else return DENY; */
49111ff34f7SAndrey Ignatov 			BPF_MOV64_IMM(BPF_REG_0, 0),
49211ff34f7SAndrey Ignatov 			BPF_EXIT_INSN(),
49311ff34f7SAndrey Ignatov 		},
49411ff34f7SAndrey Ignatov 		.attach_type = BPF_CGROUP_SYSCTL,
49511ff34f7SAndrey Ignatov 		.sysctl = "kernel/ostype",
49611ff34f7SAndrey Ignatov 		.open_flags = O_RDONLY,
49711ff34f7SAndrey Ignatov 		.result = SUCCESS,
49811ff34f7SAndrey Ignatov 	},
49911ff34f7SAndrey Ignatov 	{
50011ff34f7SAndrey Ignatov 		.descr = "sysctl_get_current_value sysctl:read E2BIG truncated",
50111ff34f7SAndrey Ignatov 		.insns = {
50211ff34f7SAndrey Ignatov 			/* sysctl_get_current_value arg2 (buf) */
50311ff34f7SAndrey Ignatov 			BPF_MOV64_REG(BPF_REG_7, BPF_REG_10),
50411ff34f7SAndrey Ignatov 			BPF_ALU64_IMM(BPF_ADD, BPF_REG_7, -8),
50511ff34f7SAndrey Ignatov 			BPF_MOV64_IMM(BPF_REG_0, 0),
50611ff34f7SAndrey Ignatov 			BPF_STX_MEM(BPF_H, BPF_REG_7, BPF_REG_0, 6),
50711ff34f7SAndrey Ignatov 
50811ff34f7SAndrey Ignatov 			BPF_MOV64_REG(BPF_REG_2, BPF_REG_7),
50911ff34f7SAndrey Ignatov 
51011ff34f7SAndrey Ignatov 			/* sysctl_get_current_value arg3 (buf_len) */
51111ff34f7SAndrey Ignatov 			BPF_MOV64_IMM(BPF_REG_3, 6),
51211ff34f7SAndrey Ignatov 
51311ff34f7SAndrey Ignatov 			/* sysctl_get_current_value(ctx, buf, buf_len) */
51411ff34f7SAndrey Ignatov 			BPF_EMIT_CALL(BPF_FUNC_sysctl_get_current_value),
51511ff34f7SAndrey Ignatov 
51611ff34f7SAndrey Ignatov 			/* if (ret == expected && */
51711ff34f7SAndrey Ignatov 			BPF_JMP_IMM(BPF_JNE, BPF_REG_0, -E2BIG, 6),
51811ff34f7SAndrey Ignatov 
51911ff34f7SAndrey Ignatov 			/*     buf[0:6] == "Linux\0") */
520*3ec2a0edSIlya Leoshkevich 			BPF_LD_IMM64(BPF_REG_8,
521*3ec2a0edSIlya Leoshkevich 				     bpf_be64_to_cpu(0x4c696e7578000000ULL)),
52211ff34f7SAndrey Ignatov 			BPF_LDX_MEM(BPF_DW, BPF_REG_9, BPF_REG_7, 0),
52311ff34f7SAndrey Ignatov 			BPF_JMP_REG(BPF_JNE, BPF_REG_8, BPF_REG_9, 2),
52411ff34f7SAndrey Ignatov 
52511ff34f7SAndrey Ignatov 			/* return ALLOW; */
52611ff34f7SAndrey Ignatov 			BPF_MOV64_IMM(BPF_REG_0, 1),
52711ff34f7SAndrey Ignatov 			BPF_JMP_A(1),
52811ff34f7SAndrey Ignatov 
52911ff34f7SAndrey Ignatov 			/* else return DENY; */
53011ff34f7SAndrey Ignatov 			BPF_MOV64_IMM(BPF_REG_0, 0),
53111ff34f7SAndrey Ignatov 			BPF_EXIT_INSN(),
53211ff34f7SAndrey Ignatov 		},
53311ff34f7SAndrey Ignatov 		.attach_type = BPF_CGROUP_SYSCTL,
53411ff34f7SAndrey Ignatov 		.sysctl = "kernel/ostype",
53511ff34f7SAndrey Ignatov 		.open_flags = O_RDONLY,
53611ff34f7SAndrey Ignatov 		.result = SUCCESS,
53711ff34f7SAndrey Ignatov 	},
53811ff34f7SAndrey Ignatov 	{
53911ff34f7SAndrey Ignatov 		.descr = "sysctl_get_current_value sysctl:read EINVAL",
54011ff34f7SAndrey Ignatov 		.insns = {
54111ff34f7SAndrey Ignatov 			/* sysctl_get_current_value arg2 (buf) */
54211ff34f7SAndrey Ignatov 			BPF_MOV64_REG(BPF_REG_7, BPF_REG_10),
54311ff34f7SAndrey Ignatov 			BPF_ALU64_IMM(BPF_ADD, BPF_REG_7, -8),
54411ff34f7SAndrey Ignatov 
54511ff34f7SAndrey Ignatov 			BPF_MOV64_REG(BPF_REG_2, BPF_REG_7),
54611ff34f7SAndrey Ignatov 
54711ff34f7SAndrey Ignatov 			/* sysctl_get_current_value arg3 (buf_len) */
54811ff34f7SAndrey Ignatov 			BPF_MOV64_IMM(BPF_REG_3, 8),
54911ff34f7SAndrey Ignatov 
55011ff34f7SAndrey Ignatov 			/* sysctl_get_current_value(ctx, buf, buf_len) */
55111ff34f7SAndrey Ignatov 			BPF_EMIT_CALL(BPF_FUNC_sysctl_get_current_value),
55211ff34f7SAndrey Ignatov 
55311ff34f7SAndrey Ignatov 			/* if (ret == expected && */
55411ff34f7SAndrey Ignatov 			BPF_JMP_IMM(BPF_JNE, BPF_REG_0, -EINVAL, 4),
55511ff34f7SAndrey Ignatov 
55611ff34f7SAndrey Ignatov 			/*     buf[0:8] is NUL-filled) */
55711ff34f7SAndrey Ignatov 			BPF_LDX_MEM(BPF_DW, BPF_REG_9, BPF_REG_7, 0),
55811ff34f7SAndrey Ignatov 			BPF_JMP_IMM(BPF_JNE, BPF_REG_9, 0, 2),
55911ff34f7SAndrey Ignatov 
56011ff34f7SAndrey Ignatov 			/* return DENY; */
56111ff34f7SAndrey Ignatov 			BPF_MOV64_IMM(BPF_REG_0, 0),
56211ff34f7SAndrey Ignatov 			BPF_JMP_A(1),
56311ff34f7SAndrey Ignatov 
56411ff34f7SAndrey Ignatov 			/* else return ALLOW; */
56511ff34f7SAndrey Ignatov 			BPF_MOV64_IMM(BPF_REG_0, 1),
56611ff34f7SAndrey Ignatov 			BPF_EXIT_INSN(),
56711ff34f7SAndrey Ignatov 		},
56811ff34f7SAndrey Ignatov 		.attach_type = BPF_CGROUP_SYSCTL,
56911ff34f7SAndrey Ignatov 		.sysctl = "net/ipv6/conf/lo/stable_secret", /* -EIO */
57011ff34f7SAndrey Ignatov 		.open_flags = O_RDONLY,
57111ff34f7SAndrey Ignatov 		.result = OP_EPERM,
57211ff34f7SAndrey Ignatov 	},
57311ff34f7SAndrey Ignatov 	{
57411ff34f7SAndrey Ignatov 		.descr = "sysctl_get_current_value sysctl:write ok",
57511ff34f7SAndrey Ignatov 		.fixup_value_insn = 6,
57611ff34f7SAndrey Ignatov 		.insns = {
57711ff34f7SAndrey Ignatov 			/* sysctl_get_current_value arg2 (buf) */
57811ff34f7SAndrey Ignatov 			BPF_MOV64_REG(BPF_REG_7, BPF_REG_10),
57911ff34f7SAndrey Ignatov 			BPF_ALU64_IMM(BPF_ADD, BPF_REG_7, -8),
58011ff34f7SAndrey Ignatov 
58111ff34f7SAndrey Ignatov 			BPF_MOV64_REG(BPF_REG_2, BPF_REG_7),
58211ff34f7SAndrey Ignatov 
58311ff34f7SAndrey Ignatov 			/* sysctl_get_current_value arg3 (buf_len) */
58411ff34f7SAndrey Ignatov 			BPF_MOV64_IMM(BPF_REG_3, 8),
58511ff34f7SAndrey Ignatov 
58611ff34f7SAndrey Ignatov 			/* sysctl_get_current_value(ctx, buf, buf_len) */
58711ff34f7SAndrey Ignatov 			BPF_EMIT_CALL(BPF_FUNC_sysctl_get_current_value),
58811ff34f7SAndrey Ignatov 
58911ff34f7SAndrey Ignatov 			/* if (ret == expected && */
59011ff34f7SAndrey Ignatov 			BPF_JMP_IMM(BPF_JNE, BPF_REG_0, 4, 6),
59111ff34f7SAndrey Ignatov 
59211ff34f7SAndrey Ignatov 			/*     buf[0:4] == expected) */
59311ff34f7SAndrey Ignatov 			BPF_LD_IMM64(BPF_REG_8, FIXUP_SYSCTL_VALUE),
59411ff34f7SAndrey Ignatov 			BPF_LDX_MEM(BPF_DW, BPF_REG_9, BPF_REG_7, 0),
59511ff34f7SAndrey Ignatov 			BPF_JMP_REG(BPF_JNE, BPF_REG_8, BPF_REG_9, 2),
59611ff34f7SAndrey Ignatov 
59711ff34f7SAndrey Ignatov 			/* return DENY; */
59811ff34f7SAndrey Ignatov 			BPF_MOV64_IMM(BPF_REG_0, 0),
59911ff34f7SAndrey Ignatov 			BPF_JMP_A(1),
60011ff34f7SAndrey Ignatov 
60111ff34f7SAndrey Ignatov 			/* else return ALLOW; */
60211ff34f7SAndrey Ignatov 			BPF_MOV64_IMM(BPF_REG_0, 1),
60311ff34f7SAndrey Ignatov 			BPF_EXIT_INSN(),
60411ff34f7SAndrey Ignatov 		},
60511ff34f7SAndrey Ignatov 		.attach_type = BPF_CGROUP_SYSCTL,
60611ff34f7SAndrey Ignatov 		.sysctl = "net/ipv4/route/mtu_expires",
60711ff34f7SAndrey Ignatov 		.open_flags = O_WRONLY,
60811ff34f7SAndrey Ignatov 		.newval = "600", /* same as default, should fail anyway */
60911ff34f7SAndrey Ignatov 		.result = OP_EPERM,
61011ff34f7SAndrey Ignatov 	},
611786047ddSAndrey Ignatov 	{
612786047ddSAndrey Ignatov 		.descr = "sysctl_get_new_value sysctl:read EINVAL",
613786047ddSAndrey Ignatov 		.insns = {
614786047ddSAndrey Ignatov 			/* sysctl_get_new_value arg2 (buf) */
615786047ddSAndrey Ignatov 			BPF_MOV64_REG(BPF_REG_7, BPF_REG_10),
616786047ddSAndrey Ignatov 			BPF_ALU64_IMM(BPF_ADD, BPF_REG_7, -8),
617786047ddSAndrey Ignatov 			BPF_MOV64_IMM(BPF_REG_0, 0),
618786047ddSAndrey Ignatov 			BPF_STX_MEM(BPF_DW, BPF_REG_7, BPF_REG_0, 0),
619786047ddSAndrey Ignatov 
620786047ddSAndrey Ignatov 			BPF_MOV64_REG(BPF_REG_2, BPF_REG_7),
621786047ddSAndrey Ignatov 
622786047ddSAndrey Ignatov 			/* sysctl_get_new_value arg3 (buf_len) */
623786047ddSAndrey Ignatov 			BPF_MOV64_IMM(BPF_REG_3, 8),
624786047ddSAndrey Ignatov 
625786047ddSAndrey Ignatov 			/* sysctl_get_new_value(ctx, buf, buf_len) */
626786047ddSAndrey Ignatov 			BPF_EMIT_CALL(BPF_FUNC_sysctl_get_new_value),
627786047ddSAndrey Ignatov 
628786047ddSAndrey Ignatov 			/* if (ret == expected) */
629786047ddSAndrey Ignatov 			BPF_JMP_IMM(BPF_JNE, BPF_REG_0, -EINVAL, 2),
630786047ddSAndrey Ignatov 
631786047ddSAndrey Ignatov 			/* return ALLOW; */
632786047ddSAndrey Ignatov 			BPF_MOV64_IMM(BPF_REG_0, 1),
633786047ddSAndrey Ignatov 			BPF_JMP_A(1),
634786047ddSAndrey Ignatov 
635786047ddSAndrey Ignatov 			/* else return DENY; */
636786047ddSAndrey Ignatov 			BPF_MOV64_IMM(BPF_REG_0, 0),
637786047ddSAndrey Ignatov 			BPF_EXIT_INSN(),
638786047ddSAndrey Ignatov 		},
639786047ddSAndrey Ignatov 		.attach_type = BPF_CGROUP_SYSCTL,
640786047ddSAndrey Ignatov 		.sysctl = "net/ipv4/tcp_mem",
641786047ddSAndrey Ignatov 		.open_flags = O_RDONLY,
642786047ddSAndrey Ignatov 		.result = SUCCESS,
643786047ddSAndrey Ignatov 	},
644786047ddSAndrey Ignatov 	{
645786047ddSAndrey Ignatov 		.descr = "sysctl_get_new_value sysctl:write ok",
646786047ddSAndrey Ignatov 		.insns = {
647786047ddSAndrey Ignatov 			/* sysctl_get_new_value arg2 (buf) */
648786047ddSAndrey Ignatov 			BPF_MOV64_REG(BPF_REG_7, BPF_REG_10),
649786047ddSAndrey Ignatov 			BPF_ALU64_IMM(BPF_ADD, BPF_REG_7, -8),
650786047ddSAndrey Ignatov 
651786047ddSAndrey Ignatov 			BPF_MOV64_REG(BPF_REG_2, BPF_REG_7),
652786047ddSAndrey Ignatov 
653786047ddSAndrey Ignatov 			/* sysctl_get_new_value arg3 (buf_len) */
654786047ddSAndrey Ignatov 			BPF_MOV64_IMM(BPF_REG_3, 4),
655786047ddSAndrey Ignatov 
656786047ddSAndrey Ignatov 			/* sysctl_get_new_value(ctx, buf, buf_len) */
657786047ddSAndrey Ignatov 			BPF_EMIT_CALL(BPF_FUNC_sysctl_get_new_value),
658786047ddSAndrey Ignatov 
659786047ddSAndrey Ignatov 			/* if (ret == expected && */
660786047ddSAndrey Ignatov 			BPF_JMP_IMM(BPF_JNE, BPF_REG_0, 3, 4),
661786047ddSAndrey Ignatov 
662786047ddSAndrey Ignatov 			/*     buf[0:4] == "606\0") */
663786047ddSAndrey Ignatov 			BPF_LDX_MEM(BPF_W, BPF_REG_9, BPF_REG_7, 0),
664*3ec2a0edSIlya Leoshkevich 			BPF_JMP_IMM(BPF_JNE, BPF_REG_9,
665*3ec2a0edSIlya Leoshkevich 				    bpf_ntohl(0x36303600), 2),
666786047ddSAndrey Ignatov 
667786047ddSAndrey Ignatov 			/* return DENY; */
668786047ddSAndrey Ignatov 			BPF_MOV64_IMM(BPF_REG_0, 0),
669786047ddSAndrey Ignatov 			BPF_JMP_A(1),
670786047ddSAndrey Ignatov 
671786047ddSAndrey Ignatov 			/* else return ALLOW; */
672786047ddSAndrey Ignatov 			BPF_MOV64_IMM(BPF_REG_0, 1),
673786047ddSAndrey Ignatov 			BPF_EXIT_INSN(),
674786047ddSAndrey Ignatov 		},
675786047ddSAndrey Ignatov 		.attach_type = BPF_CGROUP_SYSCTL,
676786047ddSAndrey Ignatov 		.sysctl = "net/ipv4/route/mtu_expires",
677786047ddSAndrey Ignatov 		.open_flags = O_WRONLY,
678786047ddSAndrey Ignatov 		.newval = "606",
679786047ddSAndrey Ignatov 		.result = OP_EPERM,
680786047ddSAndrey Ignatov 	},
681786047ddSAndrey Ignatov 	{
682786047ddSAndrey Ignatov 		.descr = "sysctl_get_new_value sysctl:write ok long",
683786047ddSAndrey Ignatov 		.insns = {
684786047ddSAndrey Ignatov 			/* sysctl_get_new_value arg2 (buf) */
685786047ddSAndrey Ignatov 			BPF_MOV64_REG(BPF_REG_7, BPF_REG_10),
686786047ddSAndrey Ignatov 			BPF_ALU64_IMM(BPF_ADD, BPF_REG_7, -24),
687786047ddSAndrey Ignatov 
688786047ddSAndrey Ignatov 			BPF_MOV64_REG(BPF_REG_2, BPF_REG_7),
689786047ddSAndrey Ignatov 
690786047ddSAndrey Ignatov 			/* sysctl_get_new_value arg3 (buf_len) */
691786047ddSAndrey Ignatov 			BPF_MOV64_IMM(BPF_REG_3, 24),
692786047ddSAndrey Ignatov 
693786047ddSAndrey Ignatov 			/* sysctl_get_new_value(ctx, buf, buf_len) */
694786047ddSAndrey Ignatov 			BPF_EMIT_CALL(BPF_FUNC_sysctl_get_new_value),
695786047ddSAndrey Ignatov 
696786047ddSAndrey Ignatov 			/* if (ret == expected && */
697786047ddSAndrey Ignatov 			BPF_JMP_IMM(BPF_JNE, BPF_REG_0, 23, 14),
698786047ddSAndrey Ignatov 
699786047ddSAndrey Ignatov 			/*     buf[0:8] == "3000000 " && */
700*3ec2a0edSIlya Leoshkevich 			BPF_LD_IMM64(BPF_REG_8,
701*3ec2a0edSIlya Leoshkevich 				     bpf_be64_to_cpu(0x3330303030303020ULL)),
702786047ddSAndrey Ignatov 			BPF_LDX_MEM(BPF_DW, BPF_REG_9, BPF_REG_7, 0),
703786047ddSAndrey Ignatov 			BPF_JMP_REG(BPF_JNE, BPF_REG_8, BPF_REG_9, 10),
704786047ddSAndrey Ignatov 
705786047ddSAndrey Ignatov 			/*     buf[8:16] == "4000000 " && */
706*3ec2a0edSIlya Leoshkevich 			BPF_LD_IMM64(BPF_REG_8,
707*3ec2a0edSIlya Leoshkevich 				     bpf_be64_to_cpu(0x3430303030303020ULL)),
708786047ddSAndrey Ignatov 			BPF_LDX_MEM(BPF_DW, BPF_REG_9, BPF_REG_7, 8),
709786047ddSAndrey Ignatov 			BPF_JMP_REG(BPF_JNE, BPF_REG_8, BPF_REG_9, 6),
710786047ddSAndrey Ignatov 
711786047ddSAndrey Ignatov 			/*     buf[16:24] == "6000000\0") */
712*3ec2a0edSIlya Leoshkevich 			BPF_LD_IMM64(BPF_REG_8,
713*3ec2a0edSIlya Leoshkevich 				     bpf_be64_to_cpu(0x3630303030303000ULL)),
714786047ddSAndrey Ignatov 			BPF_LDX_MEM(BPF_DW, BPF_REG_9, BPF_REG_7, 16),
715786047ddSAndrey Ignatov 			BPF_JMP_REG(BPF_JNE, BPF_REG_8, BPF_REG_9, 2),
716786047ddSAndrey Ignatov 
717786047ddSAndrey Ignatov 			/* return DENY; */
718786047ddSAndrey Ignatov 			BPF_MOV64_IMM(BPF_REG_0, 0),
719786047ddSAndrey Ignatov 			BPF_JMP_A(1),
720786047ddSAndrey Ignatov 
721786047ddSAndrey Ignatov 			/* else return ALLOW; */
722786047ddSAndrey Ignatov 			BPF_MOV64_IMM(BPF_REG_0, 1),
723786047ddSAndrey Ignatov 			BPF_EXIT_INSN(),
724786047ddSAndrey Ignatov 		},
725786047ddSAndrey Ignatov 		.attach_type = BPF_CGROUP_SYSCTL,
726786047ddSAndrey Ignatov 		.sysctl = "net/ipv4/tcp_mem",
727786047ddSAndrey Ignatov 		.open_flags = O_WRONLY,
728786047ddSAndrey Ignatov 		.newval = "3000000 4000000 6000000",
729786047ddSAndrey Ignatov 		.result = OP_EPERM,
730786047ddSAndrey Ignatov 	},
731786047ddSAndrey Ignatov 	{
732786047ddSAndrey Ignatov 		.descr = "sysctl_get_new_value sysctl:write E2BIG",
733786047ddSAndrey Ignatov 		.insns = {
734786047ddSAndrey Ignatov 			/* sysctl_get_new_value arg2 (buf) */
735786047ddSAndrey Ignatov 			BPF_MOV64_REG(BPF_REG_7, BPF_REG_10),
736786047ddSAndrey Ignatov 			BPF_ALU64_IMM(BPF_ADD, BPF_REG_7, -8),
737786047ddSAndrey Ignatov 			BPF_MOV64_IMM(BPF_REG_0, 0),
738786047ddSAndrey Ignatov 			BPF_STX_MEM(BPF_B, BPF_REG_7, BPF_REG_0, 3),
739786047ddSAndrey Ignatov 
740786047ddSAndrey Ignatov 			BPF_MOV64_REG(BPF_REG_2, BPF_REG_7),
741786047ddSAndrey Ignatov 
742786047ddSAndrey Ignatov 			/* sysctl_get_new_value arg3 (buf_len) */
743786047ddSAndrey Ignatov 			BPF_MOV64_IMM(BPF_REG_3, 3),
744786047ddSAndrey Ignatov 
745786047ddSAndrey Ignatov 			/* sysctl_get_new_value(ctx, buf, buf_len) */
746786047ddSAndrey Ignatov 			BPF_EMIT_CALL(BPF_FUNC_sysctl_get_new_value),
747786047ddSAndrey Ignatov 
748786047ddSAndrey Ignatov 			/* if (ret == expected && */
749786047ddSAndrey Ignatov 			BPF_JMP_IMM(BPF_JNE, BPF_REG_0, -E2BIG, 4),
750786047ddSAndrey Ignatov 
751786047ddSAndrey Ignatov 			/*     buf[0:3] == "60\0") */
752786047ddSAndrey Ignatov 			BPF_LDX_MEM(BPF_W, BPF_REG_9, BPF_REG_7, 0),
753*3ec2a0edSIlya Leoshkevich 			BPF_JMP_IMM(BPF_JNE, BPF_REG_9,
754*3ec2a0edSIlya Leoshkevich 				    bpf_ntohl(0x36300000), 2),
755786047ddSAndrey Ignatov 
756786047ddSAndrey Ignatov 			/* return DENY; */
757786047ddSAndrey Ignatov 			BPF_MOV64_IMM(BPF_REG_0, 0),
758786047ddSAndrey Ignatov 			BPF_JMP_A(1),
759786047ddSAndrey Ignatov 
760786047ddSAndrey Ignatov 			/* else return ALLOW; */
761786047ddSAndrey Ignatov 			BPF_MOV64_IMM(BPF_REG_0, 1),
762786047ddSAndrey Ignatov 			BPF_EXIT_INSN(),
763786047ddSAndrey Ignatov 		},
764786047ddSAndrey Ignatov 		.attach_type = BPF_CGROUP_SYSCTL,
765786047ddSAndrey Ignatov 		.sysctl = "net/ipv4/route/mtu_expires",
766786047ddSAndrey Ignatov 		.open_flags = O_WRONLY,
767786047ddSAndrey Ignatov 		.newval = "606",
768786047ddSAndrey Ignatov 		.result = OP_EPERM,
769786047ddSAndrey Ignatov 	},
770786047ddSAndrey Ignatov 	{
771786047ddSAndrey Ignatov 		.descr = "sysctl_set_new_value sysctl:read EINVAL",
772786047ddSAndrey Ignatov 		.insns = {
773786047ddSAndrey Ignatov 			/* sysctl_set_new_value arg2 (buf) */
774786047ddSAndrey Ignatov 			BPF_MOV64_REG(BPF_REG_7, BPF_REG_10),
775786047ddSAndrey Ignatov 			BPF_ALU64_IMM(BPF_ADD, BPF_REG_7, -8),
776*3ec2a0edSIlya Leoshkevich 			BPF_MOV64_IMM(BPF_REG_0,
777*3ec2a0edSIlya Leoshkevich 				      bpf_ntohl(0x36303000)),
778786047ddSAndrey Ignatov 			BPF_STX_MEM(BPF_DW, BPF_REG_7, BPF_REG_0, 0),
779786047ddSAndrey Ignatov 
780786047ddSAndrey Ignatov 			BPF_MOV64_REG(BPF_REG_2, BPF_REG_7),
781786047ddSAndrey Ignatov 
782786047ddSAndrey Ignatov 			/* sysctl_set_new_value arg3 (buf_len) */
783786047ddSAndrey Ignatov 			BPF_MOV64_IMM(BPF_REG_3, 3),
784786047ddSAndrey Ignatov 
785786047ddSAndrey Ignatov 			/* sysctl_set_new_value(ctx, buf, buf_len) */
786786047ddSAndrey Ignatov 			BPF_EMIT_CALL(BPF_FUNC_sysctl_set_new_value),
787786047ddSAndrey Ignatov 
788786047ddSAndrey Ignatov 			/* if (ret == expected) */
789786047ddSAndrey Ignatov 			BPF_JMP_IMM(BPF_JNE, BPF_REG_0, -EINVAL, 2),
790786047ddSAndrey Ignatov 
791786047ddSAndrey Ignatov 			/* return ALLOW; */
792786047ddSAndrey Ignatov 			BPF_MOV64_IMM(BPF_REG_0, 1),
793786047ddSAndrey Ignatov 			BPF_JMP_A(1),
794786047ddSAndrey Ignatov 
795786047ddSAndrey Ignatov 			/* else return DENY; */
796786047ddSAndrey Ignatov 			BPF_MOV64_IMM(BPF_REG_0, 0),
797786047ddSAndrey Ignatov 			BPF_EXIT_INSN(),
798786047ddSAndrey Ignatov 		},
799786047ddSAndrey Ignatov 		.attach_type = BPF_CGROUP_SYSCTL,
800786047ddSAndrey Ignatov 		.sysctl = "net/ipv4/route/mtu_expires",
801786047ddSAndrey Ignatov 		.open_flags = O_RDONLY,
802786047ddSAndrey Ignatov 		.result = SUCCESS,
803786047ddSAndrey Ignatov 	},
804786047ddSAndrey Ignatov 	{
805786047ddSAndrey Ignatov 		.descr = "sysctl_set_new_value sysctl:write ok",
806786047ddSAndrey Ignatov 		.fixup_value_insn = 2,
807786047ddSAndrey Ignatov 		.insns = {
808786047ddSAndrey Ignatov 			/* sysctl_set_new_value arg2 (buf) */
809786047ddSAndrey Ignatov 			BPF_MOV64_REG(BPF_REG_7, BPF_REG_10),
810786047ddSAndrey Ignatov 			BPF_ALU64_IMM(BPF_ADD, BPF_REG_7, -8),
811*3ec2a0edSIlya Leoshkevich 			BPF_LD_IMM64(BPF_REG_0, FIXUP_SYSCTL_VALUE),
812786047ddSAndrey Ignatov 			BPF_STX_MEM(BPF_DW, BPF_REG_7, BPF_REG_0, 0),
813786047ddSAndrey Ignatov 
814786047ddSAndrey Ignatov 			BPF_MOV64_REG(BPF_REG_2, BPF_REG_7),
815786047ddSAndrey Ignatov 
816786047ddSAndrey Ignatov 			/* sysctl_set_new_value arg3 (buf_len) */
817786047ddSAndrey Ignatov 			BPF_MOV64_IMM(BPF_REG_3, 3),
818786047ddSAndrey Ignatov 
819786047ddSAndrey Ignatov 			/* sysctl_set_new_value(ctx, buf, buf_len) */
820786047ddSAndrey Ignatov 			BPF_EMIT_CALL(BPF_FUNC_sysctl_set_new_value),
821786047ddSAndrey Ignatov 
822786047ddSAndrey Ignatov 			/* if (ret == expected) */
823786047ddSAndrey Ignatov 			BPF_JMP_IMM(BPF_JNE, BPF_REG_0, 0, 2),
824786047ddSAndrey Ignatov 
825786047ddSAndrey Ignatov 			/* return ALLOW; */
826786047ddSAndrey Ignatov 			BPF_MOV64_IMM(BPF_REG_0, 1),
827786047ddSAndrey Ignatov 			BPF_JMP_A(1),
828786047ddSAndrey Ignatov 
829786047ddSAndrey Ignatov 			/* else return DENY; */
830786047ddSAndrey Ignatov 			BPF_MOV64_IMM(BPF_REG_0, 0),
831786047ddSAndrey Ignatov 			BPF_EXIT_INSN(),
832786047ddSAndrey Ignatov 		},
833786047ddSAndrey Ignatov 		.attach_type = BPF_CGROUP_SYSCTL,
834786047ddSAndrey Ignatov 		.sysctl = "net/ipv4/route/mtu_expires",
835786047ddSAndrey Ignatov 		.open_flags = O_WRONLY,
836786047ddSAndrey Ignatov 		.newval = "606",
837786047ddSAndrey Ignatov 		.result = SUCCESS,
838786047ddSAndrey Ignatov 	},
8398549ddc8SAndrey Ignatov 	{
8408549ddc8SAndrey Ignatov 		"bpf_strtoul one number string",
8418549ddc8SAndrey Ignatov 		.insns = {
8428549ddc8SAndrey Ignatov 			/* arg1 (buf) */
8438549ddc8SAndrey Ignatov 			BPF_MOV64_REG(BPF_REG_7, BPF_REG_10),
8448549ddc8SAndrey Ignatov 			BPF_ALU64_IMM(BPF_ADD, BPF_REG_7, -8),
845*3ec2a0edSIlya Leoshkevich 			BPF_MOV64_IMM(BPF_REG_0,
846*3ec2a0edSIlya Leoshkevich 				      bpf_ntohl(0x36303000)),
847*3ec2a0edSIlya Leoshkevich 			BPF_STX_MEM(BPF_W, BPF_REG_7, BPF_REG_0, 0),
8488549ddc8SAndrey Ignatov 
8498549ddc8SAndrey Ignatov 			BPF_MOV64_REG(BPF_REG_1, BPF_REG_7),
8508549ddc8SAndrey Ignatov 
8518549ddc8SAndrey Ignatov 			/* arg2 (buf_len) */
8528549ddc8SAndrey Ignatov 			BPF_MOV64_IMM(BPF_REG_2, 4),
8538549ddc8SAndrey Ignatov 
8548549ddc8SAndrey Ignatov 			/* arg3 (flags) */
8558549ddc8SAndrey Ignatov 			BPF_MOV64_IMM(BPF_REG_3, 0),
8568549ddc8SAndrey Ignatov 
8578549ddc8SAndrey Ignatov 			/* arg4 (res) */
8588549ddc8SAndrey Ignatov 			BPF_ALU64_IMM(BPF_ADD, BPF_REG_7, -8),
8598549ddc8SAndrey Ignatov 			BPF_STX_MEM(BPF_DW, BPF_REG_7, BPF_REG_0, 0),
8608549ddc8SAndrey Ignatov 			BPF_MOV64_REG(BPF_REG_4, BPF_REG_7),
8618549ddc8SAndrey Ignatov 
8628549ddc8SAndrey Ignatov 			BPF_EMIT_CALL(BPF_FUNC_strtoul),
8638549ddc8SAndrey Ignatov 
8648549ddc8SAndrey Ignatov 			/* if (ret == expected && */
8658549ddc8SAndrey Ignatov 			BPF_JMP_IMM(BPF_JNE, BPF_REG_0, 3, 4),
8668549ddc8SAndrey Ignatov 			/*     res == expected) */
8678549ddc8SAndrey Ignatov 			BPF_LDX_MEM(BPF_DW, BPF_REG_9, BPF_REG_7, 0),
8688549ddc8SAndrey Ignatov 			BPF_JMP_IMM(BPF_JNE, BPF_REG_9, 600, 2),
8698549ddc8SAndrey Ignatov 
8708549ddc8SAndrey Ignatov 			/* return ALLOW; */
8718549ddc8SAndrey Ignatov 			BPF_MOV64_IMM(BPF_REG_0, 1),
8728549ddc8SAndrey Ignatov 			BPF_JMP_A(1),
8738549ddc8SAndrey Ignatov 
8748549ddc8SAndrey Ignatov 			/* else return DENY; */
8758549ddc8SAndrey Ignatov 			BPF_MOV64_IMM(BPF_REG_0, 0),
8768549ddc8SAndrey Ignatov 			BPF_EXIT_INSN(),
8778549ddc8SAndrey Ignatov 		},
8788549ddc8SAndrey Ignatov 		.attach_type = BPF_CGROUP_SYSCTL,
8798549ddc8SAndrey Ignatov 		.sysctl = "net/ipv4/route/mtu_expires",
8808549ddc8SAndrey Ignatov 		.open_flags = O_RDONLY,
8818549ddc8SAndrey Ignatov 		.result = SUCCESS,
8828549ddc8SAndrey Ignatov 	},
8838549ddc8SAndrey Ignatov 	{
8848549ddc8SAndrey Ignatov 		"bpf_strtoul multi number string",
8858549ddc8SAndrey Ignatov 		.insns = {
8868549ddc8SAndrey Ignatov 			/* arg1 (buf) */
8878549ddc8SAndrey Ignatov 			BPF_MOV64_REG(BPF_REG_7, BPF_REG_10),
8888549ddc8SAndrey Ignatov 			BPF_ALU64_IMM(BPF_ADD, BPF_REG_7, -8),
8898549ddc8SAndrey Ignatov 			/* "600 602\0" */
890*3ec2a0edSIlya Leoshkevich 			BPF_LD_IMM64(BPF_REG_0,
891*3ec2a0edSIlya Leoshkevich 				     bpf_be64_to_cpu(0x3630302036303200ULL)),
8928549ddc8SAndrey Ignatov 			BPF_STX_MEM(BPF_DW, BPF_REG_7, BPF_REG_0, 0),
8938549ddc8SAndrey Ignatov 			BPF_MOV64_REG(BPF_REG_1, BPF_REG_7),
8948549ddc8SAndrey Ignatov 
8958549ddc8SAndrey Ignatov 			/* arg2 (buf_len) */
8968549ddc8SAndrey Ignatov 			BPF_MOV64_IMM(BPF_REG_2, 8),
8978549ddc8SAndrey Ignatov 
8988549ddc8SAndrey Ignatov 			/* arg3 (flags) */
8998549ddc8SAndrey Ignatov 			BPF_MOV64_IMM(BPF_REG_3, 0),
9008549ddc8SAndrey Ignatov 
9018549ddc8SAndrey Ignatov 			/* arg4 (res) */
9028549ddc8SAndrey Ignatov 			BPF_ALU64_IMM(BPF_ADD, BPF_REG_7, -8),
9038549ddc8SAndrey Ignatov 			BPF_STX_MEM(BPF_DW, BPF_REG_7, BPF_REG_0, 0),
9048549ddc8SAndrey Ignatov 			BPF_MOV64_REG(BPF_REG_4, BPF_REG_7),
9058549ddc8SAndrey Ignatov 
9068549ddc8SAndrey Ignatov 			BPF_EMIT_CALL(BPF_FUNC_strtoul),
9078549ddc8SAndrey Ignatov 
9088549ddc8SAndrey Ignatov 			/* if (ret == expected && */
9098549ddc8SAndrey Ignatov 			BPF_JMP_IMM(BPF_JNE, BPF_REG_0, 3, 18),
9108549ddc8SAndrey Ignatov 			/*     res == expected) */
9118549ddc8SAndrey Ignatov 			BPF_LDX_MEM(BPF_DW, BPF_REG_9, BPF_REG_7, 0),
9128549ddc8SAndrey Ignatov 			BPF_JMP_IMM(BPF_JNE, BPF_REG_9, 600, 16),
9138549ddc8SAndrey Ignatov 
9148549ddc8SAndrey Ignatov 			/*     arg1 (buf) */
9158549ddc8SAndrey Ignatov 			BPF_MOV64_REG(BPF_REG_7, BPF_REG_10),
9168549ddc8SAndrey Ignatov 			BPF_ALU64_IMM(BPF_ADD, BPF_REG_7, -8),
9178549ddc8SAndrey Ignatov 			BPF_ALU64_REG(BPF_ADD, BPF_REG_7, BPF_REG_0),
9188549ddc8SAndrey Ignatov 			BPF_MOV64_REG(BPF_REG_1, BPF_REG_7),
9198549ddc8SAndrey Ignatov 
9208549ddc8SAndrey Ignatov 			/*     arg2 (buf_len) */
9218549ddc8SAndrey Ignatov 			BPF_MOV64_IMM(BPF_REG_2, 8),
9228549ddc8SAndrey Ignatov 			BPF_ALU64_REG(BPF_SUB, BPF_REG_2, BPF_REG_0),
9238549ddc8SAndrey Ignatov 
9248549ddc8SAndrey Ignatov 			/*     arg3 (flags) */
9258549ddc8SAndrey Ignatov 			BPF_MOV64_IMM(BPF_REG_3, 0),
9268549ddc8SAndrey Ignatov 
9278549ddc8SAndrey Ignatov 			/*     arg4 (res) */
9288549ddc8SAndrey Ignatov 			BPF_MOV64_REG(BPF_REG_7, BPF_REG_10),
9298549ddc8SAndrey Ignatov 			BPF_ALU64_IMM(BPF_ADD, BPF_REG_7, -16),
9308549ddc8SAndrey Ignatov 			BPF_MOV64_REG(BPF_REG_4, BPF_REG_7),
9318549ddc8SAndrey Ignatov 
9328549ddc8SAndrey Ignatov 			BPF_EMIT_CALL(BPF_FUNC_strtoul),
9338549ddc8SAndrey Ignatov 
9348549ddc8SAndrey Ignatov 			/*     if (ret == expected && */
9358549ddc8SAndrey Ignatov 			BPF_JMP_IMM(BPF_JNE, BPF_REG_0, 4, 4),
9368549ddc8SAndrey Ignatov 			/*         res == expected) */
9378549ddc8SAndrey Ignatov 			BPF_LDX_MEM(BPF_DW, BPF_REG_9, BPF_REG_7, 0),
9388549ddc8SAndrey Ignatov 			BPF_JMP_IMM(BPF_JNE, BPF_REG_9, 602, 2),
9398549ddc8SAndrey Ignatov 
9408549ddc8SAndrey Ignatov 			/* return ALLOW; */
9418549ddc8SAndrey Ignatov 			BPF_MOV64_IMM(BPF_REG_0, 1),
9428549ddc8SAndrey Ignatov 			BPF_JMP_A(1),
9438549ddc8SAndrey Ignatov 
9448549ddc8SAndrey Ignatov 			/* else return DENY; */
9458549ddc8SAndrey Ignatov 			BPF_MOV64_IMM(BPF_REG_0, 0),
9468549ddc8SAndrey Ignatov 			BPF_EXIT_INSN(),
9478549ddc8SAndrey Ignatov 		},
9488549ddc8SAndrey Ignatov 		.attach_type = BPF_CGROUP_SYSCTL,
9498549ddc8SAndrey Ignatov 		.sysctl = "net/ipv4/tcp_mem",
9508549ddc8SAndrey Ignatov 		.open_flags = O_RDONLY,
9518549ddc8SAndrey Ignatov 		.result = SUCCESS,
9528549ddc8SAndrey Ignatov 	},
9538549ddc8SAndrey Ignatov 	{
9548549ddc8SAndrey Ignatov 		"bpf_strtoul buf_len = 0, reject",
9558549ddc8SAndrey Ignatov 		.insns = {
9568549ddc8SAndrey Ignatov 			/* arg1 (buf) */
9578549ddc8SAndrey Ignatov 			BPF_MOV64_REG(BPF_REG_7, BPF_REG_10),
9588549ddc8SAndrey Ignatov 			BPF_ALU64_IMM(BPF_ADD, BPF_REG_7, -8),
959*3ec2a0edSIlya Leoshkevich 			BPF_MOV64_IMM(BPF_REG_0,
960*3ec2a0edSIlya Leoshkevich 				      bpf_ntohl(0x36303000)),
9618549ddc8SAndrey Ignatov 			BPF_STX_MEM(BPF_DW, BPF_REG_7, BPF_REG_0, 0),
9628549ddc8SAndrey Ignatov 
9638549ddc8SAndrey Ignatov 			BPF_MOV64_REG(BPF_REG_1, BPF_REG_7),
9648549ddc8SAndrey Ignatov 
9658549ddc8SAndrey Ignatov 			/* arg2 (buf_len) */
9668549ddc8SAndrey Ignatov 			BPF_MOV64_IMM(BPF_REG_2, 0),
9678549ddc8SAndrey Ignatov 
9688549ddc8SAndrey Ignatov 			/* arg3 (flags) */
9698549ddc8SAndrey Ignatov 			BPF_MOV64_IMM(BPF_REG_3, 0),
9708549ddc8SAndrey Ignatov 
9718549ddc8SAndrey Ignatov 			/* arg4 (res) */
9728549ddc8SAndrey Ignatov 			BPF_ALU64_IMM(BPF_ADD, BPF_REG_7, -8),
9738549ddc8SAndrey Ignatov 			BPF_STX_MEM(BPF_DW, BPF_REG_7, BPF_REG_0, 0),
9748549ddc8SAndrey Ignatov 			BPF_MOV64_REG(BPF_REG_4, BPF_REG_7),
9758549ddc8SAndrey Ignatov 
9768549ddc8SAndrey Ignatov 			BPF_EMIT_CALL(BPF_FUNC_strtoul),
9778549ddc8SAndrey Ignatov 
9788549ddc8SAndrey Ignatov 			BPF_MOV64_IMM(BPF_REG_0, 1),
9798549ddc8SAndrey Ignatov 			BPF_EXIT_INSN(),
9808549ddc8SAndrey Ignatov 		},
9818549ddc8SAndrey Ignatov 		.attach_type = BPF_CGROUP_SYSCTL,
9828549ddc8SAndrey Ignatov 		.sysctl = "net/ipv4/route/mtu_expires",
9838549ddc8SAndrey Ignatov 		.open_flags = O_RDONLY,
9848549ddc8SAndrey Ignatov 		.result = LOAD_REJECT,
9858549ddc8SAndrey Ignatov 	},
9868549ddc8SAndrey Ignatov 	{
9878549ddc8SAndrey Ignatov 		"bpf_strtoul supported base, ok",
9888549ddc8SAndrey Ignatov 		.insns = {
9898549ddc8SAndrey Ignatov 			/* arg1 (buf) */
9908549ddc8SAndrey Ignatov 			BPF_MOV64_REG(BPF_REG_7, BPF_REG_10),
9918549ddc8SAndrey Ignatov 			BPF_ALU64_IMM(BPF_ADD, BPF_REG_7, -8),
992*3ec2a0edSIlya Leoshkevich 			BPF_MOV64_IMM(BPF_REG_0,
993*3ec2a0edSIlya Leoshkevich 				      bpf_ntohl(0x30373700)),
994*3ec2a0edSIlya Leoshkevich 			BPF_STX_MEM(BPF_W, BPF_REG_7, BPF_REG_0, 0),
9958549ddc8SAndrey Ignatov 
9968549ddc8SAndrey Ignatov 			BPF_MOV64_REG(BPF_REG_1, BPF_REG_7),
9978549ddc8SAndrey Ignatov 
9988549ddc8SAndrey Ignatov 			/* arg2 (buf_len) */
9998549ddc8SAndrey Ignatov 			BPF_MOV64_IMM(BPF_REG_2, 4),
10008549ddc8SAndrey Ignatov 
10018549ddc8SAndrey Ignatov 			/* arg3 (flags) */
10028549ddc8SAndrey Ignatov 			BPF_MOV64_IMM(BPF_REG_3, 8),
10038549ddc8SAndrey Ignatov 
10048549ddc8SAndrey Ignatov 			/* arg4 (res) */
10058549ddc8SAndrey Ignatov 			BPF_ALU64_IMM(BPF_ADD, BPF_REG_7, -8),
10068549ddc8SAndrey Ignatov 			BPF_STX_MEM(BPF_DW, BPF_REG_7, BPF_REG_0, 0),
10078549ddc8SAndrey Ignatov 			BPF_MOV64_REG(BPF_REG_4, BPF_REG_7),
10088549ddc8SAndrey Ignatov 
10098549ddc8SAndrey Ignatov 			BPF_EMIT_CALL(BPF_FUNC_strtoul),
10108549ddc8SAndrey Ignatov 
10118549ddc8SAndrey Ignatov 			/* if (ret == expected && */
10128549ddc8SAndrey Ignatov 			BPF_JMP_IMM(BPF_JNE, BPF_REG_0, 3, 4),
10138549ddc8SAndrey Ignatov 			/*     res == expected) */
10148549ddc8SAndrey Ignatov 			BPF_LDX_MEM(BPF_DW, BPF_REG_9, BPF_REG_7, 0),
10158549ddc8SAndrey Ignatov 			BPF_JMP_IMM(BPF_JNE, BPF_REG_9, 63, 2),
10168549ddc8SAndrey Ignatov 
10178549ddc8SAndrey Ignatov 			/* return ALLOW; */
10188549ddc8SAndrey Ignatov 			BPF_MOV64_IMM(BPF_REG_0, 1),
10198549ddc8SAndrey Ignatov 			BPF_JMP_A(1),
10208549ddc8SAndrey Ignatov 
10218549ddc8SAndrey Ignatov 			/* else return DENY; */
10228549ddc8SAndrey Ignatov 			BPF_MOV64_IMM(BPF_REG_0, 0),
10238549ddc8SAndrey Ignatov 			BPF_EXIT_INSN(),
10248549ddc8SAndrey Ignatov 		},
10258549ddc8SAndrey Ignatov 		.attach_type = BPF_CGROUP_SYSCTL,
10268549ddc8SAndrey Ignatov 		.sysctl = "net/ipv4/route/mtu_expires",
10278549ddc8SAndrey Ignatov 		.open_flags = O_RDONLY,
10288549ddc8SAndrey Ignatov 		.result = SUCCESS,
10298549ddc8SAndrey Ignatov 	},
10308549ddc8SAndrey Ignatov 	{
10318549ddc8SAndrey Ignatov 		"bpf_strtoul unsupported base, EINVAL",
10328549ddc8SAndrey Ignatov 		.insns = {
10338549ddc8SAndrey Ignatov 			/* arg1 (buf) */
10348549ddc8SAndrey Ignatov 			BPF_MOV64_REG(BPF_REG_7, BPF_REG_10),
10358549ddc8SAndrey Ignatov 			BPF_ALU64_IMM(BPF_ADD, BPF_REG_7, -8),
1036*3ec2a0edSIlya Leoshkevich 			BPF_MOV64_IMM(BPF_REG_0,
1037*3ec2a0edSIlya Leoshkevich 				      bpf_ntohl(0x36303000)),
10388549ddc8SAndrey Ignatov 			BPF_STX_MEM(BPF_DW, BPF_REG_7, BPF_REG_0, 0),
10398549ddc8SAndrey Ignatov 
10408549ddc8SAndrey Ignatov 			BPF_MOV64_REG(BPF_REG_1, BPF_REG_7),
10418549ddc8SAndrey Ignatov 
10428549ddc8SAndrey Ignatov 			/* arg2 (buf_len) */
10438549ddc8SAndrey Ignatov 			BPF_MOV64_IMM(BPF_REG_2, 4),
10448549ddc8SAndrey Ignatov 
10458549ddc8SAndrey Ignatov 			/* arg3 (flags) */
10468549ddc8SAndrey Ignatov 			BPF_MOV64_IMM(BPF_REG_3, 3),
10478549ddc8SAndrey Ignatov 
10488549ddc8SAndrey Ignatov 			/* arg4 (res) */
10498549ddc8SAndrey Ignatov 			BPF_ALU64_IMM(BPF_ADD, BPF_REG_7, -8),
10508549ddc8SAndrey Ignatov 			BPF_STX_MEM(BPF_DW, BPF_REG_7, BPF_REG_0, 0),
10518549ddc8SAndrey Ignatov 			BPF_MOV64_REG(BPF_REG_4, BPF_REG_7),
10528549ddc8SAndrey Ignatov 
10538549ddc8SAndrey Ignatov 			BPF_EMIT_CALL(BPF_FUNC_strtoul),
10548549ddc8SAndrey Ignatov 
10558549ddc8SAndrey Ignatov 			/* if (ret == expected) */
10568549ddc8SAndrey Ignatov 			BPF_JMP_IMM(BPF_JNE, BPF_REG_0, -EINVAL, 2),
10578549ddc8SAndrey Ignatov 
10588549ddc8SAndrey Ignatov 			/* return ALLOW; */
10598549ddc8SAndrey Ignatov 			BPF_MOV64_IMM(BPF_REG_0, 1),
10608549ddc8SAndrey Ignatov 			BPF_JMP_A(1),
10618549ddc8SAndrey Ignatov 
10628549ddc8SAndrey Ignatov 			/* else return DENY; */
10638549ddc8SAndrey Ignatov 			BPF_MOV64_IMM(BPF_REG_0, 0),
10648549ddc8SAndrey Ignatov 			BPF_EXIT_INSN(),
10658549ddc8SAndrey Ignatov 		},
10668549ddc8SAndrey Ignatov 		.attach_type = BPF_CGROUP_SYSCTL,
10678549ddc8SAndrey Ignatov 		.sysctl = "net/ipv4/route/mtu_expires",
10688549ddc8SAndrey Ignatov 		.open_flags = O_RDONLY,
10698549ddc8SAndrey Ignatov 		.result = SUCCESS,
10708549ddc8SAndrey Ignatov 	},
10718549ddc8SAndrey Ignatov 	{
10728549ddc8SAndrey Ignatov 		"bpf_strtoul buf with spaces only, EINVAL",
10738549ddc8SAndrey Ignatov 		.insns = {
10748549ddc8SAndrey Ignatov 			/* arg1 (buf) */
10758549ddc8SAndrey Ignatov 			BPF_MOV64_REG(BPF_REG_7, BPF_REG_10),
10768549ddc8SAndrey Ignatov 			BPF_ALU64_IMM(BPF_ADD, BPF_REG_7, -8),
1077*3ec2a0edSIlya Leoshkevich 			BPF_MOV64_IMM(BPF_REG_0,
1078*3ec2a0edSIlya Leoshkevich 				      bpf_ntohl(0x0d0c0a09)),
10798549ddc8SAndrey Ignatov 			BPF_STX_MEM(BPF_DW, BPF_REG_7, BPF_REG_0, 0),
10808549ddc8SAndrey Ignatov 
10818549ddc8SAndrey Ignatov 			BPF_MOV64_REG(BPF_REG_1, BPF_REG_7),
10828549ddc8SAndrey Ignatov 
10838549ddc8SAndrey Ignatov 			/* arg2 (buf_len) */
10848549ddc8SAndrey Ignatov 			BPF_MOV64_IMM(BPF_REG_2, 4),
10858549ddc8SAndrey Ignatov 
10868549ddc8SAndrey Ignatov 			/* arg3 (flags) */
10878549ddc8SAndrey Ignatov 			BPF_MOV64_IMM(BPF_REG_3, 0),
10888549ddc8SAndrey Ignatov 
10898549ddc8SAndrey Ignatov 			/* arg4 (res) */
10908549ddc8SAndrey Ignatov 			BPF_ALU64_IMM(BPF_ADD, BPF_REG_7, -8),
10918549ddc8SAndrey Ignatov 			BPF_STX_MEM(BPF_DW, BPF_REG_7, BPF_REG_0, 0),
10928549ddc8SAndrey Ignatov 			BPF_MOV64_REG(BPF_REG_4, BPF_REG_7),
10938549ddc8SAndrey Ignatov 
10948549ddc8SAndrey Ignatov 			BPF_EMIT_CALL(BPF_FUNC_strtoul),
10958549ddc8SAndrey Ignatov 
10968549ddc8SAndrey Ignatov 			/* if (ret == expected) */
10978549ddc8SAndrey Ignatov 			BPF_JMP_IMM(BPF_JNE, BPF_REG_0, -EINVAL, 2),
10988549ddc8SAndrey Ignatov 
10998549ddc8SAndrey Ignatov 			/* return ALLOW; */
11008549ddc8SAndrey Ignatov 			BPF_MOV64_IMM(BPF_REG_0, 1),
11018549ddc8SAndrey Ignatov 			BPF_JMP_A(1),
11028549ddc8SAndrey Ignatov 
11038549ddc8SAndrey Ignatov 			/* else return DENY; */
11048549ddc8SAndrey Ignatov 			BPF_MOV64_IMM(BPF_REG_0, 0),
11058549ddc8SAndrey Ignatov 			BPF_EXIT_INSN(),
11068549ddc8SAndrey Ignatov 		},
11078549ddc8SAndrey Ignatov 		.attach_type = BPF_CGROUP_SYSCTL,
11088549ddc8SAndrey Ignatov 		.sysctl = "net/ipv4/route/mtu_expires",
11098549ddc8SAndrey Ignatov 		.open_flags = O_RDONLY,
11108549ddc8SAndrey Ignatov 		.result = SUCCESS,
11118549ddc8SAndrey Ignatov 	},
11128549ddc8SAndrey Ignatov 	{
11138549ddc8SAndrey Ignatov 		"bpf_strtoul negative number, EINVAL",
11148549ddc8SAndrey Ignatov 		.insns = {
11158549ddc8SAndrey Ignatov 			/* arg1 (buf) */
11168549ddc8SAndrey Ignatov 			BPF_MOV64_REG(BPF_REG_7, BPF_REG_10),
11178549ddc8SAndrey Ignatov 			BPF_ALU64_IMM(BPF_ADD, BPF_REG_7, -8),
1118*3ec2a0edSIlya Leoshkevich 			/* " -6\0" */
1119*3ec2a0edSIlya Leoshkevich 			BPF_MOV64_IMM(BPF_REG_0,
1120*3ec2a0edSIlya Leoshkevich 				      bpf_ntohl(0x0a2d3600)),
11218549ddc8SAndrey Ignatov 			BPF_STX_MEM(BPF_DW, BPF_REG_7, BPF_REG_0, 0),
11228549ddc8SAndrey Ignatov 
11238549ddc8SAndrey Ignatov 			BPF_MOV64_REG(BPF_REG_1, BPF_REG_7),
11248549ddc8SAndrey Ignatov 
11258549ddc8SAndrey Ignatov 			/* arg2 (buf_len) */
11268549ddc8SAndrey Ignatov 			BPF_MOV64_IMM(BPF_REG_2, 4),
11278549ddc8SAndrey Ignatov 
11288549ddc8SAndrey Ignatov 			/* arg3 (flags) */
11298549ddc8SAndrey Ignatov 			BPF_MOV64_IMM(BPF_REG_3, 0),
11308549ddc8SAndrey Ignatov 
11318549ddc8SAndrey Ignatov 			/* arg4 (res) */
11328549ddc8SAndrey Ignatov 			BPF_ALU64_IMM(BPF_ADD, BPF_REG_7, -8),
11338549ddc8SAndrey Ignatov 			BPF_STX_MEM(BPF_DW, BPF_REG_7, BPF_REG_0, 0),
11348549ddc8SAndrey Ignatov 			BPF_MOV64_REG(BPF_REG_4, BPF_REG_7),
11358549ddc8SAndrey Ignatov 
11368549ddc8SAndrey Ignatov 			BPF_EMIT_CALL(BPF_FUNC_strtoul),
11378549ddc8SAndrey Ignatov 
11388549ddc8SAndrey Ignatov 			/* if (ret == expected) */
11398549ddc8SAndrey Ignatov 			BPF_JMP_IMM(BPF_JNE, BPF_REG_0, -EINVAL, 2),
11408549ddc8SAndrey Ignatov 
11418549ddc8SAndrey Ignatov 			/* return ALLOW; */
11428549ddc8SAndrey Ignatov 			BPF_MOV64_IMM(BPF_REG_0, 1),
11438549ddc8SAndrey Ignatov 			BPF_JMP_A(1),
11448549ddc8SAndrey Ignatov 
11458549ddc8SAndrey Ignatov 			/* else return DENY; */
11468549ddc8SAndrey Ignatov 			BPF_MOV64_IMM(BPF_REG_0, 0),
11478549ddc8SAndrey Ignatov 			BPF_EXIT_INSN(),
11488549ddc8SAndrey Ignatov 		},
11498549ddc8SAndrey Ignatov 		.attach_type = BPF_CGROUP_SYSCTL,
11508549ddc8SAndrey Ignatov 		.sysctl = "net/ipv4/route/mtu_expires",
11518549ddc8SAndrey Ignatov 		.open_flags = O_RDONLY,
11528549ddc8SAndrey Ignatov 		.result = SUCCESS,
11538549ddc8SAndrey Ignatov 	},
11548549ddc8SAndrey Ignatov 	{
11558549ddc8SAndrey Ignatov 		"bpf_strtol negative number, ok",
11568549ddc8SAndrey Ignatov 		.insns = {
11578549ddc8SAndrey Ignatov 			/* arg1 (buf) */
11588549ddc8SAndrey Ignatov 			BPF_MOV64_REG(BPF_REG_7, BPF_REG_10),
11598549ddc8SAndrey Ignatov 			BPF_ALU64_IMM(BPF_ADD, BPF_REG_7, -8),
1160*3ec2a0edSIlya Leoshkevich 			/* " -6\0" */
1161*3ec2a0edSIlya Leoshkevich 			BPF_MOV64_IMM(BPF_REG_0,
1162*3ec2a0edSIlya Leoshkevich 				      bpf_ntohl(0x0a2d3600)),
1163*3ec2a0edSIlya Leoshkevich 			BPF_STX_MEM(BPF_W, BPF_REG_7, BPF_REG_0, 0),
11648549ddc8SAndrey Ignatov 
11658549ddc8SAndrey Ignatov 			BPF_MOV64_REG(BPF_REG_1, BPF_REG_7),
11668549ddc8SAndrey Ignatov 
11678549ddc8SAndrey Ignatov 			/* arg2 (buf_len) */
11688549ddc8SAndrey Ignatov 			BPF_MOV64_IMM(BPF_REG_2, 4),
11698549ddc8SAndrey Ignatov 
11708549ddc8SAndrey Ignatov 			/* arg3 (flags) */
11718549ddc8SAndrey Ignatov 			BPF_MOV64_IMM(BPF_REG_3, 10),
11728549ddc8SAndrey Ignatov 
11738549ddc8SAndrey Ignatov 			/* arg4 (res) */
11748549ddc8SAndrey Ignatov 			BPF_ALU64_IMM(BPF_ADD, BPF_REG_7, -8),
11758549ddc8SAndrey Ignatov 			BPF_STX_MEM(BPF_DW, BPF_REG_7, BPF_REG_0, 0),
11768549ddc8SAndrey Ignatov 			BPF_MOV64_REG(BPF_REG_4, BPF_REG_7),
11778549ddc8SAndrey Ignatov 
11788549ddc8SAndrey Ignatov 			BPF_EMIT_CALL(BPF_FUNC_strtol),
11798549ddc8SAndrey Ignatov 
11808549ddc8SAndrey Ignatov 			/* if (ret == expected && */
11818549ddc8SAndrey Ignatov 			BPF_JMP_IMM(BPF_JNE, BPF_REG_0, 3, 4),
11828549ddc8SAndrey Ignatov 			/*     res == expected) */
11838549ddc8SAndrey Ignatov 			BPF_LDX_MEM(BPF_DW, BPF_REG_9, BPF_REG_7, 0),
11848549ddc8SAndrey Ignatov 			BPF_JMP_IMM(BPF_JNE, BPF_REG_9, -6, 2),
11858549ddc8SAndrey Ignatov 
11868549ddc8SAndrey Ignatov 			/* return ALLOW; */
11878549ddc8SAndrey Ignatov 			BPF_MOV64_IMM(BPF_REG_0, 1),
11888549ddc8SAndrey Ignatov 			BPF_JMP_A(1),
11898549ddc8SAndrey Ignatov 
11908549ddc8SAndrey Ignatov 			/* else return DENY; */
11918549ddc8SAndrey Ignatov 			BPF_MOV64_IMM(BPF_REG_0, 0),
11928549ddc8SAndrey Ignatov 			BPF_EXIT_INSN(),
11938549ddc8SAndrey Ignatov 		},
11948549ddc8SAndrey Ignatov 		.attach_type = BPF_CGROUP_SYSCTL,
11958549ddc8SAndrey Ignatov 		.sysctl = "net/ipv4/route/mtu_expires",
11968549ddc8SAndrey Ignatov 		.open_flags = O_RDONLY,
11978549ddc8SAndrey Ignatov 		.result = SUCCESS,
11988549ddc8SAndrey Ignatov 	},
11998549ddc8SAndrey Ignatov 	{
12008549ddc8SAndrey Ignatov 		"bpf_strtol hex number, ok",
12018549ddc8SAndrey Ignatov 		.insns = {
12028549ddc8SAndrey Ignatov 			/* arg1 (buf) */
12038549ddc8SAndrey Ignatov 			BPF_MOV64_REG(BPF_REG_7, BPF_REG_10),
12048549ddc8SAndrey Ignatov 			BPF_ALU64_IMM(BPF_ADD, BPF_REG_7, -8),
1205*3ec2a0edSIlya Leoshkevich 			/* "0xfe" */
1206*3ec2a0edSIlya Leoshkevich 			BPF_MOV64_IMM(BPF_REG_0,
1207*3ec2a0edSIlya Leoshkevich 				      bpf_ntohl(0x30786665)),
1208*3ec2a0edSIlya Leoshkevich 			BPF_STX_MEM(BPF_W, BPF_REG_7, BPF_REG_0, 0),
12098549ddc8SAndrey Ignatov 
12108549ddc8SAndrey Ignatov 			BPF_MOV64_REG(BPF_REG_1, BPF_REG_7),
12118549ddc8SAndrey Ignatov 
12128549ddc8SAndrey Ignatov 			/* arg2 (buf_len) */
12138549ddc8SAndrey Ignatov 			BPF_MOV64_IMM(BPF_REG_2, 4),
12148549ddc8SAndrey Ignatov 
12158549ddc8SAndrey Ignatov 			/* arg3 (flags) */
12168549ddc8SAndrey Ignatov 			BPF_MOV64_IMM(BPF_REG_3, 0),
12178549ddc8SAndrey Ignatov 
12188549ddc8SAndrey Ignatov 			/* arg4 (res) */
12198549ddc8SAndrey Ignatov 			BPF_ALU64_IMM(BPF_ADD, BPF_REG_7, -8),
12208549ddc8SAndrey Ignatov 			BPF_STX_MEM(BPF_DW, BPF_REG_7, BPF_REG_0, 0),
12218549ddc8SAndrey Ignatov 			BPF_MOV64_REG(BPF_REG_4, BPF_REG_7),
12228549ddc8SAndrey Ignatov 
12238549ddc8SAndrey Ignatov 			BPF_EMIT_CALL(BPF_FUNC_strtol),
12248549ddc8SAndrey Ignatov 
12258549ddc8SAndrey Ignatov 			/* if (ret == expected && */
12268549ddc8SAndrey Ignatov 			BPF_JMP_IMM(BPF_JNE, BPF_REG_0, 4, 4),
12278549ddc8SAndrey Ignatov 			/*     res == expected) */
12288549ddc8SAndrey Ignatov 			BPF_LDX_MEM(BPF_DW, BPF_REG_9, BPF_REG_7, 0),
12298549ddc8SAndrey Ignatov 			BPF_JMP_IMM(BPF_JNE, BPF_REG_9, 254, 2),
12308549ddc8SAndrey Ignatov 
12318549ddc8SAndrey Ignatov 			/* return ALLOW; */
12328549ddc8SAndrey Ignatov 			BPF_MOV64_IMM(BPF_REG_0, 1),
12338549ddc8SAndrey Ignatov 			BPF_JMP_A(1),
12348549ddc8SAndrey Ignatov 
12358549ddc8SAndrey Ignatov 			/* else return DENY; */
12368549ddc8SAndrey Ignatov 			BPF_MOV64_IMM(BPF_REG_0, 0),
12378549ddc8SAndrey Ignatov 			BPF_EXIT_INSN(),
12388549ddc8SAndrey Ignatov 		},
12398549ddc8SAndrey Ignatov 		.attach_type = BPF_CGROUP_SYSCTL,
12408549ddc8SAndrey Ignatov 		.sysctl = "net/ipv4/route/mtu_expires",
12418549ddc8SAndrey Ignatov 		.open_flags = O_RDONLY,
12428549ddc8SAndrey Ignatov 		.result = SUCCESS,
12438549ddc8SAndrey Ignatov 	},
12448549ddc8SAndrey Ignatov 	{
12458549ddc8SAndrey Ignatov 		"bpf_strtol max long",
12468549ddc8SAndrey Ignatov 		.insns = {
12478549ddc8SAndrey Ignatov 			/* arg1 (buf) 9223372036854775807 */
12488549ddc8SAndrey Ignatov 			BPF_MOV64_REG(BPF_REG_7, BPF_REG_10),
12498549ddc8SAndrey Ignatov 			BPF_ALU64_IMM(BPF_ADD, BPF_REG_7, -24),
1250*3ec2a0edSIlya Leoshkevich 			BPF_LD_IMM64(BPF_REG_0,
1251*3ec2a0edSIlya Leoshkevich 				     bpf_be64_to_cpu(0x3932323333373230ULL)),
12528549ddc8SAndrey Ignatov 			BPF_STX_MEM(BPF_DW, BPF_REG_7, BPF_REG_0, 0),
1253*3ec2a0edSIlya Leoshkevich 			BPF_LD_IMM64(BPF_REG_0,
1254*3ec2a0edSIlya Leoshkevich 				     bpf_be64_to_cpu(0x3336383534373735ULL)),
12558549ddc8SAndrey Ignatov 			BPF_STX_MEM(BPF_DW, BPF_REG_7, BPF_REG_0, 8),
1256*3ec2a0edSIlya Leoshkevich 			BPF_LD_IMM64(BPF_REG_0,
1257*3ec2a0edSIlya Leoshkevich 				     bpf_be64_to_cpu(0x3830370000000000ULL)),
12588549ddc8SAndrey Ignatov 			BPF_STX_MEM(BPF_DW, BPF_REG_7, BPF_REG_0, 16),
12598549ddc8SAndrey Ignatov 
12608549ddc8SAndrey Ignatov 			BPF_MOV64_REG(BPF_REG_1, BPF_REG_7),
12618549ddc8SAndrey Ignatov 
12628549ddc8SAndrey Ignatov 			/* arg2 (buf_len) */
12638549ddc8SAndrey Ignatov 			BPF_MOV64_IMM(BPF_REG_2, 19),
12648549ddc8SAndrey Ignatov 
12658549ddc8SAndrey Ignatov 			/* arg3 (flags) */
12668549ddc8SAndrey Ignatov 			BPF_MOV64_IMM(BPF_REG_3, 0),
12678549ddc8SAndrey Ignatov 
12688549ddc8SAndrey Ignatov 			/* arg4 (res) */
12698549ddc8SAndrey Ignatov 			BPF_ALU64_IMM(BPF_ADD, BPF_REG_7, -8),
12708549ddc8SAndrey Ignatov 			BPF_STX_MEM(BPF_DW, BPF_REG_7, BPF_REG_0, 0),
12718549ddc8SAndrey Ignatov 			BPF_MOV64_REG(BPF_REG_4, BPF_REG_7),
12728549ddc8SAndrey Ignatov 
12738549ddc8SAndrey Ignatov 			BPF_EMIT_CALL(BPF_FUNC_strtol),
12748549ddc8SAndrey Ignatov 
12758549ddc8SAndrey Ignatov 			/* if (ret == expected && */
12768549ddc8SAndrey Ignatov 			BPF_JMP_IMM(BPF_JNE, BPF_REG_0, 19, 6),
12778549ddc8SAndrey Ignatov 			/*     res == expected) */
12788549ddc8SAndrey Ignatov 			BPF_LD_IMM64(BPF_REG_8, 0x7fffffffffffffffULL),
12798549ddc8SAndrey Ignatov 			BPF_LDX_MEM(BPF_DW, BPF_REG_9, BPF_REG_7, 0),
12808549ddc8SAndrey Ignatov 			BPF_JMP_REG(BPF_JNE, BPF_REG_8, BPF_REG_9, 2),
12818549ddc8SAndrey Ignatov 
12828549ddc8SAndrey Ignatov 			/* return ALLOW; */
12838549ddc8SAndrey Ignatov 			BPF_MOV64_IMM(BPF_REG_0, 1),
12848549ddc8SAndrey Ignatov 			BPF_JMP_A(1),
12858549ddc8SAndrey Ignatov 
12868549ddc8SAndrey Ignatov 			/* else return DENY; */
12878549ddc8SAndrey Ignatov 			BPF_MOV64_IMM(BPF_REG_0, 0),
12888549ddc8SAndrey Ignatov 			BPF_EXIT_INSN(),
12898549ddc8SAndrey Ignatov 		},
12908549ddc8SAndrey Ignatov 		.attach_type = BPF_CGROUP_SYSCTL,
12918549ddc8SAndrey Ignatov 		.sysctl = "net/ipv4/route/mtu_expires",
12928549ddc8SAndrey Ignatov 		.open_flags = O_RDONLY,
12938549ddc8SAndrey Ignatov 		.result = SUCCESS,
12948549ddc8SAndrey Ignatov 	},
12958549ddc8SAndrey Ignatov 	{
12968549ddc8SAndrey Ignatov 		"bpf_strtol overflow, ERANGE",
12978549ddc8SAndrey Ignatov 		.insns = {
12988549ddc8SAndrey Ignatov 			/* arg1 (buf) 9223372036854775808 */
12998549ddc8SAndrey Ignatov 			BPF_MOV64_REG(BPF_REG_7, BPF_REG_10),
13008549ddc8SAndrey Ignatov 			BPF_ALU64_IMM(BPF_ADD, BPF_REG_7, -24),
1301*3ec2a0edSIlya Leoshkevich 			BPF_LD_IMM64(BPF_REG_0,
1302*3ec2a0edSIlya Leoshkevich 				     bpf_be64_to_cpu(0x3932323333373230ULL)),
13038549ddc8SAndrey Ignatov 			BPF_STX_MEM(BPF_DW, BPF_REG_7, BPF_REG_0, 0),
1304*3ec2a0edSIlya Leoshkevich 			BPF_LD_IMM64(BPF_REG_0,
1305*3ec2a0edSIlya Leoshkevich 				     bpf_be64_to_cpu(0x3336383534373735ULL)),
13068549ddc8SAndrey Ignatov 			BPF_STX_MEM(BPF_DW, BPF_REG_7, BPF_REG_0, 8),
1307*3ec2a0edSIlya Leoshkevich 			BPF_LD_IMM64(BPF_REG_0,
1308*3ec2a0edSIlya Leoshkevich 				     bpf_be64_to_cpu(0x3830380000000000ULL)),
13098549ddc8SAndrey Ignatov 			BPF_STX_MEM(BPF_DW, BPF_REG_7, BPF_REG_0, 16),
13108549ddc8SAndrey Ignatov 
13118549ddc8SAndrey Ignatov 			BPF_MOV64_REG(BPF_REG_1, BPF_REG_7),
13128549ddc8SAndrey Ignatov 
13138549ddc8SAndrey Ignatov 			/* arg2 (buf_len) */
13148549ddc8SAndrey Ignatov 			BPF_MOV64_IMM(BPF_REG_2, 19),
13158549ddc8SAndrey Ignatov 
13168549ddc8SAndrey Ignatov 			/* arg3 (flags) */
13178549ddc8SAndrey Ignatov 			BPF_MOV64_IMM(BPF_REG_3, 0),
13188549ddc8SAndrey Ignatov 
13198549ddc8SAndrey Ignatov 			/* arg4 (res) */
13208549ddc8SAndrey Ignatov 			BPF_ALU64_IMM(BPF_ADD, BPF_REG_7, -8),
13218549ddc8SAndrey Ignatov 			BPF_STX_MEM(BPF_DW, BPF_REG_7, BPF_REG_0, 0),
13228549ddc8SAndrey Ignatov 			BPF_MOV64_REG(BPF_REG_4, BPF_REG_7),
13238549ddc8SAndrey Ignatov 
13248549ddc8SAndrey Ignatov 			BPF_EMIT_CALL(BPF_FUNC_strtol),
13258549ddc8SAndrey Ignatov 
13268549ddc8SAndrey Ignatov 			/* if (ret == expected) */
13278549ddc8SAndrey Ignatov 			BPF_JMP_IMM(BPF_JNE, BPF_REG_0, -ERANGE, 2),
13288549ddc8SAndrey Ignatov 
13298549ddc8SAndrey Ignatov 			/* return ALLOW; */
13308549ddc8SAndrey Ignatov 			BPF_MOV64_IMM(BPF_REG_0, 1),
13318549ddc8SAndrey Ignatov 			BPF_JMP_A(1),
13328549ddc8SAndrey Ignatov 
13338549ddc8SAndrey Ignatov 			/* else return DENY; */
13348549ddc8SAndrey Ignatov 			BPF_MOV64_IMM(BPF_REG_0, 0),
13358549ddc8SAndrey Ignatov 			BPF_EXIT_INSN(),
13368549ddc8SAndrey Ignatov 		},
13378549ddc8SAndrey Ignatov 		.attach_type = BPF_CGROUP_SYSCTL,
13388549ddc8SAndrey Ignatov 		.sysctl = "net/ipv4/route/mtu_expires",
13398549ddc8SAndrey Ignatov 		.open_flags = O_RDONLY,
13408549ddc8SAndrey Ignatov 		.result = SUCCESS,
13418549ddc8SAndrey Ignatov 	},
13427568f4cbSAndrey Ignatov 	{
13437568f4cbSAndrey Ignatov 		"C prog: deny all writes",
13447568f4cbSAndrey Ignatov 		.prog_file = "./test_sysctl_prog.o",
13457568f4cbSAndrey Ignatov 		.attach_type = BPF_CGROUP_SYSCTL,
13467568f4cbSAndrey Ignatov 		.sysctl = "net/ipv4/tcp_mem",
13477568f4cbSAndrey Ignatov 		.open_flags = O_WRONLY,
13487568f4cbSAndrey Ignatov 		.newval = "123 456 789",
13497568f4cbSAndrey Ignatov 		.result = OP_EPERM,
13507568f4cbSAndrey Ignatov 	},
13517568f4cbSAndrey Ignatov 	{
13527568f4cbSAndrey Ignatov 		"C prog: deny access by name",
13537568f4cbSAndrey Ignatov 		.prog_file = "./test_sysctl_prog.o",
13547568f4cbSAndrey Ignatov 		.attach_type = BPF_CGROUP_SYSCTL,
13557568f4cbSAndrey Ignatov 		.sysctl = "net/ipv4/route/mtu_expires",
13567568f4cbSAndrey Ignatov 		.open_flags = O_RDONLY,
13577568f4cbSAndrey Ignatov 		.result = OP_EPERM,
13587568f4cbSAndrey Ignatov 	},
13597568f4cbSAndrey Ignatov 	{
13607568f4cbSAndrey Ignatov 		"C prog: read tcp_mem",
13617568f4cbSAndrey Ignatov 		.prog_file = "./test_sysctl_prog.o",
13627568f4cbSAndrey Ignatov 		.attach_type = BPF_CGROUP_SYSCTL,
13637568f4cbSAndrey Ignatov 		.sysctl = "net/ipv4/tcp_mem",
13647568f4cbSAndrey Ignatov 		.open_flags = O_RDONLY,
13657568f4cbSAndrey Ignatov 		.result = SUCCESS,
13667568f4cbSAndrey Ignatov 	},
13671f5fa9abSAndrey Ignatov };
13681f5fa9abSAndrey Ignatov 
13691f5fa9abSAndrey Ignatov static size_t probe_prog_length(const struct bpf_insn *fp)
13701f5fa9abSAndrey Ignatov {
13711f5fa9abSAndrey Ignatov 	size_t len;
13721f5fa9abSAndrey Ignatov 
13731f5fa9abSAndrey Ignatov 	for (len = MAX_INSNS - 1; len > 0; --len)
13741f5fa9abSAndrey Ignatov 		if (fp[len].code != 0 || fp[len].imm != 0)
13751f5fa9abSAndrey Ignatov 			break;
13761f5fa9abSAndrey Ignatov 	return len + 1;
13771f5fa9abSAndrey Ignatov }
13781f5fa9abSAndrey Ignatov 
137911ff34f7SAndrey Ignatov static int fixup_sysctl_value(const char *buf, size_t buf_len,
138011ff34f7SAndrey Ignatov 			      struct bpf_insn *prog, size_t insn_num)
138111ff34f7SAndrey Ignatov {
1382*3ec2a0edSIlya Leoshkevich 	union {
1383*3ec2a0edSIlya Leoshkevich 		uint8_t raw[sizeof(uint64_t)];
1384*3ec2a0edSIlya Leoshkevich 		uint64_t num;
1385*3ec2a0edSIlya Leoshkevich 	} value = {};
138611ff34f7SAndrey Ignatov 	uint8_t c, i;
138711ff34f7SAndrey Ignatov 
1388*3ec2a0edSIlya Leoshkevich 	if (buf_len > sizeof(value)) {
138911ff34f7SAndrey Ignatov 		log_err("Value is too big (%zd) to use in fixup", buf_len);
139011ff34f7SAndrey Ignatov 		return -1;
139111ff34f7SAndrey Ignatov 	}
1392*3ec2a0edSIlya Leoshkevich 	if (prog[insn_num].code != (BPF_LD | BPF_DW | BPF_IMM)) {
1393*3ec2a0edSIlya Leoshkevich 		log_err("Can fixup only BPF_LD_IMM64 insns");
1394*3ec2a0edSIlya Leoshkevich 		return -1;
139511ff34f7SAndrey Ignatov 	}
139611ff34f7SAndrey Ignatov 
1397*3ec2a0edSIlya Leoshkevich 	memcpy(value.raw, buf, buf_len);
1398*3ec2a0edSIlya Leoshkevich 	prog[insn_num].imm = (uint32_t)value.num;
1399*3ec2a0edSIlya Leoshkevich 	prog[insn_num + 1].imm = (uint32_t)(value.num >> 32);
140011ff34f7SAndrey Ignatov 
140111ff34f7SAndrey Ignatov 	return 0;
140211ff34f7SAndrey Ignatov }
140311ff34f7SAndrey Ignatov 
14047568f4cbSAndrey Ignatov static int load_sysctl_prog_insns(struct sysctl_test *test,
14057568f4cbSAndrey Ignatov 				  const char *sysctl_path)
14061f5fa9abSAndrey Ignatov {
14071f5fa9abSAndrey Ignatov 	struct bpf_insn *prog = test->insns;
14081f5fa9abSAndrey Ignatov 	struct bpf_load_program_attr attr;
14091f5fa9abSAndrey Ignatov 	int ret;
14101f5fa9abSAndrey Ignatov 
14111f5fa9abSAndrey Ignatov 	memset(&attr, 0, sizeof(struct bpf_load_program_attr));
14121f5fa9abSAndrey Ignatov 	attr.prog_type = BPF_PROG_TYPE_CGROUP_SYSCTL;
14131f5fa9abSAndrey Ignatov 	attr.insns = prog;
14141f5fa9abSAndrey Ignatov 	attr.insns_cnt = probe_prog_length(attr.insns);
14151f5fa9abSAndrey Ignatov 	attr.license = "GPL";
14161f5fa9abSAndrey Ignatov 
141711ff34f7SAndrey Ignatov 	if (test->fixup_value_insn) {
141811ff34f7SAndrey Ignatov 		char buf[128];
141911ff34f7SAndrey Ignatov 		ssize_t len;
142011ff34f7SAndrey Ignatov 		int fd;
142111ff34f7SAndrey Ignatov 
142211ff34f7SAndrey Ignatov 		fd = open(sysctl_path, O_RDONLY | O_CLOEXEC);
142311ff34f7SAndrey Ignatov 		if (fd < 0) {
142411ff34f7SAndrey Ignatov 			log_err("open(%s) failed", sysctl_path);
142511ff34f7SAndrey Ignatov 			return -1;
142611ff34f7SAndrey Ignatov 		}
142711ff34f7SAndrey Ignatov 		len = read(fd, buf, sizeof(buf));
142811ff34f7SAndrey Ignatov 		if (len == -1) {
142911ff34f7SAndrey Ignatov 			log_err("read(%s) failed", sysctl_path);
143011ff34f7SAndrey Ignatov 			close(fd);
143111ff34f7SAndrey Ignatov 			return -1;
143211ff34f7SAndrey Ignatov 		}
143311ff34f7SAndrey Ignatov 		close(fd);
143411ff34f7SAndrey Ignatov 		if (fixup_sysctl_value(buf, len, prog, test->fixup_value_insn))
143511ff34f7SAndrey Ignatov 			return -1;
143611ff34f7SAndrey Ignatov 	}
143711ff34f7SAndrey Ignatov 
14381f5fa9abSAndrey Ignatov 	ret = bpf_load_program_xattr(&attr, bpf_log_buf, BPF_LOG_BUF_SIZE);
14391f5fa9abSAndrey Ignatov 	if (ret < 0 && test->result != LOAD_REJECT) {
14401f5fa9abSAndrey Ignatov 		log_err(">>> Loading program error.\n"
14411f5fa9abSAndrey Ignatov 			">>> Verifier output:\n%s\n-------\n", bpf_log_buf);
14421f5fa9abSAndrey Ignatov 	}
14431f5fa9abSAndrey Ignatov 
14441f5fa9abSAndrey Ignatov 	return ret;
14451f5fa9abSAndrey Ignatov }
14461f5fa9abSAndrey Ignatov 
14477568f4cbSAndrey Ignatov static int load_sysctl_prog_file(struct sysctl_test *test)
14487568f4cbSAndrey Ignatov {
14497568f4cbSAndrey Ignatov 	struct bpf_prog_load_attr attr;
14507568f4cbSAndrey Ignatov 	struct bpf_object *obj;
14517568f4cbSAndrey Ignatov 	int prog_fd;
14527568f4cbSAndrey Ignatov 
14537568f4cbSAndrey Ignatov 	memset(&attr, 0, sizeof(struct bpf_prog_load_attr));
14547568f4cbSAndrey Ignatov 	attr.file = test->prog_file;
14557568f4cbSAndrey Ignatov 	attr.prog_type = BPF_PROG_TYPE_CGROUP_SYSCTL;
14567568f4cbSAndrey Ignatov 
14577568f4cbSAndrey Ignatov 	if (bpf_prog_load_xattr(&attr, &obj, &prog_fd)) {
14587568f4cbSAndrey Ignatov 		if (test->result != LOAD_REJECT)
14597568f4cbSAndrey Ignatov 			log_err(">>> Loading program (%s) error.\n",
14607568f4cbSAndrey Ignatov 				test->prog_file);
14617568f4cbSAndrey Ignatov 		return -1;
14627568f4cbSAndrey Ignatov 	}
14637568f4cbSAndrey Ignatov 
14647568f4cbSAndrey Ignatov 	return prog_fd;
14657568f4cbSAndrey Ignatov }
14667568f4cbSAndrey Ignatov 
14677568f4cbSAndrey Ignatov static int load_sysctl_prog(struct sysctl_test *test, const char *sysctl_path)
14687568f4cbSAndrey Ignatov {
14697568f4cbSAndrey Ignatov 		return test->prog_file
14707568f4cbSAndrey Ignatov 			? load_sysctl_prog_file(test)
14717568f4cbSAndrey Ignatov 			: load_sysctl_prog_insns(test, sysctl_path);
14727568f4cbSAndrey Ignatov }
14737568f4cbSAndrey Ignatov 
14741f5fa9abSAndrey Ignatov static int access_sysctl(const char *sysctl_path,
14751f5fa9abSAndrey Ignatov 			 const struct sysctl_test *test)
14761f5fa9abSAndrey Ignatov {
14771f5fa9abSAndrey Ignatov 	int err = 0;
14781f5fa9abSAndrey Ignatov 	int fd;
14791f5fa9abSAndrey Ignatov 
14801f5fa9abSAndrey Ignatov 	fd = open(sysctl_path, test->open_flags | O_CLOEXEC);
14811f5fa9abSAndrey Ignatov 	if (fd < 0)
14821f5fa9abSAndrey Ignatov 		return fd;
14831f5fa9abSAndrey Ignatov 
14841f5fa9abSAndrey Ignatov 	if (test->open_flags == O_RDONLY) {
14851f5fa9abSAndrey Ignatov 		char buf[128];
14861f5fa9abSAndrey Ignatov 
14871f5fa9abSAndrey Ignatov 		if (read(fd, buf, sizeof(buf)) == -1)
14881f5fa9abSAndrey Ignatov 			goto err;
14899a1027e5SAndrey Ignatov 		if (test->oldval &&
14909a1027e5SAndrey Ignatov 		    strncmp(buf, test->oldval, strlen(test->oldval))) {
14919a1027e5SAndrey Ignatov 			log_err("Read value %s != %s", buf, test->oldval);
14929a1027e5SAndrey Ignatov 			goto err;
14939a1027e5SAndrey Ignatov 		}
14941f5fa9abSAndrey Ignatov 	} else if (test->open_flags == O_WRONLY) {
14951f5fa9abSAndrey Ignatov 		if (!test->newval) {
14961f5fa9abSAndrey Ignatov 			log_err("New value for sysctl is not set");
14971f5fa9abSAndrey Ignatov 			goto err;
14981f5fa9abSAndrey Ignatov 		}
14991f5fa9abSAndrey Ignatov 		if (write(fd, test->newval, strlen(test->newval)) == -1)
15001f5fa9abSAndrey Ignatov 			goto err;
15011f5fa9abSAndrey Ignatov 	} else {
15021f5fa9abSAndrey Ignatov 		log_err("Unexpected sysctl access: neither read nor write");
15031f5fa9abSAndrey Ignatov 		goto err;
15041f5fa9abSAndrey Ignatov 	}
15051f5fa9abSAndrey Ignatov 
15061f5fa9abSAndrey Ignatov 	goto out;
15071f5fa9abSAndrey Ignatov err:
15081f5fa9abSAndrey Ignatov 	err = -1;
15091f5fa9abSAndrey Ignatov out:
15101f5fa9abSAndrey Ignatov 	close(fd);
15111f5fa9abSAndrey Ignatov 	return err;
15121f5fa9abSAndrey Ignatov }
15131f5fa9abSAndrey Ignatov 
15141f5fa9abSAndrey Ignatov static int run_test_case(int cgfd, struct sysctl_test *test)
15151f5fa9abSAndrey Ignatov {
15161f5fa9abSAndrey Ignatov 	enum bpf_attach_type atype = test->attach_type;
15171f5fa9abSAndrey Ignatov 	char sysctl_path[128];
15181f5fa9abSAndrey Ignatov 	int progfd = -1;
15191f5fa9abSAndrey Ignatov 	int err = 0;
15201f5fa9abSAndrey Ignatov 
15211f5fa9abSAndrey Ignatov 	printf("Test case: %s .. ", test->descr);
15221f5fa9abSAndrey Ignatov 
15231f5fa9abSAndrey Ignatov 	snprintf(sysctl_path, sizeof(sysctl_path), "/proc/sys/%s",
15241f5fa9abSAndrey Ignatov 		 test->sysctl);
15251f5fa9abSAndrey Ignatov 
15261f5fa9abSAndrey Ignatov 	progfd = load_sysctl_prog(test, sysctl_path);
15271f5fa9abSAndrey Ignatov 	if (progfd < 0) {
15281f5fa9abSAndrey Ignatov 		if (test->result == LOAD_REJECT)
15291f5fa9abSAndrey Ignatov 			goto out;
15301f5fa9abSAndrey Ignatov 		else
15311f5fa9abSAndrey Ignatov 			goto err;
15321f5fa9abSAndrey Ignatov 	}
15331f5fa9abSAndrey Ignatov 
15341f5fa9abSAndrey Ignatov 	if (bpf_prog_attach(progfd, cgfd, atype, BPF_F_ALLOW_OVERRIDE) == -1) {
15351f5fa9abSAndrey Ignatov 		if (test->result == ATTACH_REJECT)
15361f5fa9abSAndrey Ignatov 			goto out;
15371f5fa9abSAndrey Ignatov 		else
15381f5fa9abSAndrey Ignatov 			goto err;
15391f5fa9abSAndrey Ignatov 	}
15401f5fa9abSAndrey Ignatov 
1541416c5728SIlya Leoshkevich 	errno = 0;
15421f5fa9abSAndrey Ignatov 	if (access_sysctl(sysctl_path, test) == -1) {
15431f5fa9abSAndrey Ignatov 		if (test->result == OP_EPERM && errno == EPERM)
15441f5fa9abSAndrey Ignatov 			goto out;
15451f5fa9abSAndrey Ignatov 		else
15461f5fa9abSAndrey Ignatov 			goto err;
15471f5fa9abSAndrey Ignatov 	}
15481f5fa9abSAndrey Ignatov 
15491f5fa9abSAndrey Ignatov 	if (test->result != SUCCESS) {
1550416c5728SIlya Leoshkevich 		log_err("Unexpected success");
15511f5fa9abSAndrey Ignatov 		goto err;
15521f5fa9abSAndrey Ignatov 	}
15531f5fa9abSAndrey Ignatov 
15541f5fa9abSAndrey Ignatov 	goto out;
15551f5fa9abSAndrey Ignatov err:
15561f5fa9abSAndrey Ignatov 	err = -1;
15571f5fa9abSAndrey Ignatov out:
15581f5fa9abSAndrey Ignatov 	/* Detaching w/o checking return code: best effort attempt. */
15591f5fa9abSAndrey Ignatov 	if (progfd != -1)
15601f5fa9abSAndrey Ignatov 		bpf_prog_detach(cgfd, atype);
15611f5fa9abSAndrey Ignatov 	close(progfd);
15621f5fa9abSAndrey Ignatov 	printf("[%s]\n", err ? "FAIL" : "PASS");
15631f5fa9abSAndrey Ignatov 	return err;
15641f5fa9abSAndrey Ignatov }
15651f5fa9abSAndrey Ignatov 
15661f5fa9abSAndrey Ignatov static int run_tests(int cgfd)
15671f5fa9abSAndrey Ignatov {
15681f5fa9abSAndrey Ignatov 	int passes = 0;
15691f5fa9abSAndrey Ignatov 	int fails = 0;
15701f5fa9abSAndrey Ignatov 	int i;
15711f5fa9abSAndrey Ignatov 
15721f5fa9abSAndrey Ignatov 	for (i = 0; i < ARRAY_SIZE(tests); ++i) {
15731f5fa9abSAndrey Ignatov 		if (run_test_case(cgfd, &tests[i]))
15741f5fa9abSAndrey Ignatov 			++fails;
15751f5fa9abSAndrey Ignatov 		else
15761f5fa9abSAndrey Ignatov 			++passes;
15771f5fa9abSAndrey Ignatov 	}
15781f5fa9abSAndrey Ignatov 	printf("Summary: %d PASSED, %d FAILED\n", passes, fails);
15791f5fa9abSAndrey Ignatov 	return fails ? -1 : 0;
15801f5fa9abSAndrey Ignatov }
15811f5fa9abSAndrey Ignatov 
15821f5fa9abSAndrey Ignatov int main(int argc, char **argv)
15831f5fa9abSAndrey Ignatov {
15841f5fa9abSAndrey Ignatov 	int cgfd = -1;
15851f5fa9abSAndrey Ignatov 	int err = 0;
15861f5fa9abSAndrey Ignatov 
15871f5fa9abSAndrey Ignatov 	if (setup_cgroup_environment())
15881f5fa9abSAndrey Ignatov 		goto err;
15891f5fa9abSAndrey Ignatov 
15901f5fa9abSAndrey Ignatov 	cgfd = create_and_get_cgroup(CG_PATH);
15911f5fa9abSAndrey Ignatov 	if (cgfd < 0)
15921f5fa9abSAndrey Ignatov 		goto err;
15931f5fa9abSAndrey Ignatov 
15941f5fa9abSAndrey Ignatov 	if (join_cgroup(CG_PATH))
15951f5fa9abSAndrey Ignatov 		goto err;
15961f5fa9abSAndrey Ignatov 
15971f5fa9abSAndrey Ignatov 	if (run_tests(cgfd))
15981f5fa9abSAndrey Ignatov 		goto err;
15991f5fa9abSAndrey Ignatov 
16001f5fa9abSAndrey Ignatov 	goto out;
16011f5fa9abSAndrey Ignatov err:
16021f5fa9abSAndrey Ignatov 	err = -1;
16031f5fa9abSAndrey Ignatov out:
16041f5fa9abSAndrey Ignatov 	close(cgfd);
16051f5fa9abSAndrey Ignatov 	cleanup_cgroup_environment();
16061f5fa9abSAndrey Ignatov 	return err;
16071f5fa9abSAndrey Ignatov }
1608