xref: /linux/tools/testing/selftests/bpf/test_sysctl.c (revision 4f2c0a4acffbec01079c28f839422e64ddeff004)
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 
163e689141SToke Høiland-Jørgensen #include <bpf/bpf_endian.h>
171f5fa9abSAndrey Ignatov #include "bpf_util.h"
181f5fa9abSAndrey Ignatov #include "cgroup_helpers.h"
19cbdb1461SAndrii Nakryiko #include "testing_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;
35d895a0f1SIlya Leoshkevich 	int seek;
361f5fa9abSAndrey Ignatov 	const char *newval;
379a1027e5SAndrey Ignatov 	const char *oldval;
381f5fa9abSAndrey Ignatov 	enum {
391f5fa9abSAndrey Ignatov 		LOAD_REJECT,
401f5fa9abSAndrey Ignatov 		ATTACH_REJECT,
411f5fa9abSAndrey Ignatov 		OP_EPERM,
421f5fa9abSAndrey Ignatov 		SUCCESS,
431f5fa9abSAndrey Ignatov 	} result;
441f5fa9abSAndrey Ignatov };
451f5fa9abSAndrey Ignatov 
461f5fa9abSAndrey Ignatov static struct sysctl_test tests[] = {
471f5fa9abSAndrey Ignatov 	{
481f5fa9abSAndrey Ignatov 		.descr = "sysctl wrong attach_type",
491f5fa9abSAndrey Ignatov 		.insns = {
501f5fa9abSAndrey Ignatov 			BPF_MOV64_IMM(BPF_REG_0, 1),
511f5fa9abSAndrey Ignatov 			BPF_EXIT_INSN(),
521f5fa9abSAndrey Ignatov 		},
531f5fa9abSAndrey Ignatov 		.attach_type = 0,
541f5fa9abSAndrey Ignatov 		.sysctl = "kernel/ostype",
551f5fa9abSAndrey Ignatov 		.open_flags = O_RDONLY,
561f5fa9abSAndrey Ignatov 		.result = ATTACH_REJECT,
571f5fa9abSAndrey Ignatov 	},
581f5fa9abSAndrey Ignatov 	{
591f5fa9abSAndrey Ignatov 		.descr = "sysctl:read allow all",
601f5fa9abSAndrey Ignatov 		.insns = {
611f5fa9abSAndrey Ignatov 			BPF_MOV64_IMM(BPF_REG_0, 1),
621f5fa9abSAndrey Ignatov 			BPF_EXIT_INSN(),
631f5fa9abSAndrey Ignatov 		},
641f5fa9abSAndrey Ignatov 		.attach_type = BPF_CGROUP_SYSCTL,
651f5fa9abSAndrey Ignatov 		.sysctl = "kernel/ostype",
661f5fa9abSAndrey Ignatov 		.open_flags = O_RDONLY,
671f5fa9abSAndrey Ignatov 		.result = SUCCESS,
681f5fa9abSAndrey Ignatov 	},
691f5fa9abSAndrey Ignatov 	{
701f5fa9abSAndrey Ignatov 		.descr = "sysctl:read deny all",
711f5fa9abSAndrey Ignatov 		.insns = {
721f5fa9abSAndrey Ignatov 			BPF_MOV64_IMM(BPF_REG_0, 0),
731f5fa9abSAndrey Ignatov 			BPF_EXIT_INSN(),
741f5fa9abSAndrey Ignatov 		},
751f5fa9abSAndrey Ignatov 		.attach_type = BPF_CGROUP_SYSCTL,
761f5fa9abSAndrey Ignatov 		.sysctl = "kernel/ostype",
771f5fa9abSAndrey Ignatov 		.open_flags = O_RDONLY,
781f5fa9abSAndrey Ignatov 		.result = OP_EPERM,
791f5fa9abSAndrey Ignatov 	},
801f5fa9abSAndrey Ignatov 	{
811f5fa9abSAndrey Ignatov 		.descr = "ctx:write sysctl:read read ok",
821f5fa9abSAndrey Ignatov 		.insns = {
831f5fa9abSAndrey Ignatov 			/* If (write) */
841f5fa9abSAndrey Ignatov 			BPF_LDX_MEM(BPF_W, BPF_REG_7, BPF_REG_1,
851f5fa9abSAndrey Ignatov 				    offsetof(struct bpf_sysctl, write)),
861f5fa9abSAndrey Ignatov 			BPF_JMP_IMM(BPF_JNE, BPF_REG_7, 1, 2),
871f5fa9abSAndrey Ignatov 
881f5fa9abSAndrey Ignatov 			/* return DENY; */
891f5fa9abSAndrey Ignatov 			BPF_MOV64_IMM(BPF_REG_0, 0),
901f5fa9abSAndrey Ignatov 			BPF_JMP_A(1),
911f5fa9abSAndrey Ignatov 
921f5fa9abSAndrey Ignatov 			/* else return ALLOW; */
931f5fa9abSAndrey Ignatov 			BPF_MOV64_IMM(BPF_REG_0, 1),
941f5fa9abSAndrey Ignatov 			BPF_EXIT_INSN(),
951f5fa9abSAndrey Ignatov 		},
961f5fa9abSAndrey Ignatov 		.attach_type = BPF_CGROUP_SYSCTL,
971f5fa9abSAndrey Ignatov 		.sysctl = "kernel/ostype",
981f5fa9abSAndrey Ignatov 		.open_flags = O_RDONLY,
991f5fa9abSAndrey Ignatov 		.result = SUCCESS,
1001f5fa9abSAndrey Ignatov 	},
1011f5fa9abSAndrey Ignatov 	{
1021f5fa9abSAndrey Ignatov 		.descr = "ctx:write sysctl:write read ok",
1031f5fa9abSAndrey Ignatov 		.insns = {
1041f5fa9abSAndrey Ignatov 			/* If (write) */
1053404ddf2SIlya Leoshkevich 			BPF_LDX_MEM(BPF_W, BPF_REG_7, BPF_REG_1,
1061f5fa9abSAndrey Ignatov 				    offsetof(struct bpf_sysctl, write)),
1071f5fa9abSAndrey Ignatov 			BPF_JMP_IMM(BPF_JNE, BPF_REG_7, 1, 2),
1081f5fa9abSAndrey Ignatov 
1091f5fa9abSAndrey Ignatov 			/* return DENY; */
1101f5fa9abSAndrey Ignatov 			BPF_MOV64_IMM(BPF_REG_0, 0),
1111f5fa9abSAndrey Ignatov 			BPF_JMP_A(1),
1121f5fa9abSAndrey Ignatov 
1131f5fa9abSAndrey Ignatov 			/* else return ALLOW; */
1141f5fa9abSAndrey Ignatov 			BPF_MOV64_IMM(BPF_REG_0, 1),
1151f5fa9abSAndrey Ignatov 			BPF_EXIT_INSN(),
1161f5fa9abSAndrey Ignatov 		},
1171f5fa9abSAndrey Ignatov 		.attach_type = BPF_CGROUP_SYSCTL,
1181f5fa9abSAndrey Ignatov 		.sysctl = "kernel/domainname",
1191f5fa9abSAndrey Ignatov 		.open_flags = O_WRONLY,
1201f5fa9abSAndrey Ignatov 		.newval = "(none)", /* same as default, should fail anyway */
1211f5fa9abSAndrey Ignatov 		.result = OP_EPERM,
1221f5fa9abSAndrey Ignatov 	},
1231f5fa9abSAndrey Ignatov 	{
1249ffccb76SIlya Leoshkevich 		.descr = "ctx:write sysctl:write read ok narrow",
1259ffccb76SIlya Leoshkevich 		.insns = {
1269ffccb76SIlya Leoshkevich 			/* u64 w = (u16)write & 1; */
12706fca841SIlya Leoshkevich #if __BYTE_ORDER__ == __ORDER_LITTLE_ENDIAN__
1289ffccb76SIlya Leoshkevich 			BPF_LDX_MEM(BPF_H, BPF_REG_7, BPF_REG_1,
1299ffccb76SIlya Leoshkevich 				    offsetof(struct bpf_sysctl, write)),
1309ffccb76SIlya Leoshkevich #else
1319ffccb76SIlya Leoshkevich 			BPF_LDX_MEM(BPF_H, BPF_REG_7, BPF_REG_1,
1329ffccb76SIlya Leoshkevich 				    offsetof(struct bpf_sysctl, write) + 2),
1339ffccb76SIlya Leoshkevich #endif
1349ffccb76SIlya Leoshkevich 			BPF_ALU64_IMM(BPF_AND, BPF_REG_7, 1),
1359ffccb76SIlya Leoshkevich 			/* return 1 - w; */
1369ffccb76SIlya Leoshkevich 			BPF_MOV64_IMM(BPF_REG_0, 1),
1379ffccb76SIlya Leoshkevich 			BPF_ALU64_REG(BPF_SUB, BPF_REG_0, BPF_REG_7),
1389ffccb76SIlya Leoshkevich 			BPF_EXIT_INSN(),
1399ffccb76SIlya Leoshkevich 		},
1409ffccb76SIlya Leoshkevich 		.attach_type = BPF_CGROUP_SYSCTL,
1419ffccb76SIlya Leoshkevich 		.sysctl = "kernel/domainname",
1429ffccb76SIlya Leoshkevich 		.open_flags = O_WRONLY,
1439ffccb76SIlya Leoshkevich 		.newval = "(none)", /* same as default, should fail anyway */
1449ffccb76SIlya Leoshkevich 		.result = OP_EPERM,
1459ffccb76SIlya Leoshkevich 	},
1469ffccb76SIlya Leoshkevich 	{
1471f5fa9abSAndrey Ignatov 		.descr = "ctx:write sysctl:read write reject",
1481f5fa9abSAndrey Ignatov 		.insns = {
1491f5fa9abSAndrey Ignatov 			/* write = X */
1501f5fa9abSAndrey Ignatov 			BPF_MOV64_IMM(BPF_REG_0, 0),
1511f5fa9abSAndrey Ignatov 			BPF_STX_MEM(BPF_W, BPF_REG_1, BPF_REG_0,
1521f5fa9abSAndrey Ignatov 				    offsetof(struct bpf_sysctl, write)),
1531f5fa9abSAndrey Ignatov 			BPF_MOV64_IMM(BPF_REG_0, 1),
1541f5fa9abSAndrey Ignatov 			BPF_EXIT_INSN(),
1551f5fa9abSAndrey Ignatov 		},
1561f5fa9abSAndrey Ignatov 		.attach_type = BPF_CGROUP_SYSCTL,
1571f5fa9abSAndrey Ignatov 		.sysctl = "kernel/ostype",
1581f5fa9abSAndrey Ignatov 		.open_flags = O_RDONLY,
1591f5fa9abSAndrey Ignatov 		.result = LOAD_REJECT,
1601f5fa9abSAndrey Ignatov 	},
1616041c67fSAndrey Ignatov 	{
1629a1027e5SAndrey Ignatov 		.descr = "ctx:file_pos sysctl:read read ok",
1639a1027e5SAndrey Ignatov 		.insns = {
1649a1027e5SAndrey Ignatov 			/* If (file_pos == X) */
1659a1027e5SAndrey Ignatov 			BPF_LDX_MEM(BPF_W, BPF_REG_7, BPF_REG_1,
1669a1027e5SAndrey Ignatov 				    offsetof(struct bpf_sysctl, file_pos)),
167d895a0f1SIlya Leoshkevich 			BPF_JMP_IMM(BPF_JNE, BPF_REG_7, 3, 2),
1689a1027e5SAndrey Ignatov 
1699a1027e5SAndrey Ignatov 			/* return ALLOW; */
1709a1027e5SAndrey Ignatov 			BPF_MOV64_IMM(BPF_REG_0, 1),
1719a1027e5SAndrey Ignatov 			BPF_JMP_A(1),
1729a1027e5SAndrey Ignatov 
1739a1027e5SAndrey Ignatov 			/* else return DENY; */
1749a1027e5SAndrey Ignatov 			BPF_MOV64_IMM(BPF_REG_0, 0),
1759a1027e5SAndrey Ignatov 			BPF_EXIT_INSN(),
1769a1027e5SAndrey Ignatov 		},
1779a1027e5SAndrey Ignatov 		.attach_type = BPF_CGROUP_SYSCTL,
1789a1027e5SAndrey Ignatov 		.sysctl = "kernel/ostype",
1799a1027e5SAndrey Ignatov 		.open_flags = O_RDONLY,
180d895a0f1SIlya Leoshkevich 		.seek = 3,
1819a1027e5SAndrey Ignatov 		.result = SUCCESS,
1829a1027e5SAndrey Ignatov 	},
1839a1027e5SAndrey Ignatov 	{
1849a1027e5SAndrey Ignatov 		.descr = "ctx:file_pos sysctl:read read ok narrow",
1859a1027e5SAndrey Ignatov 		.insns = {
1869a1027e5SAndrey Ignatov 			/* If (file_pos == X) */
18706fca841SIlya Leoshkevich #if __BYTE_ORDER__ == __ORDER_LITTLE_ENDIAN__
1889a1027e5SAndrey Ignatov 			BPF_LDX_MEM(BPF_B, BPF_REG_7, BPF_REG_1,
1899a1027e5SAndrey Ignatov 				    offsetof(struct bpf_sysctl, file_pos)),
1907541c87cSIlya Leoshkevich #else
1917541c87cSIlya Leoshkevich 			BPF_LDX_MEM(BPF_B, BPF_REG_7, BPF_REG_1,
1927541c87cSIlya Leoshkevich 				    offsetof(struct bpf_sysctl, file_pos) + 3),
1937541c87cSIlya Leoshkevich #endif
1947541c87cSIlya Leoshkevich 			BPF_JMP_IMM(BPF_JNE, BPF_REG_7, 4, 2),
1959a1027e5SAndrey Ignatov 
1969a1027e5SAndrey Ignatov 			/* return ALLOW; */
1979a1027e5SAndrey Ignatov 			BPF_MOV64_IMM(BPF_REG_0, 1),
1989a1027e5SAndrey Ignatov 			BPF_JMP_A(1),
1999a1027e5SAndrey Ignatov 
2009a1027e5SAndrey Ignatov 			/* else return DENY; */
2019a1027e5SAndrey Ignatov 			BPF_MOV64_IMM(BPF_REG_0, 0),
2029a1027e5SAndrey Ignatov 			BPF_EXIT_INSN(),
2039a1027e5SAndrey Ignatov 		},
2049a1027e5SAndrey Ignatov 		.attach_type = BPF_CGROUP_SYSCTL,
2059a1027e5SAndrey Ignatov 		.sysctl = "kernel/ostype",
2069a1027e5SAndrey Ignatov 		.open_flags = O_RDONLY,
2077541c87cSIlya Leoshkevich 		.seek = 4,
2089a1027e5SAndrey Ignatov 		.result = SUCCESS,
2099a1027e5SAndrey Ignatov 	},
2109a1027e5SAndrey Ignatov 	{
2119a1027e5SAndrey Ignatov 		.descr = "ctx:file_pos sysctl:read write ok",
2129a1027e5SAndrey Ignatov 		.insns = {
2139a1027e5SAndrey Ignatov 			/* file_pos = X */
2149a1027e5SAndrey Ignatov 			BPF_MOV64_IMM(BPF_REG_0, 2),
2159a1027e5SAndrey Ignatov 			BPF_STX_MEM(BPF_W, BPF_REG_1, BPF_REG_0,
2169a1027e5SAndrey Ignatov 				    offsetof(struct bpf_sysctl, file_pos)),
2179a1027e5SAndrey Ignatov 			BPF_MOV64_IMM(BPF_REG_0, 1),
2189a1027e5SAndrey Ignatov 			BPF_EXIT_INSN(),
2199a1027e5SAndrey Ignatov 		},
2209a1027e5SAndrey Ignatov 		.attach_type = BPF_CGROUP_SYSCTL,
2219a1027e5SAndrey Ignatov 		.sysctl = "kernel/ostype",
2229a1027e5SAndrey Ignatov 		.open_flags = O_RDONLY,
2239a1027e5SAndrey Ignatov 		.oldval = "nux\n",
2249a1027e5SAndrey Ignatov 		.result = SUCCESS,
2259a1027e5SAndrey Ignatov 	},
2269a1027e5SAndrey Ignatov 	{
2276041c67fSAndrey Ignatov 		.descr = "sysctl_get_name sysctl_value:base ok",
2286041c67fSAndrey Ignatov 		.insns = {
2296041c67fSAndrey Ignatov 			/* sysctl_get_name arg2 (buf) */
2306041c67fSAndrey Ignatov 			BPF_MOV64_REG(BPF_REG_7, BPF_REG_10),
2316041c67fSAndrey Ignatov 			BPF_ALU64_IMM(BPF_ADD, BPF_REG_7, -8),
2326041c67fSAndrey Ignatov 			BPF_MOV64_IMM(BPF_REG_0, 0),
2336041c67fSAndrey Ignatov 			BPF_STX_MEM(BPF_DW, BPF_REG_7, BPF_REG_0, 0),
2346041c67fSAndrey Ignatov 
2356041c67fSAndrey Ignatov 			BPF_MOV64_REG(BPF_REG_2, BPF_REG_7),
2366041c67fSAndrey Ignatov 
2376041c67fSAndrey Ignatov 			/* sysctl_get_name arg3 (buf_len) */
2386041c67fSAndrey Ignatov 			BPF_MOV64_IMM(BPF_REG_3, 8),
2396041c67fSAndrey Ignatov 
2406041c67fSAndrey Ignatov 			/* sysctl_get_name arg4 (flags) */
2416041c67fSAndrey Ignatov 			BPF_MOV64_IMM(BPF_REG_4, BPF_F_SYSCTL_BASE_NAME),
2426041c67fSAndrey Ignatov 
2436041c67fSAndrey Ignatov 			/* sysctl_get_name(ctx, buf, buf_len, flags) */
2446041c67fSAndrey Ignatov 			BPF_EMIT_CALL(BPF_FUNC_sysctl_get_name),
2456041c67fSAndrey Ignatov 
2466041c67fSAndrey Ignatov 			/* if (ret == expected && */
2476041c67fSAndrey Ignatov 			BPF_JMP_IMM(BPF_JNE, BPF_REG_0, sizeof("tcp_mem") - 1, 6),
2486041c67fSAndrey Ignatov 			/*     buf == "tcp_mem\0") */
2493ec2a0edSIlya Leoshkevich 			BPF_LD_IMM64(BPF_REG_8,
2503ec2a0edSIlya Leoshkevich 				     bpf_be64_to_cpu(0x7463705f6d656d00ULL)),
2516041c67fSAndrey Ignatov 			BPF_LDX_MEM(BPF_DW, BPF_REG_9, BPF_REG_7, 0),
2526041c67fSAndrey Ignatov 			BPF_JMP_REG(BPF_JNE, BPF_REG_8, BPF_REG_9, 2),
2536041c67fSAndrey Ignatov 
2546041c67fSAndrey Ignatov 			/* return ALLOW; */
2556041c67fSAndrey Ignatov 			BPF_MOV64_IMM(BPF_REG_0, 1),
2566041c67fSAndrey Ignatov 			BPF_JMP_A(1),
2576041c67fSAndrey Ignatov 
2586041c67fSAndrey Ignatov 			/* else return DENY; */
2596041c67fSAndrey Ignatov 			BPF_MOV64_IMM(BPF_REG_0, 0),
2606041c67fSAndrey Ignatov 			BPF_EXIT_INSN(),
2616041c67fSAndrey Ignatov 		},
2626041c67fSAndrey Ignatov 		.attach_type = BPF_CGROUP_SYSCTL,
2636041c67fSAndrey Ignatov 		.sysctl = "net/ipv4/tcp_mem",
2646041c67fSAndrey Ignatov 		.open_flags = O_RDONLY,
2656041c67fSAndrey Ignatov 		.result = SUCCESS,
2666041c67fSAndrey Ignatov 	},
2676041c67fSAndrey Ignatov 	{
2686041c67fSAndrey Ignatov 		.descr = "sysctl_get_name sysctl_value:base E2BIG truncated",
2696041c67fSAndrey Ignatov 		.insns = {
2706041c67fSAndrey Ignatov 			/* sysctl_get_name arg2 (buf) */
2716041c67fSAndrey Ignatov 			BPF_MOV64_REG(BPF_REG_7, BPF_REG_10),
2726041c67fSAndrey Ignatov 			BPF_ALU64_IMM(BPF_ADD, BPF_REG_7, -8),
2736041c67fSAndrey Ignatov 			BPF_MOV64_IMM(BPF_REG_0, 0),
2746041c67fSAndrey Ignatov 			BPF_STX_MEM(BPF_DW, BPF_REG_7, BPF_REG_0, 0),
2756041c67fSAndrey Ignatov 
2766041c67fSAndrey Ignatov 			BPF_MOV64_REG(BPF_REG_2, BPF_REG_7),
2776041c67fSAndrey Ignatov 
2786041c67fSAndrey Ignatov 			/* sysctl_get_name arg3 (buf_len) too small */
2796041c67fSAndrey Ignatov 			BPF_MOV64_IMM(BPF_REG_3, 7),
2806041c67fSAndrey Ignatov 
2816041c67fSAndrey Ignatov 			/* sysctl_get_name arg4 (flags) */
2826041c67fSAndrey Ignatov 			BPF_MOV64_IMM(BPF_REG_4, BPF_F_SYSCTL_BASE_NAME),
2836041c67fSAndrey Ignatov 
2846041c67fSAndrey Ignatov 			/* sysctl_get_name(ctx, buf, buf_len, flags) */
2856041c67fSAndrey Ignatov 			BPF_EMIT_CALL(BPF_FUNC_sysctl_get_name),
2866041c67fSAndrey Ignatov 
2876041c67fSAndrey Ignatov 			/* if (ret == expected && */
2886041c67fSAndrey Ignatov 			BPF_JMP_IMM(BPF_JNE, BPF_REG_0, -E2BIG, 6),
2896041c67fSAndrey Ignatov 
2906041c67fSAndrey Ignatov 			/*     buf[0:7] == "tcp_me\0") */
2913ec2a0edSIlya Leoshkevich 			BPF_LD_IMM64(BPF_REG_8,
2923ec2a0edSIlya Leoshkevich 				     bpf_be64_to_cpu(0x7463705f6d650000ULL)),
2936041c67fSAndrey Ignatov 			BPF_LDX_MEM(BPF_DW, BPF_REG_9, BPF_REG_7, 0),
2946041c67fSAndrey Ignatov 			BPF_JMP_REG(BPF_JNE, BPF_REG_8, BPF_REG_9, 2),
2956041c67fSAndrey Ignatov 
2966041c67fSAndrey Ignatov 			/* return ALLOW; */
2976041c67fSAndrey Ignatov 			BPF_MOV64_IMM(BPF_REG_0, 1),
2986041c67fSAndrey Ignatov 			BPF_JMP_A(1),
2996041c67fSAndrey Ignatov 
3006041c67fSAndrey Ignatov 			/* else return DENY; */
3016041c67fSAndrey Ignatov 			BPF_MOV64_IMM(BPF_REG_0, 0),
3026041c67fSAndrey Ignatov 			BPF_EXIT_INSN(),
3036041c67fSAndrey Ignatov 		},
3046041c67fSAndrey Ignatov 		.attach_type = BPF_CGROUP_SYSCTL,
3056041c67fSAndrey Ignatov 		.sysctl = "net/ipv4/tcp_mem",
3066041c67fSAndrey Ignatov 		.open_flags = O_RDONLY,
3076041c67fSAndrey Ignatov 		.result = SUCCESS,
3086041c67fSAndrey Ignatov 	},
3096041c67fSAndrey Ignatov 	{
3106041c67fSAndrey Ignatov 		.descr = "sysctl_get_name sysctl:full ok",
3116041c67fSAndrey Ignatov 		.insns = {
3126041c67fSAndrey Ignatov 			/* sysctl_get_name arg2 (buf) */
3136041c67fSAndrey Ignatov 			BPF_MOV64_REG(BPF_REG_7, BPF_REG_10),
3146041c67fSAndrey Ignatov 			BPF_ALU64_IMM(BPF_ADD, BPF_REG_7, -24),
3156041c67fSAndrey Ignatov 			BPF_MOV64_IMM(BPF_REG_0, 0),
3166041c67fSAndrey Ignatov 			BPF_STX_MEM(BPF_DW, BPF_REG_7, BPF_REG_0, 0),
3176041c67fSAndrey Ignatov 			BPF_STX_MEM(BPF_DW, BPF_REG_7, BPF_REG_0, 8),
3186041c67fSAndrey Ignatov 			BPF_STX_MEM(BPF_DW, BPF_REG_7, BPF_REG_0, 16),
3196041c67fSAndrey Ignatov 
3206041c67fSAndrey Ignatov 			BPF_MOV64_REG(BPF_REG_2, BPF_REG_7),
3216041c67fSAndrey Ignatov 
3226041c67fSAndrey Ignatov 			/* sysctl_get_name arg3 (buf_len) */
3236041c67fSAndrey Ignatov 			BPF_MOV64_IMM(BPF_REG_3, 17),
3246041c67fSAndrey Ignatov 
3256041c67fSAndrey Ignatov 			/* sysctl_get_name arg4 (flags) */
3266041c67fSAndrey Ignatov 			BPF_MOV64_IMM(BPF_REG_4, 0),
3276041c67fSAndrey Ignatov 
3286041c67fSAndrey Ignatov 			/* sysctl_get_name(ctx, buf, buf_len, flags) */
3296041c67fSAndrey Ignatov 			BPF_EMIT_CALL(BPF_FUNC_sysctl_get_name),
3306041c67fSAndrey Ignatov 
3316041c67fSAndrey Ignatov 			/* if (ret == expected && */
3326041c67fSAndrey Ignatov 			BPF_JMP_IMM(BPF_JNE, BPF_REG_0, 16, 14),
3336041c67fSAndrey Ignatov 
3346041c67fSAndrey Ignatov 			/*     buf[0:8] == "net/ipv4" && */
3353ec2a0edSIlya Leoshkevich 			BPF_LD_IMM64(BPF_REG_8,
3363ec2a0edSIlya Leoshkevich 				     bpf_be64_to_cpu(0x6e65742f69707634ULL)),
3376041c67fSAndrey Ignatov 			BPF_LDX_MEM(BPF_DW, BPF_REG_9, BPF_REG_7, 0),
3386041c67fSAndrey Ignatov 			BPF_JMP_REG(BPF_JNE, BPF_REG_8, BPF_REG_9, 10),
3396041c67fSAndrey Ignatov 
3406041c67fSAndrey Ignatov 			/*     buf[8:16] == "/tcp_mem" && */
3413ec2a0edSIlya Leoshkevich 			BPF_LD_IMM64(BPF_REG_8,
3423ec2a0edSIlya Leoshkevich 				     bpf_be64_to_cpu(0x2f7463705f6d656dULL)),
3436041c67fSAndrey Ignatov 			BPF_LDX_MEM(BPF_DW, BPF_REG_9, BPF_REG_7, 8),
3446041c67fSAndrey Ignatov 			BPF_JMP_REG(BPF_JNE, BPF_REG_8, BPF_REG_9, 6),
3456041c67fSAndrey Ignatov 
3466041c67fSAndrey Ignatov 			/*     buf[16:24] == "\0") */
3476041c67fSAndrey Ignatov 			BPF_LD_IMM64(BPF_REG_8, 0x0ULL),
3486041c67fSAndrey Ignatov 			BPF_LDX_MEM(BPF_DW, BPF_REG_9, BPF_REG_7, 16),
3496041c67fSAndrey Ignatov 			BPF_JMP_REG(BPF_JNE, BPF_REG_8, BPF_REG_9, 2),
3506041c67fSAndrey Ignatov 
3516041c67fSAndrey Ignatov 			/* return ALLOW; */
3526041c67fSAndrey Ignatov 			BPF_MOV64_IMM(BPF_REG_0, 1),
3536041c67fSAndrey Ignatov 			BPF_JMP_A(1),
3546041c67fSAndrey Ignatov 
3556041c67fSAndrey Ignatov 			/* else return DENY; */
3566041c67fSAndrey Ignatov 			BPF_MOV64_IMM(BPF_REG_0, 0),
3576041c67fSAndrey Ignatov 			BPF_EXIT_INSN(),
3586041c67fSAndrey Ignatov 		},
3596041c67fSAndrey Ignatov 		.attach_type = BPF_CGROUP_SYSCTL,
3606041c67fSAndrey Ignatov 		.sysctl = "net/ipv4/tcp_mem",
3616041c67fSAndrey Ignatov 		.open_flags = O_RDONLY,
3626041c67fSAndrey Ignatov 		.result = SUCCESS,
3636041c67fSAndrey Ignatov 	},
3646041c67fSAndrey Ignatov 	{
3656041c67fSAndrey Ignatov 		.descr = "sysctl_get_name sysctl:full E2BIG truncated",
3666041c67fSAndrey Ignatov 		.insns = {
3676041c67fSAndrey Ignatov 			/* sysctl_get_name arg2 (buf) */
3686041c67fSAndrey Ignatov 			BPF_MOV64_REG(BPF_REG_7, BPF_REG_10),
3696041c67fSAndrey Ignatov 			BPF_ALU64_IMM(BPF_ADD, BPF_REG_7, -16),
3706041c67fSAndrey Ignatov 			BPF_MOV64_IMM(BPF_REG_0, 0),
3716041c67fSAndrey Ignatov 			BPF_STX_MEM(BPF_DW, BPF_REG_7, BPF_REG_0, 0),
3726041c67fSAndrey Ignatov 			BPF_STX_MEM(BPF_DW, BPF_REG_7, BPF_REG_0, 8),
3736041c67fSAndrey Ignatov 
3746041c67fSAndrey Ignatov 			BPF_MOV64_REG(BPF_REG_2, BPF_REG_7),
3756041c67fSAndrey Ignatov 
3766041c67fSAndrey Ignatov 			/* sysctl_get_name arg3 (buf_len) */
3776041c67fSAndrey Ignatov 			BPF_MOV64_IMM(BPF_REG_3, 16),
3786041c67fSAndrey Ignatov 
3796041c67fSAndrey Ignatov 			/* sysctl_get_name arg4 (flags) */
3806041c67fSAndrey Ignatov 			BPF_MOV64_IMM(BPF_REG_4, 0),
3816041c67fSAndrey Ignatov 
3826041c67fSAndrey Ignatov 			/* sysctl_get_name(ctx, buf, buf_len, flags) */
3836041c67fSAndrey Ignatov 			BPF_EMIT_CALL(BPF_FUNC_sysctl_get_name),
3846041c67fSAndrey Ignatov 
3856041c67fSAndrey Ignatov 			/* if (ret == expected && */
3866041c67fSAndrey Ignatov 			BPF_JMP_IMM(BPF_JNE, BPF_REG_0, -E2BIG, 10),
3876041c67fSAndrey Ignatov 
3886041c67fSAndrey Ignatov 			/*     buf[0:8] == "net/ipv4" && */
3893ec2a0edSIlya Leoshkevich 			BPF_LD_IMM64(BPF_REG_8,
3903ec2a0edSIlya Leoshkevich 				     bpf_be64_to_cpu(0x6e65742f69707634ULL)),
3916041c67fSAndrey Ignatov 			BPF_LDX_MEM(BPF_DW, BPF_REG_9, BPF_REG_7, 0),
3926041c67fSAndrey Ignatov 			BPF_JMP_REG(BPF_JNE, BPF_REG_8, BPF_REG_9, 6),
3936041c67fSAndrey Ignatov 
3946041c67fSAndrey Ignatov 			/*     buf[8:16] == "/tcp_me\0") */
3953ec2a0edSIlya Leoshkevich 			BPF_LD_IMM64(BPF_REG_8,
3963ec2a0edSIlya Leoshkevich 				     bpf_be64_to_cpu(0x2f7463705f6d6500ULL)),
3976041c67fSAndrey Ignatov 			BPF_LDX_MEM(BPF_DW, BPF_REG_9, BPF_REG_7, 8),
3986041c67fSAndrey Ignatov 			BPF_JMP_REG(BPF_JNE, BPF_REG_8, BPF_REG_9, 2),
3996041c67fSAndrey Ignatov 
4006041c67fSAndrey Ignatov 			/* return ALLOW; */
4016041c67fSAndrey Ignatov 			BPF_MOV64_IMM(BPF_REG_0, 1),
4026041c67fSAndrey Ignatov 			BPF_JMP_A(1),
4036041c67fSAndrey Ignatov 
4046041c67fSAndrey Ignatov 			/* else return DENY; */
4056041c67fSAndrey Ignatov 			BPF_MOV64_IMM(BPF_REG_0, 0),
4066041c67fSAndrey Ignatov 			BPF_EXIT_INSN(),
4076041c67fSAndrey Ignatov 		},
4086041c67fSAndrey Ignatov 		.attach_type = BPF_CGROUP_SYSCTL,
4096041c67fSAndrey Ignatov 		.sysctl = "net/ipv4/tcp_mem",
4106041c67fSAndrey Ignatov 		.open_flags = O_RDONLY,
4116041c67fSAndrey Ignatov 		.result = SUCCESS,
4126041c67fSAndrey Ignatov 	},
4136041c67fSAndrey Ignatov 	{
4146041c67fSAndrey Ignatov 		.descr = "sysctl_get_name sysctl:full E2BIG truncated small",
4156041c67fSAndrey Ignatov 		.insns = {
4166041c67fSAndrey Ignatov 			/* sysctl_get_name arg2 (buf) */
4176041c67fSAndrey Ignatov 			BPF_MOV64_REG(BPF_REG_7, BPF_REG_10),
4186041c67fSAndrey Ignatov 			BPF_ALU64_IMM(BPF_ADD, BPF_REG_7, -8),
4196041c67fSAndrey Ignatov 			BPF_MOV64_IMM(BPF_REG_0, 0),
4206041c67fSAndrey Ignatov 			BPF_STX_MEM(BPF_DW, BPF_REG_7, BPF_REG_0, 0),
4216041c67fSAndrey Ignatov 
4226041c67fSAndrey Ignatov 			BPF_MOV64_REG(BPF_REG_2, BPF_REG_7),
4236041c67fSAndrey Ignatov 
4246041c67fSAndrey Ignatov 			/* sysctl_get_name arg3 (buf_len) */
4256041c67fSAndrey Ignatov 			BPF_MOV64_IMM(BPF_REG_3, 7),
4266041c67fSAndrey Ignatov 
4276041c67fSAndrey Ignatov 			/* sysctl_get_name arg4 (flags) */
4286041c67fSAndrey Ignatov 			BPF_MOV64_IMM(BPF_REG_4, 0),
4296041c67fSAndrey Ignatov 
4306041c67fSAndrey Ignatov 			/* sysctl_get_name(ctx, buf, buf_len, flags) */
4316041c67fSAndrey Ignatov 			BPF_EMIT_CALL(BPF_FUNC_sysctl_get_name),
4326041c67fSAndrey Ignatov 
4336041c67fSAndrey Ignatov 			/* if (ret == expected && */
4346041c67fSAndrey Ignatov 			BPF_JMP_IMM(BPF_JNE, BPF_REG_0, -E2BIG, 6),
4356041c67fSAndrey Ignatov 
4366041c67fSAndrey Ignatov 			/*     buf[0:8] == "net/ip\0") */
4373ec2a0edSIlya Leoshkevich 			BPF_LD_IMM64(BPF_REG_8,
4383ec2a0edSIlya Leoshkevich 				     bpf_be64_to_cpu(0x6e65742f69700000ULL)),
4396041c67fSAndrey Ignatov 			BPF_LDX_MEM(BPF_DW, BPF_REG_9, BPF_REG_7, 0),
4406041c67fSAndrey Ignatov 			BPF_JMP_REG(BPF_JNE, BPF_REG_8, BPF_REG_9, 2),
4416041c67fSAndrey Ignatov 
4426041c67fSAndrey Ignatov 			/* return ALLOW; */
4436041c67fSAndrey Ignatov 			BPF_MOV64_IMM(BPF_REG_0, 1),
4446041c67fSAndrey Ignatov 			BPF_JMP_A(1),
4456041c67fSAndrey Ignatov 
4466041c67fSAndrey Ignatov 			/* else return DENY; */
4476041c67fSAndrey Ignatov 			BPF_MOV64_IMM(BPF_REG_0, 0),
4486041c67fSAndrey Ignatov 			BPF_EXIT_INSN(),
4496041c67fSAndrey Ignatov 		},
4506041c67fSAndrey Ignatov 		.attach_type = BPF_CGROUP_SYSCTL,
4516041c67fSAndrey Ignatov 		.sysctl = "net/ipv4/tcp_mem",
4526041c67fSAndrey Ignatov 		.open_flags = O_RDONLY,
4536041c67fSAndrey Ignatov 		.result = SUCCESS,
4546041c67fSAndrey Ignatov 	},
45511ff34f7SAndrey Ignatov 	{
45611ff34f7SAndrey Ignatov 		.descr = "sysctl_get_current_value sysctl:read ok, gt",
45711ff34f7SAndrey Ignatov 		.insns = {
45811ff34f7SAndrey Ignatov 			/* sysctl_get_current_value arg2 (buf) */
45911ff34f7SAndrey Ignatov 			BPF_MOV64_REG(BPF_REG_7, BPF_REG_10),
46011ff34f7SAndrey Ignatov 			BPF_ALU64_IMM(BPF_ADD, BPF_REG_7, -8),
46111ff34f7SAndrey Ignatov 			BPF_MOV64_REG(BPF_REG_2, BPF_REG_7),
46211ff34f7SAndrey Ignatov 
46311ff34f7SAndrey Ignatov 			/* sysctl_get_current_value arg3 (buf_len) */
46411ff34f7SAndrey Ignatov 			BPF_MOV64_IMM(BPF_REG_3, 8),
46511ff34f7SAndrey Ignatov 
46611ff34f7SAndrey Ignatov 			/* sysctl_get_current_value(ctx, buf, buf_len) */
46711ff34f7SAndrey Ignatov 			BPF_EMIT_CALL(BPF_FUNC_sysctl_get_current_value),
46811ff34f7SAndrey Ignatov 
46911ff34f7SAndrey Ignatov 			/* if (ret == expected && */
47011ff34f7SAndrey Ignatov 			BPF_JMP_IMM(BPF_JNE, BPF_REG_0, 6, 6),
47111ff34f7SAndrey Ignatov 
47211ff34f7SAndrey Ignatov 			/*     buf[0:6] == "Linux\n\0") */
4733ec2a0edSIlya Leoshkevich 			BPF_LD_IMM64(BPF_REG_8,
4743ec2a0edSIlya Leoshkevich 				     bpf_be64_to_cpu(0x4c696e75780a0000ULL)),
47511ff34f7SAndrey Ignatov 			BPF_LDX_MEM(BPF_DW, BPF_REG_9, BPF_REG_7, 0),
47611ff34f7SAndrey Ignatov 			BPF_JMP_REG(BPF_JNE, BPF_REG_8, BPF_REG_9, 2),
47711ff34f7SAndrey Ignatov 
47811ff34f7SAndrey Ignatov 			/* return ALLOW; */
47911ff34f7SAndrey Ignatov 			BPF_MOV64_IMM(BPF_REG_0, 1),
48011ff34f7SAndrey Ignatov 			BPF_JMP_A(1),
48111ff34f7SAndrey Ignatov 
48211ff34f7SAndrey Ignatov 			/* else return DENY; */
48311ff34f7SAndrey Ignatov 			BPF_MOV64_IMM(BPF_REG_0, 0),
48411ff34f7SAndrey Ignatov 			BPF_EXIT_INSN(),
48511ff34f7SAndrey Ignatov 		},
48611ff34f7SAndrey Ignatov 		.attach_type = BPF_CGROUP_SYSCTL,
48711ff34f7SAndrey Ignatov 		.sysctl = "kernel/ostype",
48811ff34f7SAndrey Ignatov 		.open_flags = O_RDONLY,
48911ff34f7SAndrey Ignatov 		.result = SUCCESS,
49011ff34f7SAndrey Ignatov 	},
49111ff34f7SAndrey Ignatov 	{
49211ff34f7SAndrey Ignatov 		.descr = "sysctl_get_current_value sysctl:read ok, eq",
49311ff34f7SAndrey Ignatov 		.insns = {
49411ff34f7SAndrey Ignatov 			/* sysctl_get_current_value arg2 (buf) */
49511ff34f7SAndrey Ignatov 			BPF_MOV64_REG(BPF_REG_7, BPF_REG_10),
49611ff34f7SAndrey Ignatov 			BPF_ALU64_IMM(BPF_ADD, BPF_REG_7, -8),
49711ff34f7SAndrey Ignatov 			BPF_MOV64_IMM(BPF_REG_0, 0),
49811ff34f7SAndrey Ignatov 			BPF_STX_MEM(BPF_B, BPF_REG_7, BPF_REG_0, 7),
49911ff34f7SAndrey Ignatov 
50011ff34f7SAndrey Ignatov 			BPF_MOV64_REG(BPF_REG_2, BPF_REG_7),
50111ff34f7SAndrey Ignatov 
50211ff34f7SAndrey Ignatov 			/* sysctl_get_current_value arg3 (buf_len) */
50311ff34f7SAndrey Ignatov 			BPF_MOV64_IMM(BPF_REG_3, 7),
50411ff34f7SAndrey Ignatov 
50511ff34f7SAndrey Ignatov 			/* sysctl_get_current_value(ctx, buf, buf_len) */
50611ff34f7SAndrey Ignatov 			BPF_EMIT_CALL(BPF_FUNC_sysctl_get_current_value),
50711ff34f7SAndrey Ignatov 
50811ff34f7SAndrey Ignatov 			/* if (ret == expected && */
50911ff34f7SAndrey Ignatov 			BPF_JMP_IMM(BPF_JNE, BPF_REG_0, 6, 6),
51011ff34f7SAndrey Ignatov 
51111ff34f7SAndrey Ignatov 			/*     buf[0:6] == "Linux\n\0") */
5123ec2a0edSIlya Leoshkevich 			BPF_LD_IMM64(BPF_REG_8,
5133ec2a0edSIlya Leoshkevich 				     bpf_be64_to_cpu(0x4c696e75780a0000ULL)),
51411ff34f7SAndrey Ignatov 			BPF_LDX_MEM(BPF_DW, BPF_REG_9, BPF_REG_7, 0),
51511ff34f7SAndrey Ignatov 			BPF_JMP_REG(BPF_JNE, BPF_REG_8, BPF_REG_9, 2),
51611ff34f7SAndrey Ignatov 
51711ff34f7SAndrey Ignatov 			/* return ALLOW; */
51811ff34f7SAndrey Ignatov 			BPF_MOV64_IMM(BPF_REG_0, 1),
51911ff34f7SAndrey Ignatov 			BPF_JMP_A(1),
52011ff34f7SAndrey Ignatov 
52111ff34f7SAndrey Ignatov 			/* else return DENY; */
52211ff34f7SAndrey Ignatov 			BPF_MOV64_IMM(BPF_REG_0, 0),
52311ff34f7SAndrey Ignatov 			BPF_EXIT_INSN(),
52411ff34f7SAndrey Ignatov 		},
52511ff34f7SAndrey Ignatov 		.attach_type = BPF_CGROUP_SYSCTL,
52611ff34f7SAndrey Ignatov 		.sysctl = "kernel/ostype",
52711ff34f7SAndrey Ignatov 		.open_flags = O_RDONLY,
52811ff34f7SAndrey Ignatov 		.result = SUCCESS,
52911ff34f7SAndrey Ignatov 	},
53011ff34f7SAndrey Ignatov 	{
53111ff34f7SAndrey Ignatov 		.descr = "sysctl_get_current_value sysctl:read E2BIG truncated",
53211ff34f7SAndrey Ignatov 		.insns = {
53311ff34f7SAndrey Ignatov 			/* sysctl_get_current_value arg2 (buf) */
53411ff34f7SAndrey Ignatov 			BPF_MOV64_REG(BPF_REG_7, BPF_REG_10),
53511ff34f7SAndrey Ignatov 			BPF_ALU64_IMM(BPF_ADD, BPF_REG_7, -8),
53611ff34f7SAndrey Ignatov 			BPF_MOV64_IMM(BPF_REG_0, 0),
53711ff34f7SAndrey Ignatov 			BPF_STX_MEM(BPF_H, BPF_REG_7, BPF_REG_0, 6),
53811ff34f7SAndrey Ignatov 
53911ff34f7SAndrey Ignatov 			BPF_MOV64_REG(BPF_REG_2, BPF_REG_7),
54011ff34f7SAndrey Ignatov 
54111ff34f7SAndrey Ignatov 			/* sysctl_get_current_value arg3 (buf_len) */
54211ff34f7SAndrey Ignatov 			BPF_MOV64_IMM(BPF_REG_3, 6),
54311ff34f7SAndrey Ignatov 
54411ff34f7SAndrey Ignatov 			/* sysctl_get_current_value(ctx, buf, buf_len) */
54511ff34f7SAndrey Ignatov 			BPF_EMIT_CALL(BPF_FUNC_sysctl_get_current_value),
54611ff34f7SAndrey Ignatov 
54711ff34f7SAndrey Ignatov 			/* if (ret == expected && */
54811ff34f7SAndrey Ignatov 			BPF_JMP_IMM(BPF_JNE, BPF_REG_0, -E2BIG, 6),
54911ff34f7SAndrey Ignatov 
55011ff34f7SAndrey Ignatov 			/*     buf[0:6] == "Linux\0") */
5513ec2a0edSIlya Leoshkevich 			BPF_LD_IMM64(BPF_REG_8,
5523ec2a0edSIlya Leoshkevich 				     bpf_be64_to_cpu(0x4c696e7578000000ULL)),
55311ff34f7SAndrey Ignatov 			BPF_LDX_MEM(BPF_DW, BPF_REG_9, BPF_REG_7, 0),
55411ff34f7SAndrey Ignatov 			BPF_JMP_REG(BPF_JNE, BPF_REG_8, BPF_REG_9, 2),
55511ff34f7SAndrey Ignatov 
55611ff34f7SAndrey Ignatov 			/* return ALLOW; */
55711ff34f7SAndrey Ignatov 			BPF_MOV64_IMM(BPF_REG_0, 1),
55811ff34f7SAndrey Ignatov 			BPF_JMP_A(1),
55911ff34f7SAndrey Ignatov 
56011ff34f7SAndrey Ignatov 			/* else return DENY; */
56111ff34f7SAndrey Ignatov 			BPF_MOV64_IMM(BPF_REG_0, 0),
56211ff34f7SAndrey Ignatov 			BPF_EXIT_INSN(),
56311ff34f7SAndrey Ignatov 		},
56411ff34f7SAndrey Ignatov 		.attach_type = BPF_CGROUP_SYSCTL,
56511ff34f7SAndrey Ignatov 		.sysctl = "kernel/ostype",
56611ff34f7SAndrey Ignatov 		.open_flags = O_RDONLY,
56711ff34f7SAndrey Ignatov 		.result = SUCCESS,
56811ff34f7SAndrey Ignatov 	},
56911ff34f7SAndrey Ignatov 	{
57011ff34f7SAndrey Ignatov 		.descr = "sysctl_get_current_value sysctl:read EINVAL",
57111ff34f7SAndrey Ignatov 		.insns = {
57211ff34f7SAndrey Ignatov 			/* sysctl_get_current_value arg2 (buf) */
57311ff34f7SAndrey Ignatov 			BPF_MOV64_REG(BPF_REG_7, BPF_REG_10),
57411ff34f7SAndrey Ignatov 			BPF_ALU64_IMM(BPF_ADD, BPF_REG_7, -8),
57511ff34f7SAndrey Ignatov 
57611ff34f7SAndrey Ignatov 			BPF_MOV64_REG(BPF_REG_2, BPF_REG_7),
57711ff34f7SAndrey Ignatov 
57811ff34f7SAndrey Ignatov 			/* sysctl_get_current_value arg3 (buf_len) */
57911ff34f7SAndrey Ignatov 			BPF_MOV64_IMM(BPF_REG_3, 8),
58011ff34f7SAndrey Ignatov 
58111ff34f7SAndrey Ignatov 			/* sysctl_get_current_value(ctx, buf, buf_len) */
58211ff34f7SAndrey Ignatov 			BPF_EMIT_CALL(BPF_FUNC_sysctl_get_current_value),
58311ff34f7SAndrey Ignatov 
58411ff34f7SAndrey Ignatov 			/* if (ret == expected && */
58511ff34f7SAndrey Ignatov 			BPF_JMP_IMM(BPF_JNE, BPF_REG_0, -EINVAL, 4),
58611ff34f7SAndrey Ignatov 
58711ff34f7SAndrey Ignatov 			/*     buf[0:8] is NUL-filled) */
58811ff34f7SAndrey Ignatov 			BPF_LDX_MEM(BPF_DW, BPF_REG_9, BPF_REG_7, 0),
58911ff34f7SAndrey Ignatov 			BPF_JMP_IMM(BPF_JNE, BPF_REG_9, 0, 2),
59011ff34f7SAndrey Ignatov 
59111ff34f7SAndrey Ignatov 			/* return DENY; */
59211ff34f7SAndrey Ignatov 			BPF_MOV64_IMM(BPF_REG_0, 0),
59311ff34f7SAndrey Ignatov 			BPF_JMP_A(1),
59411ff34f7SAndrey Ignatov 
59511ff34f7SAndrey Ignatov 			/* else return ALLOW; */
59611ff34f7SAndrey Ignatov 			BPF_MOV64_IMM(BPF_REG_0, 1),
59711ff34f7SAndrey Ignatov 			BPF_EXIT_INSN(),
59811ff34f7SAndrey Ignatov 		},
59911ff34f7SAndrey Ignatov 		.attach_type = BPF_CGROUP_SYSCTL,
60011ff34f7SAndrey Ignatov 		.sysctl = "net/ipv6/conf/lo/stable_secret", /* -EIO */
60111ff34f7SAndrey Ignatov 		.open_flags = O_RDONLY,
60211ff34f7SAndrey Ignatov 		.result = OP_EPERM,
60311ff34f7SAndrey Ignatov 	},
60411ff34f7SAndrey Ignatov 	{
60511ff34f7SAndrey Ignatov 		.descr = "sysctl_get_current_value sysctl:write ok",
60611ff34f7SAndrey Ignatov 		.fixup_value_insn = 6,
60711ff34f7SAndrey Ignatov 		.insns = {
60811ff34f7SAndrey Ignatov 			/* sysctl_get_current_value arg2 (buf) */
60911ff34f7SAndrey Ignatov 			BPF_MOV64_REG(BPF_REG_7, BPF_REG_10),
61011ff34f7SAndrey Ignatov 			BPF_ALU64_IMM(BPF_ADD, BPF_REG_7, -8),
61111ff34f7SAndrey Ignatov 
61211ff34f7SAndrey Ignatov 			BPF_MOV64_REG(BPF_REG_2, BPF_REG_7),
61311ff34f7SAndrey Ignatov 
61411ff34f7SAndrey Ignatov 			/* sysctl_get_current_value arg3 (buf_len) */
61511ff34f7SAndrey Ignatov 			BPF_MOV64_IMM(BPF_REG_3, 8),
61611ff34f7SAndrey Ignatov 
61711ff34f7SAndrey Ignatov 			/* sysctl_get_current_value(ctx, buf, buf_len) */
61811ff34f7SAndrey Ignatov 			BPF_EMIT_CALL(BPF_FUNC_sysctl_get_current_value),
61911ff34f7SAndrey Ignatov 
62011ff34f7SAndrey Ignatov 			/* if (ret == expected && */
62111ff34f7SAndrey Ignatov 			BPF_JMP_IMM(BPF_JNE, BPF_REG_0, 4, 6),
62211ff34f7SAndrey Ignatov 
62311ff34f7SAndrey Ignatov 			/*     buf[0:4] == expected) */
62411ff34f7SAndrey Ignatov 			BPF_LD_IMM64(BPF_REG_8, FIXUP_SYSCTL_VALUE),
62511ff34f7SAndrey Ignatov 			BPF_LDX_MEM(BPF_DW, BPF_REG_9, BPF_REG_7, 0),
62611ff34f7SAndrey Ignatov 			BPF_JMP_REG(BPF_JNE, BPF_REG_8, BPF_REG_9, 2),
62711ff34f7SAndrey Ignatov 
62811ff34f7SAndrey Ignatov 			/* return DENY; */
62911ff34f7SAndrey Ignatov 			BPF_MOV64_IMM(BPF_REG_0, 0),
63011ff34f7SAndrey Ignatov 			BPF_JMP_A(1),
63111ff34f7SAndrey Ignatov 
63211ff34f7SAndrey Ignatov 			/* else return ALLOW; */
63311ff34f7SAndrey Ignatov 			BPF_MOV64_IMM(BPF_REG_0, 1),
63411ff34f7SAndrey Ignatov 			BPF_EXIT_INSN(),
63511ff34f7SAndrey Ignatov 		},
63611ff34f7SAndrey Ignatov 		.attach_type = BPF_CGROUP_SYSCTL,
63711ff34f7SAndrey Ignatov 		.sysctl = "net/ipv4/route/mtu_expires",
63811ff34f7SAndrey Ignatov 		.open_flags = O_WRONLY,
63911ff34f7SAndrey Ignatov 		.newval = "600", /* same as default, should fail anyway */
64011ff34f7SAndrey Ignatov 		.result = OP_EPERM,
64111ff34f7SAndrey Ignatov 	},
642786047ddSAndrey Ignatov 	{
643786047ddSAndrey Ignatov 		.descr = "sysctl_get_new_value sysctl:read EINVAL",
644786047ddSAndrey Ignatov 		.insns = {
645786047ddSAndrey Ignatov 			/* sysctl_get_new_value arg2 (buf) */
646786047ddSAndrey Ignatov 			BPF_MOV64_REG(BPF_REG_7, BPF_REG_10),
647786047ddSAndrey Ignatov 			BPF_ALU64_IMM(BPF_ADD, BPF_REG_7, -8),
648786047ddSAndrey Ignatov 			BPF_MOV64_IMM(BPF_REG_0, 0),
649786047ddSAndrey Ignatov 			BPF_STX_MEM(BPF_DW, BPF_REG_7, BPF_REG_0, 0),
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, 8),
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, -EINVAL, 2),
661786047ddSAndrey Ignatov 
662786047ddSAndrey Ignatov 			/* return ALLOW; */
663786047ddSAndrey Ignatov 			BPF_MOV64_IMM(BPF_REG_0, 1),
664786047ddSAndrey Ignatov 			BPF_JMP_A(1),
665786047ddSAndrey Ignatov 
666786047ddSAndrey Ignatov 			/* else return DENY; */
667786047ddSAndrey Ignatov 			BPF_MOV64_IMM(BPF_REG_0, 0),
668786047ddSAndrey Ignatov 			BPF_EXIT_INSN(),
669786047ddSAndrey Ignatov 		},
670786047ddSAndrey Ignatov 		.attach_type = BPF_CGROUP_SYSCTL,
671786047ddSAndrey Ignatov 		.sysctl = "net/ipv4/tcp_mem",
672786047ddSAndrey Ignatov 		.open_flags = O_RDONLY,
673786047ddSAndrey Ignatov 		.result = SUCCESS,
674786047ddSAndrey Ignatov 	},
675786047ddSAndrey Ignatov 	{
676786047ddSAndrey Ignatov 		.descr = "sysctl_get_new_value sysctl:write ok",
677786047ddSAndrey Ignatov 		.insns = {
678786047ddSAndrey Ignatov 			/* sysctl_get_new_value arg2 (buf) */
679786047ddSAndrey Ignatov 			BPF_MOV64_REG(BPF_REG_7, BPF_REG_10),
680786047ddSAndrey Ignatov 			BPF_ALU64_IMM(BPF_ADD, BPF_REG_7, -8),
681786047ddSAndrey Ignatov 
682786047ddSAndrey Ignatov 			BPF_MOV64_REG(BPF_REG_2, BPF_REG_7),
683786047ddSAndrey Ignatov 
684786047ddSAndrey Ignatov 			/* sysctl_get_new_value arg3 (buf_len) */
685786047ddSAndrey Ignatov 			BPF_MOV64_IMM(BPF_REG_3, 4),
686786047ddSAndrey Ignatov 
687786047ddSAndrey Ignatov 			/* sysctl_get_new_value(ctx, buf, buf_len) */
688786047ddSAndrey Ignatov 			BPF_EMIT_CALL(BPF_FUNC_sysctl_get_new_value),
689786047ddSAndrey Ignatov 
690786047ddSAndrey Ignatov 			/* if (ret == expected && */
691786047ddSAndrey Ignatov 			BPF_JMP_IMM(BPF_JNE, BPF_REG_0, 3, 4),
692786047ddSAndrey Ignatov 
693786047ddSAndrey Ignatov 			/*     buf[0:4] == "606\0") */
694786047ddSAndrey Ignatov 			BPF_LDX_MEM(BPF_W, BPF_REG_9, BPF_REG_7, 0),
6953ec2a0edSIlya Leoshkevich 			BPF_JMP_IMM(BPF_JNE, BPF_REG_9,
6963ec2a0edSIlya Leoshkevich 				    bpf_ntohl(0x36303600), 2),
697786047ddSAndrey Ignatov 
698786047ddSAndrey Ignatov 			/* return DENY; */
699786047ddSAndrey Ignatov 			BPF_MOV64_IMM(BPF_REG_0, 0),
700786047ddSAndrey Ignatov 			BPF_JMP_A(1),
701786047ddSAndrey Ignatov 
702786047ddSAndrey Ignatov 			/* else return ALLOW; */
703786047ddSAndrey Ignatov 			BPF_MOV64_IMM(BPF_REG_0, 1),
704786047ddSAndrey Ignatov 			BPF_EXIT_INSN(),
705786047ddSAndrey Ignatov 		},
706786047ddSAndrey Ignatov 		.attach_type = BPF_CGROUP_SYSCTL,
707786047ddSAndrey Ignatov 		.sysctl = "net/ipv4/route/mtu_expires",
708786047ddSAndrey Ignatov 		.open_flags = O_WRONLY,
709786047ddSAndrey Ignatov 		.newval = "606",
710786047ddSAndrey Ignatov 		.result = OP_EPERM,
711786047ddSAndrey Ignatov 	},
712786047ddSAndrey Ignatov 	{
713786047ddSAndrey Ignatov 		.descr = "sysctl_get_new_value sysctl:write ok long",
714786047ddSAndrey Ignatov 		.insns = {
715786047ddSAndrey Ignatov 			/* sysctl_get_new_value arg2 (buf) */
716786047ddSAndrey Ignatov 			BPF_MOV64_REG(BPF_REG_7, BPF_REG_10),
717786047ddSAndrey Ignatov 			BPF_ALU64_IMM(BPF_ADD, BPF_REG_7, -24),
718786047ddSAndrey Ignatov 
719786047ddSAndrey Ignatov 			BPF_MOV64_REG(BPF_REG_2, BPF_REG_7),
720786047ddSAndrey Ignatov 
721786047ddSAndrey Ignatov 			/* sysctl_get_new_value arg3 (buf_len) */
722786047ddSAndrey Ignatov 			BPF_MOV64_IMM(BPF_REG_3, 24),
723786047ddSAndrey Ignatov 
724786047ddSAndrey Ignatov 			/* sysctl_get_new_value(ctx, buf, buf_len) */
725786047ddSAndrey Ignatov 			BPF_EMIT_CALL(BPF_FUNC_sysctl_get_new_value),
726786047ddSAndrey Ignatov 
727786047ddSAndrey Ignatov 			/* if (ret == expected && */
728786047ddSAndrey Ignatov 			BPF_JMP_IMM(BPF_JNE, BPF_REG_0, 23, 14),
729786047ddSAndrey Ignatov 
730786047ddSAndrey Ignatov 			/*     buf[0:8] == "3000000 " && */
7313ec2a0edSIlya Leoshkevich 			BPF_LD_IMM64(BPF_REG_8,
7323ec2a0edSIlya Leoshkevich 				     bpf_be64_to_cpu(0x3330303030303020ULL)),
733786047ddSAndrey Ignatov 			BPF_LDX_MEM(BPF_DW, BPF_REG_9, BPF_REG_7, 0),
734786047ddSAndrey Ignatov 			BPF_JMP_REG(BPF_JNE, BPF_REG_8, BPF_REG_9, 10),
735786047ddSAndrey Ignatov 
736786047ddSAndrey Ignatov 			/*     buf[8:16] == "4000000 " && */
7373ec2a0edSIlya Leoshkevich 			BPF_LD_IMM64(BPF_REG_8,
7383ec2a0edSIlya Leoshkevich 				     bpf_be64_to_cpu(0x3430303030303020ULL)),
739786047ddSAndrey Ignatov 			BPF_LDX_MEM(BPF_DW, BPF_REG_9, BPF_REG_7, 8),
740786047ddSAndrey Ignatov 			BPF_JMP_REG(BPF_JNE, BPF_REG_8, BPF_REG_9, 6),
741786047ddSAndrey Ignatov 
742786047ddSAndrey Ignatov 			/*     buf[16:24] == "6000000\0") */
7433ec2a0edSIlya Leoshkevich 			BPF_LD_IMM64(BPF_REG_8,
7443ec2a0edSIlya Leoshkevich 				     bpf_be64_to_cpu(0x3630303030303000ULL)),
745786047ddSAndrey Ignatov 			BPF_LDX_MEM(BPF_DW, BPF_REG_9, BPF_REG_7, 16),
746786047ddSAndrey Ignatov 			BPF_JMP_REG(BPF_JNE, BPF_REG_8, BPF_REG_9, 2),
747786047ddSAndrey Ignatov 
748786047ddSAndrey Ignatov 			/* return DENY; */
749786047ddSAndrey Ignatov 			BPF_MOV64_IMM(BPF_REG_0, 0),
750786047ddSAndrey Ignatov 			BPF_JMP_A(1),
751786047ddSAndrey Ignatov 
752786047ddSAndrey Ignatov 			/* else return ALLOW; */
753786047ddSAndrey Ignatov 			BPF_MOV64_IMM(BPF_REG_0, 1),
754786047ddSAndrey Ignatov 			BPF_EXIT_INSN(),
755786047ddSAndrey Ignatov 		},
756786047ddSAndrey Ignatov 		.attach_type = BPF_CGROUP_SYSCTL,
757786047ddSAndrey Ignatov 		.sysctl = "net/ipv4/tcp_mem",
758786047ddSAndrey Ignatov 		.open_flags = O_WRONLY,
759786047ddSAndrey Ignatov 		.newval = "3000000 4000000 6000000",
760786047ddSAndrey Ignatov 		.result = OP_EPERM,
761786047ddSAndrey Ignatov 	},
762786047ddSAndrey Ignatov 	{
763786047ddSAndrey Ignatov 		.descr = "sysctl_get_new_value sysctl:write E2BIG",
764786047ddSAndrey Ignatov 		.insns = {
765786047ddSAndrey Ignatov 			/* sysctl_get_new_value arg2 (buf) */
766786047ddSAndrey Ignatov 			BPF_MOV64_REG(BPF_REG_7, BPF_REG_10),
767786047ddSAndrey Ignatov 			BPF_ALU64_IMM(BPF_ADD, BPF_REG_7, -8),
768786047ddSAndrey Ignatov 			BPF_MOV64_IMM(BPF_REG_0, 0),
769786047ddSAndrey Ignatov 			BPF_STX_MEM(BPF_B, BPF_REG_7, BPF_REG_0, 3),
770786047ddSAndrey Ignatov 
771786047ddSAndrey Ignatov 			BPF_MOV64_REG(BPF_REG_2, BPF_REG_7),
772786047ddSAndrey Ignatov 
773786047ddSAndrey Ignatov 			/* sysctl_get_new_value arg3 (buf_len) */
774786047ddSAndrey Ignatov 			BPF_MOV64_IMM(BPF_REG_3, 3),
775786047ddSAndrey Ignatov 
776786047ddSAndrey Ignatov 			/* sysctl_get_new_value(ctx, buf, buf_len) */
777786047ddSAndrey Ignatov 			BPF_EMIT_CALL(BPF_FUNC_sysctl_get_new_value),
778786047ddSAndrey Ignatov 
779786047ddSAndrey Ignatov 			/* if (ret == expected && */
780786047ddSAndrey Ignatov 			BPF_JMP_IMM(BPF_JNE, BPF_REG_0, -E2BIG, 4),
781786047ddSAndrey Ignatov 
782786047ddSAndrey Ignatov 			/*     buf[0:3] == "60\0") */
783786047ddSAndrey Ignatov 			BPF_LDX_MEM(BPF_W, BPF_REG_9, BPF_REG_7, 0),
7843ec2a0edSIlya Leoshkevich 			BPF_JMP_IMM(BPF_JNE, BPF_REG_9,
7853ec2a0edSIlya Leoshkevich 				    bpf_ntohl(0x36300000), 2),
786786047ddSAndrey Ignatov 
787786047ddSAndrey Ignatov 			/* return DENY; */
788786047ddSAndrey Ignatov 			BPF_MOV64_IMM(BPF_REG_0, 0),
789786047ddSAndrey Ignatov 			BPF_JMP_A(1),
790786047ddSAndrey Ignatov 
791786047ddSAndrey Ignatov 			/* else return ALLOW; */
792786047ddSAndrey Ignatov 			BPF_MOV64_IMM(BPF_REG_0, 1),
793786047ddSAndrey Ignatov 			BPF_EXIT_INSN(),
794786047ddSAndrey Ignatov 		},
795786047ddSAndrey Ignatov 		.attach_type = BPF_CGROUP_SYSCTL,
796786047ddSAndrey Ignatov 		.sysctl = "net/ipv4/route/mtu_expires",
797786047ddSAndrey Ignatov 		.open_flags = O_WRONLY,
798786047ddSAndrey Ignatov 		.newval = "606",
799786047ddSAndrey Ignatov 		.result = OP_EPERM,
800786047ddSAndrey Ignatov 	},
801786047ddSAndrey Ignatov 	{
802786047ddSAndrey Ignatov 		.descr = "sysctl_set_new_value sysctl:read EINVAL",
803786047ddSAndrey Ignatov 		.insns = {
804786047ddSAndrey Ignatov 			/* sysctl_set_new_value arg2 (buf) */
805786047ddSAndrey Ignatov 			BPF_MOV64_REG(BPF_REG_7, BPF_REG_10),
806786047ddSAndrey Ignatov 			BPF_ALU64_IMM(BPF_ADD, BPF_REG_7, -8),
8073ec2a0edSIlya Leoshkevich 			BPF_MOV64_IMM(BPF_REG_0,
8083ec2a0edSIlya Leoshkevich 				      bpf_ntohl(0x36303000)),
809786047ddSAndrey Ignatov 			BPF_STX_MEM(BPF_DW, BPF_REG_7, BPF_REG_0, 0),
810786047ddSAndrey Ignatov 
811786047ddSAndrey Ignatov 			BPF_MOV64_REG(BPF_REG_2, BPF_REG_7),
812786047ddSAndrey Ignatov 
813786047ddSAndrey Ignatov 			/* sysctl_set_new_value arg3 (buf_len) */
814786047ddSAndrey Ignatov 			BPF_MOV64_IMM(BPF_REG_3, 3),
815786047ddSAndrey Ignatov 
816786047ddSAndrey Ignatov 			/* sysctl_set_new_value(ctx, buf, buf_len) */
817786047ddSAndrey Ignatov 			BPF_EMIT_CALL(BPF_FUNC_sysctl_set_new_value),
818786047ddSAndrey Ignatov 
819786047ddSAndrey Ignatov 			/* if (ret == expected) */
820786047ddSAndrey Ignatov 			BPF_JMP_IMM(BPF_JNE, BPF_REG_0, -EINVAL, 2),
821786047ddSAndrey Ignatov 
822786047ddSAndrey Ignatov 			/* return ALLOW; */
823786047ddSAndrey Ignatov 			BPF_MOV64_IMM(BPF_REG_0, 1),
824786047ddSAndrey Ignatov 			BPF_JMP_A(1),
825786047ddSAndrey Ignatov 
826786047ddSAndrey Ignatov 			/* else return DENY; */
827786047ddSAndrey Ignatov 			BPF_MOV64_IMM(BPF_REG_0, 0),
828786047ddSAndrey Ignatov 			BPF_EXIT_INSN(),
829786047ddSAndrey Ignatov 		},
830786047ddSAndrey Ignatov 		.attach_type = BPF_CGROUP_SYSCTL,
831786047ddSAndrey Ignatov 		.sysctl = "net/ipv4/route/mtu_expires",
832786047ddSAndrey Ignatov 		.open_flags = O_RDONLY,
833786047ddSAndrey Ignatov 		.result = SUCCESS,
834786047ddSAndrey Ignatov 	},
835786047ddSAndrey Ignatov 	{
836786047ddSAndrey Ignatov 		.descr = "sysctl_set_new_value sysctl:write ok",
837786047ddSAndrey Ignatov 		.fixup_value_insn = 2,
838786047ddSAndrey Ignatov 		.insns = {
839786047ddSAndrey Ignatov 			/* sysctl_set_new_value arg2 (buf) */
840786047ddSAndrey Ignatov 			BPF_MOV64_REG(BPF_REG_7, BPF_REG_10),
841786047ddSAndrey Ignatov 			BPF_ALU64_IMM(BPF_ADD, BPF_REG_7, -8),
8423ec2a0edSIlya Leoshkevich 			BPF_LD_IMM64(BPF_REG_0, FIXUP_SYSCTL_VALUE),
843786047ddSAndrey Ignatov 			BPF_STX_MEM(BPF_DW, BPF_REG_7, BPF_REG_0, 0),
844786047ddSAndrey Ignatov 
845786047ddSAndrey Ignatov 			BPF_MOV64_REG(BPF_REG_2, BPF_REG_7),
846786047ddSAndrey Ignatov 
847786047ddSAndrey Ignatov 			/* sysctl_set_new_value arg3 (buf_len) */
848786047ddSAndrey Ignatov 			BPF_MOV64_IMM(BPF_REG_3, 3),
849786047ddSAndrey Ignatov 
850786047ddSAndrey Ignatov 			/* sysctl_set_new_value(ctx, buf, buf_len) */
851786047ddSAndrey Ignatov 			BPF_EMIT_CALL(BPF_FUNC_sysctl_set_new_value),
852786047ddSAndrey Ignatov 
853786047ddSAndrey Ignatov 			/* if (ret == expected) */
854786047ddSAndrey Ignatov 			BPF_JMP_IMM(BPF_JNE, BPF_REG_0, 0, 2),
855786047ddSAndrey Ignatov 
856786047ddSAndrey Ignatov 			/* return ALLOW; */
857786047ddSAndrey Ignatov 			BPF_MOV64_IMM(BPF_REG_0, 1),
858786047ddSAndrey Ignatov 			BPF_JMP_A(1),
859786047ddSAndrey Ignatov 
860786047ddSAndrey Ignatov 			/* else return DENY; */
861786047ddSAndrey Ignatov 			BPF_MOV64_IMM(BPF_REG_0, 0),
862786047ddSAndrey Ignatov 			BPF_EXIT_INSN(),
863786047ddSAndrey Ignatov 		},
864786047ddSAndrey Ignatov 		.attach_type = BPF_CGROUP_SYSCTL,
865786047ddSAndrey Ignatov 		.sysctl = "net/ipv4/route/mtu_expires",
866786047ddSAndrey Ignatov 		.open_flags = O_WRONLY,
867786047ddSAndrey Ignatov 		.newval = "606",
868786047ddSAndrey Ignatov 		.result = SUCCESS,
869786047ddSAndrey Ignatov 	},
8708549ddc8SAndrey Ignatov 	{
8718549ddc8SAndrey Ignatov 		"bpf_strtoul one number string",
8728549ddc8SAndrey Ignatov 		.insns = {
8738549ddc8SAndrey Ignatov 			/* arg1 (buf) */
8748549ddc8SAndrey Ignatov 			BPF_MOV64_REG(BPF_REG_7, BPF_REG_10),
8758549ddc8SAndrey Ignatov 			BPF_ALU64_IMM(BPF_ADD, BPF_REG_7, -8),
8763ec2a0edSIlya Leoshkevich 			BPF_MOV64_IMM(BPF_REG_0,
8773ec2a0edSIlya Leoshkevich 				      bpf_ntohl(0x36303000)),
8783ec2a0edSIlya Leoshkevich 			BPF_STX_MEM(BPF_W, BPF_REG_7, BPF_REG_0, 0),
8798549ddc8SAndrey Ignatov 
8808549ddc8SAndrey Ignatov 			BPF_MOV64_REG(BPF_REG_1, BPF_REG_7),
8818549ddc8SAndrey Ignatov 
8828549ddc8SAndrey Ignatov 			/* arg2 (buf_len) */
8838549ddc8SAndrey Ignatov 			BPF_MOV64_IMM(BPF_REG_2, 4),
8848549ddc8SAndrey Ignatov 
8858549ddc8SAndrey Ignatov 			/* arg3 (flags) */
8868549ddc8SAndrey Ignatov 			BPF_MOV64_IMM(BPF_REG_3, 0),
8878549ddc8SAndrey Ignatov 
8888549ddc8SAndrey Ignatov 			/* arg4 (res) */
8898549ddc8SAndrey Ignatov 			BPF_ALU64_IMM(BPF_ADD, BPF_REG_7, -8),
8908549ddc8SAndrey Ignatov 			BPF_STX_MEM(BPF_DW, BPF_REG_7, BPF_REG_0, 0),
8918549ddc8SAndrey Ignatov 			BPF_MOV64_REG(BPF_REG_4, BPF_REG_7),
8928549ddc8SAndrey Ignatov 
8938549ddc8SAndrey Ignatov 			BPF_EMIT_CALL(BPF_FUNC_strtoul),
8948549ddc8SAndrey Ignatov 
8958549ddc8SAndrey Ignatov 			/* if (ret == expected && */
8968549ddc8SAndrey Ignatov 			BPF_JMP_IMM(BPF_JNE, BPF_REG_0, 3, 4),
8978549ddc8SAndrey Ignatov 			/*     res == expected) */
8988549ddc8SAndrey Ignatov 			BPF_LDX_MEM(BPF_DW, BPF_REG_9, BPF_REG_7, 0),
8998549ddc8SAndrey Ignatov 			BPF_JMP_IMM(BPF_JNE, BPF_REG_9, 600, 2),
9008549ddc8SAndrey Ignatov 
9018549ddc8SAndrey Ignatov 			/* return ALLOW; */
9028549ddc8SAndrey Ignatov 			BPF_MOV64_IMM(BPF_REG_0, 1),
9038549ddc8SAndrey Ignatov 			BPF_JMP_A(1),
9048549ddc8SAndrey Ignatov 
9058549ddc8SAndrey Ignatov 			/* else return DENY; */
9068549ddc8SAndrey Ignatov 			BPF_MOV64_IMM(BPF_REG_0, 0),
9078549ddc8SAndrey Ignatov 			BPF_EXIT_INSN(),
9088549ddc8SAndrey Ignatov 		},
9098549ddc8SAndrey Ignatov 		.attach_type = BPF_CGROUP_SYSCTL,
9108549ddc8SAndrey Ignatov 		.sysctl = "net/ipv4/route/mtu_expires",
9118549ddc8SAndrey Ignatov 		.open_flags = O_RDONLY,
9128549ddc8SAndrey Ignatov 		.result = SUCCESS,
9138549ddc8SAndrey Ignatov 	},
9148549ddc8SAndrey Ignatov 	{
9158549ddc8SAndrey Ignatov 		"bpf_strtoul multi number string",
9168549ddc8SAndrey Ignatov 		.insns = {
9178549ddc8SAndrey Ignatov 			/* arg1 (buf) */
9188549ddc8SAndrey Ignatov 			BPF_MOV64_REG(BPF_REG_7, BPF_REG_10),
9198549ddc8SAndrey Ignatov 			BPF_ALU64_IMM(BPF_ADD, BPF_REG_7, -8),
9208549ddc8SAndrey Ignatov 			/* "600 602\0" */
9213ec2a0edSIlya Leoshkevich 			BPF_LD_IMM64(BPF_REG_0,
9223ec2a0edSIlya Leoshkevich 				     bpf_be64_to_cpu(0x3630302036303200ULL)),
9238549ddc8SAndrey Ignatov 			BPF_STX_MEM(BPF_DW, BPF_REG_7, BPF_REG_0, 0),
9248549ddc8SAndrey Ignatov 			BPF_MOV64_REG(BPF_REG_1, BPF_REG_7),
9258549ddc8SAndrey Ignatov 
9268549ddc8SAndrey Ignatov 			/* arg2 (buf_len) */
9278549ddc8SAndrey Ignatov 			BPF_MOV64_IMM(BPF_REG_2, 8),
9288549ddc8SAndrey Ignatov 
9298549ddc8SAndrey Ignatov 			/* arg3 (flags) */
9308549ddc8SAndrey Ignatov 			BPF_MOV64_IMM(BPF_REG_3, 0),
9318549ddc8SAndrey Ignatov 
9328549ddc8SAndrey Ignatov 			/* arg4 (res) */
9338549ddc8SAndrey Ignatov 			BPF_ALU64_IMM(BPF_ADD, BPF_REG_7, -8),
9348549ddc8SAndrey Ignatov 			BPF_STX_MEM(BPF_DW, BPF_REG_7, BPF_REG_0, 0),
9358549ddc8SAndrey Ignatov 			BPF_MOV64_REG(BPF_REG_4, BPF_REG_7),
9368549ddc8SAndrey Ignatov 
9378549ddc8SAndrey Ignatov 			BPF_EMIT_CALL(BPF_FUNC_strtoul),
9388549ddc8SAndrey Ignatov 
9398549ddc8SAndrey Ignatov 			/* if (ret == expected && */
9408549ddc8SAndrey Ignatov 			BPF_JMP_IMM(BPF_JNE, BPF_REG_0, 3, 18),
9418549ddc8SAndrey Ignatov 			/*     res == expected) */
9428549ddc8SAndrey Ignatov 			BPF_LDX_MEM(BPF_DW, BPF_REG_9, BPF_REG_7, 0),
9438549ddc8SAndrey Ignatov 			BPF_JMP_IMM(BPF_JNE, BPF_REG_9, 600, 16),
9448549ddc8SAndrey Ignatov 
9458549ddc8SAndrey Ignatov 			/*     arg1 (buf) */
9468549ddc8SAndrey Ignatov 			BPF_MOV64_REG(BPF_REG_7, BPF_REG_10),
9478549ddc8SAndrey Ignatov 			BPF_ALU64_IMM(BPF_ADD, BPF_REG_7, -8),
9488549ddc8SAndrey Ignatov 			BPF_ALU64_REG(BPF_ADD, BPF_REG_7, BPF_REG_0),
9498549ddc8SAndrey Ignatov 			BPF_MOV64_REG(BPF_REG_1, BPF_REG_7),
9508549ddc8SAndrey Ignatov 
9518549ddc8SAndrey Ignatov 			/*     arg2 (buf_len) */
9528549ddc8SAndrey Ignatov 			BPF_MOV64_IMM(BPF_REG_2, 8),
9538549ddc8SAndrey Ignatov 			BPF_ALU64_REG(BPF_SUB, BPF_REG_2, BPF_REG_0),
9548549ddc8SAndrey Ignatov 
9558549ddc8SAndrey Ignatov 			/*     arg3 (flags) */
9568549ddc8SAndrey Ignatov 			BPF_MOV64_IMM(BPF_REG_3, 0),
9578549ddc8SAndrey Ignatov 
9588549ddc8SAndrey Ignatov 			/*     arg4 (res) */
9598549ddc8SAndrey Ignatov 			BPF_MOV64_REG(BPF_REG_7, BPF_REG_10),
9608549ddc8SAndrey Ignatov 			BPF_ALU64_IMM(BPF_ADD, BPF_REG_7, -16),
9618549ddc8SAndrey Ignatov 			BPF_MOV64_REG(BPF_REG_4, BPF_REG_7),
9628549ddc8SAndrey Ignatov 
9638549ddc8SAndrey Ignatov 			BPF_EMIT_CALL(BPF_FUNC_strtoul),
9648549ddc8SAndrey Ignatov 
9658549ddc8SAndrey Ignatov 			/*     if (ret == expected && */
9668549ddc8SAndrey Ignatov 			BPF_JMP_IMM(BPF_JNE, BPF_REG_0, 4, 4),
9678549ddc8SAndrey Ignatov 			/*         res == expected) */
9688549ddc8SAndrey Ignatov 			BPF_LDX_MEM(BPF_DW, BPF_REG_9, BPF_REG_7, 0),
9698549ddc8SAndrey Ignatov 			BPF_JMP_IMM(BPF_JNE, BPF_REG_9, 602, 2),
9708549ddc8SAndrey Ignatov 
9718549ddc8SAndrey Ignatov 			/* return ALLOW; */
9728549ddc8SAndrey Ignatov 			BPF_MOV64_IMM(BPF_REG_0, 1),
9738549ddc8SAndrey Ignatov 			BPF_JMP_A(1),
9748549ddc8SAndrey Ignatov 
9758549ddc8SAndrey Ignatov 			/* else return DENY; */
9768549ddc8SAndrey Ignatov 			BPF_MOV64_IMM(BPF_REG_0, 0),
9778549ddc8SAndrey Ignatov 			BPF_EXIT_INSN(),
9788549ddc8SAndrey Ignatov 		},
9798549ddc8SAndrey Ignatov 		.attach_type = BPF_CGROUP_SYSCTL,
9808549ddc8SAndrey Ignatov 		.sysctl = "net/ipv4/tcp_mem",
9818549ddc8SAndrey Ignatov 		.open_flags = O_RDONLY,
9828549ddc8SAndrey Ignatov 		.result = SUCCESS,
9838549ddc8SAndrey Ignatov 	},
9848549ddc8SAndrey Ignatov 	{
9858549ddc8SAndrey Ignatov 		"bpf_strtoul buf_len = 0, reject",
9868549ddc8SAndrey Ignatov 		.insns = {
9878549ddc8SAndrey Ignatov 			/* arg1 (buf) */
9888549ddc8SAndrey Ignatov 			BPF_MOV64_REG(BPF_REG_7, BPF_REG_10),
9898549ddc8SAndrey Ignatov 			BPF_ALU64_IMM(BPF_ADD, BPF_REG_7, -8),
9903ec2a0edSIlya Leoshkevich 			BPF_MOV64_IMM(BPF_REG_0,
9913ec2a0edSIlya Leoshkevich 				      bpf_ntohl(0x36303000)),
9928549ddc8SAndrey Ignatov 			BPF_STX_MEM(BPF_DW, BPF_REG_7, BPF_REG_0, 0),
9938549ddc8SAndrey Ignatov 
9948549ddc8SAndrey Ignatov 			BPF_MOV64_REG(BPF_REG_1, BPF_REG_7),
9958549ddc8SAndrey Ignatov 
9968549ddc8SAndrey Ignatov 			/* arg2 (buf_len) */
9978549ddc8SAndrey Ignatov 			BPF_MOV64_IMM(BPF_REG_2, 0),
9988549ddc8SAndrey Ignatov 
9998549ddc8SAndrey Ignatov 			/* arg3 (flags) */
10008549ddc8SAndrey Ignatov 			BPF_MOV64_IMM(BPF_REG_3, 0),
10018549ddc8SAndrey Ignatov 
10028549ddc8SAndrey Ignatov 			/* arg4 (res) */
10038549ddc8SAndrey Ignatov 			BPF_ALU64_IMM(BPF_ADD, BPF_REG_7, -8),
10048549ddc8SAndrey Ignatov 			BPF_STX_MEM(BPF_DW, BPF_REG_7, BPF_REG_0, 0),
10058549ddc8SAndrey Ignatov 			BPF_MOV64_REG(BPF_REG_4, BPF_REG_7),
10068549ddc8SAndrey Ignatov 
10078549ddc8SAndrey Ignatov 			BPF_EMIT_CALL(BPF_FUNC_strtoul),
10088549ddc8SAndrey Ignatov 
10098549ddc8SAndrey Ignatov 			BPF_MOV64_IMM(BPF_REG_0, 1),
10108549ddc8SAndrey Ignatov 			BPF_EXIT_INSN(),
10118549ddc8SAndrey Ignatov 		},
10128549ddc8SAndrey Ignatov 		.attach_type = BPF_CGROUP_SYSCTL,
10138549ddc8SAndrey Ignatov 		.sysctl = "net/ipv4/route/mtu_expires",
10148549ddc8SAndrey Ignatov 		.open_flags = O_RDONLY,
10158549ddc8SAndrey Ignatov 		.result = LOAD_REJECT,
10168549ddc8SAndrey Ignatov 	},
10178549ddc8SAndrey Ignatov 	{
10188549ddc8SAndrey Ignatov 		"bpf_strtoul supported base, ok",
10198549ddc8SAndrey Ignatov 		.insns = {
10208549ddc8SAndrey Ignatov 			/* arg1 (buf) */
10218549ddc8SAndrey Ignatov 			BPF_MOV64_REG(BPF_REG_7, BPF_REG_10),
10228549ddc8SAndrey Ignatov 			BPF_ALU64_IMM(BPF_ADD, BPF_REG_7, -8),
10233ec2a0edSIlya Leoshkevich 			BPF_MOV64_IMM(BPF_REG_0,
10243ec2a0edSIlya Leoshkevich 				      bpf_ntohl(0x30373700)),
10253ec2a0edSIlya Leoshkevich 			BPF_STX_MEM(BPF_W, BPF_REG_7, BPF_REG_0, 0),
10268549ddc8SAndrey Ignatov 
10278549ddc8SAndrey Ignatov 			BPF_MOV64_REG(BPF_REG_1, BPF_REG_7),
10288549ddc8SAndrey Ignatov 
10298549ddc8SAndrey Ignatov 			/* arg2 (buf_len) */
10308549ddc8SAndrey Ignatov 			BPF_MOV64_IMM(BPF_REG_2, 4),
10318549ddc8SAndrey Ignatov 
10328549ddc8SAndrey Ignatov 			/* arg3 (flags) */
10338549ddc8SAndrey Ignatov 			BPF_MOV64_IMM(BPF_REG_3, 8),
10348549ddc8SAndrey Ignatov 
10358549ddc8SAndrey Ignatov 			/* arg4 (res) */
10368549ddc8SAndrey Ignatov 			BPF_ALU64_IMM(BPF_ADD, BPF_REG_7, -8),
10378549ddc8SAndrey Ignatov 			BPF_STX_MEM(BPF_DW, BPF_REG_7, BPF_REG_0, 0),
10388549ddc8SAndrey Ignatov 			BPF_MOV64_REG(BPF_REG_4, BPF_REG_7),
10398549ddc8SAndrey Ignatov 
10408549ddc8SAndrey Ignatov 			BPF_EMIT_CALL(BPF_FUNC_strtoul),
10418549ddc8SAndrey Ignatov 
10428549ddc8SAndrey Ignatov 			/* if (ret == expected && */
10438549ddc8SAndrey Ignatov 			BPF_JMP_IMM(BPF_JNE, BPF_REG_0, 3, 4),
10448549ddc8SAndrey Ignatov 			/*     res == expected) */
10458549ddc8SAndrey Ignatov 			BPF_LDX_MEM(BPF_DW, BPF_REG_9, BPF_REG_7, 0),
10468549ddc8SAndrey Ignatov 			BPF_JMP_IMM(BPF_JNE, BPF_REG_9, 63, 2),
10478549ddc8SAndrey Ignatov 
10488549ddc8SAndrey Ignatov 			/* return ALLOW; */
10498549ddc8SAndrey Ignatov 			BPF_MOV64_IMM(BPF_REG_0, 1),
10508549ddc8SAndrey Ignatov 			BPF_JMP_A(1),
10518549ddc8SAndrey Ignatov 
10528549ddc8SAndrey Ignatov 			/* else return DENY; */
10538549ddc8SAndrey Ignatov 			BPF_MOV64_IMM(BPF_REG_0, 0),
10548549ddc8SAndrey Ignatov 			BPF_EXIT_INSN(),
10558549ddc8SAndrey Ignatov 		},
10568549ddc8SAndrey Ignatov 		.attach_type = BPF_CGROUP_SYSCTL,
10578549ddc8SAndrey Ignatov 		.sysctl = "net/ipv4/route/mtu_expires",
10588549ddc8SAndrey Ignatov 		.open_flags = O_RDONLY,
10598549ddc8SAndrey Ignatov 		.result = SUCCESS,
10608549ddc8SAndrey Ignatov 	},
10618549ddc8SAndrey Ignatov 	{
10628549ddc8SAndrey Ignatov 		"bpf_strtoul unsupported base, EINVAL",
10638549ddc8SAndrey Ignatov 		.insns = {
10648549ddc8SAndrey Ignatov 			/* arg1 (buf) */
10658549ddc8SAndrey Ignatov 			BPF_MOV64_REG(BPF_REG_7, BPF_REG_10),
10668549ddc8SAndrey Ignatov 			BPF_ALU64_IMM(BPF_ADD, BPF_REG_7, -8),
10673ec2a0edSIlya Leoshkevich 			BPF_MOV64_IMM(BPF_REG_0,
10683ec2a0edSIlya Leoshkevich 				      bpf_ntohl(0x36303000)),
10698549ddc8SAndrey Ignatov 			BPF_STX_MEM(BPF_DW, BPF_REG_7, BPF_REG_0, 0),
10708549ddc8SAndrey Ignatov 
10718549ddc8SAndrey Ignatov 			BPF_MOV64_REG(BPF_REG_1, BPF_REG_7),
10728549ddc8SAndrey Ignatov 
10738549ddc8SAndrey Ignatov 			/* arg2 (buf_len) */
10748549ddc8SAndrey Ignatov 			BPF_MOV64_IMM(BPF_REG_2, 4),
10758549ddc8SAndrey Ignatov 
10768549ddc8SAndrey Ignatov 			/* arg3 (flags) */
10778549ddc8SAndrey Ignatov 			BPF_MOV64_IMM(BPF_REG_3, 3),
10788549ddc8SAndrey Ignatov 
10798549ddc8SAndrey Ignatov 			/* arg4 (res) */
10808549ddc8SAndrey Ignatov 			BPF_ALU64_IMM(BPF_ADD, BPF_REG_7, -8),
10818549ddc8SAndrey Ignatov 			BPF_STX_MEM(BPF_DW, BPF_REG_7, BPF_REG_0, 0),
10828549ddc8SAndrey Ignatov 			BPF_MOV64_REG(BPF_REG_4, BPF_REG_7),
10838549ddc8SAndrey Ignatov 
10848549ddc8SAndrey Ignatov 			BPF_EMIT_CALL(BPF_FUNC_strtoul),
10858549ddc8SAndrey Ignatov 
10868549ddc8SAndrey Ignatov 			/* if (ret == expected) */
10878549ddc8SAndrey Ignatov 			BPF_JMP_IMM(BPF_JNE, BPF_REG_0, -EINVAL, 2),
10888549ddc8SAndrey Ignatov 
10898549ddc8SAndrey Ignatov 			/* return ALLOW; */
10908549ddc8SAndrey Ignatov 			BPF_MOV64_IMM(BPF_REG_0, 1),
10918549ddc8SAndrey Ignatov 			BPF_JMP_A(1),
10928549ddc8SAndrey Ignatov 
10938549ddc8SAndrey Ignatov 			/* else return DENY; */
10948549ddc8SAndrey Ignatov 			BPF_MOV64_IMM(BPF_REG_0, 0),
10958549ddc8SAndrey Ignatov 			BPF_EXIT_INSN(),
10968549ddc8SAndrey Ignatov 		},
10978549ddc8SAndrey Ignatov 		.attach_type = BPF_CGROUP_SYSCTL,
10988549ddc8SAndrey Ignatov 		.sysctl = "net/ipv4/route/mtu_expires",
10998549ddc8SAndrey Ignatov 		.open_flags = O_RDONLY,
11008549ddc8SAndrey Ignatov 		.result = SUCCESS,
11018549ddc8SAndrey Ignatov 	},
11028549ddc8SAndrey Ignatov 	{
11038549ddc8SAndrey Ignatov 		"bpf_strtoul buf with spaces only, EINVAL",
11048549ddc8SAndrey Ignatov 		.insns = {
11058549ddc8SAndrey Ignatov 			/* arg1 (buf) */
11068549ddc8SAndrey Ignatov 			BPF_MOV64_REG(BPF_REG_7, BPF_REG_10),
11078549ddc8SAndrey Ignatov 			BPF_ALU64_IMM(BPF_ADD, BPF_REG_7, -8),
11083ec2a0edSIlya Leoshkevich 			BPF_MOV64_IMM(BPF_REG_0,
11093ec2a0edSIlya Leoshkevich 				      bpf_ntohl(0x0d0c0a09)),
11108549ddc8SAndrey Ignatov 			BPF_STX_MEM(BPF_DW, BPF_REG_7, BPF_REG_0, 0),
11118549ddc8SAndrey Ignatov 
11128549ddc8SAndrey Ignatov 			BPF_MOV64_REG(BPF_REG_1, BPF_REG_7),
11138549ddc8SAndrey Ignatov 
11148549ddc8SAndrey Ignatov 			/* arg2 (buf_len) */
11158549ddc8SAndrey Ignatov 			BPF_MOV64_IMM(BPF_REG_2, 4),
11168549ddc8SAndrey Ignatov 
11178549ddc8SAndrey Ignatov 			/* arg3 (flags) */
11188549ddc8SAndrey Ignatov 			BPF_MOV64_IMM(BPF_REG_3, 0),
11198549ddc8SAndrey Ignatov 
11208549ddc8SAndrey Ignatov 			/* arg4 (res) */
11218549ddc8SAndrey Ignatov 			BPF_ALU64_IMM(BPF_ADD, BPF_REG_7, -8),
11228549ddc8SAndrey Ignatov 			BPF_STX_MEM(BPF_DW, BPF_REG_7, BPF_REG_0, 0),
11238549ddc8SAndrey Ignatov 			BPF_MOV64_REG(BPF_REG_4, BPF_REG_7),
11248549ddc8SAndrey Ignatov 
11258549ddc8SAndrey Ignatov 			BPF_EMIT_CALL(BPF_FUNC_strtoul),
11268549ddc8SAndrey Ignatov 
11278549ddc8SAndrey Ignatov 			/* if (ret == expected) */
11288549ddc8SAndrey Ignatov 			BPF_JMP_IMM(BPF_JNE, BPF_REG_0, -EINVAL, 2),
11298549ddc8SAndrey Ignatov 
11308549ddc8SAndrey Ignatov 			/* return ALLOW; */
11318549ddc8SAndrey Ignatov 			BPF_MOV64_IMM(BPF_REG_0, 1),
11328549ddc8SAndrey Ignatov 			BPF_JMP_A(1),
11338549ddc8SAndrey Ignatov 
11348549ddc8SAndrey Ignatov 			/* else return DENY; */
11358549ddc8SAndrey Ignatov 			BPF_MOV64_IMM(BPF_REG_0, 0),
11368549ddc8SAndrey Ignatov 			BPF_EXIT_INSN(),
11378549ddc8SAndrey Ignatov 		},
11388549ddc8SAndrey Ignatov 		.attach_type = BPF_CGROUP_SYSCTL,
11398549ddc8SAndrey Ignatov 		.sysctl = "net/ipv4/route/mtu_expires",
11408549ddc8SAndrey Ignatov 		.open_flags = O_RDONLY,
11418549ddc8SAndrey Ignatov 		.result = SUCCESS,
11428549ddc8SAndrey Ignatov 	},
11438549ddc8SAndrey Ignatov 	{
11448549ddc8SAndrey Ignatov 		"bpf_strtoul negative number, EINVAL",
11458549ddc8SAndrey Ignatov 		.insns = {
11468549ddc8SAndrey Ignatov 			/* arg1 (buf) */
11478549ddc8SAndrey Ignatov 			BPF_MOV64_REG(BPF_REG_7, BPF_REG_10),
11488549ddc8SAndrey Ignatov 			BPF_ALU64_IMM(BPF_ADD, BPF_REG_7, -8),
11493ec2a0edSIlya Leoshkevich 			/* " -6\0" */
11503ec2a0edSIlya Leoshkevich 			BPF_MOV64_IMM(BPF_REG_0,
11513ec2a0edSIlya Leoshkevich 				      bpf_ntohl(0x0a2d3600)),
11528549ddc8SAndrey Ignatov 			BPF_STX_MEM(BPF_DW, BPF_REG_7, BPF_REG_0, 0),
11538549ddc8SAndrey Ignatov 
11548549ddc8SAndrey Ignatov 			BPF_MOV64_REG(BPF_REG_1, BPF_REG_7),
11558549ddc8SAndrey Ignatov 
11568549ddc8SAndrey Ignatov 			/* arg2 (buf_len) */
11578549ddc8SAndrey Ignatov 			BPF_MOV64_IMM(BPF_REG_2, 4),
11588549ddc8SAndrey Ignatov 
11598549ddc8SAndrey Ignatov 			/* arg3 (flags) */
11608549ddc8SAndrey Ignatov 			BPF_MOV64_IMM(BPF_REG_3, 0),
11618549ddc8SAndrey Ignatov 
11628549ddc8SAndrey Ignatov 			/* arg4 (res) */
11638549ddc8SAndrey Ignatov 			BPF_ALU64_IMM(BPF_ADD, BPF_REG_7, -8),
11648549ddc8SAndrey Ignatov 			BPF_STX_MEM(BPF_DW, BPF_REG_7, BPF_REG_0, 0),
11658549ddc8SAndrey Ignatov 			BPF_MOV64_REG(BPF_REG_4, BPF_REG_7),
11668549ddc8SAndrey Ignatov 
11678549ddc8SAndrey Ignatov 			BPF_EMIT_CALL(BPF_FUNC_strtoul),
11688549ddc8SAndrey Ignatov 
11698549ddc8SAndrey Ignatov 			/* if (ret == expected) */
11708549ddc8SAndrey Ignatov 			BPF_JMP_IMM(BPF_JNE, BPF_REG_0, -EINVAL, 2),
11718549ddc8SAndrey Ignatov 
11728549ddc8SAndrey Ignatov 			/* return ALLOW; */
11738549ddc8SAndrey Ignatov 			BPF_MOV64_IMM(BPF_REG_0, 1),
11748549ddc8SAndrey Ignatov 			BPF_JMP_A(1),
11758549ddc8SAndrey Ignatov 
11768549ddc8SAndrey Ignatov 			/* else return DENY; */
11778549ddc8SAndrey Ignatov 			BPF_MOV64_IMM(BPF_REG_0, 0),
11788549ddc8SAndrey Ignatov 			BPF_EXIT_INSN(),
11798549ddc8SAndrey Ignatov 		},
11808549ddc8SAndrey Ignatov 		.attach_type = BPF_CGROUP_SYSCTL,
11818549ddc8SAndrey Ignatov 		.sysctl = "net/ipv4/route/mtu_expires",
11828549ddc8SAndrey Ignatov 		.open_flags = O_RDONLY,
11838549ddc8SAndrey Ignatov 		.result = SUCCESS,
11848549ddc8SAndrey Ignatov 	},
11858549ddc8SAndrey Ignatov 	{
11868549ddc8SAndrey Ignatov 		"bpf_strtol negative number, ok",
11878549ddc8SAndrey Ignatov 		.insns = {
11888549ddc8SAndrey Ignatov 			/* arg1 (buf) */
11898549ddc8SAndrey Ignatov 			BPF_MOV64_REG(BPF_REG_7, BPF_REG_10),
11908549ddc8SAndrey Ignatov 			BPF_ALU64_IMM(BPF_ADD, BPF_REG_7, -8),
11913ec2a0edSIlya Leoshkevich 			/* " -6\0" */
11923ec2a0edSIlya Leoshkevich 			BPF_MOV64_IMM(BPF_REG_0,
11933ec2a0edSIlya Leoshkevich 				      bpf_ntohl(0x0a2d3600)),
11943ec2a0edSIlya Leoshkevich 			BPF_STX_MEM(BPF_W, BPF_REG_7, BPF_REG_0, 0),
11958549ddc8SAndrey Ignatov 
11968549ddc8SAndrey Ignatov 			BPF_MOV64_REG(BPF_REG_1, BPF_REG_7),
11978549ddc8SAndrey Ignatov 
11988549ddc8SAndrey Ignatov 			/* arg2 (buf_len) */
11998549ddc8SAndrey Ignatov 			BPF_MOV64_IMM(BPF_REG_2, 4),
12008549ddc8SAndrey Ignatov 
12018549ddc8SAndrey Ignatov 			/* arg3 (flags) */
12028549ddc8SAndrey Ignatov 			BPF_MOV64_IMM(BPF_REG_3, 10),
12038549ddc8SAndrey Ignatov 
12048549ddc8SAndrey Ignatov 			/* arg4 (res) */
12058549ddc8SAndrey Ignatov 			BPF_ALU64_IMM(BPF_ADD, BPF_REG_7, -8),
12068549ddc8SAndrey Ignatov 			BPF_STX_MEM(BPF_DW, BPF_REG_7, BPF_REG_0, 0),
12078549ddc8SAndrey Ignatov 			BPF_MOV64_REG(BPF_REG_4, BPF_REG_7),
12088549ddc8SAndrey Ignatov 
12098549ddc8SAndrey Ignatov 			BPF_EMIT_CALL(BPF_FUNC_strtol),
12108549ddc8SAndrey Ignatov 
12118549ddc8SAndrey Ignatov 			/* if (ret == expected && */
12128549ddc8SAndrey Ignatov 			BPF_JMP_IMM(BPF_JNE, BPF_REG_0, 3, 4),
12138549ddc8SAndrey Ignatov 			/*     res == expected) */
12148549ddc8SAndrey Ignatov 			BPF_LDX_MEM(BPF_DW, BPF_REG_9, BPF_REG_7, 0),
12158549ddc8SAndrey Ignatov 			BPF_JMP_IMM(BPF_JNE, BPF_REG_9, -6, 2),
12168549ddc8SAndrey Ignatov 
12178549ddc8SAndrey Ignatov 			/* return ALLOW; */
12188549ddc8SAndrey Ignatov 			BPF_MOV64_IMM(BPF_REG_0, 1),
12198549ddc8SAndrey Ignatov 			BPF_JMP_A(1),
12208549ddc8SAndrey Ignatov 
12218549ddc8SAndrey Ignatov 			/* else return DENY; */
12228549ddc8SAndrey Ignatov 			BPF_MOV64_IMM(BPF_REG_0, 0),
12238549ddc8SAndrey Ignatov 			BPF_EXIT_INSN(),
12248549ddc8SAndrey Ignatov 		},
12258549ddc8SAndrey Ignatov 		.attach_type = BPF_CGROUP_SYSCTL,
12268549ddc8SAndrey Ignatov 		.sysctl = "net/ipv4/route/mtu_expires",
12278549ddc8SAndrey Ignatov 		.open_flags = O_RDONLY,
12288549ddc8SAndrey Ignatov 		.result = SUCCESS,
12298549ddc8SAndrey Ignatov 	},
12308549ddc8SAndrey Ignatov 	{
12318549ddc8SAndrey Ignatov 		"bpf_strtol hex number, ok",
12328549ddc8SAndrey Ignatov 		.insns = {
12338549ddc8SAndrey Ignatov 			/* arg1 (buf) */
12348549ddc8SAndrey Ignatov 			BPF_MOV64_REG(BPF_REG_7, BPF_REG_10),
12358549ddc8SAndrey Ignatov 			BPF_ALU64_IMM(BPF_ADD, BPF_REG_7, -8),
12363ec2a0edSIlya Leoshkevich 			/* "0xfe" */
12373ec2a0edSIlya Leoshkevich 			BPF_MOV64_IMM(BPF_REG_0,
12383ec2a0edSIlya Leoshkevich 				      bpf_ntohl(0x30786665)),
12393ec2a0edSIlya Leoshkevich 			BPF_STX_MEM(BPF_W, BPF_REG_7, BPF_REG_0, 0),
12408549ddc8SAndrey Ignatov 
12418549ddc8SAndrey Ignatov 			BPF_MOV64_REG(BPF_REG_1, BPF_REG_7),
12428549ddc8SAndrey Ignatov 
12438549ddc8SAndrey Ignatov 			/* arg2 (buf_len) */
12448549ddc8SAndrey Ignatov 			BPF_MOV64_IMM(BPF_REG_2, 4),
12458549ddc8SAndrey Ignatov 
12468549ddc8SAndrey Ignatov 			/* arg3 (flags) */
12478549ddc8SAndrey Ignatov 			BPF_MOV64_IMM(BPF_REG_3, 0),
12488549ddc8SAndrey Ignatov 
12498549ddc8SAndrey Ignatov 			/* arg4 (res) */
12508549ddc8SAndrey Ignatov 			BPF_ALU64_IMM(BPF_ADD, BPF_REG_7, -8),
12518549ddc8SAndrey Ignatov 			BPF_STX_MEM(BPF_DW, BPF_REG_7, BPF_REG_0, 0),
12528549ddc8SAndrey Ignatov 			BPF_MOV64_REG(BPF_REG_4, BPF_REG_7),
12538549ddc8SAndrey Ignatov 
12548549ddc8SAndrey Ignatov 			BPF_EMIT_CALL(BPF_FUNC_strtol),
12558549ddc8SAndrey Ignatov 
12568549ddc8SAndrey Ignatov 			/* if (ret == expected && */
12578549ddc8SAndrey Ignatov 			BPF_JMP_IMM(BPF_JNE, BPF_REG_0, 4, 4),
12588549ddc8SAndrey Ignatov 			/*     res == expected) */
12598549ddc8SAndrey Ignatov 			BPF_LDX_MEM(BPF_DW, BPF_REG_9, BPF_REG_7, 0),
12608549ddc8SAndrey Ignatov 			BPF_JMP_IMM(BPF_JNE, BPF_REG_9, 254, 2),
12618549ddc8SAndrey Ignatov 
12628549ddc8SAndrey Ignatov 			/* return ALLOW; */
12638549ddc8SAndrey Ignatov 			BPF_MOV64_IMM(BPF_REG_0, 1),
12648549ddc8SAndrey Ignatov 			BPF_JMP_A(1),
12658549ddc8SAndrey Ignatov 
12668549ddc8SAndrey Ignatov 			/* else return DENY; */
12678549ddc8SAndrey Ignatov 			BPF_MOV64_IMM(BPF_REG_0, 0),
12688549ddc8SAndrey Ignatov 			BPF_EXIT_INSN(),
12698549ddc8SAndrey Ignatov 		},
12708549ddc8SAndrey Ignatov 		.attach_type = BPF_CGROUP_SYSCTL,
12718549ddc8SAndrey Ignatov 		.sysctl = "net/ipv4/route/mtu_expires",
12728549ddc8SAndrey Ignatov 		.open_flags = O_RDONLY,
12738549ddc8SAndrey Ignatov 		.result = SUCCESS,
12748549ddc8SAndrey Ignatov 	},
12758549ddc8SAndrey Ignatov 	{
12768549ddc8SAndrey Ignatov 		"bpf_strtol max long",
12778549ddc8SAndrey Ignatov 		.insns = {
12788549ddc8SAndrey Ignatov 			/* arg1 (buf) 9223372036854775807 */
12798549ddc8SAndrey Ignatov 			BPF_MOV64_REG(BPF_REG_7, BPF_REG_10),
12808549ddc8SAndrey Ignatov 			BPF_ALU64_IMM(BPF_ADD, BPF_REG_7, -24),
12813ec2a0edSIlya Leoshkevich 			BPF_LD_IMM64(BPF_REG_0,
12823ec2a0edSIlya Leoshkevich 				     bpf_be64_to_cpu(0x3932323333373230ULL)),
12838549ddc8SAndrey Ignatov 			BPF_STX_MEM(BPF_DW, BPF_REG_7, BPF_REG_0, 0),
12843ec2a0edSIlya Leoshkevich 			BPF_LD_IMM64(BPF_REG_0,
12853ec2a0edSIlya Leoshkevich 				     bpf_be64_to_cpu(0x3336383534373735ULL)),
12868549ddc8SAndrey Ignatov 			BPF_STX_MEM(BPF_DW, BPF_REG_7, BPF_REG_0, 8),
12873ec2a0edSIlya Leoshkevich 			BPF_LD_IMM64(BPF_REG_0,
12883ec2a0edSIlya Leoshkevich 				     bpf_be64_to_cpu(0x3830370000000000ULL)),
12898549ddc8SAndrey Ignatov 			BPF_STX_MEM(BPF_DW, BPF_REG_7, BPF_REG_0, 16),
12908549ddc8SAndrey Ignatov 
12918549ddc8SAndrey Ignatov 			BPF_MOV64_REG(BPF_REG_1, BPF_REG_7),
12928549ddc8SAndrey Ignatov 
12938549ddc8SAndrey Ignatov 			/* arg2 (buf_len) */
12948549ddc8SAndrey Ignatov 			BPF_MOV64_IMM(BPF_REG_2, 19),
12958549ddc8SAndrey Ignatov 
12968549ddc8SAndrey Ignatov 			/* arg3 (flags) */
12978549ddc8SAndrey Ignatov 			BPF_MOV64_IMM(BPF_REG_3, 0),
12988549ddc8SAndrey Ignatov 
12998549ddc8SAndrey Ignatov 			/* arg4 (res) */
13008549ddc8SAndrey Ignatov 			BPF_ALU64_IMM(BPF_ADD, BPF_REG_7, -8),
13018549ddc8SAndrey Ignatov 			BPF_STX_MEM(BPF_DW, BPF_REG_7, BPF_REG_0, 0),
13028549ddc8SAndrey Ignatov 			BPF_MOV64_REG(BPF_REG_4, BPF_REG_7),
13038549ddc8SAndrey Ignatov 
13048549ddc8SAndrey Ignatov 			BPF_EMIT_CALL(BPF_FUNC_strtol),
13058549ddc8SAndrey Ignatov 
13068549ddc8SAndrey Ignatov 			/* if (ret == expected && */
13078549ddc8SAndrey Ignatov 			BPF_JMP_IMM(BPF_JNE, BPF_REG_0, 19, 6),
13088549ddc8SAndrey Ignatov 			/*     res == expected) */
13098549ddc8SAndrey Ignatov 			BPF_LD_IMM64(BPF_REG_8, 0x7fffffffffffffffULL),
13108549ddc8SAndrey Ignatov 			BPF_LDX_MEM(BPF_DW, BPF_REG_9, BPF_REG_7, 0),
13118549ddc8SAndrey Ignatov 			BPF_JMP_REG(BPF_JNE, BPF_REG_8, BPF_REG_9, 2),
13128549ddc8SAndrey Ignatov 
13138549ddc8SAndrey Ignatov 			/* return ALLOW; */
13148549ddc8SAndrey Ignatov 			BPF_MOV64_IMM(BPF_REG_0, 1),
13158549ddc8SAndrey Ignatov 			BPF_JMP_A(1),
13168549ddc8SAndrey Ignatov 
13178549ddc8SAndrey Ignatov 			/* else return DENY; */
13188549ddc8SAndrey Ignatov 			BPF_MOV64_IMM(BPF_REG_0, 0),
13198549ddc8SAndrey Ignatov 			BPF_EXIT_INSN(),
13208549ddc8SAndrey Ignatov 		},
13218549ddc8SAndrey Ignatov 		.attach_type = BPF_CGROUP_SYSCTL,
13228549ddc8SAndrey Ignatov 		.sysctl = "net/ipv4/route/mtu_expires",
13238549ddc8SAndrey Ignatov 		.open_flags = O_RDONLY,
13248549ddc8SAndrey Ignatov 		.result = SUCCESS,
13258549ddc8SAndrey Ignatov 	},
13268549ddc8SAndrey Ignatov 	{
13278549ddc8SAndrey Ignatov 		"bpf_strtol overflow, ERANGE",
13288549ddc8SAndrey Ignatov 		.insns = {
13298549ddc8SAndrey Ignatov 			/* arg1 (buf) 9223372036854775808 */
13308549ddc8SAndrey Ignatov 			BPF_MOV64_REG(BPF_REG_7, BPF_REG_10),
13318549ddc8SAndrey Ignatov 			BPF_ALU64_IMM(BPF_ADD, BPF_REG_7, -24),
13323ec2a0edSIlya Leoshkevich 			BPF_LD_IMM64(BPF_REG_0,
13333ec2a0edSIlya Leoshkevich 				     bpf_be64_to_cpu(0x3932323333373230ULL)),
13348549ddc8SAndrey Ignatov 			BPF_STX_MEM(BPF_DW, BPF_REG_7, BPF_REG_0, 0),
13353ec2a0edSIlya Leoshkevich 			BPF_LD_IMM64(BPF_REG_0,
13363ec2a0edSIlya Leoshkevich 				     bpf_be64_to_cpu(0x3336383534373735ULL)),
13378549ddc8SAndrey Ignatov 			BPF_STX_MEM(BPF_DW, BPF_REG_7, BPF_REG_0, 8),
13383ec2a0edSIlya Leoshkevich 			BPF_LD_IMM64(BPF_REG_0,
13393ec2a0edSIlya Leoshkevich 				     bpf_be64_to_cpu(0x3830380000000000ULL)),
13408549ddc8SAndrey Ignatov 			BPF_STX_MEM(BPF_DW, BPF_REG_7, BPF_REG_0, 16),
13418549ddc8SAndrey Ignatov 
13428549ddc8SAndrey Ignatov 			BPF_MOV64_REG(BPF_REG_1, BPF_REG_7),
13438549ddc8SAndrey Ignatov 
13448549ddc8SAndrey Ignatov 			/* arg2 (buf_len) */
13458549ddc8SAndrey Ignatov 			BPF_MOV64_IMM(BPF_REG_2, 19),
13468549ddc8SAndrey Ignatov 
13478549ddc8SAndrey Ignatov 			/* arg3 (flags) */
13488549ddc8SAndrey Ignatov 			BPF_MOV64_IMM(BPF_REG_3, 0),
13498549ddc8SAndrey Ignatov 
13508549ddc8SAndrey Ignatov 			/* arg4 (res) */
13518549ddc8SAndrey Ignatov 			BPF_ALU64_IMM(BPF_ADD, BPF_REG_7, -8),
13528549ddc8SAndrey Ignatov 			BPF_STX_MEM(BPF_DW, BPF_REG_7, BPF_REG_0, 0),
13538549ddc8SAndrey Ignatov 			BPF_MOV64_REG(BPF_REG_4, BPF_REG_7),
13548549ddc8SAndrey Ignatov 
13558549ddc8SAndrey Ignatov 			BPF_EMIT_CALL(BPF_FUNC_strtol),
13568549ddc8SAndrey Ignatov 
13578549ddc8SAndrey Ignatov 			/* if (ret == expected) */
13588549ddc8SAndrey Ignatov 			BPF_JMP_IMM(BPF_JNE, BPF_REG_0, -ERANGE, 2),
13598549ddc8SAndrey Ignatov 
13608549ddc8SAndrey Ignatov 			/* return ALLOW; */
13618549ddc8SAndrey Ignatov 			BPF_MOV64_IMM(BPF_REG_0, 1),
13628549ddc8SAndrey Ignatov 			BPF_JMP_A(1),
13638549ddc8SAndrey Ignatov 
13648549ddc8SAndrey Ignatov 			/* else return DENY; */
13658549ddc8SAndrey Ignatov 			BPF_MOV64_IMM(BPF_REG_0, 0),
13668549ddc8SAndrey Ignatov 			BPF_EXIT_INSN(),
13678549ddc8SAndrey Ignatov 		},
13688549ddc8SAndrey Ignatov 		.attach_type = BPF_CGROUP_SYSCTL,
13698549ddc8SAndrey Ignatov 		.sysctl = "net/ipv4/route/mtu_expires",
13708549ddc8SAndrey Ignatov 		.open_flags = O_RDONLY,
13718549ddc8SAndrey Ignatov 		.result = SUCCESS,
13728549ddc8SAndrey Ignatov 	},
13737568f4cbSAndrey Ignatov 	{
13747568f4cbSAndrey Ignatov 		"C prog: deny all writes",
1375*afef88e6SDaniel Müller 		.prog_file = "./test_sysctl_prog.bpf.o",
13767568f4cbSAndrey Ignatov 		.attach_type = BPF_CGROUP_SYSCTL,
13777568f4cbSAndrey Ignatov 		.sysctl = "net/ipv4/tcp_mem",
13787568f4cbSAndrey Ignatov 		.open_flags = O_WRONLY,
13797568f4cbSAndrey Ignatov 		.newval = "123 456 789",
13807568f4cbSAndrey Ignatov 		.result = OP_EPERM,
13817568f4cbSAndrey Ignatov 	},
13827568f4cbSAndrey Ignatov 	{
13837568f4cbSAndrey Ignatov 		"C prog: deny access by name",
1384*afef88e6SDaniel Müller 		.prog_file = "./test_sysctl_prog.bpf.o",
13857568f4cbSAndrey Ignatov 		.attach_type = BPF_CGROUP_SYSCTL,
13867568f4cbSAndrey Ignatov 		.sysctl = "net/ipv4/route/mtu_expires",
13877568f4cbSAndrey Ignatov 		.open_flags = O_RDONLY,
13887568f4cbSAndrey Ignatov 		.result = OP_EPERM,
13897568f4cbSAndrey Ignatov 	},
13907568f4cbSAndrey Ignatov 	{
13917568f4cbSAndrey Ignatov 		"C prog: read tcp_mem",
1392*afef88e6SDaniel Müller 		.prog_file = "./test_sysctl_prog.bpf.o",
13937568f4cbSAndrey Ignatov 		.attach_type = BPF_CGROUP_SYSCTL,
13947568f4cbSAndrey Ignatov 		.sysctl = "net/ipv4/tcp_mem",
13957568f4cbSAndrey Ignatov 		.open_flags = O_RDONLY,
13967568f4cbSAndrey Ignatov 		.result = SUCCESS,
13977568f4cbSAndrey Ignatov 	},
13981f5fa9abSAndrey Ignatov };
13991f5fa9abSAndrey Ignatov 
probe_prog_length(const struct bpf_insn * fp)14001f5fa9abSAndrey Ignatov static size_t probe_prog_length(const struct bpf_insn *fp)
14011f5fa9abSAndrey Ignatov {
14021f5fa9abSAndrey Ignatov 	size_t len;
14031f5fa9abSAndrey Ignatov 
14041f5fa9abSAndrey Ignatov 	for (len = MAX_INSNS - 1; len > 0; --len)
14051f5fa9abSAndrey Ignatov 		if (fp[len].code != 0 || fp[len].imm != 0)
14061f5fa9abSAndrey Ignatov 			break;
14071f5fa9abSAndrey Ignatov 	return len + 1;
14081f5fa9abSAndrey Ignatov }
14091f5fa9abSAndrey Ignatov 
fixup_sysctl_value(const char * buf,size_t buf_len,struct bpf_insn * prog,size_t insn_num)141011ff34f7SAndrey Ignatov static int fixup_sysctl_value(const char *buf, size_t buf_len,
141111ff34f7SAndrey Ignatov 			      struct bpf_insn *prog, size_t insn_num)
141211ff34f7SAndrey Ignatov {
14133ec2a0edSIlya Leoshkevich 	union {
14143ec2a0edSIlya Leoshkevich 		uint8_t raw[sizeof(uint64_t)];
14153ec2a0edSIlya Leoshkevich 		uint64_t num;
14163ec2a0edSIlya Leoshkevich 	} value = {};
141711ff34f7SAndrey Ignatov 
14183ec2a0edSIlya Leoshkevich 	if (buf_len > sizeof(value)) {
141911ff34f7SAndrey Ignatov 		log_err("Value is too big (%zd) to use in fixup", buf_len);
142011ff34f7SAndrey Ignatov 		return -1;
142111ff34f7SAndrey Ignatov 	}
14223ec2a0edSIlya Leoshkevich 	if (prog[insn_num].code != (BPF_LD | BPF_DW | BPF_IMM)) {
14233ec2a0edSIlya Leoshkevich 		log_err("Can fixup only BPF_LD_IMM64 insns");
14243ec2a0edSIlya Leoshkevich 		return -1;
142511ff34f7SAndrey Ignatov 	}
142611ff34f7SAndrey Ignatov 
14273ec2a0edSIlya Leoshkevich 	memcpy(value.raw, buf, buf_len);
14283ec2a0edSIlya Leoshkevich 	prog[insn_num].imm = (uint32_t)value.num;
14293ec2a0edSIlya Leoshkevich 	prog[insn_num + 1].imm = (uint32_t)(value.num >> 32);
143011ff34f7SAndrey Ignatov 
143111ff34f7SAndrey Ignatov 	return 0;
143211ff34f7SAndrey Ignatov }
143311ff34f7SAndrey Ignatov 
load_sysctl_prog_insns(struct sysctl_test * test,const char * sysctl_path)14347568f4cbSAndrey Ignatov static int load_sysctl_prog_insns(struct sysctl_test *test,
14357568f4cbSAndrey Ignatov 				  const char *sysctl_path)
14361f5fa9abSAndrey Ignatov {
14371f5fa9abSAndrey Ignatov 	struct bpf_insn *prog = test->insns;
1438d8e86407SAndrii Nakryiko 	LIBBPF_OPTS(bpf_prog_load_opts, opts);
1439d8e86407SAndrii Nakryiko 	int ret, insn_cnt;
14401f5fa9abSAndrey Ignatov 
1441d8e86407SAndrii Nakryiko 	insn_cnt = probe_prog_length(prog);
14421f5fa9abSAndrey Ignatov 
144311ff34f7SAndrey Ignatov 	if (test->fixup_value_insn) {
144411ff34f7SAndrey Ignatov 		char buf[128];
144511ff34f7SAndrey Ignatov 		ssize_t len;
144611ff34f7SAndrey Ignatov 		int fd;
144711ff34f7SAndrey Ignatov 
144811ff34f7SAndrey Ignatov 		fd = open(sysctl_path, O_RDONLY | O_CLOEXEC);
144911ff34f7SAndrey Ignatov 		if (fd < 0) {
145011ff34f7SAndrey Ignatov 			log_err("open(%s) failed", sysctl_path);
145111ff34f7SAndrey Ignatov 			return -1;
145211ff34f7SAndrey Ignatov 		}
145311ff34f7SAndrey Ignatov 		len = read(fd, buf, sizeof(buf));
145411ff34f7SAndrey Ignatov 		if (len == -1) {
145511ff34f7SAndrey Ignatov 			log_err("read(%s) failed", sysctl_path);
145611ff34f7SAndrey Ignatov 			close(fd);
145711ff34f7SAndrey Ignatov 			return -1;
145811ff34f7SAndrey Ignatov 		}
145911ff34f7SAndrey Ignatov 		close(fd);
146011ff34f7SAndrey Ignatov 		if (fixup_sysctl_value(buf, len, prog, test->fixup_value_insn))
146111ff34f7SAndrey Ignatov 			return -1;
146211ff34f7SAndrey Ignatov 	}
146311ff34f7SAndrey Ignatov 
1464d8e86407SAndrii Nakryiko 	opts.log_buf = bpf_log_buf;
1465d8e86407SAndrii Nakryiko 	opts.log_size = BPF_LOG_BUF_SIZE;
1466d8e86407SAndrii Nakryiko 
1467d8e86407SAndrii Nakryiko 	ret = bpf_prog_load(BPF_PROG_TYPE_CGROUP_SYSCTL, NULL, "GPL", prog, insn_cnt, &opts);
14681f5fa9abSAndrey Ignatov 	if (ret < 0 && test->result != LOAD_REJECT) {
14691f5fa9abSAndrey Ignatov 		log_err(">>> Loading program error.\n"
14701f5fa9abSAndrey Ignatov 			">>> Verifier output:\n%s\n-------\n", bpf_log_buf);
14711f5fa9abSAndrey Ignatov 	}
14721f5fa9abSAndrey Ignatov 
14731f5fa9abSAndrey Ignatov 	return ret;
14741f5fa9abSAndrey Ignatov }
14751f5fa9abSAndrey Ignatov 
load_sysctl_prog_file(struct sysctl_test * test)14767568f4cbSAndrey Ignatov static int load_sysctl_prog_file(struct sysctl_test *test)
14777568f4cbSAndrey Ignatov {
14787568f4cbSAndrey Ignatov 	struct bpf_object *obj;
14797568f4cbSAndrey Ignatov 	int prog_fd;
14807568f4cbSAndrey Ignatov 
1481d8e86407SAndrii Nakryiko 	if (bpf_prog_test_load(test->prog_file, BPF_PROG_TYPE_CGROUP_SYSCTL, &obj, &prog_fd)) {
14827568f4cbSAndrey Ignatov 		if (test->result != LOAD_REJECT)
14837568f4cbSAndrey Ignatov 			log_err(">>> Loading program (%s) error.\n",
14847568f4cbSAndrey Ignatov 				test->prog_file);
14857568f4cbSAndrey Ignatov 		return -1;
14867568f4cbSAndrey Ignatov 	}
14877568f4cbSAndrey Ignatov 
14887568f4cbSAndrey Ignatov 	return prog_fd;
14897568f4cbSAndrey Ignatov }
14907568f4cbSAndrey Ignatov 
load_sysctl_prog(struct sysctl_test * test,const char * sysctl_path)14917568f4cbSAndrey Ignatov static int load_sysctl_prog(struct sysctl_test *test, const char *sysctl_path)
14927568f4cbSAndrey Ignatov {
14937568f4cbSAndrey Ignatov 		return test->prog_file
14947568f4cbSAndrey Ignatov 			? load_sysctl_prog_file(test)
14957568f4cbSAndrey Ignatov 			: load_sysctl_prog_insns(test, sysctl_path);
14967568f4cbSAndrey Ignatov }
14977568f4cbSAndrey Ignatov 
access_sysctl(const char * sysctl_path,const struct sysctl_test * test)14981f5fa9abSAndrey Ignatov static int access_sysctl(const char *sysctl_path,
14991f5fa9abSAndrey Ignatov 			 const struct sysctl_test *test)
15001f5fa9abSAndrey Ignatov {
15011f5fa9abSAndrey Ignatov 	int err = 0;
15021f5fa9abSAndrey Ignatov 	int fd;
15031f5fa9abSAndrey Ignatov 
15041f5fa9abSAndrey Ignatov 	fd = open(sysctl_path, test->open_flags | O_CLOEXEC);
15051f5fa9abSAndrey Ignatov 	if (fd < 0)
15061f5fa9abSAndrey Ignatov 		return fd;
15071f5fa9abSAndrey Ignatov 
1508d895a0f1SIlya Leoshkevich 	if (test->seek && lseek(fd, test->seek, SEEK_SET) == -1) {
1509d895a0f1SIlya Leoshkevich 		log_err("lseek(%d) failed", test->seek);
1510d895a0f1SIlya Leoshkevich 		goto err;
1511d895a0f1SIlya Leoshkevich 	}
1512d895a0f1SIlya Leoshkevich 
15131f5fa9abSAndrey Ignatov 	if (test->open_flags == O_RDONLY) {
15141f5fa9abSAndrey Ignatov 		char buf[128];
15151f5fa9abSAndrey Ignatov 
15161f5fa9abSAndrey Ignatov 		if (read(fd, buf, sizeof(buf)) == -1)
15171f5fa9abSAndrey Ignatov 			goto err;
15189a1027e5SAndrey Ignatov 		if (test->oldval &&
15199a1027e5SAndrey Ignatov 		    strncmp(buf, test->oldval, strlen(test->oldval))) {
15209a1027e5SAndrey Ignatov 			log_err("Read value %s != %s", buf, test->oldval);
15219a1027e5SAndrey Ignatov 			goto err;
15229a1027e5SAndrey Ignatov 		}
15231f5fa9abSAndrey Ignatov 	} else if (test->open_flags == O_WRONLY) {
15241f5fa9abSAndrey Ignatov 		if (!test->newval) {
15251f5fa9abSAndrey Ignatov 			log_err("New value for sysctl is not set");
15261f5fa9abSAndrey Ignatov 			goto err;
15271f5fa9abSAndrey Ignatov 		}
15281f5fa9abSAndrey Ignatov 		if (write(fd, test->newval, strlen(test->newval)) == -1)
15291f5fa9abSAndrey Ignatov 			goto err;
15301f5fa9abSAndrey Ignatov 	} else {
15311f5fa9abSAndrey Ignatov 		log_err("Unexpected sysctl access: neither read nor write");
15321f5fa9abSAndrey Ignatov 		goto err;
15331f5fa9abSAndrey Ignatov 	}
15341f5fa9abSAndrey Ignatov 
15351f5fa9abSAndrey Ignatov 	goto out;
15361f5fa9abSAndrey Ignatov err:
15371f5fa9abSAndrey Ignatov 	err = -1;
15381f5fa9abSAndrey Ignatov out:
15391f5fa9abSAndrey Ignatov 	close(fd);
15401f5fa9abSAndrey Ignatov 	return err;
15411f5fa9abSAndrey Ignatov }
15421f5fa9abSAndrey Ignatov 
run_test_case(int cgfd,struct sysctl_test * test)15431f5fa9abSAndrey Ignatov static int run_test_case(int cgfd, struct sysctl_test *test)
15441f5fa9abSAndrey Ignatov {
15451f5fa9abSAndrey Ignatov 	enum bpf_attach_type atype = test->attach_type;
15461f5fa9abSAndrey Ignatov 	char sysctl_path[128];
15471f5fa9abSAndrey Ignatov 	int progfd = -1;
15481f5fa9abSAndrey Ignatov 	int err = 0;
15491f5fa9abSAndrey Ignatov 
15501f5fa9abSAndrey Ignatov 	printf("Test case: %s .. ", test->descr);
15511f5fa9abSAndrey Ignatov 
15521f5fa9abSAndrey Ignatov 	snprintf(sysctl_path, sizeof(sysctl_path), "/proc/sys/%s",
15531f5fa9abSAndrey Ignatov 		 test->sysctl);
15541f5fa9abSAndrey Ignatov 
15551f5fa9abSAndrey Ignatov 	progfd = load_sysctl_prog(test, sysctl_path);
15561f5fa9abSAndrey Ignatov 	if (progfd < 0) {
15571f5fa9abSAndrey Ignatov 		if (test->result == LOAD_REJECT)
15581f5fa9abSAndrey Ignatov 			goto out;
15591f5fa9abSAndrey Ignatov 		else
15601f5fa9abSAndrey Ignatov 			goto err;
15611f5fa9abSAndrey Ignatov 	}
15621f5fa9abSAndrey Ignatov 
1563920fd5e1SArtem Savkov 	if (bpf_prog_attach(progfd, cgfd, atype, BPF_F_ALLOW_OVERRIDE) < 0) {
15641f5fa9abSAndrey Ignatov 		if (test->result == ATTACH_REJECT)
15651f5fa9abSAndrey Ignatov 			goto out;
15661f5fa9abSAndrey Ignatov 		else
15671f5fa9abSAndrey Ignatov 			goto err;
15681f5fa9abSAndrey Ignatov 	}
15691f5fa9abSAndrey Ignatov 
1570416c5728SIlya Leoshkevich 	errno = 0;
15711f5fa9abSAndrey Ignatov 	if (access_sysctl(sysctl_path, test) == -1) {
15721f5fa9abSAndrey Ignatov 		if (test->result == OP_EPERM && errno == EPERM)
15731f5fa9abSAndrey Ignatov 			goto out;
15741f5fa9abSAndrey Ignatov 		else
15751f5fa9abSAndrey Ignatov 			goto err;
15761f5fa9abSAndrey Ignatov 	}
15771f5fa9abSAndrey Ignatov 
15781f5fa9abSAndrey Ignatov 	if (test->result != SUCCESS) {
1579416c5728SIlya Leoshkevich 		log_err("Unexpected success");
15801f5fa9abSAndrey Ignatov 		goto err;
15811f5fa9abSAndrey Ignatov 	}
15821f5fa9abSAndrey Ignatov 
15831f5fa9abSAndrey Ignatov 	goto out;
15841f5fa9abSAndrey Ignatov err:
15851f5fa9abSAndrey Ignatov 	err = -1;
15861f5fa9abSAndrey Ignatov out:
15871f5fa9abSAndrey Ignatov 	/* Detaching w/o checking return code: best effort attempt. */
15881f5fa9abSAndrey Ignatov 	if (progfd != -1)
15891f5fa9abSAndrey Ignatov 		bpf_prog_detach(cgfd, atype);
15901f5fa9abSAndrey Ignatov 	close(progfd);
15911f5fa9abSAndrey Ignatov 	printf("[%s]\n", err ? "FAIL" : "PASS");
15921f5fa9abSAndrey Ignatov 	return err;
15931f5fa9abSAndrey Ignatov }
15941f5fa9abSAndrey Ignatov 
run_tests(int cgfd)15951f5fa9abSAndrey Ignatov static int run_tests(int cgfd)
15961f5fa9abSAndrey Ignatov {
15971f5fa9abSAndrey Ignatov 	int passes = 0;
15981f5fa9abSAndrey Ignatov 	int fails = 0;
15991f5fa9abSAndrey Ignatov 	int i;
16001f5fa9abSAndrey Ignatov 
16011f5fa9abSAndrey Ignatov 	for (i = 0; i < ARRAY_SIZE(tests); ++i) {
16021f5fa9abSAndrey Ignatov 		if (run_test_case(cgfd, &tests[i]))
16031f5fa9abSAndrey Ignatov 			++fails;
16041f5fa9abSAndrey Ignatov 		else
16051f5fa9abSAndrey Ignatov 			++passes;
16061f5fa9abSAndrey Ignatov 	}
16071f5fa9abSAndrey Ignatov 	printf("Summary: %d PASSED, %d FAILED\n", passes, fails);
16081f5fa9abSAndrey Ignatov 	return fails ? -1 : 0;
16091f5fa9abSAndrey Ignatov }
16101f5fa9abSAndrey Ignatov 
main(int argc,char ** argv)16111f5fa9abSAndrey Ignatov int main(int argc, char **argv)
16121f5fa9abSAndrey Ignatov {
16131f5fa9abSAndrey Ignatov 	int cgfd = -1;
16141f5fa9abSAndrey Ignatov 	int err = 0;
16151f5fa9abSAndrey Ignatov 
16164939b284SJohn Fastabend 	cgfd = cgroup_setup_and_join(CG_PATH);
16171f5fa9abSAndrey Ignatov 	if (cgfd < 0)
16181f5fa9abSAndrey Ignatov 		goto err;
16191f5fa9abSAndrey Ignatov 
1620b858ba8cSYafang Shao 	/* Use libbpf 1.0 API mode */
1621b858ba8cSYafang Shao 	libbpf_set_strict_mode(LIBBPF_STRICT_ALL);
1622b858ba8cSYafang Shao 
16231f5fa9abSAndrey Ignatov 	if (run_tests(cgfd))
16241f5fa9abSAndrey Ignatov 		goto err;
16251f5fa9abSAndrey Ignatov 
16261f5fa9abSAndrey Ignatov 	goto out;
16271f5fa9abSAndrey Ignatov err:
16281f5fa9abSAndrey Ignatov 	err = -1;
16291f5fa9abSAndrey Ignatov out:
16301f5fa9abSAndrey Ignatov 	close(cgfd);
16311f5fa9abSAndrey Ignatov 	cleanup_cgroup_environment();
16321f5fa9abSAndrey Ignatov 	return err;
16331f5fa9abSAndrey Ignatov }
1634