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_rlimit.h" 181f5fa9abSAndrey Ignatov #include "bpf_util.h" 191f5fa9abSAndrey Ignatov #include "cgroup_helpers.h" 201f5fa9abSAndrey Ignatov 211f5fa9abSAndrey Ignatov #define CG_PATH "/foo" 221f5fa9abSAndrey Ignatov #define MAX_INSNS 512 2311ff34f7SAndrey Ignatov #define FIXUP_SYSCTL_VALUE 0 241f5fa9abSAndrey Ignatov 251f5fa9abSAndrey Ignatov char bpf_log_buf[BPF_LOG_BUF_SIZE]; 261f5fa9abSAndrey Ignatov 271f5fa9abSAndrey Ignatov struct sysctl_test { 281f5fa9abSAndrey Ignatov const char *descr; 2911ff34f7SAndrey Ignatov size_t fixup_value_insn; 301f5fa9abSAndrey Ignatov struct bpf_insn insns[MAX_INSNS]; 317568f4cbSAndrey Ignatov const char *prog_file; 321f5fa9abSAndrey Ignatov enum bpf_attach_type attach_type; 331f5fa9abSAndrey Ignatov const char *sysctl; 341f5fa9abSAndrey Ignatov int open_flags; 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; */ 1279ffccb76SIlya Leoshkevich #if __BYTE_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) */ 1877541c87cSIlya Leoshkevich #if __BYTE_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", 13757568f4cbSAndrey Ignatov .prog_file = "./test_sysctl_prog.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", 13847568f4cbSAndrey Ignatov .prog_file = "./test_sysctl_prog.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", 13927568f4cbSAndrey Ignatov .prog_file = "./test_sysctl_prog.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 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 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 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; 14381f5fa9abSAndrey Ignatov struct bpf_load_program_attr attr; 14391f5fa9abSAndrey Ignatov int ret; 14401f5fa9abSAndrey Ignatov 14411f5fa9abSAndrey Ignatov memset(&attr, 0, sizeof(struct bpf_load_program_attr)); 14421f5fa9abSAndrey Ignatov attr.prog_type = BPF_PROG_TYPE_CGROUP_SYSCTL; 14431f5fa9abSAndrey Ignatov attr.insns = prog; 14441f5fa9abSAndrey Ignatov attr.insns_cnt = probe_prog_length(attr.insns); 14451f5fa9abSAndrey Ignatov attr.license = "GPL"; 14461f5fa9abSAndrey Ignatov 144711ff34f7SAndrey Ignatov if (test->fixup_value_insn) { 144811ff34f7SAndrey Ignatov char buf[128]; 144911ff34f7SAndrey Ignatov ssize_t len; 145011ff34f7SAndrey Ignatov int fd; 145111ff34f7SAndrey Ignatov 145211ff34f7SAndrey Ignatov fd = open(sysctl_path, O_RDONLY | O_CLOEXEC); 145311ff34f7SAndrey Ignatov if (fd < 0) { 145411ff34f7SAndrey Ignatov log_err("open(%s) failed", sysctl_path); 145511ff34f7SAndrey Ignatov return -1; 145611ff34f7SAndrey Ignatov } 145711ff34f7SAndrey Ignatov len = read(fd, buf, sizeof(buf)); 145811ff34f7SAndrey Ignatov if (len == -1) { 145911ff34f7SAndrey Ignatov log_err("read(%s) failed", sysctl_path); 146011ff34f7SAndrey Ignatov close(fd); 146111ff34f7SAndrey Ignatov return -1; 146211ff34f7SAndrey Ignatov } 146311ff34f7SAndrey Ignatov close(fd); 146411ff34f7SAndrey Ignatov if (fixup_sysctl_value(buf, len, prog, test->fixup_value_insn)) 146511ff34f7SAndrey Ignatov return -1; 146611ff34f7SAndrey Ignatov } 146711ff34f7SAndrey Ignatov 14681f5fa9abSAndrey Ignatov ret = bpf_load_program_xattr(&attr, bpf_log_buf, BPF_LOG_BUF_SIZE); 14691f5fa9abSAndrey Ignatov if (ret < 0 && test->result != LOAD_REJECT) { 14701f5fa9abSAndrey Ignatov log_err(">>> Loading program error.\n" 14711f5fa9abSAndrey Ignatov ">>> Verifier output:\n%s\n-------\n", bpf_log_buf); 14721f5fa9abSAndrey Ignatov } 14731f5fa9abSAndrey Ignatov 14741f5fa9abSAndrey Ignatov return ret; 14751f5fa9abSAndrey Ignatov } 14761f5fa9abSAndrey Ignatov 14777568f4cbSAndrey Ignatov static int load_sysctl_prog_file(struct sysctl_test *test) 14787568f4cbSAndrey Ignatov { 14797568f4cbSAndrey Ignatov struct bpf_prog_load_attr attr; 14807568f4cbSAndrey Ignatov struct bpf_object *obj; 14817568f4cbSAndrey Ignatov int prog_fd; 14827568f4cbSAndrey Ignatov 14837568f4cbSAndrey Ignatov memset(&attr, 0, sizeof(struct bpf_prog_load_attr)); 14847568f4cbSAndrey Ignatov attr.file = test->prog_file; 14857568f4cbSAndrey Ignatov attr.prog_type = BPF_PROG_TYPE_CGROUP_SYSCTL; 14867568f4cbSAndrey Ignatov 14877568f4cbSAndrey Ignatov if (bpf_prog_load_xattr(&attr, &obj, &prog_fd)) { 14887568f4cbSAndrey Ignatov if (test->result != LOAD_REJECT) 14897568f4cbSAndrey Ignatov log_err(">>> Loading program (%s) error.\n", 14907568f4cbSAndrey Ignatov test->prog_file); 14917568f4cbSAndrey Ignatov return -1; 14927568f4cbSAndrey Ignatov } 14937568f4cbSAndrey Ignatov 14947568f4cbSAndrey Ignatov return prog_fd; 14957568f4cbSAndrey Ignatov } 14967568f4cbSAndrey Ignatov 14977568f4cbSAndrey Ignatov static int load_sysctl_prog(struct sysctl_test *test, const char *sysctl_path) 14987568f4cbSAndrey Ignatov { 14997568f4cbSAndrey Ignatov return test->prog_file 15007568f4cbSAndrey Ignatov ? load_sysctl_prog_file(test) 15017568f4cbSAndrey Ignatov : load_sysctl_prog_insns(test, sysctl_path); 15027568f4cbSAndrey Ignatov } 15037568f4cbSAndrey Ignatov 15041f5fa9abSAndrey Ignatov static int access_sysctl(const char *sysctl_path, 15051f5fa9abSAndrey Ignatov const struct sysctl_test *test) 15061f5fa9abSAndrey Ignatov { 15071f5fa9abSAndrey Ignatov int err = 0; 15081f5fa9abSAndrey Ignatov int fd; 15091f5fa9abSAndrey Ignatov 15101f5fa9abSAndrey Ignatov fd = open(sysctl_path, test->open_flags | O_CLOEXEC); 15111f5fa9abSAndrey Ignatov if (fd < 0) 15121f5fa9abSAndrey Ignatov return fd; 15131f5fa9abSAndrey Ignatov 1514d895a0f1SIlya Leoshkevich if (test->seek && lseek(fd, test->seek, SEEK_SET) == -1) { 1515d895a0f1SIlya Leoshkevich log_err("lseek(%d) failed", test->seek); 1516d895a0f1SIlya Leoshkevich goto err; 1517d895a0f1SIlya Leoshkevich } 1518d895a0f1SIlya Leoshkevich 15191f5fa9abSAndrey Ignatov if (test->open_flags == O_RDONLY) { 15201f5fa9abSAndrey Ignatov char buf[128]; 15211f5fa9abSAndrey Ignatov 15221f5fa9abSAndrey Ignatov if (read(fd, buf, sizeof(buf)) == -1) 15231f5fa9abSAndrey Ignatov goto err; 15249a1027e5SAndrey Ignatov if (test->oldval && 15259a1027e5SAndrey Ignatov strncmp(buf, test->oldval, strlen(test->oldval))) { 15269a1027e5SAndrey Ignatov log_err("Read value %s != %s", buf, test->oldval); 15279a1027e5SAndrey Ignatov goto err; 15289a1027e5SAndrey Ignatov } 15291f5fa9abSAndrey Ignatov } else if (test->open_flags == O_WRONLY) { 15301f5fa9abSAndrey Ignatov if (!test->newval) { 15311f5fa9abSAndrey Ignatov log_err("New value for sysctl is not set"); 15321f5fa9abSAndrey Ignatov goto err; 15331f5fa9abSAndrey Ignatov } 15341f5fa9abSAndrey Ignatov if (write(fd, test->newval, strlen(test->newval)) == -1) 15351f5fa9abSAndrey Ignatov goto err; 15361f5fa9abSAndrey Ignatov } else { 15371f5fa9abSAndrey Ignatov log_err("Unexpected sysctl access: neither read nor write"); 15381f5fa9abSAndrey Ignatov goto err; 15391f5fa9abSAndrey Ignatov } 15401f5fa9abSAndrey Ignatov 15411f5fa9abSAndrey Ignatov goto out; 15421f5fa9abSAndrey Ignatov err: 15431f5fa9abSAndrey Ignatov err = -1; 15441f5fa9abSAndrey Ignatov out: 15451f5fa9abSAndrey Ignatov close(fd); 15461f5fa9abSAndrey Ignatov return err; 15471f5fa9abSAndrey Ignatov } 15481f5fa9abSAndrey Ignatov 15491f5fa9abSAndrey Ignatov static int run_test_case(int cgfd, struct sysctl_test *test) 15501f5fa9abSAndrey Ignatov { 15511f5fa9abSAndrey Ignatov enum bpf_attach_type atype = test->attach_type; 15521f5fa9abSAndrey Ignatov char sysctl_path[128]; 15531f5fa9abSAndrey Ignatov int progfd = -1; 15541f5fa9abSAndrey Ignatov int err = 0; 15551f5fa9abSAndrey Ignatov 15561f5fa9abSAndrey Ignatov printf("Test case: %s .. ", test->descr); 15571f5fa9abSAndrey Ignatov 15581f5fa9abSAndrey Ignatov snprintf(sysctl_path, sizeof(sysctl_path), "/proc/sys/%s", 15591f5fa9abSAndrey Ignatov test->sysctl); 15601f5fa9abSAndrey Ignatov 15611f5fa9abSAndrey Ignatov progfd = load_sysctl_prog(test, sysctl_path); 15621f5fa9abSAndrey Ignatov if (progfd < 0) { 15631f5fa9abSAndrey Ignatov if (test->result == LOAD_REJECT) 15641f5fa9abSAndrey Ignatov goto out; 15651f5fa9abSAndrey Ignatov else 15661f5fa9abSAndrey Ignatov goto err; 15671f5fa9abSAndrey Ignatov } 15681f5fa9abSAndrey Ignatov 15691f5fa9abSAndrey Ignatov if (bpf_prog_attach(progfd, cgfd, atype, BPF_F_ALLOW_OVERRIDE) == -1) { 15701f5fa9abSAndrey Ignatov if (test->result == ATTACH_REJECT) 15711f5fa9abSAndrey Ignatov goto out; 15721f5fa9abSAndrey Ignatov else 15731f5fa9abSAndrey Ignatov goto err; 15741f5fa9abSAndrey Ignatov } 15751f5fa9abSAndrey Ignatov 1576416c5728SIlya Leoshkevich errno = 0; 15771f5fa9abSAndrey Ignatov if (access_sysctl(sysctl_path, test) == -1) { 15781f5fa9abSAndrey Ignatov if (test->result == OP_EPERM && errno == EPERM) 15791f5fa9abSAndrey Ignatov goto out; 15801f5fa9abSAndrey Ignatov else 15811f5fa9abSAndrey Ignatov goto err; 15821f5fa9abSAndrey Ignatov } 15831f5fa9abSAndrey Ignatov 15841f5fa9abSAndrey Ignatov if (test->result != SUCCESS) { 1585416c5728SIlya Leoshkevich log_err("Unexpected success"); 15861f5fa9abSAndrey Ignatov goto err; 15871f5fa9abSAndrey Ignatov } 15881f5fa9abSAndrey Ignatov 15891f5fa9abSAndrey Ignatov goto out; 15901f5fa9abSAndrey Ignatov err: 15911f5fa9abSAndrey Ignatov err = -1; 15921f5fa9abSAndrey Ignatov out: 15931f5fa9abSAndrey Ignatov /* Detaching w/o checking return code: best effort attempt. */ 15941f5fa9abSAndrey Ignatov if (progfd != -1) 15951f5fa9abSAndrey Ignatov bpf_prog_detach(cgfd, atype); 15961f5fa9abSAndrey Ignatov close(progfd); 15971f5fa9abSAndrey Ignatov printf("[%s]\n", err ? "FAIL" : "PASS"); 15981f5fa9abSAndrey Ignatov return err; 15991f5fa9abSAndrey Ignatov } 16001f5fa9abSAndrey Ignatov 16011f5fa9abSAndrey Ignatov static int run_tests(int cgfd) 16021f5fa9abSAndrey Ignatov { 16031f5fa9abSAndrey Ignatov int passes = 0; 16041f5fa9abSAndrey Ignatov int fails = 0; 16051f5fa9abSAndrey Ignatov int i; 16061f5fa9abSAndrey Ignatov 16071f5fa9abSAndrey Ignatov for (i = 0; i < ARRAY_SIZE(tests); ++i) { 16081f5fa9abSAndrey Ignatov if (run_test_case(cgfd, &tests[i])) 16091f5fa9abSAndrey Ignatov ++fails; 16101f5fa9abSAndrey Ignatov else 16111f5fa9abSAndrey Ignatov ++passes; 16121f5fa9abSAndrey Ignatov } 16131f5fa9abSAndrey Ignatov printf("Summary: %d PASSED, %d FAILED\n", passes, fails); 16141f5fa9abSAndrey Ignatov return fails ? -1 : 0; 16151f5fa9abSAndrey Ignatov } 16161f5fa9abSAndrey Ignatov 16171f5fa9abSAndrey Ignatov int main(int argc, char **argv) 16181f5fa9abSAndrey Ignatov { 16191f5fa9abSAndrey Ignatov int cgfd = -1; 16201f5fa9abSAndrey Ignatov int err = 0; 16211f5fa9abSAndrey Ignatov 1622*4939b284SJohn Fastabend cgfd = cgroup_setup_and_join(CG_PATH); 16231f5fa9abSAndrey Ignatov if (cgfd < 0) 16241f5fa9abSAndrey Ignatov goto err; 16251f5fa9abSAndrey Ignatov 16261f5fa9abSAndrey Ignatov if (run_tests(cgfd)) 16271f5fa9abSAndrey Ignatov goto err; 16281f5fa9abSAndrey Ignatov 16291f5fa9abSAndrey Ignatov goto out; 16301f5fa9abSAndrey Ignatov err: 16311f5fa9abSAndrey Ignatov err = -1; 16321f5fa9abSAndrey Ignatov out: 16331f5fa9abSAndrey Ignatov close(cgfd); 16341f5fa9abSAndrey Ignatov cleanup_cgroup_environment(); 16351f5fa9abSAndrey Ignatov return err; 16361f5fa9abSAndrey Ignatov } 1637