brintos

brintos / linux-shallow public Read only

0
0
Text · 40.1 KiB · bcdbd27 Raw
1634 lines · c
1// SPDX-License-Identifier: GPL-2.02// Copyright (c) 2019 Facebook3 4#include <fcntl.h>5#include <stdint.h>6#include <stdio.h>7#include <stdlib.h>8#include <string.h>9#include <unistd.h>10 11#include <linux/filter.h>12 13#include <bpf/bpf.h>14#include <bpf/libbpf.h>15 16#include <bpf/bpf_endian.h>17#include "bpf_util.h"18#include "cgroup_helpers.h"19#include "testing_helpers.h"20 21#define CG_PATH			"/foo"22#define MAX_INSNS		51223#define FIXUP_SYSCTL_VALUE	024 25char bpf_log_buf[BPF_LOG_BUF_SIZE];26 27struct sysctl_test {28	const char *descr;29	size_t fixup_value_insn;30	struct bpf_insn	insns[MAX_INSNS];31	const char *prog_file;32	enum bpf_attach_type attach_type;33	const char *sysctl;34	int open_flags;35	int seek;36	const char *newval;37	const char *oldval;38	enum {39		LOAD_REJECT,40		ATTACH_REJECT,41		OP_EPERM,42		SUCCESS,43	} result;44};45 46static struct sysctl_test tests[] = {47	{48		.descr = "sysctl wrong attach_type",49		.insns = {50			BPF_MOV64_IMM(BPF_REG_0, 1),51			BPF_EXIT_INSN(),52		},53		.attach_type = 0,54		.sysctl = "kernel/ostype",55		.open_flags = O_RDONLY,56		.result = ATTACH_REJECT,57	},58	{59		.descr = "sysctl:read allow all",60		.insns = {61			BPF_MOV64_IMM(BPF_REG_0, 1),62			BPF_EXIT_INSN(),63		},64		.attach_type = BPF_CGROUP_SYSCTL,65		.sysctl = "kernel/ostype",66		.open_flags = O_RDONLY,67		.result = SUCCESS,68	},69	{70		.descr = "sysctl:read deny all",71		.insns = {72			BPF_MOV64_IMM(BPF_REG_0, 0),73			BPF_EXIT_INSN(),74		},75		.attach_type = BPF_CGROUP_SYSCTL,76		.sysctl = "kernel/ostype",77		.open_flags = O_RDONLY,78		.result = OP_EPERM,79	},80	{81		.descr = "ctx:write sysctl:read read ok",82		.insns = {83			/* If (write) */84			BPF_LDX_MEM(BPF_W, BPF_REG_7, BPF_REG_1,85				    offsetof(struct bpf_sysctl, write)),86			BPF_JMP_IMM(BPF_JNE, BPF_REG_7, 1, 2),87 88			/* return DENY; */89			BPF_MOV64_IMM(BPF_REG_0, 0),90			BPF_JMP_A(1),91 92			/* else return ALLOW; */93			BPF_MOV64_IMM(BPF_REG_0, 1),94			BPF_EXIT_INSN(),95		},96		.attach_type = BPF_CGROUP_SYSCTL,97		.sysctl = "kernel/ostype",98		.open_flags = O_RDONLY,99		.result = SUCCESS,100	},101	{102		.descr = "ctx:write sysctl:write read ok",103		.insns = {104			/* If (write) */105			BPF_LDX_MEM(BPF_W, BPF_REG_7, BPF_REG_1,106				    offsetof(struct bpf_sysctl, write)),107			BPF_JMP_IMM(BPF_JNE, BPF_REG_7, 1, 2),108 109			/* return DENY; */110			BPF_MOV64_IMM(BPF_REG_0, 0),111			BPF_JMP_A(1),112 113			/* else return ALLOW; */114			BPF_MOV64_IMM(BPF_REG_0, 1),115			BPF_EXIT_INSN(),116		},117		.attach_type = BPF_CGROUP_SYSCTL,118		.sysctl = "kernel/domainname",119		.open_flags = O_WRONLY,120		.newval = "(none)", /* same as default, should fail anyway */121		.result = OP_EPERM,122	},123	{124		.descr = "ctx:write sysctl:write read ok narrow",125		.insns = {126			/* u64 w = (u16)write & 1; */127#if __BYTE_ORDER__ == __ORDER_LITTLE_ENDIAN__128			BPF_LDX_MEM(BPF_H, BPF_REG_7, BPF_REG_1,129				    offsetof(struct bpf_sysctl, write)),130#else131			BPF_LDX_MEM(BPF_H, BPF_REG_7, BPF_REG_1,132				    offsetof(struct bpf_sysctl, write) + 2),133#endif134			BPF_ALU64_IMM(BPF_AND, BPF_REG_7, 1),135			/* return 1 - w; */136			BPF_MOV64_IMM(BPF_REG_0, 1),137			BPF_ALU64_REG(BPF_SUB, BPF_REG_0, BPF_REG_7),138			BPF_EXIT_INSN(),139		},140		.attach_type = BPF_CGROUP_SYSCTL,141		.sysctl = "kernel/domainname",142		.open_flags = O_WRONLY,143		.newval = "(none)", /* same as default, should fail anyway */144		.result = OP_EPERM,145	},146	{147		.descr = "ctx:write sysctl:read write reject",148		.insns = {149			/* write = X */150			BPF_MOV64_IMM(BPF_REG_0, 0),151			BPF_STX_MEM(BPF_W, BPF_REG_1, BPF_REG_0,152				    offsetof(struct bpf_sysctl, write)),153			BPF_MOV64_IMM(BPF_REG_0, 1),154			BPF_EXIT_INSN(),155		},156		.attach_type = BPF_CGROUP_SYSCTL,157		.sysctl = "kernel/ostype",158		.open_flags = O_RDONLY,159		.result = LOAD_REJECT,160	},161	{162		.descr = "ctx:file_pos sysctl:read read ok",163		.insns = {164			/* If (file_pos == X) */165			BPF_LDX_MEM(BPF_W, BPF_REG_7, BPF_REG_1,166				    offsetof(struct bpf_sysctl, file_pos)),167			BPF_JMP_IMM(BPF_JNE, BPF_REG_7, 3, 2),168 169			/* return ALLOW; */170			BPF_MOV64_IMM(BPF_REG_0, 1),171			BPF_JMP_A(1),172 173			/* else return DENY; */174			BPF_MOV64_IMM(BPF_REG_0, 0),175			BPF_EXIT_INSN(),176		},177		.attach_type = BPF_CGROUP_SYSCTL,178		.sysctl = "kernel/ostype",179		.open_flags = O_RDONLY,180		.seek = 3,181		.result = SUCCESS,182	},183	{184		.descr = "ctx:file_pos sysctl:read read ok narrow",185		.insns = {186			/* If (file_pos == X) */187#if __BYTE_ORDER__ == __ORDER_LITTLE_ENDIAN__188			BPF_LDX_MEM(BPF_B, BPF_REG_7, BPF_REG_1,189				    offsetof(struct bpf_sysctl, file_pos)),190#else191			BPF_LDX_MEM(BPF_B, BPF_REG_7, BPF_REG_1,192				    offsetof(struct bpf_sysctl, file_pos) + 3),193#endif194			BPF_JMP_IMM(BPF_JNE, BPF_REG_7, 4, 2),195 196			/* return ALLOW; */197			BPF_MOV64_IMM(BPF_REG_0, 1),198			BPF_JMP_A(1),199 200			/* else return DENY; */201			BPF_MOV64_IMM(BPF_REG_0, 0),202			BPF_EXIT_INSN(),203		},204		.attach_type = BPF_CGROUP_SYSCTL,205		.sysctl = "kernel/ostype",206		.open_flags = O_RDONLY,207		.seek = 4,208		.result = SUCCESS,209	},210	{211		.descr = "ctx:file_pos sysctl:read write ok",212		.insns = {213			/* file_pos = X */214			BPF_MOV64_IMM(BPF_REG_0, 2),215			BPF_STX_MEM(BPF_W, BPF_REG_1, BPF_REG_0,216				    offsetof(struct bpf_sysctl, file_pos)),217			BPF_MOV64_IMM(BPF_REG_0, 1),218			BPF_EXIT_INSN(),219		},220		.attach_type = BPF_CGROUP_SYSCTL,221		.sysctl = "kernel/ostype",222		.open_flags = O_RDONLY,223		.oldval = "nux\n",224		.result = SUCCESS,225	},226	{227		.descr = "sysctl_get_name sysctl_value:base ok",228		.insns = {229			/* sysctl_get_name arg2 (buf) */230			BPF_MOV64_REG(BPF_REG_7, BPF_REG_10),231			BPF_ALU64_IMM(BPF_ADD, BPF_REG_7, -8),232			BPF_MOV64_IMM(BPF_REG_0, 0),233			BPF_STX_MEM(BPF_DW, BPF_REG_7, BPF_REG_0, 0),234 235			BPF_MOV64_REG(BPF_REG_2, BPF_REG_7),236 237			/* sysctl_get_name arg3 (buf_len) */238			BPF_MOV64_IMM(BPF_REG_3, 8),239 240			/* sysctl_get_name arg4 (flags) */241			BPF_MOV64_IMM(BPF_REG_4, BPF_F_SYSCTL_BASE_NAME),242 243			/* sysctl_get_name(ctx, buf, buf_len, flags) */244			BPF_EMIT_CALL(BPF_FUNC_sysctl_get_name),245 246			/* if (ret == expected && */247			BPF_JMP_IMM(BPF_JNE, BPF_REG_0, sizeof("tcp_mem") - 1, 6),248			/*     buf == "tcp_mem\0") */249			BPF_LD_IMM64(BPF_REG_8,250				     bpf_be64_to_cpu(0x7463705f6d656d00ULL)),251			BPF_LDX_MEM(BPF_DW, BPF_REG_9, BPF_REG_7, 0),252			BPF_JMP_REG(BPF_JNE, BPF_REG_8, BPF_REG_9, 2),253 254			/* return ALLOW; */255			BPF_MOV64_IMM(BPF_REG_0, 1),256			BPF_JMP_A(1),257 258			/* else return DENY; */259			BPF_MOV64_IMM(BPF_REG_0, 0),260			BPF_EXIT_INSN(),261		},262		.attach_type = BPF_CGROUP_SYSCTL,263		.sysctl = "net/ipv4/tcp_mem",264		.open_flags = O_RDONLY,265		.result = SUCCESS,266	},267	{268		.descr = "sysctl_get_name sysctl_value:base E2BIG truncated",269		.insns = {270			/* sysctl_get_name arg2 (buf) */271			BPF_MOV64_REG(BPF_REG_7, BPF_REG_10),272			BPF_ALU64_IMM(BPF_ADD, BPF_REG_7, -8),273			BPF_MOV64_IMM(BPF_REG_0, 0),274			BPF_STX_MEM(BPF_DW, BPF_REG_7, BPF_REG_0, 0),275 276			BPF_MOV64_REG(BPF_REG_2, BPF_REG_7),277 278			/* sysctl_get_name arg3 (buf_len) too small */279			BPF_MOV64_IMM(BPF_REG_3, 7),280 281			/* sysctl_get_name arg4 (flags) */282			BPF_MOV64_IMM(BPF_REG_4, BPF_F_SYSCTL_BASE_NAME),283 284			/* sysctl_get_name(ctx, buf, buf_len, flags) */285			BPF_EMIT_CALL(BPF_FUNC_sysctl_get_name),286 287			/* if (ret == expected && */288			BPF_JMP_IMM(BPF_JNE, BPF_REG_0, -E2BIG, 6),289 290			/*     buf[0:7] == "tcp_me\0") */291			BPF_LD_IMM64(BPF_REG_8,292				     bpf_be64_to_cpu(0x7463705f6d650000ULL)),293			BPF_LDX_MEM(BPF_DW, BPF_REG_9, BPF_REG_7, 0),294			BPF_JMP_REG(BPF_JNE, BPF_REG_8, BPF_REG_9, 2),295 296			/* return ALLOW; */297			BPF_MOV64_IMM(BPF_REG_0, 1),298			BPF_JMP_A(1),299 300			/* else return DENY; */301			BPF_MOV64_IMM(BPF_REG_0, 0),302			BPF_EXIT_INSN(),303		},304		.attach_type = BPF_CGROUP_SYSCTL,305		.sysctl = "net/ipv4/tcp_mem",306		.open_flags = O_RDONLY,307		.result = SUCCESS,308	},309	{310		.descr = "sysctl_get_name sysctl:full ok",311		.insns = {312			/* sysctl_get_name arg2 (buf) */313			BPF_MOV64_REG(BPF_REG_7, BPF_REG_10),314			BPF_ALU64_IMM(BPF_ADD, BPF_REG_7, -24),315			BPF_MOV64_IMM(BPF_REG_0, 0),316			BPF_STX_MEM(BPF_DW, BPF_REG_7, BPF_REG_0, 0),317			BPF_STX_MEM(BPF_DW, BPF_REG_7, BPF_REG_0, 8),318			BPF_STX_MEM(BPF_DW, BPF_REG_7, BPF_REG_0, 16),319 320			BPF_MOV64_REG(BPF_REG_2, BPF_REG_7),321 322			/* sysctl_get_name arg3 (buf_len) */323			BPF_MOV64_IMM(BPF_REG_3, 17),324 325			/* sysctl_get_name arg4 (flags) */326			BPF_MOV64_IMM(BPF_REG_4, 0),327 328			/* sysctl_get_name(ctx, buf, buf_len, flags) */329			BPF_EMIT_CALL(BPF_FUNC_sysctl_get_name),330 331			/* if (ret == expected && */332			BPF_JMP_IMM(BPF_JNE, BPF_REG_0, 16, 14),333 334			/*     buf[0:8] == "net/ipv4" && */335			BPF_LD_IMM64(BPF_REG_8,336				     bpf_be64_to_cpu(0x6e65742f69707634ULL)),337			BPF_LDX_MEM(BPF_DW, BPF_REG_9, BPF_REG_7, 0),338			BPF_JMP_REG(BPF_JNE, BPF_REG_8, BPF_REG_9, 10),339 340			/*     buf[8:16] == "/tcp_mem" && */341			BPF_LD_IMM64(BPF_REG_8,342				     bpf_be64_to_cpu(0x2f7463705f6d656dULL)),343			BPF_LDX_MEM(BPF_DW, BPF_REG_9, BPF_REG_7, 8),344			BPF_JMP_REG(BPF_JNE, BPF_REG_8, BPF_REG_9, 6),345 346			/*     buf[16:24] == "\0") */347			BPF_LD_IMM64(BPF_REG_8, 0x0ULL),348			BPF_LDX_MEM(BPF_DW, BPF_REG_9, BPF_REG_7, 16),349			BPF_JMP_REG(BPF_JNE, BPF_REG_8, BPF_REG_9, 2),350 351			/* return ALLOW; */352			BPF_MOV64_IMM(BPF_REG_0, 1),353			BPF_JMP_A(1),354 355			/* else return DENY; */356			BPF_MOV64_IMM(BPF_REG_0, 0),357			BPF_EXIT_INSN(),358		},359		.attach_type = BPF_CGROUP_SYSCTL,360		.sysctl = "net/ipv4/tcp_mem",361		.open_flags = O_RDONLY,362		.result = SUCCESS,363	},364	{365		.descr = "sysctl_get_name sysctl:full E2BIG truncated",366		.insns = {367			/* sysctl_get_name arg2 (buf) */368			BPF_MOV64_REG(BPF_REG_7, BPF_REG_10),369			BPF_ALU64_IMM(BPF_ADD, BPF_REG_7, -16),370			BPF_MOV64_IMM(BPF_REG_0, 0),371			BPF_STX_MEM(BPF_DW, BPF_REG_7, BPF_REG_0, 0),372			BPF_STX_MEM(BPF_DW, BPF_REG_7, BPF_REG_0, 8),373 374			BPF_MOV64_REG(BPF_REG_2, BPF_REG_7),375 376			/* sysctl_get_name arg3 (buf_len) */377			BPF_MOV64_IMM(BPF_REG_3, 16),378 379			/* sysctl_get_name arg4 (flags) */380			BPF_MOV64_IMM(BPF_REG_4, 0),381 382			/* sysctl_get_name(ctx, buf, buf_len, flags) */383			BPF_EMIT_CALL(BPF_FUNC_sysctl_get_name),384 385			/* if (ret == expected && */386			BPF_JMP_IMM(BPF_JNE, BPF_REG_0, -E2BIG, 10),387 388			/*     buf[0:8] == "net/ipv4" && */389			BPF_LD_IMM64(BPF_REG_8,390				     bpf_be64_to_cpu(0x6e65742f69707634ULL)),391			BPF_LDX_MEM(BPF_DW, BPF_REG_9, BPF_REG_7, 0),392			BPF_JMP_REG(BPF_JNE, BPF_REG_8, BPF_REG_9, 6),393 394			/*     buf[8:16] == "/tcp_me\0") */395			BPF_LD_IMM64(BPF_REG_8,396				     bpf_be64_to_cpu(0x2f7463705f6d6500ULL)),397			BPF_LDX_MEM(BPF_DW, BPF_REG_9, BPF_REG_7, 8),398			BPF_JMP_REG(BPF_JNE, BPF_REG_8, BPF_REG_9, 2),399 400			/* return ALLOW; */401			BPF_MOV64_IMM(BPF_REG_0, 1),402			BPF_JMP_A(1),403 404			/* else return DENY; */405			BPF_MOV64_IMM(BPF_REG_0, 0),406			BPF_EXIT_INSN(),407		},408		.attach_type = BPF_CGROUP_SYSCTL,409		.sysctl = "net/ipv4/tcp_mem",410		.open_flags = O_RDONLY,411		.result = SUCCESS,412	},413	{414		.descr = "sysctl_get_name sysctl:full E2BIG truncated small",415		.insns = {416			/* sysctl_get_name arg2 (buf) */417			BPF_MOV64_REG(BPF_REG_7, BPF_REG_10),418			BPF_ALU64_IMM(BPF_ADD, BPF_REG_7, -8),419			BPF_MOV64_IMM(BPF_REG_0, 0),420			BPF_STX_MEM(BPF_DW, BPF_REG_7, BPF_REG_0, 0),421 422			BPF_MOV64_REG(BPF_REG_2, BPF_REG_7),423 424			/* sysctl_get_name arg3 (buf_len) */425			BPF_MOV64_IMM(BPF_REG_3, 7),426 427			/* sysctl_get_name arg4 (flags) */428			BPF_MOV64_IMM(BPF_REG_4, 0),429 430			/* sysctl_get_name(ctx, buf, buf_len, flags) */431			BPF_EMIT_CALL(BPF_FUNC_sysctl_get_name),432 433			/* if (ret == expected && */434			BPF_JMP_IMM(BPF_JNE, BPF_REG_0, -E2BIG, 6),435 436			/*     buf[0:8] == "net/ip\0") */437			BPF_LD_IMM64(BPF_REG_8,438				     bpf_be64_to_cpu(0x6e65742f69700000ULL)),439			BPF_LDX_MEM(BPF_DW, BPF_REG_9, BPF_REG_7, 0),440			BPF_JMP_REG(BPF_JNE, BPF_REG_8, BPF_REG_9, 2),441 442			/* return ALLOW; */443			BPF_MOV64_IMM(BPF_REG_0, 1),444			BPF_JMP_A(1),445 446			/* else return DENY; */447			BPF_MOV64_IMM(BPF_REG_0, 0),448			BPF_EXIT_INSN(),449		},450		.attach_type = BPF_CGROUP_SYSCTL,451		.sysctl = "net/ipv4/tcp_mem",452		.open_flags = O_RDONLY,453		.result = SUCCESS,454	},455	{456		.descr = "sysctl_get_current_value sysctl:read ok, gt",457		.insns = {458			/* sysctl_get_current_value arg2 (buf) */459			BPF_MOV64_REG(BPF_REG_7, BPF_REG_10),460			BPF_ALU64_IMM(BPF_ADD, BPF_REG_7, -8),461			BPF_MOV64_REG(BPF_REG_2, BPF_REG_7),462 463			/* sysctl_get_current_value arg3 (buf_len) */464			BPF_MOV64_IMM(BPF_REG_3, 8),465 466			/* sysctl_get_current_value(ctx, buf, buf_len) */467			BPF_EMIT_CALL(BPF_FUNC_sysctl_get_current_value),468 469			/* if (ret == expected && */470			BPF_JMP_IMM(BPF_JNE, BPF_REG_0, 6, 6),471 472			/*     buf[0:6] == "Linux\n\0") */473			BPF_LD_IMM64(BPF_REG_8,474				     bpf_be64_to_cpu(0x4c696e75780a0000ULL)),475			BPF_LDX_MEM(BPF_DW, BPF_REG_9, BPF_REG_7, 0),476			BPF_JMP_REG(BPF_JNE, BPF_REG_8, BPF_REG_9, 2),477 478			/* return ALLOW; */479			BPF_MOV64_IMM(BPF_REG_0, 1),480			BPF_JMP_A(1),481 482			/* else return DENY; */483			BPF_MOV64_IMM(BPF_REG_0, 0),484			BPF_EXIT_INSN(),485		},486		.attach_type = BPF_CGROUP_SYSCTL,487		.sysctl = "kernel/ostype",488		.open_flags = O_RDONLY,489		.result = SUCCESS,490	},491	{492		.descr = "sysctl_get_current_value sysctl:read ok, eq",493		.insns = {494			/* sysctl_get_current_value arg2 (buf) */495			BPF_MOV64_REG(BPF_REG_7, BPF_REG_10),496			BPF_ALU64_IMM(BPF_ADD, BPF_REG_7, -8),497			BPF_MOV64_IMM(BPF_REG_0, 0),498			BPF_STX_MEM(BPF_B, BPF_REG_7, BPF_REG_0, 7),499 500			BPF_MOV64_REG(BPF_REG_2, BPF_REG_7),501 502			/* sysctl_get_current_value arg3 (buf_len) */503			BPF_MOV64_IMM(BPF_REG_3, 7),504 505			/* sysctl_get_current_value(ctx, buf, buf_len) */506			BPF_EMIT_CALL(BPF_FUNC_sysctl_get_current_value),507 508			/* if (ret == expected && */509			BPF_JMP_IMM(BPF_JNE, BPF_REG_0, 6, 6),510 511			/*     buf[0:6] == "Linux\n\0") */512			BPF_LD_IMM64(BPF_REG_8,513				     bpf_be64_to_cpu(0x4c696e75780a0000ULL)),514			BPF_LDX_MEM(BPF_DW, BPF_REG_9, BPF_REG_7, 0),515			BPF_JMP_REG(BPF_JNE, BPF_REG_8, BPF_REG_9, 2),516 517			/* return ALLOW; */518			BPF_MOV64_IMM(BPF_REG_0, 1),519			BPF_JMP_A(1),520 521			/* else return DENY; */522			BPF_MOV64_IMM(BPF_REG_0, 0),523			BPF_EXIT_INSN(),524		},525		.attach_type = BPF_CGROUP_SYSCTL,526		.sysctl = "kernel/ostype",527		.open_flags = O_RDONLY,528		.result = SUCCESS,529	},530	{531		.descr = "sysctl_get_current_value sysctl:read E2BIG truncated",532		.insns = {533			/* sysctl_get_current_value arg2 (buf) */534			BPF_MOV64_REG(BPF_REG_7, BPF_REG_10),535			BPF_ALU64_IMM(BPF_ADD, BPF_REG_7, -8),536			BPF_MOV64_IMM(BPF_REG_0, 0),537			BPF_STX_MEM(BPF_H, BPF_REG_7, BPF_REG_0, 6),538 539			BPF_MOV64_REG(BPF_REG_2, BPF_REG_7),540 541			/* sysctl_get_current_value arg3 (buf_len) */542			BPF_MOV64_IMM(BPF_REG_3, 6),543 544			/* sysctl_get_current_value(ctx, buf, buf_len) */545			BPF_EMIT_CALL(BPF_FUNC_sysctl_get_current_value),546 547			/* if (ret == expected && */548			BPF_JMP_IMM(BPF_JNE, BPF_REG_0, -E2BIG, 6),549 550			/*     buf[0:6] == "Linux\0") */551			BPF_LD_IMM64(BPF_REG_8,552				     bpf_be64_to_cpu(0x4c696e7578000000ULL)),553			BPF_LDX_MEM(BPF_DW, BPF_REG_9, BPF_REG_7, 0),554			BPF_JMP_REG(BPF_JNE, BPF_REG_8, BPF_REG_9, 2),555 556			/* return ALLOW; */557			BPF_MOV64_IMM(BPF_REG_0, 1),558			BPF_JMP_A(1),559 560			/* else return DENY; */561			BPF_MOV64_IMM(BPF_REG_0, 0),562			BPF_EXIT_INSN(),563		},564		.attach_type = BPF_CGROUP_SYSCTL,565		.sysctl = "kernel/ostype",566		.open_flags = O_RDONLY,567		.result = SUCCESS,568	},569	{570		.descr = "sysctl_get_current_value sysctl:read EINVAL",571		.insns = {572			/* sysctl_get_current_value arg2 (buf) */573			BPF_MOV64_REG(BPF_REG_7, BPF_REG_10),574			BPF_ALU64_IMM(BPF_ADD, BPF_REG_7, -8),575 576			BPF_MOV64_REG(BPF_REG_2, BPF_REG_7),577 578			/* sysctl_get_current_value arg3 (buf_len) */579			BPF_MOV64_IMM(BPF_REG_3, 8),580 581			/* sysctl_get_current_value(ctx, buf, buf_len) */582			BPF_EMIT_CALL(BPF_FUNC_sysctl_get_current_value),583 584			/* if (ret == expected && */585			BPF_JMP_IMM(BPF_JNE, BPF_REG_0, -EINVAL, 4),586 587			/*     buf[0:8] is NUL-filled) */588			BPF_LDX_MEM(BPF_DW, BPF_REG_9, BPF_REG_7, 0),589			BPF_JMP_IMM(BPF_JNE, BPF_REG_9, 0, 2),590 591			/* return DENY; */592			BPF_MOV64_IMM(BPF_REG_0, 0),593			BPF_JMP_A(1),594 595			/* else return ALLOW; */596			BPF_MOV64_IMM(BPF_REG_0, 1),597			BPF_EXIT_INSN(),598		},599		.attach_type = BPF_CGROUP_SYSCTL,600		.sysctl = "net/ipv6/conf/lo/stable_secret", /* -EIO */601		.open_flags = O_RDONLY,602		.result = OP_EPERM,603	},604	{605		.descr = "sysctl_get_current_value sysctl:write ok",606		.fixup_value_insn = 6,607		.insns = {608			/* sysctl_get_current_value arg2 (buf) */609			BPF_MOV64_REG(BPF_REG_7, BPF_REG_10),610			BPF_ALU64_IMM(BPF_ADD, BPF_REG_7, -8),611 612			BPF_MOV64_REG(BPF_REG_2, BPF_REG_7),613 614			/* sysctl_get_current_value arg3 (buf_len) */615			BPF_MOV64_IMM(BPF_REG_3, 8),616 617			/* sysctl_get_current_value(ctx, buf, buf_len) */618			BPF_EMIT_CALL(BPF_FUNC_sysctl_get_current_value),619 620			/* if (ret == expected && */621			BPF_JMP_IMM(BPF_JNE, BPF_REG_0, 4, 6),622 623			/*     buf[0:4] == expected) */624			BPF_LD_IMM64(BPF_REG_8, FIXUP_SYSCTL_VALUE),625			BPF_LDX_MEM(BPF_DW, BPF_REG_9, BPF_REG_7, 0),626			BPF_JMP_REG(BPF_JNE, BPF_REG_8, BPF_REG_9, 2),627 628			/* return DENY; */629			BPF_MOV64_IMM(BPF_REG_0, 0),630			BPF_JMP_A(1),631 632			/* else return ALLOW; */633			BPF_MOV64_IMM(BPF_REG_0, 1),634			BPF_EXIT_INSN(),635		},636		.attach_type = BPF_CGROUP_SYSCTL,637		.sysctl = "net/ipv4/route/mtu_expires",638		.open_flags = O_WRONLY,639		.newval = "600", /* same as default, should fail anyway */640		.result = OP_EPERM,641	},642	{643		.descr = "sysctl_get_new_value sysctl:read EINVAL",644		.insns = {645			/* sysctl_get_new_value arg2 (buf) */646			BPF_MOV64_REG(BPF_REG_7, BPF_REG_10),647			BPF_ALU64_IMM(BPF_ADD, BPF_REG_7, -8),648			BPF_MOV64_IMM(BPF_REG_0, 0),649			BPF_STX_MEM(BPF_DW, BPF_REG_7, BPF_REG_0, 0),650 651			BPF_MOV64_REG(BPF_REG_2, BPF_REG_7),652 653			/* sysctl_get_new_value arg3 (buf_len) */654			BPF_MOV64_IMM(BPF_REG_3, 8),655 656			/* sysctl_get_new_value(ctx, buf, buf_len) */657			BPF_EMIT_CALL(BPF_FUNC_sysctl_get_new_value),658 659			/* if (ret == expected) */660			BPF_JMP_IMM(BPF_JNE, BPF_REG_0, -EINVAL, 2),661 662			/* return ALLOW; */663			BPF_MOV64_IMM(BPF_REG_0, 1),664			BPF_JMP_A(1),665 666			/* else return DENY; */667			BPF_MOV64_IMM(BPF_REG_0, 0),668			BPF_EXIT_INSN(),669		},670		.attach_type = BPF_CGROUP_SYSCTL,671		.sysctl = "net/ipv4/tcp_mem",672		.open_flags = O_RDONLY,673		.result = SUCCESS,674	},675	{676		.descr = "sysctl_get_new_value sysctl:write ok",677		.insns = {678			/* sysctl_get_new_value arg2 (buf) */679			BPF_MOV64_REG(BPF_REG_7, BPF_REG_10),680			BPF_ALU64_IMM(BPF_ADD, BPF_REG_7, -8),681 682			BPF_MOV64_REG(BPF_REG_2, BPF_REG_7),683 684			/* sysctl_get_new_value arg3 (buf_len) */685			BPF_MOV64_IMM(BPF_REG_3, 4),686 687			/* sysctl_get_new_value(ctx, buf, buf_len) */688			BPF_EMIT_CALL(BPF_FUNC_sysctl_get_new_value),689 690			/* if (ret == expected && */691			BPF_JMP_IMM(BPF_JNE, BPF_REG_0, 3, 4),692 693			/*     buf[0:4] == "606\0") */694			BPF_LDX_MEM(BPF_W, BPF_REG_9, BPF_REG_7, 0),695			BPF_JMP_IMM(BPF_JNE, BPF_REG_9,696				    bpf_ntohl(0x36303600), 2),697 698			/* return DENY; */699			BPF_MOV64_IMM(BPF_REG_0, 0),700			BPF_JMP_A(1),701 702			/* else return ALLOW; */703			BPF_MOV64_IMM(BPF_REG_0, 1),704			BPF_EXIT_INSN(),705		},706		.attach_type = BPF_CGROUP_SYSCTL,707		.sysctl = "net/ipv4/route/mtu_expires",708		.open_flags = O_WRONLY,709		.newval = "606",710		.result = OP_EPERM,711	},712	{713		.descr = "sysctl_get_new_value sysctl:write ok long",714		.insns = {715			/* sysctl_get_new_value arg2 (buf) */716			BPF_MOV64_REG(BPF_REG_7, BPF_REG_10),717			BPF_ALU64_IMM(BPF_ADD, BPF_REG_7, -24),718 719			BPF_MOV64_REG(BPF_REG_2, BPF_REG_7),720 721			/* sysctl_get_new_value arg3 (buf_len) */722			BPF_MOV64_IMM(BPF_REG_3, 24),723 724			/* sysctl_get_new_value(ctx, buf, buf_len) */725			BPF_EMIT_CALL(BPF_FUNC_sysctl_get_new_value),726 727			/* if (ret == expected && */728			BPF_JMP_IMM(BPF_JNE, BPF_REG_0, 23, 14),729 730			/*     buf[0:8] == "3000000 " && */731			BPF_LD_IMM64(BPF_REG_8,732				     bpf_be64_to_cpu(0x3330303030303020ULL)),733			BPF_LDX_MEM(BPF_DW, BPF_REG_9, BPF_REG_7, 0),734			BPF_JMP_REG(BPF_JNE, BPF_REG_8, BPF_REG_9, 10),735 736			/*     buf[8:16] == "4000000 " && */737			BPF_LD_IMM64(BPF_REG_8,738				     bpf_be64_to_cpu(0x3430303030303020ULL)),739			BPF_LDX_MEM(BPF_DW, BPF_REG_9, BPF_REG_7, 8),740			BPF_JMP_REG(BPF_JNE, BPF_REG_8, BPF_REG_9, 6),741 742			/*     buf[16:24] == "6000000\0") */743			BPF_LD_IMM64(BPF_REG_8,744				     bpf_be64_to_cpu(0x3630303030303000ULL)),745			BPF_LDX_MEM(BPF_DW, BPF_REG_9, BPF_REG_7, 16),746			BPF_JMP_REG(BPF_JNE, BPF_REG_8, BPF_REG_9, 2),747 748			/* return DENY; */749			BPF_MOV64_IMM(BPF_REG_0, 0),750			BPF_JMP_A(1),751 752			/* else return ALLOW; */753			BPF_MOV64_IMM(BPF_REG_0, 1),754			BPF_EXIT_INSN(),755		},756		.attach_type = BPF_CGROUP_SYSCTL,757		.sysctl = "net/ipv4/tcp_mem",758		.open_flags = O_WRONLY,759		.newval = "3000000 4000000 6000000",760		.result = OP_EPERM,761	},762	{763		.descr = "sysctl_get_new_value sysctl:write E2BIG",764		.insns = {765			/* sysctl_get_new_value arg2 (buf) */766			BPF_MOV64_REG(BPF_REG_7, BPF_REG_10),767			BPF_ALU64_IMM(BPF_ADD, BPF_REG_7, -8),768			BPF_MOV64_IMM(BPF_REG_0, 0),769			BPF_STX_MEM(BPF_B, BPF_REG_7, BPF_REG_0, 3),770 771			BPF_MOV64_REG(BPF_REG_2, BPF_REG_7),772 773			/* sysctl_get_new_value arg3 (buf_len) */774			BPF_MOV64_IMM(BPF_REG_3, 3),775 776			/* sysctl_get_new_value(ctx, buf, buf_len) */777			BPF_EMIT_CALL(BPF_FUNC_sysctl_get_new_value),778 779			/* if (ret == expected && */780			BPF_JMP_IMM(BPF_JNE, BPF_REG_0, -E2BIG, 4),781 782			/*     buf[0:3] == "60\0") */783			BPF_LDX_MEM(BPF_W, BPF_REG_9, BPF_REG_7, 0),784			BPF_JMP_IMM(BPF_JNE, BPF_REG_9,785				    bpf_ntohl(0x36300000), 2),786 787			/* return DENY; */788			BPF_MOV64_IMM(BPF_REG_0, 0),789			BPF_JMP_A(1),790 791			/* else return ALLOW; */792			BPF_MOV64_IMM(BPF_REG_0, 1),793			BPF_EXIT_INSN(),794		},795		.attach_type = BPF_CGROUP_SYSCTL,796		.sysctl = "net/ipv4/route/mtu_expires",797		.open_flags = O_WRONLY,798		.newval = "606",799		.result = OP_EPERM,800	},801	{802		.descr = "sysctl_set_new_value sysctl:read EINVAL",803		.insns = {804			/* sysctl_set_new_value arg2 (buf) */805			BPF_MOV64_REG(BPF_REG_7, BPF_REG_10),806			BPF_ALU64_IMM(BPF_ADD, BPF_REG_7, -8),807			BPF_MOV64_IMM(BPF_REG_0,808				      bpf_ntohl(0x36303000)),809			BPF_STX_MEM(BPF_DW, BPF_REG_7, BPF_REG_0, 0),810 811			BPF_MOV64_REG(BPF_REG_2, BPF_REG_7),812 813			/* sysctl_set_new_value arg3 (buf_len) */814			BPF_MOV64_IMM(BPF_REG_3, 3),815 816			/* sysctl_set_new_value(ctx, buf, buf_len) */817			BPF_EMIT_CALL(BPF_FUNC_sysctl_set_new_value),818 819			/* if (ret == expected) */820			BPF_JMP_IMM(BPF_JNE, BPF_REG_0, -EINVAL, 2),821 822			/* return ALLOW; */823			BPF_MOV64_IMM(BPF_REG_0, 1),824			BPF_JMP_A(1),825 826			/* else return DENY; */827			BPF_MOV64_IMM(BPF_REG_0, 0),828			BPF_EXIT_INSN(),829		},830		.attach_type = BPF_CGROUP_SYSCTL,831		.sysctl = "net/ipv4/route/mtu_expires",832		.open_flags = O_RDONLY,833		.result = SUCCESS,834	},835	{836		.descr = "sysctl_set_new_value sysctl:write ok",837		.fixup_value_insn = 2,838		.insns = {839			/* sysctl_set_new_value arg2 (buf) */840			BPF_MOV64_REG(BPF_REG_7, BPF_REG_10),841			BPF_ALU64_IMM(BPF_ADD, BPF_REG_7, -8),842			BPF_LD_IMM64(BPF_REG_0, FIXUP_SYSCTL_VALUE),843			BPF_STX_MEM(BPF_DW, BPF_REG_7, BPF_REG_0, 0),844 845			BPF_MOV64_REG(BPF_REG_2, BPF_REG_7),846 847			/* sysctl_set_new_value arg3 (buf_len) */848			BPF_MOV64_IMM(BPF_REG_3, 3),849 850			/* sysctl_set_new_value(ctx, buf, buf_len) */851			BPF_EMIT_CALL(BPF_FUNC_sysctl_set_new_value),852 853			/* if (ret == expected) */854			BPF_JMP_IMM(BPF_JNE, BPF_REG_0, 0, 2),855 856			/* return ALLOW; */857			BPF_MOV64_IMM(BPF_REG_0, 1),858			BPF_JMP_A(1),859 860			/* else return DENY; */861			BPF_MOV64_IMM(BPF_REG_0, 0),862			BPF_EXIT_INSN(),863		},864		.attach_type = BPF_CGROUP_SYSCTL,865		.sysctl = "net/ipv4/route/mtu_expires",866		.open_flags = O_WRONLY,867		.newval = "606",868		.result = SUCCESS,869	},870	{871		"bpf_strtoul one number string",872		.insns = {873			/* arg1 (buf) */874			BPF_MOV64_REG(BPF_REG_7, BPF_REG_10),875			BPF_ALU64_IMM(BPF_ADD, BPF_REG_7, -8),876			BPF_MOV64_IMM(BPF_REG_0,877				      bpf_ntohl(0x36303000)),878			BPF_STX_MEM(BPF_W, BPF_REG_7, BPF_REG_0, 0),879 880			BPF_MOV64_REG(BPF_REG_1, BPF_REG_7),881 882			/* arg2 (buf_len) */883			BPF_MOV64_IMM(BPF_REG_2, 4),884 885			/* arg3 (flags) */886			BPF_MOV64_IMM(BPF_REG_3, 0),887 888			/* arg4 (res) */889			BPF_ALU64_IMM(BPF_ADD, BPF_REG_7, -8),890			BPF_STX_MEM(BPF_DW, BPF_REG_7, BPF_REG_0, 0),891			BPF_MOV64_REG(BPF_REG_4, BPF_REG_7),892 893			BPF_EMIT_CALL(BPF_FUNC_strtoul),894 895			/* if (ret == expected && */896			BPF_JMP_IMM(BPF_JNE, BPF_REG_0, 3, 4),897			/*     res == expected) */898			BPF_LDX_MEM(BPF_DW, BPF_REG_9, BPF_REG_7, 0),899			BPF_JMP_IMM(BPF_JNE, BPF_REG_9, 600, 2),900 901			/* return ALLOW; */902			BPF_MOV64_IMM(BPF_REG_0, 1),903			BPF_JMP_A(1),904 905			/* else return DENY; */906			BPF_MOV64_IMM(BPF_REG_0, 0),907			BPF_EXIT_INSN(),908		},909		.attach_type = BPF_CGROUP_SYSCTL,910		.sysctl = "net/ipv4/route/mtu_expires",911		.open_flags = O_RDONLY,912		.result = SUCCESS,913	},914	{915		"bpf_strtoul multi number string",916		.insns = {917			/* arg1 (buf) */918			BPF_MOV64_REG(BPF_REG_7, BPF_REG_10),919			BPF_ALU64_IMM(BPF_ADD, BPF_REG_7, -8),920			/* "600 602\0" */921			BPF_LD_IMM64(BPF_REG_0,922				     bpf_be64_to_cpu(0x3630302036303200ULL)),923			BPF_STX_MEM(BPF_DW, BPF_REG_7, BPF_REG_0, 0),924			BPF_MOV64_REG(BPF_REG_1, BPF_REG_7),925 926			/* arg2 (buf_len) */927			BPF_MOV64_IMM(BPF_REG_2, 8),928 929			/* arg3 (flags) */930			BPF_MOV64_IMM(BPF_REG_3, 0),931 932			/* arg4 (res) */933			BPF_ALU64_IMM(BPF_ADD, BPF_REG_7, -8),934			BPF_STX_MEM(BPF_DW, BPF_REG_7, BPF_REG_0, 0),935			BPF_MOV64_REG(BPF_REG_4, BPF_REG_7),936 937			BPF_EMIT_CALL(BPF_FUNC_strtoul),938 939			/* if (ret == expected && */940			BPF_JMP_IMM(BPF_JNE, BPF_REG_0, 3, 18),941			/*     res == expected) */942			BPF_LDX_MEM(BPF_DW, BPF_REG_9, BPF_REG_7, 0),943			BPF_JMP_IMM(BPF_JNE, BPF_REG_9, 600, 16),944 945			/*     arg1 (buf) */946			BPF_MOV64_REG(BPF_REG_7, BPF_REG_10),947			BPF_ALU64_IMM(BPF_ADD, BPF_REG_7, -8),948			BPF_ALU64_REG(BPF_ADD, BPF_REG_7, BPF_REG_0),949			BPF_MOV64_REG(BPF_REG_1, BPF_REG_7),950 951			/*     arg2 (buf_len) */952			BPF_MOV64_IMM(BPF_REG_2, 8),953			BPF_ALU64_REG(BPF_SUB, BPF_REG_2, BPF_REG_0),954 955			/*     arg3 (flags) */956			BPF_MOV64_IMM(BPF_REG_3, 0),957 958			/*     arg4 (res) */959			BPF_MOV64_REG(BPF_REG_7, BPF_REG_10),960			BPF_ALU64_IMM(BPF_ADD, BPF_REG_7, -16),961			BPF_MOV64_REG(BPF_REG_4, BPF_REG_7),962 963			BPF_EMIT_CALL(BPF_FUNC_strtoul),964 965			/*     if (ret == expected && */966			BPF_JMP_IMM(BPF_JNE, BPF_REG_0, 4, 4),967			/*         res == expected) */968			BPF_LDX_MEM(BPF_DW, BPF_REG_9, BPF_REG_7, 0),969			BPF_JMP_IMM(BPF_JNE, BPF_REG_9, 602, 2),970 971			/* return ALLOW; */972			BPF_MOV64_IMM(BPF_REG_0, 1),973			BPF_JMP_A(1),974 975			/* else return DENY; */976			BPF_MOV64_IMM(BPF_REG_0, 0),977			BPF_EXIT_INSN(),978		},979		.attach_type = BPF_CGROUP_SYSCTL,980		.sysctl = "net/ipv4/tcp_mem",981		.open_flags = O_RDONLY,982		.result = SUCCESS,983	},984	{985		"bpf_strtoul buf_len = 0, reject",986		.insns = {987			/* arg1 (buf) */988			BPF_MOV64_REG(BPF_REG_7, BPF_REG_10),989			BPF_ALU64_IMM(BPF_ADD, BPF_REG_7, -8),990			BPF_MOV64_IMM(BPF_REG_0,991				      bpf_ntohl(0x36303000)),992			BPF_STX_MEM(BPF_DW, BPF_REG_7, BPF_REG_0, 0),993 994			BPF_MOV64_REG(BPF_REG_1, BPF_REG_7),995 996			/* arg2 (buf_len) */997			BPF_MOV64_IMM(BPF_REG_2, 0),998 999			/* arg3 (flags) */1000			BPF_MOV64_IMM(BPF_REG_3, 0),1001 1002			/* arg4 (res) */1003			BPF_ALU64_IMM(BPF_ADD, BPF_REG_7, -8),1004			BPF_STX_MEM(BPF_DW, BPF_REG_7, BPF_REG_0, 0),1005			BPF_MOV64_REG(BPF_REG_4, BPF_REG_7),1006 1007			BPF_EMIT_CALL(BPF_FUNC_strtoul),1008 1009			BPF_MOV64_IMM(BPF_REG_0, 1),1010			BPF_EXIT_INSN(),1011		},1012		.attach_type = BPF_CGROUP_SYSCTL,1013		.sysctl = "net/ipv4/route/mtu_expires",1014		.open_flags = O_RDONLY,1015		.result = LOAD_REJECT,1016	},1017	{1018		"bpf_strtoul supported base, ok",1019		.insns = {1020			/* arg1 (buf) */1021			BPF_MOV64_REG(BPF_REG_7, BPF_REG_10),1022			BPF_ALU64_IMM(BPF_ADD, BPF_REG_7, -8),1023			BPF_MOV64_IMM(BPF_REG_0,1024				      bpf_ntohl(0x30373700)),1025			BPF_STX_MEM(BPF_W, BPF_REG_7, BPF_REG_0, 0),1026 1027			BPF_MOV64_REG(BPF_REG_1, BPF_REG_7),1028 1029			/* arg2 (buf_len) */1030			BPF_MOV64_IMM(BPF_REG_2, 4),1031 1032			/* arg3 (flags) */1033			BPF_MOV64_IMM(BPF_REG_3, 8),1034 1035			/* arg4 (res) */1036			BPF_ALU64_IMM(BPF_ADD, BPF_REG_7, -8),1037			BPF_STX_MEM(BPF_DW, BPF_REG_7, BPF_REG_0, 0),1038			BPF_MOV64_REG(BPF_REG_4, BPF_REG_7),1039 1040			BPF_EMIT_CALL(BPF_FUNC_strtoul),1041 1042			/* if (ret == expected && */1043			BPF_JMP_IMM(BPF_JNE, BPF_REG_0, 3, 4),1044			/*     res == expected) */1045			BPF_LDX_MEM(BPF_DW, BPF_REG_9, BPF_REG_7, 0),1046			BPF_JMP_IMM(BPF_JNE, BPF_REG_9, 63, 2),1047 1048			/* return ALLOW; */1049			BPF_MOV64_IMM(BPF_REG_0, 1),1050			BPF_JMP_A(1),1051 1052			/* else return DENY; */1053			BPF_MOV64_IMM(BPF_REG_0, 0),1054			BPF_EXIT_INSN(),1055		},1056		.attach_type = BPF_CGROUP_SYSCTL,1057		.sysctl = "net/ipv4/route/mtu_expires",1058		.open_flags = O_RDONLY,1059		.result = SUCCESS,1060	},1061	{1062		"bpf_strtoul unsupported base, EINVAL",1063		.insns = {1064			/* arg1 (buf) */1065			BPF_MOV64_REG(BPF_REG_7, BPF_REG_10),1066			BPF_ALU64_IMM(BPF_ADD, BPF_REG_7, -8),1067			BPF_MOV64_IMM(BPF_REG_0,1068				      bpf_ntohl(0x36303000)),1069			BPF_STX_MEM(BPF_DW, BPF_REG_7, BPF_REG_0, 0),1070 1071			BPF_MOV64_REG(BPF_REG_1, BPF_REG_7),1072 1073			/* arg2 (buf_len) */1074			BPF_MOV64_IMM(BPF_REG_2, 4),1075 1076			/* arg3 (flags) */1077			BPF_MOV64_IMM(BPF_REG_3, 3),1078 1079			/* arg4 (res) */1080			BPF_ALU64_IMM(BPF_ADD, BPF_REG_7, -8),1081			BPF_STX_MEM(BPF_DW, BPF_REG_7, BPF_REG_0, 0),1082			BPF_MOV64_REG(BPF_REG_4, BPF_REG_7),1083 1084			BPF_EMIT_CALL(BPF_FUNC_strtoul),1085 1086			/* if (ret == expected) */1087			BPF_JMP_IMM(BPF_JNE, BPF_REG_0, -EINVAL, 2),1088 1089			/* return ALLOW; */1090			BPF_MOV64_IMM(BPF_REG_0, 1),1091			BPF_JMP_A(1),1092 1093			/* else return DENY; */1094			BPF_MOV64_IMM(BPF_REG_0, 0),1095			BPF_EXIT_INSN(),1096		},1097		.attach_type = BPF_CGROUP_SYSCTL,1098		.sysctl = "net/ipv4/route/mtu_expires",1099		.open_flags = O_RDONLY,1100		.result = SUCCESS,1101	},1102	{1103		"bpf_strtoul buf with spaces only, EINVAL",1104		.insns = {1105			/* arg1 (buf) */1106			BPF_MOV64_REG(BPF_REG_7, BPF_REG_10),1107			BPF_ALU64_IMM(BPF_ADD, BPF_REG_7, -8),1108			BPF_MOV64_IMM(BPF_REG_0,1109				      bpf_ntohl(0x0d0c0a09)),1110			BPF_STX_MEM(BPF_DW, BPF_REG_7, BPF_REG_0, 0),1111 1112			BPF_MOV64_REG(BPF_REG_1, BPF_REG_7),1113 1114			/* arg2 (buf_len) */1115			BPF_MOV64_IMM(BPF_REG_2, 4),1116 1117			/* arg3 (flags) */1118			BPF_MOV64_IMM(BPF_REG_3, 0),1119 1120			/* arg4 (res) */1121			BPF_ALU64_IMM(BPF_ADD, BPF_REG_7, -8),1122			BPF_STX_MEM(BPF_DW, BPF_REG_7, BPF_REG_0, 0),1123			BPF_MOV64_REG(BPF_REG_4, BPF_REG_7),1124 1125			BPF_EMIT_CALL(BPF_FUNC_strtoul),1126 1127			/* if (ret == expected) */1128			BPF_JMP_IMM(BPF_JNE, BPF_REG_0, -EINVAL, 2),1129 1130			/* return ALLOW; */1131			BPF_MOV64_IMM(BPF_REG_0, 1),1132			BPF_JMP_A(1),1133 1134			/* else return DENY; */1135			BPF_MOV64_IMM(BPF_REG_0, 0),1136			BPF_EXIT_INSN(),1137		},1138		.attach_type = BPF_CGROUP_SYSCTL,1139		.sysctl = "net/ipv4/route/mtu_expires",1140		.open_flags = O_RDONLY,1141		.result = SUCCESS,1142	},1143	{1144		"bpf_strtoul negative number, EINVAL",1145		.insns = {1146			/* arg1 (buf) */1147			BPF_MOV64_REG(BPF_REG_7, BPF_REG_10),1148			BPF_ALU64_IMM(BPF_ADD, BPF_REG_7, -8),1149			/* " -6\0" */1150			BPF_MOV64_IMM(BPF_REG_0,1151				      bpf_ntohl(0x0a2d3600)),1152			BPF_STX_MEM(BPF_DW, BPF_REG_7, BPF_REG_0, 0),1153 1154			BPF_MOV64_REG(BPF_REG_1, BPF_REG_7),1155 1156			/* arg2 (buf_len) */1157			BPF_MOV64_IMM(BPF_REG_2, 4),1158 1159			/* arg3 (flags) */1160			BPF_MOV64_IMM(BPF_REG_3, 0),1161 1162			/* arg4 (res) */1163			BPF_ALU64_IMM(BPF_ADD, BPF_REG_7, -8),1164			BPF_STX_MEM(BPF_DW, BPF_REG_7, BPF_REG_0, 0),1165			BPF_MOV64_REG(BPF_REG_4, BPF_REG_7),1166 1167			BPF_EMIT_CALL(BPF_FUNC_strtoul),1168 1169			/* if (ret == expected) */1170			BPF_JMP_IMM(BPF_JNE, BPF_REG_0, -EINVAL, 2),1171 1172			/* return ALLOW; */1173			BPF_MOV64_IMM(BPF_REG_0, 1),1174			BPF_JMP_A(1),1175 1176			/* else return DENY; */1177			BPF_MOV64_IMM(BPF_REG_0, 0),1178			BPF_EXIT_INSN(),1179		},1180		.attach_type = BPF_CGROUP_SYSCTL,1181		.sysctl = "net/ipv4/route/mtu_expires",1182		.open_flags = O_RDONLY,1183		.result = SUCCESS,1184	},1185	{1186		"bpf_strtol negative number, ok",1187		.insns = {1188			/* arg1 (buf) */1189			BPF_MOV64_REG(BPF_REG_7, BPF_REG_10),1190			BPF_ALU64_IMM(BPF_ADD, BPF_REG_7, -8),1191			/* " -6\0" */1192			BPF_MOV64_IMM(BPF_REG_0,1193				      bpf_ntohl(0x0a2d3600)),1194			BPF_STX_MEM(BPF_W, BPF_REG_7, BPF_REG_0, 0),1195 1196			BPF_MOV64_REG(BPF_REG_1, BPF_REG_7),1197 1198			/* arg2 (buf_len) */1199			BPF_MOV64_IMM(BPF_REG_2, 4),1200 1201			/* arg3 (flags) */1202			BPF_MOV64_IMM(BPF_REG_3, 10),1203 1204			/* arg4 (res) */1205			BPF_ALU64_IMM(BPF_ADD, BPF_REG_7, -8),1206			BPF_STX_MEM(BPF_DW, BPF_REG_7, BPF_REG_0, 0),1207			BPF_MOV64_REG(BPF_REG_4, BPF_REG_7),1208 1209			BPF_EMIT_CALL(BPF_FUNC_strtol),1210 1211			/* if (ret == expected && */1212			BPF_JMP_IMM(BPF_JNE, BPF_REG_0, 3, 4),1213			/*     res == expected) */1214			BPF_LDX_MEM(BPF_DW, BPF_REG_9, BPF_REG_7, 0),1215			BPF_JMP_IMM(BPF_JNE, BPF_REG_9, -6, 2),1216 1217			/* return ALLOW; */1218			BPF_MOV64_IMM(BPF_REG_0, 1),1219			BPF_JMP_A(1),1220 1221			/* else return DENY; */1222			BPF_MOV64_IMM(BPF_REG_0, 0),1223			BPF_EXIT_INSN(),1224		},1225		.attach_type = BPF_CGROUP_SYSCTL,1226		.sysctl = "net/ipv4/route/mtu_expires",1227		.open_flags = O_RDONLY,1228		.result = SUCCESS,1229	},1230	{1231		"bpf_strtol hex number, ok",1232		.insns = {1233			/* arg1 (buf) */1234			BPF_MOV64_REG(BPF_REG_7, BPF_REG_10),1235			BPF_ALU64_IMM(BPF_ADD, BPF_REG_7, -8),1236			/* "0xfe" */1237			BPF_MOV64_IMM(BPF_REG_0,1238				      bpf_ntohl(0x30786665)),1239			BPF_STX_MEM(BPF_W, BPF_REG_7, BPF_REG_0, 0),1240 1241			BPF_MOV64_REG(BPF_REG_1, BPF_REG_7),1242 1243			/* arg2 (buf_len) */1244			BPF_MOV64_IMM(BPF_REG_2, 4),1245 1246			/* arg3 (flags) */1247			BPF_MOV64_IMM(BPF_REG_3, 0),1248 1249			/* arg4 (res) */1250			BPF_ALU64_IMM(BPF_ADD, BPF_REG_7, -8),1251			BPF_STX_MEM(BPF_DW, BPF_REG_7, BPF_REG_0, 0),1252			BPF_MOV64_REG(BPF_REG_4, BPF_REG_7),1253 1254			BPF_EMIT_CALL(BPF_FUNC_strtol),1255 1256			/* if (ret == expected && */1257			BPF_JMP_IMM(BPF_JNE, BPF_REG_0, 4, 4),1258			/*     res == expected) */1259			BPF_LDX_MEM(BPF_DW, BPF_REG_9, BPF_REG_7, 0),1260			BPF_JMP_IMM(BPF_JNE, BPF_REG_9, 254, 2),1261 1262			/* return ALLOW; */1263			BPF_MOV64_IMM(BPF_REG_0, 1),1264			BPF_JMP_A(1),1265 1266			/* else return DENY; */1267			BPF_MOV64_IMM(BPF_REG_0, 0),1268			BPF_EXIT_INSN(),1269		},1270		.attach_type = BPF_CGROUP_SYSCTL,1271		.sysctl = "net/ipv4/route/mtu_expires",1272		.open_flags = O_RDONLY,1273		.result = SUCCESS,1274	},1275	{1276		"bpf_strtol max long",1277		.insns = {1278			/* arg1 (buf) 9223372036854775807 */1279			BPF_MOV64_REG(BPF_REG_7, BPF_REG_10),1280			BPF_ALU64_IMM(BPF_ADD, BPF_REG_7, -24),1281			BPF_LD_IMM64(BPF_REG_0,1282				     bpf_be64_to_cpu(0x3932323333373230ULL)),1283			BPF_STX_MEM(BPF_DW, BPF_REG_7, BPF_REG_0, 0),1284			BPF_LD_IMM64(BPF_REG_0,1285				     bpf_be64_to_cpu(0x3336383534373735ULL)),1286			BPF_STX_MEM(BPF_DW, BPF_REG_7, BPF_REG_0, 8),1287			BPF_LD_IMM64(BPF_REG_0,1288				     bpf_be64_to_cpu(0x3830370000000000ULL)),1289			BPF_STX_MEM(BPF_DW, BPF_REG_7, BPF_REG_0, 16),1290 1291			BPF_MOV64_REG(BPF_REG_1, BPF_REG_7),1292 1293			/* arg2 (buf_len) */1294			BPF_MOV64_IMM(BPF_REG_2, 19),1295 1296			/* arg3 (flags) */1297			BPF_MOV64_IMM(BPF_REG_3, 0),1298 1299			/* arg4 (res) */1300			BPF_ALU64_IMM(BPF_ADD, BPF_REG_7, -8),1301			BPF_STX_MEM(BPF_DW, BPF_REG_7, BPF_REG_0, 0),1302			BPF_MOV64_REG(BPF_REG_4, BPF_REG_7),1303 1304			BPF_EMIT_CALL(BPF_FUNC_strtol),1305 1306			/* if (ret == expected && */1307			BPF_JMP_IMM(BPF_JNE, BPF_REG_0, 19, 6),1308			/*     res == expected) */1309			BPF_LD_IMM64(BPF_REG_8, 0x7fffffffffffffffULL),1310			BPF_LDX_MEM(BPF_DW, BPF_REG_9, BPF_REG_7, 0),1311			BPF_JMP_REG(BPF_JNE, BPF_REG_8, BPF_REG_9, 2),1312 1313			/* return ALLOW; */1314			BPF_MOV64_IMM(BPF_REG_0, 1),1315			BPF_JMP_A(1),1316 1317			/* else return DENY; */1318			BPF_MOV64_IMM(BPF_REG_0, 0),1319			BPF_EXIT_INSN(),1320		},1321		.attach_type = BPF_CGROUP_SYSCTL,1322		.sysctl = "net/ipv4/route/mtu_expires",1323		.open_flags = O_RDONLY,1324		.result = SUCCESS,1325	},1326	{1327		"bpf_strtol overflow, ERANGE",1328		.insns = {1329			/* arg1 (buf) 9223372036854775808 */1330			BPF_MOV64_REG(BPF_REG_7, BPF_REG_10),1331			BPF_ALU64_IMM(BPF_ADD, BPF_REG_7, -24),1332			BPF_LD_IMM64(BPF_REG_0,1333				     bpf_be64_to_cpu(0x3932323333373230ULL)),1334			BPF_STX_MEM(BPF_DW, BPF_REG_7, BPF_REG_0, 0),1335			BPF_LD_IMM64(BPF_REG_0,1336				     bpf_be64_to_cpu(0x3336383534373735ULL)),1337			BPF_STX_MEM(BPF_DW, BPF_REG_7, BPF_REG_0, 8),1338			BPF_LD_IMM64(BPF_REG_0,1339				     bpf_be64_to_cpu(0x3830380000000000ULL)),1340			BPF_STX_MEM(BPF_DW, BPF_REG_7, BPF_REG_0, 16),1341 1342			BPF_MOV64_REG(BPF_REG_1, BPF_REG_7),1343 1344			/* arg2 (buf_len) */1345			BPF_MOV64_IMM(BPF_REG_2, 19),1346 1347			/* arg3 (flags) */1348			BPF_MOV64_IMM(BPF_REG_3, 0),1349 1350			/* arg4 (res) */1351			BPF_ALU64_IMM(BPF_ADD, BPF_REG_7, -8),1352			BPF_STX_MEM(BPF_DW, BPF_REG_7, BPF_REG_0, 0),1353			BPF_MOV64_REG(BPF_REG_4, BPF_REG_7),1354 1355			BPF_EMIT_CALL(BPF_FUNC_strtol),1356 1357			/* if (ret == expected) */1358			BPF_JMP_IMM(BPF_JNE, BPF_REG_0, -ERANGE, 2),1359 1360			/* return ALLOW; */1361			BPF_MOV64_IMM(BPF_REG_0, 1),1362			BPF_JMP_A(1),1363 1364			/* else return DENY; */1365			BPF_MOV64_IMM(BPF_REG_0, 0),1366			BPF_EXIT_INSN(),1367		},1368		.attach_type = BPF_CGROUP_SYSCTL,1369		.sysctl = "net/ipv4/route/mtu_expires",1370		.open_flags = O_RDONLY,1371		.result = SUCCESS,1372	},1373	{1374		"C prog: deny all writes",1375		.prog_file = "./test_sysctl_prog.bpf.o",1376		.attach_type = BPF_CGROUP_SYSCTL,1377		.sysctl = "net/ipv4/tcp_mem",1378		.open_flags = O_WRONLY,1379		.newval = "123 456 789",1380		.result = OP_EPERM,1381	},1382	{1383		"C prog: deny access by name",1384		.prog_file = "./test_sysctl_prog.bpf.o",1385		.attach_type = BPF_CGROUP_SYSCTL,1386		.sysctl = "net/ipv4/route/mtu_expires",1387		.open_flags = O_RDONLY,1388		.result = OP_EPERM,1389	},1390	{1391		"C prog: read tcp_mem",1392		.prog_file = "./test_sysctl_prog.bpf.o",1393		.attach_type = BPF_CGROUP_SYSCTL,1394		.sysctl = "net/ipv4/tcp_mem",1395		.open_flags = O_RDONLY,1396		.result = SUCCESS,1397	},1398};1399 1400static size_t probe_prog_length(const struct bpf_insn *fp)1401{1402	size_t len;1403 1404	for (len = MAX_INSNS - 1; len > 0; --len)1405		if (fp[len].code != 0 || fp[len].imm != 0)1406			break;1407	return len + 1;1408}1409 1410static int fixup_sysctl_value(const char *buf, size_t buf_len,1411			      struct bpf_insn *prog, size_t insn_num)1412{1413	union {1414		uint8_t raw[sizeof(uint64_t)];1415		uint64_t num;1416	} value = {};1417 1418	if (buf_len > sizeof(value)) {1419		log_err("Value is too big (%zd) to use in fixup", buf_len);1420		return -1;1421	}1422	if (prog[insn_num].code != (BPF_LD | BPF_DW | BPF_IMM)) {1423		log_err("Can fixup only BPF_LD_IMM64 insns");1424		return -1;1425	}1426 1427	memcpy(value.raw, buf, buf_len);1428	prog[insn_num].imm = (uint32_t)value.num;1429	prog[insn_num + 1].imm = (uint32_t)(value.num >> 32);1430 1431	return 0;1432}1433 1434static int load_sysctl_prog_insns(struct sysctl_test *test,1435				  const char *sysctl_path)1436{1437	struct bpf_insn *prog = test->insns;1438	LIBBPF_OPTS(bpf_prog_load_opts, opts);1439	int ret, insn_cnt;1440 1441	insn_cnt = probe_prog_length(prog);1442 1443	if (test->fixup_value_insn) {1444		char buf[128];1445		ssize_t len;1446		int fd;1447 1448		fd = open(sysctl_path, O_RDONLY | O_CLOEXEC);1449		if (fd < 0) {1450			log_err("open(%s) failed", sysctl_path);1451			return -1;1452		}1453		len = read(fd, buf, sizeof(buf));1454		if (len == -1) {1455			log_err("read(%s) failed", sysctl_path);1456			close(fd);1457			return -1;1458		}1459		close(fd);1460		if (fixup_sysctl_value(buf, len, prog, test->fixup_value_insn))1461			return -1;1462	}1463 1464	opts.log_buf = bpf_log_buf;1465	opts.log_size = BPF_LOG_BUF_SIZE;1466 1467	ret = bpf_prog_load(BPF_PROG_TYPE_CGROUP_SYSCTL, NULL, "GPL", prog, insn_cnt, &opts);1468	if (ret < 0 && test->result != LOAD_REJECT) {1469		log_err(">>> Loading program error.\n"1470			">>> Verifier output:\n%s\n-------\n", bpf_log_buf);1471	}1472 1473	return ret;1474}1475 1476static int load_sysctl_prog_file(struct sysctl_test *test)1477{1478	struct bpf_object *obj;1479	int prog_fd;1480 1481	if (bpf_prog_test_load(test->prog_file, BPF_PROG_TYPE_CGROUP_SYSCTL, &obj, &prog_fd)) {1482		if (test->result != LOAD_REJECT)1483			log_err(">>> Loading program (%s) error.\n",1484				test->prog_file);1485		return -1;1486	}1487 1488	return prog_fd;1489}1490 1491static int load_sysctl_prog(struct sysctl_test *test, const char *sysctl_path)1492{1493		return test->prog_file1494			? load_sysctl_prog_file(test)1495			: load_sysctl_prog_insns(test, sysctl_path);1496}1497 1498static int access_sysctl(const char *sysctl_path,1499			 const struct sysctl_test *test)1500{1501	int err = 0;1502	int fd;1503 1504	fd = open(sysctl_path, test->open_flags | O_CLOEXEC);1505	if (fd < 0)1506		return fd;1507 1508	if (test->seek && lseek(fd, test->seek, SEEK_SET) == -1) {1509		log_err("lseek(%d) failed", test->seek);1510		goto err;1511	}1512 1513	if (test->open_flags == O_RDONLY) {1514		char buf[128];1515 1516		if (read(fd, buf, sizeof(buf)) == -1)1517			goto err;1518		if (test->oldval &&1519		    strncmp(buf, test->oldval, strlen(test->oldval))) {1520			log_err("Read value %s != %s", buf, test->oldval);1521			goto err;1522		}1523	} else if (test->open_flags == O_WRONLY) {1524		if (!test->newval) {1525			log_err("New value for sysctl is not set");1526			goto err;1527		}1528		if (write(fd, test->newval, strlen(test->newval)) == -1)1529			goto err;1530	} else {1531		log_err("Unexpected sysctl access: neither read nor write");1532		goto err;1533	}1534 1535	goto out;1536err:1537	err = -1;1538out:1539	close(fd);1540	return err;1541}1542 1543static int run_test_case(int cgfd, struct sysctl_test *test)1544{1545	enum bpf_attach_type atype = test->attach_type;1546	char sysctl_path[128];1547	int progfd = -1;1548	int err = 0;1549 1550	printf("Test case: %s .. ", test->descr);1551 1552	snprintf(sysctl_path, sizeof(sysctl_path), "/proc/sys/%s",1553		 test->sysctl);1554 1555	progfd = load_sysctl_prog(test, sysctl_path);1556	if (progfd < 0) {1557		if (test->result == LOAD_REJECT)1558			goto out;1559		else1560			goto err;1561	}1562 1563	if (bpf_prog_attach(progfd, cgfd, atype, BPF_F_ALLOW_OVERRIDE) < 0) {1564		if (test->result == ATTACH_REJECT)1565			goto out;1566		else1567			goto err;1568	}1569 1570	errno = 0;1571	if (access_sysctl(sysctl_path, test) == -1) {1572		if (test->result == OP_EPERM && errno == EPERM)1573			goto out;1574		else1575			goto err;1576	}1577 1578	if (test->result != SUCCESS) {1579		log_err("Unexpected success");1580		goto err;1581	}1582 1583	goto out;1584err:1585	err = -1;1586out:1587	/* Detaching w/o checking return code: best effort attempt. */1588	if (progfd != -1)1589		bpf_prog_detach(cgfd, atype);1590	close(progfd);1591	printf("[%s]\n", err ? "FAIL" : "PASS");1592	return err;1593}1594 1595static int run_tests(int cgfd)1596{1597	int passes = 0;1598	int fails = 0;1599	int i;1600 1601	for (i = 0; i < ARRAY_SIZE(tests); ++i) {1602		if (run_test_case(cgfd, &tests[i]))1603			++fails;1604		else1605			++passes;1606	}1607	printf("Summary: %d PASSED, %d FAILED\n", passes, fails);1608	return fails ? -1 : 0;1609}1610 1611int main(int argc, char **argv)1612{1613	int cgfd = -1;1614	int err = 0;1615 1616	cgfd = cgroup_setup_and_join(CG_PATH);1617	if (cgfd < 0)1618		goto err;1619 1620	/* Use libbpf 1.0 API mode */1621	libbpf_set_strict_mode(LIBBPF_STRICT_ALL);1622 1623	if (run_tests(cgfd))1624		goto err;1625 1626	goto out;1627err:1628	err = -1;1629out:1630	close(cgfd);1631	cleanup_cgroup_environment();1632	return err;1633}1634