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