diff --git a/Makefile b/Makefile index 69e63e472..64aad39a5 100644 --- a/Makefile +++ b/Makefile @@ -141,7 +141,7 @@ ifneq ("$(NO_CROSS_COMPILER)", "") else mkdir -p ./bin/$(TARGETOS)_$(TARGETARCH) $(CC) -o ./bin/$(TARGETOS)_$(TARGETARCH)/syz-executor$(EXE) executor/executor.cc \ - $(ADDCFLAGS) $(CFLAGS) -DGOOS_$(TARGETOS)=1 -DGOARCH_$(TARGETARCH)=1 \ + $(ADDCFLAGS) $(CFLAGS) -L/usr/local/lib64 -lbpf -lelf -lz -DGOOS_$(TARGETOS)=1 -DGOARCH_$(TARGETARCH)=1 \ -DHOSTGOOS_$(HOSTOS)=1 -DGIT_REVISION=\"$(REV)\" endif endif diff --git a/README.md b/README.md index 607147fd5..b0fdef2a2 100644 --- a/README.md +++ b/README.md @@ -1,44 +1,137 @@ -# syzkaller - kernel fuzzer - -[![CI Status](https://github.com/google/syzkaller/workflows/ci/badge.svg)](https://github.com/google/syzkaller/actions?query=workflow/ci) -[![OSS-Fuzz](https://oss-fuzz-build-logs.storage.googleapis.com/badges/syzkaller.svg)](https://bugs.chromium.org/p/oss-fuzz/issues/list?q=label:Proj-syzkaller) -[![Go Report Card](https://goreportcard.com/badge/github.com/google/syzkaller)](https://goreportcard.com/report/github.com/google/syzkaller) -[![Coverage Status](https://codecov.io/gh/google/syzkaller/graph/badge.svg)](https://codecov.io/gh/google/syzkaller) -[![GoDoc](https://godoc.org/github.com/google/syzkaller?status.svg)](https://godoc.org/github.com/google/syzkaller) -[![License](https://img.shields.io/badge/License-Apache%202.0-blue.svg)](LICENSE) - -`syzkaller` (`[siːzˈkɔːlə]`) is an unsupervised coverage-guided kernel fuzzer.\ -Supported OSes: `Akaros`, `FreeBSD`, `Fuchsia`, `gVisor`, `Linux`, `NetBSD`, `OpenBSD`, `Windows`. - -Mailing list: [syzkaller@googlegroups.com](https://groups.google.com/forum/#!forum/syzkaller) (join on [web](https://groups.google.com/forum/#!forum/syzkaller) or by [email](mailto:syzkaller+subscribe@googlegroups.com)). - -Found bugs: [Akaros](docs/akaros/found_bugs.md), [Darwin/XNU](docs/darwin/README.md), [FreeBSD](docs/freebsd/found_bugs.md), [Linux](docs/linux/found_bugs.md), [NetBSD](docs/netbsd/found_bugs.md), [OpenBSD](docs/openbsd/found_bugs.md), [Windows](docs/windows/README.md). - -## Documentation - -Initially, syzkaller was developed with Linux kernel fuzzing in mind, but now -it's being extended to support other OS kernels as well. -Most of the documentation at this moment is related to the [Linux](docs/linux/setup.md) kernel. -For other OS kernels check: -[Akaros](docs/akaros/README.md), -[Darwin/XNU](docs/darwin/README.md), -[FreeBSD](docs/freebsd/README.md), -[Fuchsia](docs/fuchsia/README.md), -[NetBSD](docs/netbsd/README.md), -[OpenBSD](docs/openbsd/setup.md), -[Starnix](docs/starnix/README.md), -[Windows](docs/windows/README.md), -[gVisor](docs/gvisor/README.md). - -- [How to install syzkaller](docs/setup.md) -- [How to use syzkaller](docs/usage.md) -- [How syzkaller works](docs/internals.md) -- [How to install syzbot](docs/setup_syzbot.md) -- [How to contribute to syzkaller](docs/contributing.md) -- [How to report Linux kernel bugs](docs/linux/reporting_kernel_bugs.md) -- [Tech talks and articles](docs/talks.md) -- [Research work based on syzkaller](docs/research.md) - -## Disclaimer - -This is not an official Google product. +# BPF Runtime Fuzzer (BRF) +BRF is a coverage-guided fuzzer that aims to fuzz the runtime compononets of eBPF shielded by the verifier. BRF uses semantic-aware and dependency-aware input generation/mutation logic as well as generating syscalls to trigger the execution of eBPF programs to achieve the goal. The implementation of BRF is based on Syzkaller. + +## Prerequisites + +### LLVM +To use latest bpf features, it is better to build the kernel using the latest llvm. + +``` bash +git clone --branch llvmorg-17.0.6 https://github.com/llvm/llvm-project.git +mkdir llvm-project/build; cd llvm-project/build +cmake ../llvm -DLLVM_TARGETS_TO_BUILD="BPF;X86" \ + -DLLVM_ENABLE_PROJECTS=clang \ + -DBUILD_SHARED_LIBS=OFF \ + -DCMAKE_BUILD_TYPE=Release \ + -DLLVM_BUILD_RUNTIME=OFF +make +``` +After the build completes, export build/bin to $PATH. + +### Pahole +``` bash +git clone --branch v1.24 https://github.com/acmel/dwarves.git +mkdir dwarves/build; cd dwarves/build +cmake ../ +make +sudo make install +``` + +More to be added. Let us know if you think something should be added here. + +### Build Linux kernel +Here we use the development branch of network device subsystem of the Linux kernel. +``` bash +git clone https://git.kernel.org/pub/scm/linux/kernel/git/netdev/net-next.git $KERNEL +cd $KERNEL +make CC=clang-17 defconfig +make CC=clang-17 kvm_guest.config +``` +Follow the [guide](/docs/linux/kernel_configs.md) and enable kernel configs required by Syzkaller + +Enable bpf-related configs by editing .config or through menuconfig. +``` make +CONFIG_BPF_SYSCALL +CONFIG_BPF_JIT +CONFIG_BPF_LSM +CONFIG_DEBUG_INFO_BTF +CONFIG_MODULE_ALLOW_BTF_MISMATCH +CONFIG_TEST_BPF +CONFIG_CGROUP_BPF +CONFIG_NET_ACT_BPF +CONFIG_NET_CLS_BPF +CONFIG_BPF_STREAM_PARSER +CONFIG_LWTUNNEL_BPF +CONFIG_IPV6_SEG6_BPF +CONFIG_LIRC +CONFIG_BPF_LIRC_MODE2 +``` + +Finally, build the Linux kernel with Clang/LLVM. +``` make +make CC=clang-17 +``` + +Build bpftool and libbpf to be used later +``` bash +cd $KERNEL/tools/bpf/bpftool +make CC=clang-17 +cd $KERNEL/tools/lib/bpf +make +``` + +### Create Debian Bookworm Linux image +``` bash +mkdir $IMAGE; cd $IMAGE +cp $SYZKALLER/tools/create-image.sh . +chmod +x create-image.sh +ADD_PACKAGE="make,sysbench,git,vim,tmux,usbutils,tcpdump,clang-16" ./create-image.sh --feature full --distribution bookworm --seek 8191 +``` + +### Prepare the image for compiling BPF programs +Prepare BRF working directory. The directory will be shared with the guest to store and compile BPF programs. +``` bash +mkdir $BRF_WORKDIR; cd $BRF_WORKDIR +cp $KERNEL/tools/bpf/bpftool/vmlinux.h . +``` + +Boot into the guest and install libbpf headers. +``` bash +qemu-system-x86_64 \ + -m 2G \ + -smp 2 \ + -kernel $KERNEL/arch/x86/boot/bzImage \ + -append "console=ttyS0 root=/dev/sda earlyprintk=serial net.ifnames=0" \ + -drive file=$IMAGE/bookworm.img,format=raw \ + -net user,host=10.0.2.10,hostfwd=tcp:127.0.0.1:10021-:22 \ + -net nic,model=e1000 \ + -virtfs local,path=$KERNEL,mount_tag=host0,security_model=mapped,id=host0 \ + -enable-kvm \ + -nographic \ + -pidfile vm.pid \ + 2>&1 | tee vm.log +``` +``` bash +mkdir /mnt/kernel_src +mount -t 9p -o trans=virtio,version=9p2000.L host0 /mnt/kernel_src +cd /mnt/kernel_src/tools/lib/bpf +make install_headers +``` +## Run BRF +Create a config like the following and replace $SYZKALLER, $KERNEL, $IMAGE and $BRF\_WORKDIR with the actual paths. +``` json +{ + "target": "linux/amd64", + "http": "127.0.0.1:56741", + "workdir": "$SYZKALLER/workdir/bookworm", + "kernel_obj": "$KERNEL", + "image": "$IMAGE/bookworm.img", + "sshkey": "$IMAGE/bookworm.id_rsa", + "syzkaller": "$SYZKALLER", + "procs": 8, + "type": "qemu", + "vm": { + "count": 4, + "kernel": "$KERNEL/arch/x86/boot/bzImage", + "cpu": 2, + "mem": 2048, + "brf_workdir": "$BRF_WORKDIR" + } +} +``` +Run Syzkaller manager: +``` +mkdir -p workdir/bookworm +./bin/syzkaller -config my.cfg +``` +## Acknoledgement diff --git a/executor/common_brf_linux.h b/executor/common_brf_linux.h new file mode 100644 index 000000000..e74e9957f --- /dev/null +++ b/executor/common_brf_linux.h @@ -0,0 +1,256 @@ + +#define OBJ_LIST_SIZE 32 + +static struct bpf_object *bpf_object_list[OBJ_LIST_SIZE]; + +struct bpf_res { + int prog_fds[32]; + int prog_num; + int map_fds[32]; + int map_num; +}; + +static long syz_bpf_prog_open(volatile long a0) +{ + const char* file = (char*)a0; + struct bpf_object* obj; + char bpf_err_buf[256]; + unsigned int i; + long err; + + obj = bpf_object__open(file); + err = libbpf_get_error(obj); + if (err) { + debug("syz_bpf_prog_open: failed to open bpf object %s: %s", file, bpf_err_buf); + return -1; + } + + for (i = 0; i < OBJ_LIST_SIZE; i++) { + if (!bpf_object_list[i]) { + bpf_object_list[i] = obj; + return 0; + } + } + + debug("syz_bpf_prog_open: bpf_object_list full"); + return -1; +} + +static struct bpf_object *find_bpf_object_by_basename(const char *path) +{ + char name[BPF_OBJ_NAME_LEN]; + char *end; + int i = 0; + + for (i = 0; i < OBJ_LIST_SIZE; i++) { + if (!bpf_object_list[i]) + break; + + strncpy(name, basename(path), sizeof(name) - 1); + end = strchr(name, '.'); + if (end) + *end = 0; + + if (strcmp(bpf_object__name(bpf_object_list[i]), name) == 0) + return bpf_object_list[i]; + } + return NULL; +} + +static long syz_bpf_prog_load(volatile long a0, volatile long a1) +{ + const char *file = (char *)a0; + struct bpf_res *res = (struct bpf_res *)a1; + struct bpf_program *prog; + struct bpf_object *obj; + struct bpf_map *map; + int i, err; + + obj = find_bpf_object_by_basename(file); + if (!obj) { + debug("syz_bpf_prog_load: cannot find %s", file); + return -1; + } + + err = bpf_object__load(obj); + if (err) { + debug("syz_bpf_prog_load: failed to load bpf prog, errno %d", err); + return -1; + } + + i = 0; + bpf_object__for_each_program(prog, obj) + res->prog_fds[i++] = bpf_program__fd(prog); + + i = 0; + bpf_object__for_each_map(map, obj) + res->map_fds[i++] = bpf_map__fd(map); + + return res->prog_fds[0]; +} + +#define LO_IFINDEX 1 + +static bool check_attach_res(struct bpf_program *prog, int *res) +{ + LIBBPF_OPTS(bpf_map_create_opts, opts); + struct perf_event_attr attr = { + .type = PERF_TYPE_HARDWARE, + .config = PERF_COUNT_HW_CPU_CYCLES, + .sample_freq = 50, + .inherit = 1, + .freq = 1, + }; + + if (*res > 0) + return true; + + switch (bpf_program__type(prog)) { + case BPF_PROG_TYPE_SOCKET_FILTER: + *res = socket(AF_PACKET, SOCK_RAW, htons(ETH_P_ALL)); + goto check_fd; + case BPF_PROG_TYPE_SCHED_CLS: + case BPF_PROG_TYPE_SCHED_ACT: + case BPF_PROG_TYPE_XDP: + *res = LO_IFINDEX; + return true; + case BPF_PROG_TYPE_PERF_EVENT: + *res = syscall(__NR_perf_event_open, &attr, 0, -1, -1, 0); + goto check_fd; + case BPF_PROG_TYPE_CGROUP_SKB: + case BPF_PROG_TYPE_CGROUP_SOCK: + case BPF_PROG_TYPE_CGROUP_DEVICE: + case BPF_PROG_TYPE_CGROUP_SOCK_ADDR: + case BPF_PROG_TYPE_CGROUP_SYSCTL: + case BPF_PROG_TYPE_CGROUP_SOCKOPT: + *res = open("/sys/fs/cgroup", O_RDONLY); + goto check_fd; + case BPF_PROG_TYPE_SK_SKB: + case BPF_PROG_TYPE_SK_MSG: + *res = bpf_map_create(BPF_MAP_TYPE_SOCKMAP, "brf", + sizeof(int), sizeof(int), 1, &opts); + goto check_fd; + case BPF_PROG_TYPE_LIRC_MODE2: + *res = open("/dev/lirc0", O_RDWR); + goto check_fd; + case BPF_PROG_TYPE_SK_REUSEPORT: + *res = socket(AF_INET, SOCK_DGRAM, 0); + goto check_fd; + case BPF_PROG_TYPE_FLOW_DISSECTOR: + case BPF_PROG_TYPE_SK_LOOKUP: + *res = open("/proc/self/ns/net", O_RDONLY); + goto check_fd; + default: + return true; + } + +check_fd: + return *res >= 0; +} + +static int bpf_program_attach(struct bpf_program *prog, int res, struct bpf_link **link) +{ + struct bpf_tcx_opts tcx_opts; + struct bpf_netfilter_opts nf_opts; + int optval = 1; + int fd, ret; + + if (!check_attach_res(prog, &res)) { + debug("syz_bpf_prog_attach: no attach point for %s", + libbpf_bpf_prog_type_str(bpf_program__type(prog))); + return -1; + } + + fd = bpf_program__fd(prog); + + switch (bpf_program__type(prog)) { + case BPF_PROG_TYPE_SOCKET_FILTER: + return setsockopt(res, SOL_SOCKET, SO_ATTACH_BPF, &fd, sizeof(fd)); + case BPF_PROG_TYPE_KPROBE: + case BPF_PROG_TYPE_TRACEPOINT: + case BPF_PROG_TYPE_RAW_TRACEPOINT: + case BPF_PROG_TYPE_RAW_TRACEPOINT_WRITABLE: + case BPF_PROG_TYPE_TRACING: + *link = bpf_program__attach(prog); + goto check_link; + case BPF_PROG_TYPE_SCHED_CLS: + case BPF_PROG_TYPE_SCHED_ACT: + *link = bpf_program__attach_tcx(prog, res, &tcx_opts); + goto check_link; + case BPF_PROG_TYPE_XDP: + *link = bpf_program__attach_xdp(prog, res); + goto check_link; + case BPF_PROG_TYPE_PERF_EVENT: + *link = bpf_program__attach_perf_event(prog, res); + goto check_link; + case BPF_PROG_TYPE_CGROUP_SKB: + case BPF_PROG_TYPE_CGROUP_SOCK: + case BPF_PROG_TYPE_CGROUP_DEVICE: + case BPF_PROG_TYPE_CGROUP_SOCK_ADDR: + case BPF_PROG_TYPE_CGROUP_SYSCTL: + case BPF_PROG_TYPE_CGROUP_SOCKOPT: + *link = bpf_program__attach_cgroup(prog, res); + goto check_link; + case BPF_PROG_TYPE_LWT_IN: + case BPF_PROG_TYPE_LWT_OUT: + case BPF_PROG_TYPE_LWT_XMIT: + case BPF_PROG_TYPE_LWT_SEG6LOCAL: + break; + case BPF_PROG_TYPE_SOCK_OPS: + *link = bpf_program__attach_cgroup(prog, res); + goto check_link; + case BPF_PROG_TYPE_SK_SKB: + return bpf_prog_attach(fd, res, BPF_SK_SKB_VERDICT, 0); + case BPF_PROG_TYPE_SK_MSG: + return bpf_prog_attach(fd, res, BPF_SK_MSG_VERDICT, 0); + case BPF_PROG_TYPE_LIRC_MODE2: + return bpf_prog_attach(fd, res, BPF_LIRC_MODE2, 0); + case BPF_PROG_TYPE_SK_REUSEPORT: + ret = setsockopt(res, SOL_SOCKET, SO_REUSEPORT, &optval, sizeof(optval)); + return ret?: setsockopt(res, SOL_SOCKET, SO_ATTACH_REUSEPORT_EBPF, &fd, sizeof(fd)); + case BPF_PROG_TYPE_FLOW_DISSECTOR: + *link = bpf_program__attach_netns(prog, res); + goto check_link; + case BPF_PROG_TYPE_STRUCT_OPS: + case BPF_PROG_TYPE_EXT: + case BPF_PROG_TYPE_LSM: + *link = bpf_program__attach_lsm(prog); + goto check_link; + case BPF_PROG_TYPE_SK_LOOKUP: + *link = bpf_program__attach_netns(prog, res); + goto check_link; + case BPF_PROG_TYPE_SYSCALL: + break; + case BPF_PROG_TYPE_NETFILTER: + *link = bpf_program__attach_netfilter(prog, &nf_opts); + goto check_link; + default: + break; + } + + return -1; + +check_link: + return (*link != NULL) ? 0 : -1; +} + +static long syz_bpf_prog_attach(volatile long a0) +{ + const char *file = (char *)a0; + int attach_res = -1; + struct bpf_program *prog; + struct bpf_object *obj; + struct bpf_link *link = NULL; + + obj = find_bpf_object_by_basename(file); + if (!obj) { + debug("syz_bpf_prog_attach: cannot find %s", file); + return -1; + } + + bpf_object__for_each_program(prog, obj) { + bpf_program_attach(prog, attach_res, &link); + } + + return link? bpf_link__fd(link) : 0; +} diff --git a/executor/common_linux.h b/executor/common_linux.h index 9558bdb7d..b3f4f90c4 100644 --- a/executor/common_linux.h +++ b/executor/common_linux.h @@ -5682,3 +5682,12 @@ static long syz_pidfd_open(volatile long pid, volatile long flags) } #endif + +#if SYZ_EXECUTOR || __NR_syz_bpf_prog_open || __NR_syz_bpf_prog_load || __NR_syz_bpf_prog_attach +#include +#include +#include + +#include "common_brf_linux.h" + +#endif diff --git a/go.mod b/go.mod index 8e4bd4e0a..46954cb08 100644 --- a/go.mod +++ b/go.mod @@ -19,7 +19,7 @@ require ( golang.org/x/net v0.19.0 golang.org/x/oauth2 v0.15.0 golang.org/x/perf v0.0.0-20230221235046-aebcfb61e84c - golang.org/x/sync v0.5.0 + golang.org/x/sync v0.6.0 golang.org/x/sys v0.15.0 golang.org/x/tools v0.14.0 google.golang.org/api v0.153.0 diff --git a/go.sum b/go.sum index e1ec58157..92574da17 100644 --- a/go.sum +++ b/go.sum @@ -816,8 +816,8 @@ golang.org/x/sync v0.0.0-20201207232520-09787c993a3a/go.mod h1:RxMgew5VJxzue5/jJ golang.org/x/sync v0.0.0-20210220032951-036812b2e83c/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM= golang.org/x/sync v0.0.0-20220722155255-886fb9371eb4/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM= golang.org/x/sync v0.1.0/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM= -golang.org/x/sync v0.5.0 h1:60k92dhOjHxJkrqnwsfl8KuaHbn/5dl0lUPUklKo3qE= -golang.org/x/sync v0.5.0/go.mod h1:Czt+wKu1gCyEFDUtn0jG5QVvpJ6rzVqr5aXyt9drQfk= +golang.org/x/sync v0.6.0 h1:5BMeUDZ7vkXGfEr1x9B4bRcTH4lpkTkpdh0T/J+qjbQ= +golang.org/x/sync v0.6.0/go.mod h1:Czt+wKu1gCyEFDUtn0jG5QVvpJ6rzVqr5aXyt9drQfk= golang.org/x/sys v0.0.0-20180830151530-49385e6e1522/go.mod h1:STP8DvDyc/dI5b8T5hshtkjS+E42TnysNCUPdjciGhY= golang.org/x/sys v0.0.0-20180905080454-ebe1bf3edb33/go.mod h1:STP8DvDyc/dI5b8T5hshtkjS+E42TnysNCUPdjciGhY= golang.org/x/sys v0.0.0-20181116152217-5ac8a444bdc5/go.mod h1:STP8DvDyc/dI5b8T5hshtkjS+E42TnysNCUPdjciGhY= diff --git a/pkg/csource/generated.go b/pkg/csource/generated.go index dbb18a811..5a87318c6 100644 --- a/pkg/csource/generated.go +++ b/pkg/csource/generated.go @@ -11842,6 +11842,95 @@ static long syz_pidfd_open(volatile long pid, volatile long flags) #endif +#if SYZ_EXECUTOR || __NR_syz_bpf_prog_open || __NR_syz_bpf_prog_load +#include +#include + +#define OBJ_LIST_SIZE 32 + +static struct bpf_object *bpf_object_list[OBJ_LIST_SIZE]; + +static long syz_bpf_prog_open(volatile long a0) +{ + const char* file = (char*)a0; + struct bpf_object* obj; + char bpf_err_buf[256]; + unsigned int i; + long err; + + obj = bpf_object__open(file); + err = libbpf_get_error(obj); + if (err) { + debug("syz_bpf_prog_open: failed to open bpf object %s: %s", file, bpf_err_buf); + return -1; + } + + for (i = 0; i < OBJ_LIST_SIZE; i++) { + if (!bpf_object_list[i]) { + bpf_object_list[i] = obj; + return 0; + } + } + + debug("syz_bpf_prog_open: bpf_object_list full"); + return -1; +} + +static struct bpf_object *find_bpf_object_by_basename(const char *path) +{ + char name[BPF_OBJ_NAME_LEN]; + char *end; + int i = 0; + + for (i = 0; i < OBJ_LIST_SIZE; i++) { + if (!bpf_object_list[i]) + break; + + strncpy(name, basename(path), sizeof(name) - 1); + end = strchr(name, '.'); + if (end) + *end = 0; + + if (strcmp(bpf_object__name(bpf_object_list[i]), name) == 0) + return bpf_object_list[i]; + } + return NULL; +} + +static long syz_bpf_prog_load(volatile long a0, volatile long a1) +{ + const char *file = (char *)a0; + struct bpf_res *res = (struct bpf_res *)a1; + struct bpf_program *prog; + struct bpf_object *obj; + struct bpf_map *map; + int i, err; + + obj = find_bpf_object_by_basename(file); + if (!obj) { + debug("syz_bpf_prog_load: cannot find %s", file); + return -1; + } + + err = bpf_object__load(obj); + if (err) { + debug("syz_bpf_prog_load: failed to load bpf prog, errno %d", err); + return -1; + } + + i = 0; + bpf_object__for_each_program(prog, obj) + res->prog_fds[i++] = bpf_program__fd(prog); + + i = 0; + bpf_object__for_each_map(map, obj) + res->map_fds[i++] = bpf_map__fd(map); + + return res->prog_fds[0]; +} + +#endif + #elif GOOS_test #include diff --git a/pkg/host/syscalls_linux.go b/pkg/host/syscalls_linux.go index d59fe491b..ee3ee170e 100644 --- a/pkg/host/syscalls_linux.go +++ b/pkg/host/syscalls_linux.go @@ -328,6 +328,9 @@ var syzkallSupport = map[string]func(*prog.Syscall, *prog.Target, string) (bool, "syz_pkey_set": isSyzPkeySetSupported, "syz_socket_connect_nvme_tcp": isSyzSocketConnectNvmeTCPSupported, "syz_pidfd_open": alwaysSupported, + "syz_bpf_prog_open": alwaysSupported, + "syz_bpf_prog_load": alwaysSupported, + "syz_bpf_prog_attach": alwaysSupported, } func isSupportedSyzkall(c *prog.Syscall, target *prog.Target, sandbox string) (bool, string) { diff --git a/prog/brf.go b/prog/brf.go index d40d5f030..adf9593d1 100644 --- a/prog/brf.go +++ b/prog/brf.go @@ -1,17 +1,240 @@ package prog +import ( + "fmt" + "os" + "os/exec" + "time" + + "github.com/google/syzkaller/pkg/osutil" +) + type BpfRuntimeFuzzer struct { isEnabled bool + workDir string + + helperFuncMap map[string]*BpfHelperFunc + progTypeMap map[BpfProgTypeEnum]*BpfProgTypeDef + ctxAccessMap map[BpfProgTypeEnum]*BpfCtxAccess } func NewBpfRuntimeFuzzer(enable bool) *BpfRuntimeFuzzer { brf := new(BpfRuntimeFuzzer) + + if (!enable) { + return brf + } + + brf.workDir = "/mnt/brf_work_dir" + err := mountBrfWorkDir(brf.workDir) + if (err != nil) { + return brf + } + brf.isEnabled = true + brf.helperFuncMap = make(map[string]*BpfHelperFunc) + brf.progTypeMap = make(map[BpfProgTypeEnum]*BpfProgTypeDef) + brf.ctxAccessMap = make(map[BpfProgTypeEnum]*BpfCtxAccess) + + brf.InitFromSrc(HelperFuncMap, ProgTypeMap, CtxAccessMap) return brf } +func mountBrfWorkDir(dir string) error { + var timeout time.Duration = 10000000000 + + err := os.Mkdir(dir, os.ModeDir) + if err != nil { + fmt.Printf("failed to create brf work dir: %v\n", err) + return err + } + + args := []string{"-t", "9p", "-o", "trans=virtio,version=9p2000.L", "brf", dir} + _, err = osutil.RunCmd(timeout, "", "mount", args...) + if err != nil { + fmt.Printf("failed to mount brf work dir: %v\n", err) + return err + } + return nil +} + func (brf *BpfRuntimeFuzzer) IsEnabled() bool { return brf.isEnabled } +func (brf *BpfRuntimeFuzzer) GenPrologue(r *randGen, s *state, prog *Prog) { + var p *BpfProg + + if !brf.isEnabled { + return + } + + p = brf.genSeedBpfProg(r) + + c0 := genBpfProgOpenCall(r, s, p) + s.analyze(c0) + prog.Calls = append(prog.Calls, c0) + + c1 := genBpfProgLoadCall(r, s, p) + s.analyze(c1) + prog.Calls = append(prog.Calls, c1) + + c2 := genBpfProgAttachCall(r, s, p) + s.analyze(c2) + prog.Calls = append(prog.Calls, c2) +} + +func genBpfProgOpenCall(r *randGen, s *state, p *BpfProg) *Call { + meta := r.target.SyscallMap["syz_bpf_prog_open"] + args := make([]Arg, len(meta.Args)) + c := MakeCall(meta, nil) + + pathStr := []byte(p.BasePath + ".o") + pathArg := meta.Args[0] + pathPtr := pathArg.Type.(*PtrType) + pathBuffer := pathPtr.Elem.(*BufferType) + pathBufferDir := pathPtr.ElemDir + pathBufferArg := MakeDataArg(pathBuffer, pathBufferDir, pathStr) + args[0] = r.allocAddr(s, pathArg.Type, pathArg.Dir(DirIn), pathBufferArg.Size(), pathBufferArg) + + c.Args = args + r.target.assignSizesCall(c) + return c +} + +func genBpfProgLoadCall(r *randGen, s *state, p *BpfProg) *Call { + meta := r.target.SyscallMap["syz_bpf_prog_load"] + args := make([]Arg, len(meta.Args)) + c := MakeCall(meta, nil) + + pathStr := []byte(p.BasePath + ".o") + pathArg := meta.Args[0] + pathPtr := pathArg.Type.(*PtrType) + pathBuffer := pathPtr.Elem.(*BufferType) + pathBufferDir := pathPtr.ElemDir + pathBufferArg := MakeDataArg(pathBuffer, pathBufferDir, pathStr) + args[0] = r.allocAddr(s, pathArg.Type, pathArg.Dir(DirIn), pathBufferArg.Size(), pathBufferArg) + args[1], _ = r.generateArg(s, meta.Args[1].Type, meta.Args[1].Dir(DirIn)) + + c.Args = args + r.target.assignSizesCall(c) + return c +} + +func genBpfProgAttachCall(r *randGen, s *state, p *BpfProg) *Call { + meta := r.target.SyscallMap["syz_bpf_prog_attach"] + args := make([]Arg, len(meta.Args)) + c := MakeCall(meta, nil) + + pathStr := []byte(p.BasePath + ".o") + pathArg := meta.Args[0] + pathPtr := pathArg.Type.(*PtrType) + pathBuffer := pathPtr.Elem.(*BufferType) + pathBufferDir := pathPtr.ElemDir + pathBufferArg := MakeDataArg(pathBuffer, pathBufferDir, pathStr) + args[0] = r.allocAddr(s, pathArg.Type, pathArg.Dir(DirIn), pathBufferArg.Size(), pathBufferArg) + + c.Args = args + r.target.assignSizesCall(c) + return c +} + +func (brf *BpfRuntimeFuzzer) genSeedBpfProg(r *randGen) *BpfProg { + var opt BrfGenProgOpt + var p *BpfProg + var ok bool + +// opt.useTestSrc = true + opt.genProgAttempt = 20 + opt.basePath = brf.workDir + + for i := 0; i < opt.genProgAttempt; i++ { + if p, ok = brf.GenBpfProg(r, opt); !ok { + continue + } + p.FixRef(r) + p.FixSpinLock(r) + + if err := p.writeCSource(); err != nil { + fmt.Printf("failed to write bpf program c source: %v\n", err) + return nil + } + + if err := p.writeGob(); err != nil { + fmt.Printf("failed to serialize bpf program: %v\n", err) + return nil + } + + if err := brf.compileBpfProg(p); err != nil { + fmt.Printf("failed to compile bpf program: %v\n", err) + continue + } + return p + } + return nil +} + +func (brf *BpfRuntimeFuzzer) mutSeedBpfProg(r *randGen, path string) *BpfProg { + var opt BrfGenProgOpt + var p *BpfProg + +// opt.useTestSrc = true + opt.genProgAttempt = 20 + opt.basePath = brf.workDir + + p = NewBpfProg(nil, nil, opt) + p.readGob(path) + p.pt = brf.progTypeMap[p.TypeEnum] + + for i := 0; i < opt.genProgAttempt; i++ { + for ok := false; !ok; { + ok = brf.MutBpfProg(r, p, opt) + } + p.FixRef(r) + p.FixSpinLock(r) + + if err := p.writeCSource(); err != nil { + fmt.Printf("failed to write bpf program c source: %v\n", err) + return nil + } + + if err := p.writeGob(); err != nil { + fmt.Printf("failed to serialize bpf program: %v\n", err) + return nil + } + + if err := brf.compileBpfProg(p); err != nil { + fmt.Printf("failed to compile bpf program: %v\n", err) + continue + } + return p + } + return nil +} + +func (brf *BpfRuntimeFuzzer) genBpfProg(r *randGen, opt BrfGenProgOpt) (*BpfProg, bool) { + p := newBpfProg(r, opt) + + return p, true +} + +func (brf *BpfRuntimeFuzzer) mutBpfProg(r *randGen, p *BpfProg, opt BrfGenProgOpt) bool { + return true +} + +func (brf *BpfRuntimeFuzzer) compileBpfProg(p *BpfProg) error { + var timeout time.Duration = 10000000000 + cmd := exec.Command("clang-16", "-g", "-D__TARGET_ARCH_x86", "-mlittle-endian", + "-idirafter", "/usr/local/include", + "-idirafter", "/usr/local/llvm/include", + "-idirafter", "/usr/include/x86_64-linux-gnu", + "-idirafter", "/usr/include", + "-Wno-compare-distinct-pointer-types", "-O2", "-target", "bpf", "-mcpu=v3", + "-c", p.BasePath + ".c", + "-o", p.BasePath + ".o") + cmd.Dir = brf.workDir + + _, err := osutil.Run(timeout, cmd) + return err +} diff --git a/prog/brf_legacy.go b/prog/brf_legacy.go new file mode 100644 index 000000000..dc3f3deef --- /dev/null +++ b/prog/brf_legacy.go @@ -0,0 +1,2835 @@ +package prog + +import ( + "bytes" + "fmt" + "time" + "strings" +) + +type PathLinePair struct { + Path string + Line int +} + +type BpfAttachOption struct { + Str1 string + Str2 string + IntOpts []int64 +} + +type SecDefGenFunc func(r *randGen) (string, *StructDef) + +type SecDef struct { + Sec string + SecDefGen SecDefGenFunc + Sleepable bool +} + +type BpfProgTypeEnum int + +const ( + BPF_PROG_TYPE_UNSPEC BpfProgTypeEnum = iota + BPF_PROG_TYPE_SOCKET_FILTER + BPF_PROG_TYPE_KPROBE + BPF_PROG_TYPE_SCHED_CLS + BPF_PROG_TYPE_SCHED_ACT + BPF_PROG_TYPE_TRACEPOINT + BPF_PROG_TYPE_XDP + BPF_PROG_TYPE_PERF_EVENT + BPF_PROG_TYPE_CGROUP_SKB + BPF_PROG_TYPE_CGROUP_SOCK + BPF_PROG_TYPE_LWT_IN + BPF_PROG_TYPE_LWT_OUT + BPF_PROG_TYPE_LWT_XMIT + BPF_PROG_TYPE_SOCK_OPS + BPF_PROG_TYPE_SK_SKB + BPF_PROG_TYPE_CGROUP_DEVICE + BPF_PROG_TYPE_SK_MSG + BPF_PROG_TYPE_RAW_TRACEPOINT + BPF_PROG_TYPE_CGROUP_SOCK_ADDR + BPF_PROG_TYPE_LWT_SEG6LOCAL + BPF_PROG_TYPE_LIRC_MODE2 + BPF_PROG_TYPE_SK_REUSEPORT + BPF_PROG_TYPE_FLOW_DISSECTOR + BPF_PROG_TYPE_CGROUP_SYSCTL + BPF_PROG_TYPE_RAW_TRACEPOINT_WRITABLE + BPF_PROG_TYPE_CGROUP_SOCKOPT + BPF_PROG_TYPE_TRACING + BPF_PROG_TYPE_STRUCT_OPS + BPF_PROG_TYPE_EXT + BPF_PROG_TYPE_LSM + BPF_PROG_TYPE_SK_LOOKUP + BPF_PROG_TYPE_SYSCALL + BPF_PROG_TYPE_NETFILTER + BPF_PROG_TYPE_MAX +) + +type BpfProgTypeDef struct { + Name string + User string + Kern string + Enum BpfProgTypeEnum + SecDefs []SecDef + FuncProtos []string + Helpers []*BpfHelperFunc + ctxAccess *BpfCtxAccess +} + +func NewBpfProgTypeDef() *BpfProgTypeDef { + bpfProgType := new(BpfProgTypeDef) + return bpfProgType +} + +func (pt *BpfProgTypeDef) getHelper(helperEnum string) *BpfHelperFunc { + for _, helper := range pt.Helpers { + if helper.Enum == helperEnum { + return helper + } + } + return nil +} + +func (pt *BpfProgTypeDef) getHelpers(helperEnums []string) []*BpfHelperFunc { + var helpers []*BpfHelperFunc + for _, helper := range pt.Helpers { + for _, enum := range helperEnums { + if helper.Enum == enum { + helpers = append(helpers, helper) + } + } + } + return helpers +} + +type BpfHelperFunc struct { + Num int + Enum string + Name string + Proto string + Args []string + ArgBtfIds []string + Ret string + RetBtfId string + GplOnly bool + PktAccess bool +} + +type BpfMap struct { + MapType string + MapFlags []string + MapName string + Key *StructDef + Val *StructDef + MaxEntries int64 + InnerMap *BpfMap +} + +func (m *BpfMap) getFlag(f string) int { + for i, flag := range m.MapFlags { + if flag == f { + return i + } + } + return -1 +} + +func (m *BpfMap) addFlag(flag string) { + if f := m.getFlag(flag); f == -1 { + m.MapFlags = append(m.MapFlags, flag) + } +} + +func (m *BpfMap) removeFlag(flag string) { + if f := m.getFlag(flag); f != -1 { + m.MapFlags = append(m.MapFlags[0:f], m.MapFlags[f+1:]...) + } +} + +func (m *BpfMap) FlagsStr() string { + flags := "0" + for _, f := range m.MapFlags { + flags = flags + " | " + f + } + return flags +} + +type ArgHint int32 + +const ( + HintGenSpinlock = iota + HintGenTimer + HintGenConstStr + HintGenXdpSockMap + HintGenSockMap +) + +type BpfCallGenHint struct { + ArgHints map[ArgHint]bool + RetAccessSize int // return value will be accessed with the size + IsRetAccessRaw bool // return value is used for raw memory access + PreferredMap *BpfMap +} + +func newBpfCallGenHint(m *BpfMap) *BpfCallGenHint { + hint := &BpfCallGenHint { + ArgHints: make(map[ArgHint]bool), + RetAccessSize: 0, + IsRetAccessRaw: false, + PreferredMap: m, + } + return hint +} + +type BpfArg struct { + Name string + ArgType string + Prepare string + CanBeNull bool + IsNotNull bool + Umin int64 + Umax int64 + IsPktAccess bool + IsPktMetaAccess bool + AccessSize int +} + +func NewBpfArg(helper *BpfHelperFunc, arg int) *BpfArg { + newArg := &BpfArg{ + ArgType: helper.Args[arg], + CanBeNull: true, + Umin: int64(-1), + Umax: int64(-1), + } + + argType := newArg.ArgType + //XXX need to review the constraints + if argType[0:9] == "ARG_CONST" { + if argType == "ARG_CONST_SIZE" { + newArg.Umin = int64(0) + newArg.Umax = int64(1 << 29) + } else if argType == "ARG_CONST_SIZE_OR_ZERO" { + newArg.Umax = int64(1 << 29) + } + //"ARG_CONST_ALLOC_SIZE_OR_ZERO" + } else if argType[len(argType)-7:len(argType)] != "OR_NULL" || argType == "ARG_PTR_TO_MAP_VALUE_OR_NULL"{ //XXX investigate 5065 to how may_be_null work/the difference between ARG_PTR_TO_MAP_VALUE and ARG_PTR_TO_MAP_VALUE_OR_NULL + newArg.CanBeNull = false + } + return newArg +} + +type BpfCall struct { + Helper *BpfHelperFunc + Args []*BpfArg + ArgMap *BpfMap + Ret string + RetType string //XXX switch to StructDef + StackVarSize int + Hint *BpfCallGenHint + PostCalls []*BpfCall +} + +func NewBpfCall(helper *BpfHelperFunc, hint *BpfCallGenHint) *BpfCall { + newCall := &BpfCall{ + Helper: helper, + Args: make([]*BpfArg, len(helper.Args)), + Hint: hint, + } + return newCall +} + +func (call *BpfCall) getArgConstraints(s *BpfProg) []string { + var constraints []string + for _, arg := range call.Args { + if arg.IsPktMetaAccess { + constraints = append(constraints, fmt.Sprintf("%v + %v < %v", s.CtxVars["data_meta"], arg.AccessSize, s.CtxVars["data"])) + continue + } + if arg.IsPktAccess { + constraints = append(constraints, fmt.Sprintf("%v + %v < %v", s.CtxVars["data"], arg.AccessSize, s.CtxVars["data_end"])) + continue + } + //if !arg.CanBeNull && !arg.IsNotNull && strings.Contains(arg.ArgType, "ARG_PTR_TO") { + if !arg.CanBeNull && !arg.IsNotNull { + varStart := strings.Index(arg.Name, "&") + 1 + if idx := strings.Index(arg.Name, "->"); idx != -1 { + constraints = append(constraints, fmt.Sprintf("%v", arg.Name[varStart:idx])) + } else { + constraints = append(constraints, fmt.Sprintf("%v", arg.Name[varStart:len(arg.Name)])) + } + continue + } + if arg.Umin != int64(-1) { + if arg.Umin == int64(0) { + constraints = append(constraints, fmt.Sprintf("(%v != 0 && (%v & 0x8000000000000000UL == 0))", arg.Name, arg.Name)) + } else { + constraints = append(constraints, fmt.Sprintf("%v > %v", arg.Name, arg.Umin)) //XXX potential mutation point + } + } + if arg.Umax != int64(-1) { + constraints = append(constraints, fmt.Sprintf("%v < %v", arg.Name, arg.Umax)) + } + } + return constraints +} + +//XXX use prog.Arg +type StructDef struct { + Name string + FieldNames []string + FieldTypes []string + Size int + Hints map[ArgHint]bool + IsStruct bool +} + +func (sd *StructDef) offsetOfMember(mi int) int { + offset := 0 + for i := 0; i < mi; i++ { + switch (sd.FieldTypes[i]) { + case "struct bpf_spin_lock": offset += 4 + case "struct bpf_timer": offset += 16 + case "char [8]": offset += 8 + case "uint64_t": offset += 8 + case "uint32_t": offset += 4 + case "uint16_t": offset += 2 + case "uint8_t": offset += 1 + } + } + return offset +} + +func (sd *StructDef) findMember(m string) int { + for i, mt := range sd.FieldTypes { + if mt == m { + return i + } + } + return -1 +} + +func occupiedSize(hints map[ArgHint]bool) int { + occupied := 0 + if _, ok := hints[HintGenSpinlock]; ok { + occupied += 4 + } + if _, ok := hints[HintGenTimer]; ok { + occupied += 16 + } + if _, ok := hints[HintGenConstStr]; ok { + occupied += 8 + } + return occupied +} + +func NewBpfProg(pt *BpfProgTypeDef, r *randGen, opt BrfGenProgOpt) *BpfProg { + p := &BpfProg{ + pt: pt, + Externs: make(map[string]string), + CtxVars: make(map[string]string), + CtxTypes: make(map[string]string), + } + + if (opt.useTestSrc) { + p.BasePath = opt.basePath + "/test_prog" + p.UseTestSrc = true + } else { + p.BasePath = opt.basePath + fmt.Sprintf("/prog_%x", time.Now().UnixNano()) + } + + if r != nil { + p.RetVal = genRandReturnVal(r, pt.Enum) + p.Sec = pt.SecDefs[r.Intn(len(pt.SecDefs))] + if p.Sec.SecDefGen != nil { + name, _ := p.Sec.SecDefGen(r) + p.SecStr = fmt.Sprintf("SEC(\"%s%s\")\n", p.Sec.Sec, name) + } else { + p.SecStr = fmt.Sprintf("SEC(\"%s\")\n", p.Sec.Sec) + } + } + p.AttachOpt.IntOpts = make([]int64, 8) + return p +} + +func (s *BpfProg) NewMap(newMapType BpfMapType, hint *BpfCallGenHint, minValSize int, r *randGen) *BpfMap { + mapType := newMapType.Type + maxEntries := int64(0) + if newMapType.MaxEntries == -1 { + maxEntries = int64(r.Intn(1 << 10)) // XXX negative? + } else if newMapType.MaxEntries == 0 { + maxEntries = int64(0) + } else if newMapType.Type == "BPF_MAP_TYPE_RINGBUF" { + maxEntries = (int64(1) << r.Intn(newMapType.MaxEntries)) * 4096 + } else { + maxEntries = int64(r.Intn(newMapType.MaxEntries)) + } + if _, ok := hint.ArgHints[HintGenConstStr]; ok { + maxEntries = 1 + } + + kok := false + var mapKey *StructDef + compatKeyStructs := getCompatKeyStructDefs(s, newMapType); + if r.Intn(2) == 1 && len(compatKeyStructs) > 0 { + mapKey = compatKeyStructs[r.Intn(len(compatKeyStructs))] + } else { + mapKey, kok = generateStruct(s, r, newMapType.KeySize, hint.ArgHints, false, 0) + if !kok { + return nil + } + } + + vok := false + var mapVal *StructDef + compatValStructs := getCompatValStructDefs(s, hint, minValSize, newMapType); + if r.Intn(2) == 1 && len(compatValStructs) > 0 { + mapVal = compatValStructs[r.Intn(len(compatValStructs))] + } else { + mapVal, vok = generateStruct(s, r, newMapType.ValSize, hint.ArgHints, true, minValSize) + if !vok { + return nil + } + } + + var innerMap *BpfMap + if mapType == "BPF_MAP_TYPE_ARRAY_OF_MAPS" || mapType == "BPF_MAP_TYPE_HASH_OF_MAPS" { + var innerMapHint BpfCallGenHint + innerMapType := bpfMapTypes[r.Intn(len(bpfMapTypes))] + innerMap = s.NewMap(innerMapType, &innerMapHint, 0, r) + } + + var mapFlags []string + for _, fs := range newMapType.ManFlags { + if len(fs) == 1 { + mapFlags = append(mapFlags, fs[0]) + } else { + mapFlags = append(mapFlags, fs[r.Intn(len(fs))]) + } + } + for _, fs := range newMapType.OptFlags { + if mapVal != nil { + if _, ok := mapVal.Hints[HintGenConstStr]; ok && len(fs) == 2 && fs[0] == "BPF_F_WRONLY" { + mapFlags = append(mapFlags, fs[1]) + continue + } + } + if r.Intn(2) == 1 { + continue + } + if len(fs) == 1 { + mapFlags = append(mapFlags, fs[0]) + } else { + mapFlags = append(mapFlags, fs[r.Intn(len(fs))]) + } + } + + newMap := &BpfMap{ + MapType: mapType, + MapFlags: mapFlags, + MapName: fmt.Sprintf("map_%v", len(s.Maps)), + Key: mapKey, + Val: mapVal, + MaxEntries: maxEntries, + InnerMap: innerMap, + } + s.Maps = append(s.Maps, newMap) + return newMap +} + +func (s *BpfProg) AddMap(typ string, flags []string, name string, key *StructDef, val *StructDef, size int64) *BpfMap { + newMap := &BpfMap{ + MapType: typ, + MapFlags: flags, + MapName: name, + Key: key, + Val: val, + MaxEntries: size, + } + s.Maps = append(s.Maps, newMap) + return newMap +} + +//func (s *BpfProg) ProgType() int { +// return s.pt.Num +//} +// +//func (s *BpfProg) ProgTypeEnum() string { +// return s.pt.Enum +//} + +func NewBpfFuncProto(attr map[string]string) *BpfHelperFunc { + bfp := new(BpfHelperFunc) + bfp.Proto = attr["proto"] + bfp.Name = attr["func"] + bfp.Ret = attr["ret_type"] + bfp.GplOnly = attr["gpl_only"] == "true" + for i := 1; i <= 5; i++ { + argName := fmt.Sprintf("arg%d_type", i) + if argType, ok := attr[argName]; ok { + bfp.Args = append(bfp.Args, argType) + } + } + return bfp +} + +func isPtrRegType(t RegType) bool { + return t.String() != "SCALAR_VALUE" +} + +type RegType interface { + String() string + Generate(s *BpfProg, r *randGen, call *BpfCall, arg int) *BpfArg + CheckAccess(s *BpfProg, h *BpfHelperFunc, isWrite bool) bool +} + +type ScalarValRegType struct { +} + +func (t ScalarValRegType) String() string { + return "SCALAR_VALUE" +} + +func (t ScalarValRegType) Generate(s *BpfProg, r *randGen, call *BpfCall, arg int) *BpfArg { + a := NewBpfArg(call.Helper, arg) + + size := r.Intn(64) + if call.StackVarSize != 0 { + size = call.StackVarSize + } + + a.IsNotNull = true + a.Name = fmt.Sprintf("v%d", s.VarId) + a.Prepare = fmt.Sprintf(" int64_t %s = %d;\n", a.Name, size) // XXX does uint64 or int64 matter? + s.VarId += 1 + return a +} + +func (t ScalarValRegType) CheckAccess(s *BpfProg, h *BpfHelperFunc, isWrite bool) bool { + return true +} + +var ctxStructsMap = map[string]*StructDef{ + "bpf_sock_ops": &StructDef{ + Name: "bpf_sock_ops", + FieldTypes: []string{"uint32_t", "uint32_t [4]", "uint32_t", "uint32_t", "uint32_t", "uint32_t [4]", "uint32_t [4]", "uint32_t", "uint32_t", "uint32_t", + "uint32_t", "uint32_t", "uint32_t", "uint32_t", "uint32_t", "uint32_t", "uint32_t", "uint32_t", "uint32_t", "uint32_t", + "uint32_t", "uint32_t", "uint32_t", "uint32_t", "uint32_t", "uint32_t", "uint32_t", "uint32_t", "uint32_t", "uint32_t", + "uint32_t", "uint32_t", "uint32_t", "uint64_t", "uint64_t", "struct bpf_sock*", "void*", "void*", "uint32_t", "uint32_t"}, + FieldNames: []string{"op", "args", "family", "remote_ip4", "local_ip4", "remote_ip6", "local_ip6", "remote_port", "local_port", "is_fullsock", + "snd_cwnd", "srtt_us", "bpf_sock_ops_cb_flags", "state", "rtt_min", "snd_ssthresh", "rcv_nxt", "snd_nxt", "snd_una", "mss_cache", + "ecn_flags", "rate_delivered", "rate_interval_us", "packets_out", "retrans_out", "total_retrans", "segs_in", "data_segs_in", "segs_out", "data_segs_out", + "lost_out", "sacked_out", "sk_txhash", "bytes_received", "bytes_acked", "sk", "skb_data", "skb_data_end", "skb_len", "skb_tcp_flags"}, + Size: 216, + IsStruct: true, + }, + "sk_reuseport_md": &StructDef{ + Name: "sk_reuseport_md", + FieldTypes: []string{"void *", "void *", "uint32_t", "uint32_t", "uint32_t", "uint32_t", "uint32_t", "struct bpf_sock*", "struct bpf_sock*"}, + FieldNames: []string{"data", "data_end", "len", "eth_protocol", "ip_protocol", "bind_inany", "hash", "sk", "migrating_sk"}, + Size: 52, + IsStruct: true, + }, + "sk_msg_md": &StructDef{ + Name: "sk_msg_md", + FieldTypes: []string{"void *", "void *", "uint32_t", "uint32_t", "uint32_t", "uint32_t [4]", "uint32_t [4]", "uint32_t", "uint32_t", "uint32_t", + "struct bpf_sock*"}, + FieldNames: []string{"data", "data_end", "family", "remote_ip4", "local_ip4", "remote_ip6", "local_ip6", "remote_port", "local_port", "size", + "sk"}, + Size: 80, + IsStruct: true, + }, + "__sk_buff": &StructDef{ + Name: "__sk_buff", + FieldTypes: []string{"uint32_t", "uint32_t", "uint32_t", "uint32_t", "uint32_t", "uint32_t", "uint32_t", "uint32_t", "uint32_t", "uint32_t", + "uint32_t", "uint32_t", "uint32_t [5]", "uint32_t", "uint32_t", "uint32_t", "uint32_t", "uint32_t", "uint32_t", "uint32_t", + "uint32_t", "uint32_t [4]", "uint32_t [4]", "uint32_t", "uint32_t", "uint32_t", "struct bpf_flow_keys*", "uint64_t", "uint32_t", "uint32_t", + "struct bpf_sock*", "uint32_t"}, + FieldNames: []string{"len", "pkt_type", "mark", "queue_mapping", "protocol", "vlan_present", "vlan_tci", "vlan_proto", "priority", "ingress_ifindex", + "ifindex", "tc_index", "cb", "hash", "tc_classid", "data", "data_end", "napi_id", "family", "remote_ip4", + "local_ip4", "remote_ip6", "local_ip6", "remote_port", "local_port", "data_meta", "flow_keys", "tstamp", "wire_len", "gso_segs", + "sk", "gso_size"}, + Size: 180, + IsStruct: true, + }, + "bpf_sock": &StructDef{ + Name: "bpf_sock", + FieldTypes: []string{"uint32_t", "uint32_t", "uint32_t", "uint32_t", "uint32_t", "uint32_t", "uint32_t", "uint32_t [4]", "uint32_t", "uint32_t", + "uint32_t", "uint32_t [4]", "uint32_t", "int32_t"}, + FieldNames: []string{"bound_dev_if", "family", "type", "protocol", "mark", "priority", "src_ip4", "src_ip6", "src_port", "dst_port", + "dst_ip4", "dst_ip6", "state", "rx_queue_mapping"}, + Size: 80, + IsStruct: true, + }, + "bpf_raw_tracepoint_args": &StructDef{ + Name: "bpf_raw_tracepoint_args", + FieldTypes: []string{"uint64_t [0]"}, + FieldNames: []string{"args"}, + Size: 8, + IsStruct: true,//XXX fix this + }, + "bpf_sockopt": &StructDef{ + Name: "bpf_sockopt", + FieldTypes: []string{"struct bpf_sock*", "void *", "void *", "int32_t", "int32_t", "int32_t", "int32_t"}, + FieldNames: []string{"sk", "optval", "optval_end", "level", "optname", "optlen", "retval"}, + Size: 40, + IsStruct: true, + }, + "bpf_sk_lookup": &StructDef{ + Name: "bpf_sk_lookup", + FieldTypes: []string{"struct bpf_sock*", "uint32_t", "uint32_t", "uint32_t", "uint32_t [4]", "uint32_t", "uint32_t", "uint32_t [4]", "uint32_t"}, + FieldNames: []string{"sk", "family", "protocol", "remote_ip4", "remote_ip6", "remote_port", "local_ip4", "local_ip6", "local_port"}, + Size: 64, + IsStruct: true, + }, + "bpf_sock_addr": &StructDef{ + Name: "bpf_sock_addr", + FieldTypes: []string{"uint32_t", "uint32_t", "uint32_t [4]", "uint32_t", "uint32_t", "uint32_t", "uint32_t", "uint32_t", "uint32_t [4]", "struct bpf_sock*"}, + FieldNames: []string{"user_family", "user_ip4", "user_ip6", "user_port", "family", "type", "protocol", "msg_src_ip4", "msg_src_ip6", "sk"}, + Size: 68, + IsStruct: true, + }, + "bpf_perf_event_data": &StructDef{ + Name: "bpf_perf_event_data", + FieldTypes: []string{"struct bpf_user_pt_regs_t", "uint64_t", "uint64_t"}, + FieldNames: []string{"regs", "sample_period", "addr"}, + Size: 184, + IsStruct: true, + }, + "bpf_sysctl": &StructDef{ + Name: "bpf_sysctl", + FieldTypes: []string{"uint32_t", "uint32_t"}, + FieldNames: []string{"write", "file_pos"}, + Size: 8, + IsStruct: true, + }, + "xdp_md": &StructDef{ + Name: "xdp_md", + FieldTypes: []string{"uint32_t", "uint32_t", "uint32_t", "uint32_t", "uint32_t", "uint32_t"}, + FieldNames: []string{"data", "data_end", "data_meta", "ingress_ifindex", "rx_queue_index", "egress_ifindex"}, + Size: 24, + IsStruct: true, + }, + "bpf_user_pt_regs_t": &StructDef{ + Name: "bpf_user_pt_regs_t", + FieldTypes: []string{"uint64_t", "uint64_t", "uint64_t", "uint64_t", "uint64_t", "uint64_t", "uint64_t", "uint64_t", "uint64_t", "uint64_t", + "uint64_t", "uint64_t", "uint64_t", "uint64_t", "uint64_t", "uint64_t", "uint64_t", "uint64_t", "uint64_t", "uint64_t", + "uint64_t"}, + FieldNames: []string{"r15", "r14", "r13", "r12", "bp", "bx", "r11", "r10", "r9", "r8", + "ax", "cx", "dx", "si", "di", "orig_ax", "ip", "cs", "flags", "sp", + "ss"}, + Size: 168, + IsStruct: true, + }, +} + +type PtrToCtxRegType struct { +} + +func (t PtrToCtxRegType) String() string { + return "PTR_TO_CTX" +} + +func (t PtrToCtxRegType) Generate(s *BpfProg, r *randGen, call *BpfCall, arg int) *BpfArg { + a := NewBpfArg(call.Helper, arg) + //CTX access is handled by genRandBpfCtxAccess + a.Name = fmt.Sprintf("ctx") + a.IsNotNull = true + return a +} + +func (t PtrToCtxRegType) CheckAccess(s *BpfProg, h *BpfHelperFunc, isWrite bool) bool { + return true +} + +type ConstPtrToMapRegType struct { +} + +func (t ConstPtrToMapRegType) String() string { + return "CONST_PTR_TO_MAP" +} + +type BpfMapType struct { + Type string + ManFlags [][]string + OptFlags [][]string + KeySize []int + ValSize []int + MaxEntries int +} + +//XXX add key, value constraints +var bpfMapTypes = []BpfMapType { +// BpfMapType{"BPF_PROG_TYPE_UNSPEC",[]string{}}, + BpfMapType{"BPF_MAP_TYPE_HASH", + [][]string{}, + [][]string{[]string{"BPF_F_NO_PREALLOC"},[]string{"BPF_F_NUMA_NODE"},[]string{"BPF_F_WRONLY","BPF_F_RDONLY"},[]string{"BPF_F_WRONLY_PROG","BPF_F_RDONLY_PROG"},[]string{"BPF_F_ZERO_SEED"}}, + []int{1,1<<12},[]int{1,1<<12},-1}, + BpfMapType{"BPF_MAP_TYPE_ARRAY", + [][]string{}, + [][]string{[]string{"BPF_F_NUMA_NODE"},[]string{"BPF_F_MMAPABLE"},[]string{"BPF_F_WRONLY","BPF_F_RDONLY"},[]string{"BPF_F_WRONLY_PROG","BPF_F_RDONLY_PROG"},[]string{"BPF_F_INNER_MAP"}}, + []int{4,4},[]int{1,1<<12},-1}, + BpfMapType{"BPF_MAP_TYPE_PROG_ARRAY", + [][]string{}, + [][]string{[]string{"BPF_F_NUMA_NODE"},[]string{"BPF_F_WRONLY","BPF_F_RDONLY"}}, + []int{4,4},[]int{4,4},-1}, + BpfMapType{"BPF_MAP_TYPE_PERF_EVENT_ARRAY", + [][]string{}, + [][]string{[]string{"BPF_F_NUMA_NODE"},[]string{"BPF_F_WRONLY","BPF_F_RDONLY"},[]string{"BPF_F_PRESERVE_ELEMS"}}, + []int{4,4},[]int{4,4},-1}, + BpfMapType{"BPF_MAP_TYPE_PERCPU_HASH", + [][]string{}, + [][]string{[]string{"BPF_F_NO_PREALLOC"},[]string{"BPF_F_WRONLY","BPF_F_RDONLY"},[]string{"BPF_F_WRONLY_PROG","BPF_F_RDONLY_PROG"},[]string{"BPF_F_ZERO_SEED"}}, + []int{1,1<<12},[]int{1,1<<12},-1}, + BpfMapType{"BPF_MAP_TYPE_PERCPU_ARRAY", + [][]string{}, + [][]string{[]string{"BPF_F_WRONLY","BPF_F_RDONLY"},[]string{"BPF_F_WRONLY_PROG","BPF_F_RDONLY_PROG"}}, + []int{4,4},[]int{1,1<<12},-1}, + BpfMapType{"BPF_MAP_TYPE_STACK_TRACE", + [][]string{}, + [][]string{[]string{"BPF_F_NUMA_NODE"},[]string{"BPF_F_RDONLY","BPF_F_WRONLY"},[]string{"BPF_F_STACK_BUILD_ID"}}, + []int{4,4},[]int{8,1<<12,8},-1}, + BpfMapType{"BPF_MAP_TYPE_CGROUP_ARRAY", + [][]string{}, + [][]string{[]string{"BPF_F_NUMA_NODE"},[]string{"BPF_F_WRONLY","BPF_F_RDONLY"}}, + []int{4,4},[]int{4,4},-1}, + BpfMapType{"BPF_MAP_TYPE_LRU_HASH", + [][]string{}, + [][]string{[]string{"BPF_F_NO_COMMON_LRU","BPF_F_NUMA_NODE"},[]string{"BPF_F_WRONLY","BPF_F_RDONLY"},[]string{"BPF_F_WRONLY_PROG","BPF_F_RDONLY_PROG"},[]string{"BPF_F_ZERO_SEED"}}, + []int{1,1<<12},[]int{1,1<<12},-1}, + BpfMapType{"BPF_MAP_TYPE_LRU_PERCPU_HASH", + [][]string{}, + [][]string{[]string{"BPF_F_NO_COMMON_LRU"},[]string{"BPF_F_WRONLY","BPF_F_RDONLY"},[]string{"BPF_F_WRONLY_PROG","BPF_F_RDONLY_PROG"},[]string{"BPF_F_ZERO_SEED"}}, + []int{1,1<<12},[]int{1,1<<12},-1}, + BpfMapType{"BPF_MAP_TYPE_LPM_TRIE", + [][]string{[]string{"BPF_F_NO_PREALLOC"}}, +// [][]string{[]string{"BPF_F_NUMA_NODE"},[]string{"BPF_F_WRONLY","BPF_F_RDONLY"},[]string{"BPF_F_WRONLY_PROG","BPF_F_RDONLY_PROG"}}, + [][]string{[]string{"BPF_F_NUMA_NODE"},[]string{"BPF_F_WRONLY"},[]string{"BPF_F_WRONLY_PROG","BPF_F_RDONLY_PROG"}}, + []int{9,264},[]int{1,1<<12},-1}, + BpfMapType{"BPF_MAP_TYPE_ARRAY_OF_MAPS", + [][]string{}, + [][]string{[]string{"BPF_F_NUMA_NODE"},[]string{"BPF_F_WRONLY","BPF_F_RDONLY"}}, + []int{4,4},[]int{4,4},-1}, + BpfMapType{"BPF_MAP_TYPE_HASH_OF_MAPS", + [][]string{}, +// [][]string{[]string{"BPF_F_NO_PREALLOC"},[]string{"BPF_F_NUMA_NODE"},[]string{"BPF_F_WRONLY","BPF_F_RDONLY"},[]string{"BPF_F_WRONLY_PROG","BPF_F_RDONLY_PROG"},[]string{"BPF_F_ZERO_SEED"}}, +// do not use BPF_F_RDONLY so that libbpf can fill in the inner maps + [][]string{[]string{"BPF_F_NO_PREALLOC"},[]string{"BPF_F_NUMA_NODE"},[]string{"BPF_F_WRONLY"},[]string{"BPF_F_WRONLY_PROG","BPF_F_RDONLY_PROG"},[]string{"BPF_F_ZERO_SEED"}}, + []int{1,1<<12},[]int{4,4},-1}, + BpfMapType{"BPF_MAP_TYPE_DEVMAP", + [][]string{}, + [][]string{[]string{"BPF_F_NUMA_NODE"},[]string{"BPF_F_WRONLY","BPF_F_RDONLY"}}, + []int{4,4},[]int{4,8,4},-1}, + BpfMapType{"BPF_MAP_TYPE_SOCKMAP", + [][]string{}, + [][]string{[]string{"BPF_F_NUMA_NODE"},[]string{"BPF_F_WRONLY","BPF_F_RDONLY"}}, + []int{4,4},[]int{4,8,4},-1}, + BpfMapType{"BPF_MAP_TYPE_CPUMAP", + [][]string{}, + [][]string{[]string{"BPF_F_NUMA_NODE"}}, + []int{4,4},[]int{4,8,4},-1}, + BpfMapType{"BPF_MAP_TYPE_XSKMAP", + [][]string{}, + [][]string{[]string{"BPF_F_NUMA_NODE"},[]string{"BPF_F_WRONLY","BPF_F_RDONLY"}}, + []int{4,4},[]int{4,4},-1}, + BpfMapType{"BPF_MAP_TYPE_SOCKHASH", + [][]string{}, + [][]string{[]string{"BPF_F_NUMA_NODE"},[]string{"BPF_F_WRONLY","BPF_F_RDONLY"}}, + []int{1,512},[]int{4,8,4},-1}, + BpfMapType{"BPF_MAP_TYPE_CGROUP_STORAGE", + [][]string{}, + [][]string{[]string{"BPF_F_NUMA_NODE"},[]string{"BPF_F_RDONLY_PROG","BPF_F_WRONLY_PROG"}}, + []int{8,12,4},[]int{8,1<<16},0}, + BpfMapType{"BPF_MAP_TYPE_REUSEPORT_SOCKARRAY", + [][]string{}, + [][]string{[]string{"BPF_F_NUMA_NODE"},[]string{"BPF_F_WRONLY","BPF_F_RDONLY"},[]string{"BPF_F_WRONLY_PROG","BPF_F_RDONLY_PROG"}}, + []int{1,1<<16},[]int{4,8,4},-1}, //XXX 16 for max for now + BpfMapType{"BPF_MAP_TYPE_PERCPU_CGROUP_STORAGE", + [][]string{}, + [][]string{[]string{"BPF_F_NUMA_NODE"},[]string{"BPF_F_RDONLY_PROG","BPF_F_WRONLY_PROG"}}, + []int{8,12,4},[]int{8,1<<16},0}, +// []int{4,4},[]int{1,1<<16},0}, // XXX 16 for max for now + BpfMapType{"BPF_MAP_TYPE_QUEUE", + [][]string{}, + [][]string{[]string{"BPF_F_NUMA_NODE"},[]string{"BPF_F_WRONLY","BPF_F_RDONLY"},[]string{"BPF_F_RDONLY_PROG"},[]string{"BPF_F_WRONLY_PROG"}}, + []int{0,0},[]int{1,1<<12},-1}, + BpfMapType{"BPF_MAP_TYPE_STACK", + [][]string{}, + [][]string{[]string{"BPF_F_NUMA_NODE"},[]string{"BPF_F_WRONLY","BPF_F_RDONLY"},[]string{"BPF_F_RDONLY_PROG"},[]string{"BPF_F_WRONLY_PROG"}}, + []int{0,0},[]int{1,1<<12},-1}, + BpfMapType{"BPF_MAP_TYPE_SK_STORAGE", + [][]string{[]string{"BPF_F_NO_PREALLOC"}}, + [][]string{[]string{"BPF_F_CLONE"}}, + []int{4,4},[]int{1,1<<16},0}, // XXX 16 for max for now + BpfMapType{"BPF_MAP_TYPE_DEVMAP_HASH", + [][]string{}, + [][]string{[]string{"BPF_F_NUMA_NODE"},[]string{"BPF_F_WRONLY","BPF_F_RDONLY"}}, + []int{4,4},[]int{4,8,4},-1}, + BpfMapType{"BPF_MAP_TYPE_STRUCT_OPS", + [][]string{}, + [][]string{}, + []int{4,4},[]int{0,1<<12},1}, // XXX 12 for now + BpfMapType{"BPF_MAP_TYPE_RINGBUF", + [][]string{}, + [][]string{[]string{"BPF_F_NUMA_NODE"}}, + []int{0,0},[]int{0,0},24}, // 1<<24 + BpfMapType{"BPF_MAP_TYPE_INODE_STORAGE", + [][]string{[]string{"BPF_F_NO_PREALLOC"}}, + [][]string{[]string{"BPF_F_CLONE"}}, + []int{4,4},[]int{1,1<<16},0}, // XXX 16 for max for now + BpfMapType{"BPF_MAP_TYPE_TASK_STORAGE", + [][]string{[]string{"BPF_F_NO_PREALLOC"}}, + [][]string{[]string{"BPF_F_CLONE"}}, + []int{4,4},[]int{1,1<<16},0}, // XXX 16 for max for now +} + +func generateStruct(s *BpfProg, r *randGen, sizeConstraints []int, hints map[ArgHint]bool, useHint bool, minSizeHint int) (*StructDef, bool) { + min := sizeConstraints[0] + max := sizeConstraints[1] + align := 1 + if len(sizeConstraints) == 3 { + align = sizeConstraints[2] + } + + sd := new(StructDef) + sd.Hints = make(map[ArgHint]bool) + target := "key" + if useHint { + target = "val" + } + fmt.Printf("(%v) gen %v struct_%d initial min=%v max=%v align=%v ArgHints=%x occu=%d\n", + rd, target, len(s.Structs), min, max, align, hints, occupiedSize(hints)) + + if useHint { + occupied := occupiedSize(hints) + if occupied > max { + fmt.Printf("error: map type value size not large enough to accommodate %x\n", hints) + return nil, false + } + if occupied > min { + min = occupied + } + + if minSizeHint > max { + fmt.Printf("error: map type size not large enough to accommodate %x\n", minSizeHint) + return nil, false + } else if min != max && minSizeHint > min { + min = minSizeHint + } + } + + size := 0 + if min == max { + size = min + } else if max > min { + // XXX Re-adjust max to 128 for now + if max > 128 { + max = 128 + } + size = r.Intn(max-min+1) + min + // adjust size according to alignment + if align != 1 { + size = size - (size%align) + } + } else { + fmt.Printf("error: max < min\n") + return nil, false + } + if size == 0 { + return nil, true + } + sd.Size = size + + fmt.Printf("(%v) gen %v struct_%d adjust min=%v max=%v align=%v, size=%v\n", + rd, target, len(s.Structs), min, max, align, size) + + offset := 0 + for { + if offset >= size { + break + } + toEnd := size - offset + if _, ok := hints[HintGenSpinlock]; useHint && ok { + sd.Hints[HintGenSpinlock] = true + delete(hints, HintGenSpinlock) + sd.FieldTypes = append(sd.FieldTypes, "struct bpf_spin_lock") + offset += 4 + } else if _, ok := hints[HintGenTimer]; useHint && ok { + sd.Hints[HintGenTimer] = true + delete(hints, HintGenTimer) + sd.FieldTypes = append(sd.FieldTypes, "struct bpf_timer") + offset += 16 + } else if _, ok := hints[HintGenConstStr]; useHint && ok { + sd.Hints[HintGenConstStr] = true + delete(hints, HintGenConstStr) + sd.FieldTypes = append(sd.FieldTypes, "char [8]") + offset += 8 + } else if toEnd >= 8 { + sd.FieldTypes = append(sd.FieldTypes, "uint64_t") + offset += 8 + } else if toEnd >= 4 { + sd.FieldTypes = append(sd.FieldTypes, "uint32_t") + offset += 4 + } else if toEnd >= 2 { + sd.FieldTypes = append(sd.FieldTypes, "uint16_t") + offset += 2 + } else { + sd.FieldTypes = append(sd.FieldTypes, "uint8_t") + offset += 1 + } + } + + if len(sd.FieldTypes) == 1 { + sd.IsStruct = false + sd.Name = fmt.Sprintf("%v", sd.FieldTypes[0]) + } else { + sd.IsStruct = true + sd.Name = fmt.Sprintf("struct_%d", len(s.Structs)) + } + + s.Structs = append(s.Structs, sd) + return sd, true +} + +var mayUpdateSockmapProgs = map[BpfProgTypeEnum]bool { + BPF_PROG_TYPE_TRACING: true, +// if (eatype == BPF_TRACE_ITER) + BPF_PROG_TYPE_SOCKET_FILTER: true, + BPF_PROG_TYPE_SCHED_CLS: true, + BPF_PROG_TYPE_SCHED_ACT: true, + BPF_PROG_TYPE_XDP: true, + BPF_PROG_TYPE_SK_REUSEPORT: true, + BPF_PROG_TYPE_FLOW_DISSECTOR: true, + BPF_PROG_TYPE_SK_LOOKUP: true, +} + +var funcCompMaps = map[string][]string { + "BPF_FUNC_tail_call": []string{"BPF_MAP_TYPE_PROG_ARRAY"}, + "BPF_FUNC_perf_event_read": []string{"BPF_MAP_TYPE_PERF_EVENT_ARRAY"}, + "BPF_FUNC_perf_event_output": []string{"BPF_MAP_TYPE_PERF_EVENT_ARRAY"}, + "BPF_FUNC_perf_event_read_value": []string{"BPF_MAP_TYPE_PERF_EVENT_ARRAY"}, + "BPF_FUNC_skb_output": []string{"BPF_MAP_TYPE_PERF_EVENT_ARRAY"}, + "BPF_FUNC_xdp_output": []string{"BPF_MAP_TYPE_PERF_EVENT_ARRAY"}, + "BPF_FUNC_ringbuf_output": []string{"BPF_MAP_TYPE_RINGBUF"}, + "BPF_FUNC_ringbuf_reserve": []string{"BPF_MAP_TYPE_RINGBUF"}, + "BPF_FUNC_ringbuf_query": []string{"BPF_MAP_TYPE_RINGBUF"}, + "BPF_FUNC_get_stackid": []string{"BPF_MAP_TYPE_STACK_TRACE"}, + "BPF_FUNC_current_task_under_cgroup": []string{"BPF_MAP_TYPE_CGROUP_ARRAY"}, + "BPF_FUNC_skb_under_cgroup": []string{"BPF_MAP_TYPE_CGROUP_ARRAY"}, + "BPF_FUNC_redirect_map": []string{"BPF_MAP_TYPE_DEVMAP","BPF_MAP_TYPE_DEVMAP_HASH","BPF_MAP_TYPE_CPUMAP","BPF_MAP_TYPE_XSKMAP"}, + "BPF_FUNC_sk_redirect_map": []string{"BPF_MAP_TYPE_SOCKMAP"}, + "BPF_FUNC_msg_redirect_map": []string{"BPF_MAP_TYPE_SOCKMAP"}, + "BPF_FUNC_sock_map_update": []string{"BPF_MAP_TYPE_SOCKMAP"}, + "BPF_FUNC_sk_redirect_hash": []string{"BPF_MAP_TYPE_SOCKHASH"}, + "BPF_FUNC_msg_redirect_hash": []string{"BPF_MAP_TYPE_SOCKHASH"}, + "BPF_FUNC_sock_hash_update": []string{"BPF_MAP_TYPE_SOCKHASH"}, + "BPF_FUNC_get_local_storage": []string{"BPF_MAP_TYPE_CGROUP_STORAGE","BPF_MAP_TYPE_PERCPU_CGROUP_STORAGE"}, + "BPF_FUNC_sk_select_reuseport": []string{"BPF_MAP_TYPE_REUSEPORT_SOCKARRAY","BPF_MAP_TYPE_SOCKMAP","BPF_MAP_TYPE_SOCKHASH"}, + "BPF_FUNC_map_peek_elem": []string{"BPF_MAP_TYPE_QUEUE","BPF_MAP_TYPE_STACK"}, + "BPF_FUNC_map_pop_elem": []string{"BPF_MAP_TYPE_QUEUE","BPF_MAP_TYPE_STACK"}, + "BPF_FUNC_map_push_elem": []string{"BPF_MAP_TYPE_QUEUE","BPF_MAP_TYPE_STACK"}, + "BPF_FUNC_sk_storage_get": []string{"BPF_MAP_TYPE_SK_STORAGE"}, + "BPF_FUNC_sk_storage_delete": []string{"BPF_MAP_TYPE_SK_STORAGE"}, + "BPF_FUNC_inode_storage_get": []string{"BPF_MAP_TYPE_INODE_STORAGE"}, + "BPF_FUNC_inode_storage_delete": []string{"BPF_MAP_TYPE_INODE_STORAGE"}, + "BPF_FUNC_task_storage_get": []string{"BPF_MAP_TYPE_TASK_STORAGE"}, + "BPF_FUNC_task_storage_delete": []string{"BPF_MAP_TYPE_TASK_STORAGE"}, +} + +var mapCompFuncs = map[string][]string { + "BPF_MAP_TYPE_PROG_ARRAY": []string{"BPF_FUNC_tail_call"}, + "BPF_MAP_TYPE_PERF_EVENT_ARRAY": []string{"BPF_FUNC_perf_event_read","BPF_FUNC_perf_event_output","BPF_FUNC_skb_output","BPF_FUNC_perf_event_read_value","BPF_FUNC_xdp_output"}, + "BPF_MAP_TYPE_RINGBUF": []string{"BPF_FUNC_ringbuf_output","BPF_FUNC_ringbuf_reserve","BPF_FUNC_ringbuf_query"}, + "BPF_MAP_TYPE_STACK_TRACE": []string{"BPF_FUNC_get_stackid"}, + "BPF_MAP_TYPE_CGROUP_ARRAY": []string{"BPF_FUNC_skb_under_cgroup","BPF_FUNC_current_task_under_cgroup"}, + "BPF_MAP_TYPE_CGROUP_STORAGE": []string{"BPF_FUNC_get_local_storage"}, + "BPF_MAP_TYPE_PERCPU_CGROUP_STORAGE": []string{"BPF_FUNC_get_local_storage"}, + "BPF_MAP_TYPE_DEVMAP": []string{"BPF_FUNC_redirect_map","BPF_FUNC_map_lookup_elem"}, + "BPF_MAP_TYPE_DEVMAP_HASH": []string{"BPF_FUNC_redirect_map","BPF_FUNC_map_lookup_elem"}, + "BPF_MAP_TYPE_CPUMAP": []string{"BPF_FUNC_redirect_map"}, + "BPF_MAP_TYPE_XSKMAP": []string{"BPF_FUNC_redirect_map","BPF_FUNC_map_lookup_elem"}, + "BPF_MAP_TYPE_ARRAY_OF_MAPS": []string{"BPF_FUNC_map_lookup_elem"}, + "BPF_MAP_TYPE_HASH_OF_MAPS": []string{"BPF_FUNC_map_lookup_elem"}, + "BPF_MAP_TYPE_SOCKMAP": []string{"BPF_FUNC_sk_redirect_map","BPF_FUNC_sock_map_update","BPF_FUNC_map_delete_elem","BPF_FUNC_msg_redirect_map","BPF_FUNC_sk_select_reuseport","BPF_FUNC_map_lookup_elem"}, + // XXX !may_update_sockmap(env, func_id)) + "BPF_MAP_TYPE_SOCKHASH": []string{"BPF_FUNC_sk_redirect_hash","BPF_FUNC_sock_hash_update","BPF_FUNC_map_delete_elem","BPF_FUNC_msg_redirect_hash","BPF_FUNC_sk_select_reuseport","BPF_FUNC_map_lookup_elem"}, + // XXX !may_update_sockmap(env, func_id)) + "BPF_MAP_TYPE_REUSEPORT_SOCKARRAY": []string{"BPF_FUNC_sk_select_reuseport"}, + "BPF_MAP_TYPE_QUEUE": []string{"BPF_FUNC_map_peek_elem","BPF_FUNC_map_pop_elem","BPF_FUNC_map_push_elem"}, + "BPF_MAP_TYPE_STACK": []string{"BPF_FUNC_map_peek_elem","BPF_FUNC_map_pop_elem","BPF_FUNC_map_push_elem"}, + "BPF_MAP_TYPE_SK_STORAGE": []string{"BPF_FUNC_sk_storage_get","BPF_FUNC_sk_storage_delete"}, + "BPF_MAP_TYPE_INODE_STORAGE": []string{"BPF_FUNC_inode_storage_get","BPF_FUNC_inode_storage_delete"}, + "BPF_MAP_TYPE_TASK_STORAGE": []string{"BPF_FUNC_task_storage_get","BPF_FUNC_task_storage_delete"}, +} + +func isMapFuncCompatible(m string, f string) bool { + if maps, ok := funcCompMaps[f]; ok { + compatible := false + for _, cm := range maps { + if cm == m { + compatible = true + break + } + } + if !compatible { + return false + } + } + if funcs, ok := mapCompFuncs[m]; ok { + compatible := false + for _, cf := range funcs { + if cf == f { + compatible = true + break + } + } + if !compatible { + return false + } + } + return true +} + +func getHelperCompatMaps(s *BpfProg, call *BpfCall) []*BpfMap { + var compatMaps []*BpfMap + for _, m := range s.Maps { + if !isMapFuncCompatible(m.MapType, call.Helper.Enum) { + continue + } + + mapHasSpinlock := (m.Val != nil && m.Val.findMember("struct bpf_spin_lock") != -1) + mapHasTimer := (m.Val != nil && m.Val.findMember("struct bpf_timer") != -1) + mapHasConstStr := (m.Val != nil && m.Val.findMember("char [8]") != -1) + mapIsRdOnly := (m.getFlag("BPF_F_RDONLY_PROG") != -1) + mapIsWrOnly := (m.getFlag("BPF_F_WRONLY_PROG") != -1) + + //6084 + if (call.Helper.Enum == "BPF_FUNC_map_delete_elem" || call.Helper.Enum == "BPF_FUNC_map_update_elem" || + call.Helper.Enum == "BPF_FUNC_map_push_elem" || call.Helper.Enum == "BPF_FUNC_map_pop_elem") && + mapIsRdOnly { + continue + } + //4706, 4767 + _, genSpinlock := call.Hint.ArgHints[HintGenSpinlock] + _, genTimer := call.Hint.ArgHints[HintGenTimer] + _, genConstStr := call.Hint.ArgHints[HintGenConstStr] + if (genSpinlock && (!mapHasSpinlock || mapIsRdOnly)) || + (genTimer && (!mapHasTimer || mapIsRdOnly)) || + (genConstStr && !mapHasConstStr) { + continue + } + //11473, 11478, 11484 + if mapHasSpinlock && + (s.pt.Enum == BPF_PROG_TYPE_SOCKET_FILTER || isTracingProgType(s.pt.Enum) || s.Sec.Sleepable) { + continue + } + //11503 + if m.MapType == "BPF_MAP_TYPE_STRUCT_OPS" { + continue + } + //11526 + if s.Sec.Sleepable && + !(m.MapType == "BPF_MAP_TYPE_HASH" || m.MapType == "BPF_MAP_TYPE_LRU_HASH" || m.MapType == "BPF_MAP_TYPE_ARRAY" || + m.MapType == "BPF_MAP_TYPE_PERCPU_HASH" || m.MapType == "BPF_MAP_TYPE_PERCPU_ARRAY" || m.MapType == "BPF_MAP_TYPE_LRU_PERCPU_HASH" || + m.MapType == "BPF_MAP_TYPE_ARRAY_OF_MAPS" || m.MapType == "BPF_MAP_TYPE_HASH_OF_MAPS" || m.MapType == "BPF_MAP_TYPE_RINGBUF") { + continue + } + //11704 + if m.MapType == "BPF_MAP_TYPE_CGROUP_STORAGE" { + hasCgroupStorageMap := false + for _, pm := range s.Maps { + if pm.MapType == "BPF_MAP_TYPE_CGROUP_STORAGE" { + hasCgroupStorageMap = true + } + } + if hasCgroupStorageMap { + continue + } + } + if m.MapType == "BPF_MAP_TYPE_PERCPU_CGROUP_STORAGE" { + hasPercpuCgroupStorageMap := false + for _, pm := range s.Maps { + if pm.MapType == "BPF_MAP_TYPE_PERCPU_CGROUP_STORAGE" { + hasPercpuCgroupStorageMap = true + } + } + if hasPercpuCgroupStorageMap { + continue + } + } + + _, genSockMap := call.Hint.ArgHints[HintGenSockMap] + _, genXdpSockMap := call.Hint.ArgHints[HintGenXdpSockMap] + if call.Helper.Ret == "RET_PTR_TO_MAP_VALUE_OR_NULL" { + if genXdpSockMap != (m.MapType == "BPF_MAP_TYPE_XSKMAP") { + continue + } + if genSockMap != (m.MapType == "BPF_MAP_TYPE_SOCKMAP" || m.MapType == "BPF_MAP_TYPE_SOCKHASH") { + continue + } + } + + if (call.Helper.Ret == "RET_PTR_TO_MAP_VALUE" || call.Helper.Ret == "RET_PTR_TO_MAP_VALUE_OR_NULL") && call.Hint.RetAccessSize != 0 { + if m.Val == nil || m.Val.Size < call.Hint.RetAccessSize { + continue + } + if mapIsRdOnly && call.Hint.IsRetAccessRaw { + continue + } + if mapIsWrOnly && !call.Hint.IsRetAccessRaw { + continue + } + if call.Hint.IsRetAccessRaw && (m.MapType == "BPF_MAP_TYPE_DEVMAP" || m.MapType == "BPF_MAP_TYPE_DEVMAP_HASH") { + continue + } + } + compatMaps = append(compatMaps, m) + } + return compatMaps +} + +func isTracingProgType(e BpfProgTypeEnum) bool { + return e == BPF_PROG_TYPE_KPROBE || e == BPF_PROG_TYPE_TRACEPOINT || e == BPF_PROG_TYPE_PERF_EVENT || e == BPF_PROG_TYPE_RAW_TRACEPOINT +} + +func getHelperCompatMapTypes(s *BpfProg, call *BpfCall) []BpfMapType { + var compatMapTypes []BpfMapType + for _, mt := range bpfMapTypes { + if !isMapFuncCompatible(mt.Type, call.Helper.Enum) { + continue + } + if mt.ValSize[1] < occupiedSize(call.Hint.ArgHints) { + continue + } + if _, ok := call.Hint.ArgHints[HintGenSpinlock]; ok { + if mt.Type != "BPF_MAP_TYPE_HASH" && mt.Type != "BPF_MAP_TYPE_ARRAY" && + mt.Type != "BPF_MAP_TYPE_CGROUP_STORAGE" && mt.Type != "BPF_MAP_TYPE_SK_STORAGE" && + mt.Type != "BPF_MAP_TYPE_INODE_STORAGE" && mt.Type != "BPF_MAP_TYPE_TASK_STORAGE" { + continue + } + //11473, 11478, 11484 + if s.pt.Enum == BPF_PROG_TYPE_SOCKET_FILTER || isTracingProgType(s.pt.Enum) || s.Sec.Sleepable { + continue + } + } + if _, ok := call.Hint.ArgHints[HintGenTimer]; ok { + if mt.Type != "BPF_MAP_TYPE_HASH" && mt.Type != "BPF_MAP_TYPE_LRU_HASH" && mt.Type != "BPF_MAP_TYPE_ARRAY" { + continue + } + if isTracingProgType(s.pt.Enum) { // 11491 + continue + } + } + //11503 + if mt.Type == "BPF_MAP_TYPE_STRUCT_OPS" { + continue + } + //11526 + if s.Sec.Sleepable && + !(mt.Type == "BPF_MAP_TYPE_HASH" || mt.Type == "BPF_MAP_TYPE_LRU_HASH" || mt.Type == "BPF_MAP_TYPE_ARRAY" || + mt.Type == "BPF_MAP_TYPE_PERCPU_HASH" || mt.Type == "BPF_MAP_TYPE_PERCPU_ARRAY" || mt.Type == "BPF_MAP_TYPE_LRU_PERCPU_HASH" || + mt.Type == "BPF_MAP_TYPE_ARRAY_OF_MAPS" || mt.Type == "BPF_MAP_TYPE_HASH_OF_MAPS" || mt.Type == "BPF_MAP_TYPE_RINGBUF") { + continue + } + //11704 + if mt.Type == "BPF_MAP_TYPE_CGROUP_STORAGE" { + hasCgroupStorageMap := false + for _, pm := range s.Maps { + if pm.MapType == "BPF_MAP_TYPE_CGROUP_STORAGE" { + hasCgroupStorageMap = true + } + } + if hasCgroupStorageMap { + continue + } + } + if mt.Type == "BPF_MAP_TYPE_PERCPU_CGROUP_STORAGE" { + hasPercpuCgroupStorageMap := false + for _, pm := range s.Maps { + if pm.MapType == "BPF_MAP_TYPE_PERCPU_CGROUP_STORAGE" { + hasPercpuCgroupStorageMap = true + } + } + if hasPercpuCgroupStorageMap { + continue + } + } + _, genSockMap := call.Hint.ArgHints[HintGenSockMap] + _, genXdpSockMap := call.Hint.ArgHints[HintGenXdpSockMap] + if call.Helper.Ret == "RET_PTR_TO_MAP_VALUE_OR_NULL" { + if genXdpSockMap != (mt.Type == "BPF_MAP_TYPE_XSKMAP") { + continue + } + if genSockMap != (mt.Type == "BPF_MAP_TYPE_SOCKMAP" || mt.Type == "BPF_MAP_TYPE_SOCKHASH") { + continue + } + } + if call.Hint.IsRetAccessRaw && (mt.Type == "BPF_MAP_TYPE_DEVMAP" || mt.Type == "BPF_MAP_TYPE_DEVMAP_HASH") { + continue + } + // check if the current program type permits updating sockmap + if call.Helper.Enum == "BPF_FUNC_map_update_elem" && (mt.Type == "BPF_MAP_TYPE_SOCKMAP" || mt.Type == "BPF_MAP_TYPE_SOCKHASH") { + if _, ok := mayUpdateSockmapProgs[s.pt.Enum]; !ok { + continue + } + } + compatMapTypes = append(compatMapTypes, mt) + } + return compatMapTypes +} + +func getCompatKeyStructDefs(s *BpfProg, mapType BpfMapType) []*StructDef { + var compatStructs []*StructDef + for _, structDef := range s.Structs { + if structDef.Size < mapType.KeySize[0] || structDef.Size > mapType.KeySize[1] { + continue + } + compatStructs = append(compatStructs, structDef) + } + return compatStructs +} + +func getCompatValStructDefs(s *BpfProg, hint *BpfCallGenHint, minValSize int, mapType BpfMapType) []*StructDef { + var compatStructs []*StructDef + for _, structDef := range s.Structs { + //if (call.Helper.Ret == "RET_PTR_TO_MAP_VALUE" || call.Helper.Ret == "RET_PTR_TO_MAP_VALUE_OR_NULL") && + // structDef.Size < call.Hint.RetAccessSize { + // continue + //} + if minValSize != -1 && structDef.Size < minValSize { + continue + } + if _, ok := hint.ArgHints[HintGenSpinlock]; ok && + structDef.findMember("struct bpf_spin_lock") == -1 { + continue + } + if _, ok := hint.ArgHints[HintGenTimer]; ok && + structDef.findMember("struct bpf_timer") == -1 { + continue + } + if _, ok := hint.ArgHints[HintGenConstStr]; ok && + structDef.findMember("char [8]") == -1 { + continue + } + if _, ok := hint.ArgHints[HintGenSockMap]; ok { + continue + } + if _, ok := hint.ArgHints[HintGenXdpSockMap]; ok { + continue + } + if structDef.Size < mapType.ValSize[0] || structDef.Size > mapType.ValSize[1] { + continue + } + if len(mapType.KeySize) == 3 && structDef.Size % mapType.KeySize[2] != 0 { + continue + } + compatStructs = append(compatStructs, structDef) + } + return compatStructs +} + +func (t ConstPtrToMapRegType) Generate(s *BpfProg, r *randGen, call *BpfCall, arg int) *BpfArg { + a := NewBpfArg(call.Helper, arg) + a.IsNotNull = true + + if call.Hint.PreferredMap != nil { + call.ArgMap = call.Hint.PreferredMap + a.Name = fmt.Sprintf("&%v", call.ArgMap.MapName) + return a + } + + if call.ArgMap != nil { + a.Name = fmt.Sprintf("&%v", call.ArgMap.MapName) + return a + } + + var m *BpfMap + + if compatMaps := getHelperCompatMaps(s, call); len(compatMaps) != 0 && r.nOutOf(2, 3) { + // Choose an existing map + m = compatMaps[r.Intn(len(compatMaps))] + } else { + // Use a newly generated map + var newMapType BpfMapType + compatMapTypes := getHelperCompatMapTypes(s, call) + if len(compatMapTypes) == 0 { + return nil// XXX failed + } + + if _, ok := call.Hint.ArgHints[HintGenConstStr]; ok { + mapTypeArrayIdx := -1 + for mi, mt := range compatMapTypes { + if mt.Type == "BPF_MAP_TYPE_ARRAY" { + mapTypeArrayIdx = mi + break + } + } + if mapTypeArrayIdx == -1 { + return nil + } + newMapType = compatMapTypes[mapTypeArrayIdx] + } else { + newMapType = compatMapTypes[r.Intn(len(compatMapTypes))] + } + + minValSize := -1 + if call.Helper.Ret == "RET_PTR_TO_MAP_VALUE" || call.Helper.Ret == "RET_PTR_TO_MAP_VALUE_OR_NULL" { + minValSize = call.Hint.RetAccessSize + } + m = s.NewMap(newMapType, call.Hint, minValSize, r) + + if m == nil { + return nil + } + + if call.Helper.Enum == "BPF_FUNC_map_delete_elem" || call.Helper.Enum == "BPF_FUNC_map_update_elem" || + call.Helper.Enum == "BPF_FUNC_map_push_elem" || call.Helper.Enum == "BPF_FUNC_map_pop_elem" { + m.removeFlag("BPF_F_RDONLY_PROG") + } + //4706,4767 + if m.Val != nil && (m.Val.findMember("struct bpf_spin_lock") != -1 || m.Val.findMember("struct bpf_timer") != -1) { + m.removeFlag("BPF_F_RDONLY_PROG") + } + //11461 + if s.pt.Enum == BPF_PROG_TYPE_PERF_EVENT && + (newMapType.Type == "BPF_MAP_TYPE_HASH" || newMapType.Type == "BPF_MAP_TYPE_PERCPU_HASH" || newMapType.Type == "BPF_MAP_TYPE_HASH_OF_MAPS") { + m.removeFlag("BPF_F_NO_PREALLOC") + } + //11518 + if s.Sec.Sleepable && + (newMapType.Type == "BPF_MAP_TYPE_HASH" || newMapType.Type == "BPF_MAP_TYPE_LRU_HASH" || newMapType.Type == "BPF_MAP_TYPE_ARRAY" || + newMapType.Type == "BPF_MAP_TYPE_PERCPU_HASH" || newMapType.Type == "BPF_MAP_TYPE_PERCPU_ARRAY" || newMapType.Type == "BPF_MAP_TYPE_LRU_PERCPU_HASH" || + newMapType.Type == "BPF_MAP_TYPE_ARRAY_OF_MAPS" || newMapType.Type == "BPF_MAP_TYPE_HASH_OF_MAPS") { + m.removeFlag("BPF_F_NO_PREALLOC") + } + } + call.ArgMap = m + a.Name = fmt.Sprintf("&%v", m.MapName) + return a +} + +func (t ConstPtrToMapRegType) CheckAccess(s *BpfProg, h *BpfHelperFunc, isWrite bool) bool { + return true +} + +type PtrToMapValueRegType struct { +} + +func (t PtrToMapValueRegType) String() string { + return "PTR_TO_MAP_VALUE" +} + +func (t PtrToMapValueRegType) Generate(s *BpfProg, r *randGen, call *BpfCall, arg int) *BpfArg { + //XXX Consider record loaded map values and reuse them + return nil +} + +func (t PtrToMapValueRegType) CheckAccess(s *BpfProg, h *BpfHelperFunc, isWrite bool) bool { + return true +} + +type PtrToStackRegType struct { +} + +func (t PtrToStackRegType) String() string { + return "PTR_TO_STACK" +} + +func roundUp(val int, align int) int { + ret := val / align + if val % align != 0 { + ret += 1 + } + return ret * align +} + +func (t PtrToStackRegType) Generate(s *BpfProg, r *randGen, call *BpfCall, arg int) *BpfArg { + a := NewBpfArg(call.Helper, arg) + + varSize := r.Intn(64) + if call.ArgMap != nil { + if call.Helper.Args[arg] == "ARG_PTR_TO_MAP_KEY" && call.ArgMap.Key != nil { + varSize = roundUp(call.ArgMap.Key.Size, 8) //XXX need to round up key size? + } + if (call.Helper.Args[arg] == "ARG_PTR_TO_MAP_VALUE" || call.Helper.Args[arg] == "ARG_PTR_TO_MAP_VALUE_OR_NULL" || call.Helper.Args[arg] == "ARG_PTR_TO_UNINIT_MAP_VALUE") && call.ArgMap.Val != nil { + varSize = roundUp(call.ArgMap.Val.Size, 8) + } + } + + call.StackVarSize = varSize + a.IsNotNull = true + a.Name = fmt.Sprintf("v%d", s.VarId) + a.Prepare = fmt.Sprintf(" char %s[%d] = {};\n", a.Name, varSize) + s.VarId += 1 + return a +} + +func (t PtrToStackRegType) CheckAccess(s *BpfProg, h *BpfHelperFunc, isWrite bool) bool { + return true +} + +var PktPtrReadOnly = map[BpfProgTypeEnum]bool { + BPF_PROG_TYPE_LWT_IN: true, + BPF_PROG_TYPE_LWT_OUT: true, + BPF_PROG_TYPE_LWT_SEG6LOCAL: true, + BPF_PROG_TYPE_SK_REUSEPORT: true, + BPF_PROG_TYPE_FLOW_DISSECTOR: true, + BPF_PROG_TYPE_CGROUP_SKB: true, +} + +var PktPtrReadWrite = map[BpfProgTypeEnum]bool { + BPF_PROG_TYPE_SCHED_CLS: true, + BPF_PROG_TYPE_SCHED_ACT: true, + BPF_PROG_TYPE_XDP: true, + BPF_PROG_TYPE_LWT_XMIT: true, + BPF_PROG_TYPE_SK_SKB: true, + BPF_PROG_TYPE_SK_MSG: true, +} + +var PktPtrReadWriteNoCheck = map[BpfProgTypeEnum]bool { + BPF_PROG_TYPE_CGROUP_SOCKOPT: true, +} + +func checkPktAccess(s *BpfProg, h *BpfHelperFunc, isWrite bool) bool { + canWrite := true + if _, ok := PktPtrReadOnly[s.pt.Enum]; ok { + canWrite = false + } else if _, ok := PktPtrReadWrite[s.pt.Enum]; ok { + canWrite = true + } else if _, ok := PktPtrReadWriteNoCheck[s.pt.Enum]; ok { + return true + } else { + return false + } + + if (!canWrite && isWrite) { + return false + } else { + return h.PktAccess + } +} + +type PtrToPacketMetaRegType struct { +} + +func (t PtrToPacketMetaRegType) String() string { + return "PTR_TO_PACKET_META" +} + +func (t PtrToPacketMetaRegType) Generate(s *BpfProg, r *randGen, call *BpfCall, arg int) *BpfArg { + return nil +} + +func (t PtrToPacketMetaRegType) CheckAccess(s *BpfProg, h *BpfHelperFunc, isWrite bool) bool { + return checkPktAccess(s, h, isWrite) +} + +type PtrToPacketRegType struct { +} + +func (t PtrToPacketRegType) String() string { + return "PTR_TO_PACKET" +} + +func (t PtrToPacketRegType) Generate(s *BpfProg, r *randGen, call *BpfCall, arg int) *BpfArg { + return nil +} + +func (t PtrToPacketRegType) CheckAccess(s *BpfProg, h *BpfHelperFunc, isWrite bool) bool { + return checkPktAccess(s, h, isWrite) +} + +type PtrToPacketEndRegType struct { +} + +func (t PtrToPacketEndRegType) String() string { + return "PTR_TO_PACKET_END" +} + +func (t PtrToPacketEndRegType) Generate(s *BpfProg, r *randGen, call *BpfCall, arg int) *BpfArg { + return nil +} + +func (t PtrToPacketEndRegType) CheckAccess(s *BpfProg, h *BpfHelperFunc, isWrite bool) bool { + //XXX not found in check_mem_access + return false +} + +type PtrToFlowKeysRegType struct { +} + +func (t PtrToFlowKeysRegType) String() string { + return "PTR_TO_FLOW_KEYS" +} + +func (t PtrToFlowKeysRegType) Generate(s *BpfProg, r *randGen, call *BpfCall, arg int) *BpfArg { + return nil +} + +func (t PtrToFlowKeysRegType) CheckAccess(s *BpfProg, h *BpfHelperFunc, isWrite bool) bool { + return true +} + +type PtrToSocketRegType struct { +} + +func (t PtrToSocketRegType) String() string { + return "PTR_TO_SOCKET" +} + +func (t PtrToSocketRegType) Generate(s *BpfProg, r *randGen, call *BpfCall, arg int) *BpfArg { + return nil +} + +func (t PtrToSocketRegType) CheckAccess(s *BpfProg, h *BpfHelperFunc, isWrite bool) bool { + return !isWrite +} + +type PtrToSockCommonRegType struct { +} + +func (t PtrToSockCommonRegType) String() string { + return "PTR_TO_SOCK_COMMON" +} + +func (t PtrToSockCommonRegType) Generate(s *BpfProg, r *randGen, call *BpfCall, arg int) *BpfArg { + return nil +} + +func (t PtrToSockCommonRegType) CheckAccess(s *BpfProg, h *BpfHelperFunc, isWrite bool) bool { + return !isWrite +} + +type PtrToTcpSockRegType struct { +} + +func (t PtrToTcpSockRegType) String() string { + return "PTR_TO_TCP_SOCK" +} + +func (t PtrToTcpSockRegType) Generate(s *BpfProg, r *randGen, call *BpfCall, arg int) *BpfArg { + return nil +} + +func (t PtrToTcpSockRegType) CheckAccess(s *BpfProg, h *BpfHelperFunc, isWrite bool) bool { + return !isWrite +} + +type PtrToTpBufferRegType struct { +} + +func (t PtrToTpBufferRegType) String() string { + return "PTR_TO_TP_BUFFER" +} + +func (t PtrToTpBufferRegType) Generate(s *BpfProg, r *randGen, call *BpfCall, arg int) *BpfArg { + return nil +} + +func (t PtrToTpBufferRegType) CheckAccess(s *BpfProg, h *BpfHelperFunc, isWrite bool) bool { + return true +} + +type PtrToXdpSockRegType struct { +} + +func (t PtrToXdpSockRegType) String() string { + return "PTR_TO_XDP_SOCK" +} + +func (t PtrToXdpSockRegType) Generate(s *BpfProg, r *randGen, call *BpfCall, arg int) *BpfArg { + return nil +} + +func (t PtrToXdpSockRegType) CheckAccess(s *BpfProg, h *BpfHelperFunc, isWrite bool) bool { + return !isWrite +} + +type PtrToBtfIdRegType struct { +} + +func (t PtrToBtfIdRegType) String() string { + return "PTR_TO_BTF_ID" +} + +func (t PtrToBtfIdRegType) Generate(s *BpfProg, r *randGen, call *BpfCall, arg int) *BpfArg { + return nil +} + +func (t PtrToBtfIdRegType) CheckAccess(s *BpfProg, h *BpfHelperFunc, isWrite bool) bool { + return true +} + +type PtrToMemRegType struct { +} + +func (t PtrToMemRegType) String() string { + return "PTR_TO_ALLOC_MEM" +} + +func (t PtrToMemRegType) Generate(s *BpfProg, r *randGen, call *BpfCall, arg int) *BpfArg { + return nil +} + +func (t PtrToMemRegType) CheckAccess(s *BpfProg, h *BpfHelperFunc, isWrite bool) bool { + return true +} + +type PtrToRdOnlyBufRegType struct { +} + +func (t PtrToRdOnlyBufRegType) String() string { + return "PTR_TO_RDONLY_BUF" +} + +func (t PtrToRdOnlyBufRegType) Generate(s *BpfProg, r *randGen, call *BpfCall, arg int) *BpfArg { + return nil +} + +func (t PtrToRdOnlyBufRegType) CheckAccess(s *BpfProg, h *BpfHelperFunc, isWrite bool) bool { + return !isWrite +} + +type PtrToRdWrBufRegType struct { +} + +func (t PtrToRdWrBufRegType) String() string { + return "PTR_TO_RDWR_BUF" +} + +func (t PtrToRdWrBufRegType) Generate(s *BpfProg, r *randGen, call *BpfCall, arg int) *BpfArg { + return nil +} + +func (t PtrToRdWrBufRegType) CheckAccess(s *BpfProg, h *BpfHelperFunc, isWrite bool) bool { + return true +} + +type PtrToPercpuBtfIdRegType struct { +} + +func (t PtrToPercpuBtfIdRegType) String() string { + return "PTR_TO_PERCPU_BTF_ID" +} + +func (t PtrToPercpuBtfIdRegType) Generate(s *BpfProg, r *randGen, call *BpfCall, arg int) *BpfArg { + a := NewBpfArg(call.Helper, arg) + s.Externs["bpf_prog_active"] = "int" + a.IsNotNull = true + a.Name = fmt.Sprintf("&bpf_prog_active") + return a +} + +func (t PtrToPercpuBtfIdRegType) CheckAccess(s *BpfProg, h *BpfHelperFunc, isWrite bool) bool { + //XXX not found in check_mem_access + return false +} + +type PtrToFuncRegType struct { +} + +func (t PtrToFuncRegType) String() string { + return "PTR_TO_FUNC" +} + +func (t PtrToFuncRegType) Generate(s *BpfProg, r *randGen, call *BpfCall, arg int) *BpfArg { + return nil +} + +func (t PtrToFuncRegType) CheckAccess(s *BpfProg, h *BpfHelperFunc, isWrite bool) bool { + //XXX not found in check_mem_access + return false +} + +type PtrToMapKeyRegType struct { +} + +func (t PtrToMapKeyRegType) String() string { + return "PTR_TO_MAP_KEY" +} + +func (t PtrToMapKeyRegType) Generate(s *BpfProg, r *randGen, call *BpfCall, arg int) *BpfArg { + return nil +} + +func (t PtrToMapKeyRegType) CheckAccess(s *BpfProg, h *BpfHelperFunc, isWrite bool) bool { + return !isWrite +} + +type BpfCtxAccessAttr struct { + rangeInCtx []string + canRead bool + canWrite bool + size int //exact size check + defaultSize int //for wide/narrow access check + wideAccess bool //wide access check + narrowAccess bool //narrow access check + regType RegType + attachTypes []string +} + +type BpfCtxAccess struct { + regTypeMap map[string][][]string + others map[string]*BpfCtxAccess + accesses []BpfCtxAccessAttr +} + +func NewBpfCtxAccess() *BpfCtxAccess { + newCtxAccess := &BpfCtxAccess{ + regTypeMap: make(map[string][][]string), + others: make(map[string]*BpfCtxAccess), + } + return newCtxAccess +} + +var Brf *BpfRuntimeFuzzer + +func InitBrf(enable bool) { + Brf = NewBpfRuntimeFuzzer(enable) + + Brf.InitFromSrc(HelperFuncMap, ProgTypeMap, CtxAccessMap) +} + +var map_key_value_types = []RegType{ + PtrToStackRegType{}, + PtrToPacketRegType{}, + PtrToPacketMetaRegType{}, + PtrToMapKeyRegType{}, + PtrToMapValueRegType{}, +} + +var scalar_types = []RegType{ScalarValRegType{}} + +var const_map_ptr_types = []RegType{ConstPtrToMapRegType{}} + +var context_types = []RegType{PtrToCtxRegType{}} + +var sock_types = []RegType{ + PtrToSockCommonRegType{}, + PtrToSocketRegType{}, + PtrToTcpSockRegType{}, + PtrToXdpSockRegType{}, +} + +var btf_id_sock_common_types = []RegType{ + PtrToSockCommonRegType{}, + PtrToSocketRegType{}, + PtrToTcpSockRegType{}, + PtrToXdpSockRegType{}, + PtrToBtfIdRegType{}, +} + +var fullsock_types = []RegType{PtrToSocketRegType{}} + +var btf_ptr_types = []RegType{PtrToBtfIdRegType{}} + +var spin_lock_types = []RegType{PtrToMapValueRegType{}} + +var mem_types = []RegType{ + PtrToStackRegType{}, + PtrToPacketRegType{}, + PtrToPacketMetaRegType{}, + PtrToMapKeyRegType{}, + PtrToMapValueRegType{}, + PtrToMemRegType{}, + PtrToRdOnlyBufRegType{}, + PtrToRdWrBufRegType{}, +} + +var alloc_mem_types = []RegType{PtrToMemRegType{}} + +var int_ptr_types = []RegType{ + PtrToStackRegType{}, + PtrToPacketRegType{}, + PtrToPacketMetaRegType{}, + PtrToMapKeyRegType{}, + PtrToMapValueRegType{}, +} + +var percpu_btf_ptr_types = []RegType{PtrToPercpuBtfIdRegType{}} + +var func_ptr_types = []RegType{PtrToFuncRegType{}} + +var stack_ptr_types = []RegType{PtrToStackRegType{}} + +var const_str_ptr_types = []RegType{PtrToMapValueRegType{}} + +var timer_types = []RegType{PtrToMapValueRegType{}} + +var all_types = []RegType{ + ScalarValRegType{}, + PtrToCtxRegType{}, + ConstPtrToMapRegType{}, + PtrToMapValueRegType{}, + PtrToStackRegType{}, + PtrToPacketMetaRegType{}, + PtrToPacketRegType{}, + PtrToPacketEndRegType{}, + PtrToFlowKeysRegType{}, + PtrToSocketRegType{}, + PtrToSockCommonRegType{}, + PtrToTcpSockRegType{}, + PtrToTpBufferRegType{}, + PtrToXdpSockRegType{}, + PtrToBtfIdRegType{}, + PtrToMemRegType{}, + PtrToRdOnlyBufRegType{}, + PtrToRdWrBufRegType{}, + PtrToPercpuBtfIdRegType{}, + PtrToFuncRegType{}, + PtrToMapKeyRegType{}, +} + +var compatibleRegType = map[string][]RegType { + "ARG_ANYTHING": all_types, + "ARG_PTR_TO_MAP_KEY": map_key_value_types, + "ARG_PTR_TO_MAP_VALUE": map_key_value_types, + "ARG_PTR_TO_UNINIT_MAP_VALUE": map_key_value_types, + "ARG_PTR_TO_MAP_VALUE_OR_NULL": map_key_value_types, + "ARG_CONST_SIZE": scalar_types, + "ARG_CONST_SIZE_OR_ZERO": scalar_types, + "ARG_CONST_ALLOC_SIZE_OR_ZERO": scalar_types, + "ARG_CONST_MAP_PTR": const_map_ptr_types, + "ARG_PTR_TO_CTX": context_types, + "ARG_PTR_TO_CTX_OR_NULL": context_types, + "ARG_PTR_TO_SOCK_COMMON": sock_types, + "ARG_PTR_TO_BTF_ID_SOCK_COMMON": btf_id_sock_common_types, + "ARG_PTR_TO_SOCKET": fullsock_types, + "ARG_PTR_TO_SOCKET_OR_NULL": fullsock_types, + "ARG_PTR_TO_BTF_ID": btf_ptr_types, + "ARG_PTR_TO_SPIN_LOCK": spin_lock_types, + "ARG_PTR_TO_MEM": mem_types, + "ARG_PTR_TO_MEM_OR_NULL": mem_types, + "ARG_PTR_TO_UNINIT_MEM": mem_types, + "ARG_PTR_TO_ALLOC_MEM": alloc_mem_types, + "ARG_PTR_TO_ALLOC_MEM_OR_NULL": alloc_mem_types, + "ARG_PTR_TO_INT": int_ptr_types, + "ARG_PTR_TO_LONG": int_ptr_types, + "ARG_PTR_TO_PERCPU_BTF_ID": percpu_btf_ptr_types, + "ARG_PTR_TO_FUNC": func_ptr_types, + "ARG_PTR_TO_STACK_OR_NULL": stack_ptr_types, + "ARG_PTR_TO_CONST_STR": const_str_ptr_types, + "ARG_PTR_TO_TIMER": timer_types, +} + +func (sd *StructDef) fieldIdx(f string) int { + fieldName := f + if f[len(f)-1: len(f)] == "]" { + fieldName = f[0:len(f)-3] + } + + for i, name := range sd.FieldNames { + if name == fieldName { + return i + } + } + fmt.Printf("cannot find field %v (%v) in %v\n", f, fieldName, sd.Name) + return -1 +} + +func getCtxAccessAttr(sd *StructDef, accesses []BpfCtxAccessAttr, fieldIdx int, isWrite bool) (BpfCtxAccessAttr, int) { + for _, fi := range accesses { + if len(fi.rangeInCtx) == 1 && sd.fieldIdx(fi.rangeInCtx[0]) == fieldIdx && fi.canWrite == isWrite { + return fi, 1 + } else if len(fi.rangeInCtx) == 2 && sd.fieldIdx(fi.rangeInCtx[0]) <= fieldIdx && sd.fieldIdx(fi.rangeInCtx[1]) >= fieldIdx && fi.canWrite == isWrite { + if fi.rangeInCtx[0] == fi.rangeInCtx[1] { + return fi, 1 + } else { + return fi, 2 + } + } else if fi.rangeInCtx[0] == "default" && fi.canWrite == isWrite { + return fi, 2 + } + } + return BpfCtxAccessAttr{}, -1 +} + +func (brf *BpfRuntimeFuzzer) InitFromSrc(hMap map[string]*BpfHelperFunc, ptMap map[BpfProgTypeEnum]*BpfProgTypeDef, caMap map[BpfProgTypeEnum]*BpfCtxAccess) { + brf.helperFuncMap = hMap + brf.progTypeMap = ptMap + brf.ctxAccessMap = caMap + + for name, pt := range brf.progTypeMap { + availableHelper := make(map[string]bool) + for _, proto := range pt.FuncProtos { + helper := brf.helperFuncMap[proto] + if _, ok := availableHelper[helper.Enum]; !ok { + availableHelper[helper.Enum] = true + pt.Helpers = append(pt.Helpers, helper) + } + } + + var accesses []BpfCtxAccessAttr + pt.ctxAccess = brf.ctxAccessMap[name] + var sd *StructDef + var ctxStructName = pt.User + if len(pt.User) > 6 && pt.User[0:6] == "struct" { + sd = ctxStructsMap[pt.User[7:len(pt.User)]] + ctxStructName = pt.User[7:len(pt.User)] + } + if ctxStruct, ok := ctxStructsMap[ctxStructName]; ok { + for i, fi := range ctxStruct.FieldNames { + if readAccess, res := getCtxAccessAttr(sd, pt.ctxAccess.accesses, i, false); res != -1 { + if res == 2 { + readAccess.rangeInCtx = []string{fi, fi} + } + accesses = append(accesses, readAccess) + } else { + accesses = append(accesses, BpfCtxAccessAttr{rangeInCtx: []string{fi, fi}}) + } + if writeAccess, res := getCtxAccessAttr(sd, pt.ctxAccess.accesses, i, true); res != -1 { + if res == 2 { + writeAccess.rangeInCtx = []string{fi, fi} + } + accesses = append(accesses, writeAccess) + } else { + accesses = append(accesses, BpfCtxAccessAttr{rangeInCtx: []string{fi, fi}}) + } + } + pt.ctxAccess.accesses = accesses + } + } +} + +//func (brf *BpfRuntimeFuzzer) ProgTypeEnumToString(pv int) string { +// pe := "" +// var pt *BpfProgTypeDef +// for _, pt = range brf.progTypeMap { +// if pt.Num == pv { +// pe = pt.Enum +// break; +// } +// } +// return pe +//} + +//func (brf *BpfRuntimeFuzzer) HelperEnumToString(pv int, hv int) string { +// var pt *BpfProgTypeDef +// for _, pt = range brf.progTypeMap { +// if pt.Num == pv { +// break; +// } +// } +// +// if pt == nil { +// return "" +// } +// +// he := "" +// for _, helper := range pt.Helpers { +// if helper.Num == hv { +// he = helper.Enum +// } +// } +// return he +//} + +func (brf *BpfRuntimeFuzzer) MapTypeEnumToString(mv int) string { + me := "" + if mv > 0 && mv <= len(bpfMapTypes) { + me = bpfMapTypes[mv-1].Type + } + return me +} + +func findMember(s *BpfProg, structType string, memberType string) int { + for _, sd := range s.Structs { + if sd.Name == structType { + return sd.findMember(memberType) + } + } + return -1 +} + +//XXX record fail prog:func pair +func (s *BpfProg) genBpfHelperCallArg(r *randGen, call *BpfCall, arg int) bool { + argType := call.Helper.Args[arg] + fmt.Printf("(%v) gen call[%v] arg[%v]=%v (%v)\n", rd, len(s.Calls), arg, argType, call.Helper.Enum) + + var a *BpfArg + ok := false + if !ok && call.Helper.Enum == "BPF_FUNC_get_local_storage" && arg == 1 {//6311 + a = NewBpfArg(call.Helper, arg) + a.Name = "0" + a.IsNotNull = true + ok = true + } + if !ok && r.nOutOf(1, 3) { + fmt.Printf("(%v) gen arg using helper return value\n", rd) + a, ok = s.genRandBpfHelperCall(r, call, arg) + } + if !ok && r.nOutOf(1, 2) { + fmt.Printf("(%v) gen arg using ctx access\n", rd) + a, ok = s.genRandBpfCtxAccess(r, call, arg) + } + if !ok { + fmt.Printf("(%v) gen arg directly\n", rd) + a, ok = s.genRandDirectAccess(r, call, arg) + } + if !ok { + return false + } + fmt.Printf("(%v) gen arg v%v\n", r, ok, s.VarId) + + if argType == "ARG_CONST_SIZE" || argType == "ARG_CONST_SIZE_OR_ZERO" { + a.Umax = int64(call.StackVarSize) //XXX check if this handle multiple mem size pairs + } + + // Adding a predicate other than the referenced object can produce paths that may leak references + // XXX Is it possible to achieve so without leaking ref? + if call.isRefReleaseCall() != -1 && arg != 0 { + //if a.IsNotNull && a.CanBeNull { + if !a.IsNotNull && !a.CanBeNull { + return false + } + } + + call.Args[arg] = a + return true +} + +//XXX add mem size constraints +func (s *BpfProg) genCompatibleRegTypes(call *BpfCall, arg int) ([]RegType, string) { + argType := call.Helper.Args[arg] + regTypes := compatibleRegType[argType] + if argType == "ARG_PTR_TO_UNINIT_MAP_VALUE" || argType == "ARG_PTR_TO_UNINIT_MEM" { + for i, t := range regTypes { + if !t.CheckAccess(s, call.Helper, true) { + regTypes = append(regTypes[0:i], regTypes[i+1:]...) + } + } + } + if !checkPktAccess(s, call.Helper, false) { //verbose_5053 + for i, t := range regTypes { + if t.String() == "PTR_TO_PACKET" || t.String() == "PTR_TO_PACKET_META" { + regTypes = append(regTypes[0:i], regTypes[i+1:]...) + } + } + } + + btfId := "" + if argType == "ARG_PTR_TO_BTF_ID" { + btfId = call.Helper.ArgBtfIds[0] //XXX helpers have only one at most now + } else if argType == "ARG_PTR_TO_BTF_ID_SOCK_COMMON" { + btfId = "struct sock_common" + } + return regTypes, btfId +} + +func (s *BpfProg) genRandDirectAccess(r *randGen, call *BpfCall, arg int) (*BpfArg, bool) { + compatRegTypes, _ := s.genCompatibleRegTypes(call, arg) + for i := 0; i < 5; i++ { + rt := compatRegTypes[r.Intn(len(compatRegTypes))] + a := rt.Generate(s, r, call, arg) + if a != nil { + fmt.Printf("(%v) gen arg using %v directly\n", rd, rt.String()) + return a, true + } + } + return nil, false +} + +func (s *BpfProg) genRandBpfCtxAccess(r *randGen, call *BpfCall, arg int) (*BpfArg, bool) { + compatRegTypes, _ := s.genCompatibleRegTypes(call, arg) + for i := 0; i < 5; i++ { + a := NewBpfArg(call.Helper, arg) + rt := compatRegTypes[r.Intn(len(compatRegTypes))].String() + ranges, ok := s.pt.ctxAccess.regTypeMap[rt] + if !ok { + ranges, ok = s.pt.ctxAccess.regTypeMap[rt+"_OR_NULL"]//XXX improve arg OR_NULL compatibility check/propagation + } + + if !ok { + continue + } + + var ctxStruct *StructDef + if len(s.pt.User) > 6 && s.pt.User[0:6] == "struct" { + ctxStruct = ctxStructsMap[s.pt.User[7:len(s.pt.User)]] + readAccess := s.pt.ctxAccess.accesses[ctxStruct.fieldIdx(ranges[0][2])*2].canRead + writeAccess := s.pt.ctxAccess.accesses[ctxStruct.fieldIdx(ranges[0][2])*2+1].canWrite + if !readAccess && !writeAccess { + continue + } + } else { + var defaultAccess BpfCtxAccessAttr + for _, access := range s.pt.ctxAccess.accesses { + if access.rangeInCtx[0] == "default" { + defaultAccess = access + } + } + if !defaultAccess.canRead && !defaultAccess.canWrite { + continue + } + } + + typ := "void *" + if rt == "PTR_TO_SOCK_COMMON" { + typ = "struct sock_common*" + } + + field := ranges[0][2] + if v, ok := s.CtxVars[field]; ok { + a.Name = v + } else { + a.Name = fmt.Sprintf("v%d", s.VarId) + s.VarId += 1 + s.CtxVars[field] = a.Name + s.CtxTypes[field] = typ + } + if rt == "PTR_TO_PACKET_META" { + if _, ok := s.CtxVars["data"]; !ok { + a1 := fmt.Sprintf("v%d", s.VarId) + s.VarId += 1 + s.CtxVars["data"] = a1 + s.CtxTypes["data"] = typ + } + argType := call.Helper.Args[arg] + a.IsPktMetaAccess = true + if argType == "ARG_PTR_TO_MAP_KEY" { + if call.ArgMap != nil && call.ArgMap.Key != nil { + //a.AccessSize = call.ArgMap.Key.Size + a.AccessSize = roundUp(call.ArgMap.Key.Size, 8) //XXX need to round up key size? + } + } + if argType == "ARG_PTR_TO_MAP_VALUE" || argType == "ARG_PTR_TO_MAP_VALUE_OR_NULL" || argType == "ARG_PTR_TO_UNINIT_MAP_VALUE" { + if call.ArgMap != nil && call.ArgMap.Val != nil { + //a.AccessSize = call.ArgMap.Val.Size + a.AccessSize = roundUp(call.ArgMap.Val.Size, 8) + } + } + if argType == "ARG_PTR_TO_MEM" || argType == "ARG_PTR_TO_MEM_OR_NULL" || argType == "ARG_PTR_TO_UNINIT_MEM" { + size := r.Intn(128)//XXX determine max + a.AccessSize = size + call.StackVarSize = size + } + if argType == "ARG_PTR_TO_INT" { + a.AccessSize = 4 + } + if argType == "ARG_PTR_TO_LONG" { + a.AccessSize = 8 + } +// a.AccessSize = call.Hint.RetAccessSize + } + if rt == "PTR_TO_PACKET" { + if _, ok := s.CtxVars["data_end"]; !ok { + a1 := fmt.Sprintf("v%d", s.VarId) + s.VarId += 1 + s.CtxVars["data_end"] = a1 + s.CtxTypes["data_end"] = typ + } + argType := call.Helper.Args[arg] + a.IsPktAccess = true + if argType == "ARG_PTR_TO_MAP_KEY" { + if call.ArgMap != nil && call.ArgMap.Key != nil { + //a.AccessSize = call.ArgMap.Key.Size + a.AccessSize = roundUp(call.ArgMap.Key.Size, 8) //XXX need to round up key size? + } + } + if argType == "ARG_PTR_TO_MAP_VALUE" || argType == "ARG_PTR_TO_MAP_VALUE_OR_NULL" || argType == "ARG_PTR_TO_UNINIT_MAP_VALUE" { + if call.ArgMap != nil && call.ArgMap.Val != nil { + //a.AccessSize = call.ArgMap.Val.Size + a.AccessSize = roundUp(call.ArgMap.Val.Size, 8) + } + } + if argType == "ARG_PTR_TO_MEM" || argType == "ARG_PTR_TO_MEM_OR_NULL" || argType == "ARG_PTR_TO_UNINIT_MEM" { + size := r.Intn(128)//XXX determine max + a.AccessSize = size + call.StackVarSize = size + } + if argType == "ARG_PTR_TO_INT" { + a.AccessSize = 4 + } + if argType == "ARG_PTR_TO_LONG" { + a.AccessSize = 8 + } +// a.AccessSize = call.Hint.RetAccessSize + } + return a, true + } + return nil, false +} + + +//RET_INTEGER, /* function returns integer */ +//RET_VOID, /* function doesn't return anything */ +//RET_PTR_TO_MAP_VALUE, /* returns a pointer to map elem value */ +//RET_PTR_TO_MAP_VALUE_OR_NULL, /* returns a pointer to map elem value or NULL */ +//RET_PTR_TO_SOCKET_OR_NULL, /* returns a pointer to a socket or NULL */ +//RET_PTR_TO_TCP_SOCK_OR_NULL, /* returns a pointer to a tcp_sock or NULL */ +//RET_PTR_TO_SOCK_COMMON_OR_NULL, /* returns a pointer to a sock_common or NULL */ +//RET_PTR_TO_ALLOC_MEM_OR_NULL, /* returns a pointer to dynamically allocated memory or NULL */ +//RET_PTR_TO_BTF_ID_OR_NULL, /* returns a pointer to a btf_id or NULL */ +//RET_PTR_TO_MEM_OR_BTF_ID_OR_NULL, /* returns a pointer to a valid memory or a btf_id or NULL */ +//RET_PTR_TO_MEM_OR_BTF_ID, /* returns a pointer to a valid memory or a btf_id */ +//RET_PTR_TO_BTF_ID, /* returns a pointer to a btf_id */ +func bpfRetType(call *BpfCall) string { + if call.Helper.Ret == "RET_INTEGER" { + return "uint64_t" + } else if call.Helper.Ret == "RET_PTR_TO_MAP_VALUE" || + call.Helper.Ret == "RET_PTR_TO_MAP_VALUE_OR_NULL" { + if call.ArgMap.Val == nil { + return "void *" + } else { + return fmt.Sprintf("%v*", call.ArgMap.Val.Name) + } + } else if call.Helper.Ret == "RET_PTR_TO_BTF_ID_OR_NULL" || + call.Helper.Ret == "RET_PTR_TO_BTF_ID" { + return fmt.Sprintf("%v*", call.Helper.RetBtfId) + } else if call.Helper.Ret == "RET_PTR_TO_ALLOC_MEM_OR_NULL" || + call.Helper.Ret == "RET_PTR_TO_MEM_OR_BTF_ID_OR_NULL" || + call.Helper.Ret == "RET_PTR_TO_MEM_OR_BTF_ID" { + return "void *" + } else if call.Helper.Ret == "RET_PTR_TO_TCP_SOCK_OR_NULL" || + call.Helper.Ret == "RET_PTR_TO_SOCKET_OR_NULL" || + call.Helper.Ret == "RET_PTR_TO_SOCK_COMMON_OR_NULL" { + return "struct bpf_sock*" + } else { + return "" + } +} + +// recursion depth of genBpfHelperCall +var rd int + +func (s *BpfProg) getBpfHelpers(enums []string) ([]*BpfHelperFunc) { + var helpers []*BpfHelperFunc + for _, helper := range s.pt.Helpers { + for _, enum := range enums { + if helper.Enum == enum { + helpers = append(helpers, helper) + } + } + } + return helpers +} + +func (s *BpfProg) genBpfHelperCall(r *randGen, helper *BpfHelperFunc, hint *BpfCallGenHint, prepend bool) (*BpfCall, bool) { + rd += 1 + if rd > 100 { + fmt.Printf("(%v) failed to gen helper call. Tried generating helper call resursively too hard\n", rd) + return nil, false + } + + preferredMapName := "nil" + if hint.PreferredMap != nil { + preferredMapName = hint.PreferredMap.MapName + } + fmt.Printf("(%v) gen call[%v] hint: ArgHints=%v, RetAccessSize=%v, IsRetAccessRaw=%v, PreferredMap=%v\n", + rd, len(s.Calls), hint.ArgHints, hint.RetAccessSize, hint.IsRetAccessRaw, preferredMapName) + + call := NewBpfCall(helper, hint) + attempt := 0 + for i := 0; i < len(helper.Args); { + fmt.Printf("(%v) attempt=%v\n", rd, attempt) + if s.genBpfHelperCallArg(r, call, i) { + attempt = 0 + i++ + } else if attempt += 1; attempt > 50 { + fmt.Printf("failed to gen arg[%d] for %v\n", i , helper.Enum) + return nil, false + } + } + + // Do not acquire references if the program has no helper to release them + if call.isRefAcquireCall() == 1 && len(s.getBpfHelpers([]string{"BPF_FUNC_sk_release"})) == 0 { + return nil, false + } + + if typ := bpfRetType(call); typ != "" { + call.RetType = typ + } + call.Ret = fmt.Sprintf("v%v", s.VarId) + s.VarId += 1 + if prepend { + s.Calls = append([]*BpfCall{call}, s.Calls...) + } else { + s.Calls = append(s.Calls, call) + } + rd -= 1 + + return call, true +} + +var retToRegTypeMap = map[string]map[string]bool{ + "RET_INTEGER": map[string]bool{"SCALAR_VALUE": true}, + "RET_VOID": map[string]bool{"NOT_INIT": true}, + "RET_PTR_TO_MAP_VALUE": map[string]bool{"PTR_TO_MAP_VALUE": true}, +// "RET_PTR_TO_MAP_VALUE_OR_NULL": map[string]bool{"PTR_TO_MAP_VALUE": true}, + "RET_PTR_TO_MAP_VALUE_OR_NULL": map[string]bool{"PTR_TO_MAP_VALUE": true, "PTR_TO_XDP_SOCK": true, "PTR_TO_SOCKET": true}, + "RET_PTR_TO_SOCKET_OR_NULL": map[string]bool{"PTR_TO_SOCKET": true}, + "RET_PTR_TO_TCP_SOCK_OR_NULL": map[string]bool{"PTR_TO_TCP_SOCK": true}, + "RET_PTR_TO_SOCK_COMMON_OR_NULL": map[string]bool{"PTR_TO_SOCK_COMMON": true}, + "RET_PTR_TO_ALLOC_MEM_OR_NULL": map[string]bool{"PTR_TO_ALLOC_MEM": true}, + "RET_PTR_TO_BTF_ID_OR_NULL": map[string]bool{"PTR_TO_BTF_ID": true}, + "RET_PTR_TO_MEM_OR_BTF_ID_OR_NULL": map[string]bool{"PTR_TO_MEM": true, "PTR_TO_BTF_ID":true}, + "RET_PTR_TO_MEM_OR_BTF_ID": map[string]bool{"PTR_TO_MEM": true, "PTR_TO_BTF_ID":true}, + "RET_PTR_TO_BTF_ID": map[string]bool{"PTR_TO_BTF_ID": true}, +} + +func helperCanReturn(helper *BpfHelperFunc, reg RegType, btfId string) bool { + if retToRegTypeMap[helper.Ret][reg.String()] { + if btfId != "" { + if helper.Ret == "RET_PTR_TO_BTF_ID_OR_NULL" || helper.Ret == "RET_PTR_TO_BTF_ID" { + return btfId == helper.RetBtfId + } + if helper.Ret == "RET_PTR_TO_MEM_OR_BTF_ID_OR_NULL" || helper.Ret == "RET_PTR_TO_MEM_OR_BTF_ID" { + //XXX gen random ksym + return false + } + } + return true + } + return false +} + +func genHint(r *randGen, producer *BpfHelperFunc, consumer *BpfCall, arg int) *BpfCallGenHint { + hint := newBpfCallGenHint(nil) + consumerArg := consumer.Helper.Args[arg] + + if (consumerArg == "ARG_PTR_TO_SOCK_COMMON" || consumerArg == "ARG_PTR_TO_BTF_ID_SOCK_COMMON") { + if producer.Ret == "RET_PTR_TO_MAP_VALUE_OR_NULL" { + if r.nOutOf(1, 2) { + hint.ArgHints[HintGenXdpSockMap] = true + } else { + hint.ArgHints[HintGenSockMap] = true + } + } + } + if (consumerArg == "ARG_PTR_TO_SOCKET" || consumerArg == "ARG_PTR_TO_SOCKET_OR_NULL") { + if producer.Ret == "RET_PTR_TO_MAP_VALUE_OR_NULL" { + hint.ArgHints[HintGenSockMap] = true + } + } + if consumerArg == "ARG_PTR_TO_SPIN_LOCK" { + hint.ArgHints[HintGenSpinlock] = true + } + if consumerArg == "ARG_PTR_TO_TIMER" { + hint.ArgHints[HintGenTimer] = true + } + if consumerArg == "ARG_PTR_TO_CONST_STR" { + hint.ArgHints[HintGenConstStr] = true + } + + if consumerArg == "ARG_PTR_TO_MAP_KEY" { + if consumer.ArgMap != nil && consumer.ArgMap.Key != nil { + hint.RetAccessSize = roundUp(consumer.ArgMap.Key.Size, 8) + //hint.RetAccessSize = consumer.ArgMap.Key.Size + } + } + if consumerArg == "ARG_PTR_TO_MAP_VALUE" || consumerArg == "ARG_PTR_TO_MAP_VALUE_OR_NULL" || consumerArg == "ARG_PTR_TO_UNINIT_MAP_VALUE" { + if consumer.ArgMap != nil && consumer.ArgMap.Val != nil { + hint.RetAccessSize = roundUp(consumer.ArgMap.Val.Size, 8) + //hint.RetAccessSize = consumer.ArgMap.Val.Size + } + } + + if consumerArg == "ARG_PTR_TO_UNINIT_MAP_VALUE" || consumerArg == "ARG_PTR_TO_UNINIT_MEM" { + hint.IsRetAccessRaw = true + } + + return hint +} + +/* Generate a random helper call that returns values compatible with *arg*-th argument of *call* */ +func (s *BpfProg) genRandBpfHelperCall(r *randGen, call *BpfCall, arg int) (*BpfArg, bool) { + a := NewBpfArg(call.Helper, arg) + var compatHelpers []*BpfHelperFunc + compatRegTypes, btfId := s.genCompatibleRegTypes(call, arg) + for _, helper := range s.pt.Helpers { + for _, regType := range compatRegTypes { + if !helperCanReturn(helper, regType, btfId) { + continue + } + if call.Helper.Args[arg] == "ARG_CONST_ALLOC_SIZE_OR_ZERO" && regType.String() == "SCALAR_VALUE" { //5228 + continue + } + compatHelpers = append(compatHelpers, helper) + fmt.Printf("(%v) compatible helper: %v\n", rd, helper.Enum) + } + } + + if len(compatHelpers) == 0 { + return nil, false + } + + helper := compatHelpers[r.Intn(len(compatHelpers))] + hint := genHint(r, helper, call, arg) + prodCall, ok := s.genBpfHelperCall(r, helper, hint, false) + if ok { + argType := call.Helper.Args[arg] + retStruct := "" + if start := strings.Index(prodCall.RetType, "struct_"); start != -1 { + if end := strings.Index(prodCall.RetType, "*"); end != -1 { + retStruct = prodCall.RetType[start:end] + } + } + if argType == "ARG_PTR_TO_SPIN_LOCK" { + mi := findMember(s, retStruct, "struct bpf_spin_lock") + a.Name = fmt.Sprintf("&%v->e%v", prodCall.Ret, mi) + } else if argType == "ARG_PTR_TO_TIMER" { + call.ArgMap = prodCall.ArgMap + mi := findMember(s, retStruct, "struct bpf_timer") + a.Name = fmt.Sprintf("&%v->e%v", prodCall.Ret, mi) + } else if argType == "ARG_PTR_TO_CONST_STR" { + mi := findMember(s, retStruct, "char [8]") + a.Name = fmt.Sprintf("%v->e%v", prodCall.Ret, mi) + } else if (prodCall.Helper.Ret == "RET_PTR_TO_MAP_VALUE" || prodCall.Helper.Ret == "RET_PTR_TO_MAP_VALUE_OR_NULL") && + prodCall.ArgMap.Val != nil && len(prodCall.ArgMap.Val.FieldTypes) >= 2 { + var members []int + for mi, mt := range prodCall.ArgMap.Val.FieldTypes { + if mt != "struct bpf_spin_lock" && mt != "struct bpf_timer" && + (prodCall.ArgMap.Val.Size - prodCall.ArgMap.Val.offsetOfMember(mi) >= prodCall.Hint.RetAccessSize) { + members = append(members, mi) + } + } + if len(members) == 0 { + fmt.Printf("(%v) failed to find a valid offset in %v\n", rd, prodCall.ArgMap.MapName) + ok = false + } else { + a.Name = fmt.Sprintf("&%v->e%v", prodCall.Ret, members[r.Intn(len(members))]) + a.CanBeNull = false //XXX add this in case it is passed to ANYTHING + } + } else { + a.Name = prodCall.Ret + } + + if ok { + if prodCall.Helper.Ret == "RET_INTEGER" || prodCall.Helper.Ret == "RET_VOID" || + prodCall.Helper.Ret == "RET_PTR_TO_MAP_VALUE" || + prodCall.Helper.Ret == "RET_PTR_TO_MEM_OR_BTF_ID" || + prodCall.Helper.Ret == "RET_PTR_TO_BTF_ID" { + if !a.CanBeNull { + a.IsNotNull = true + } + } + + //3149, 3155 + if prodCall.Helper.Ret == "RET_PTR_TO_MAP_VALUE" || prodCall.Helper.Ret == "RET_PTR_TO_MAP_VALUE_OR_NULL" { + if argType == "ARG_PTR_TO_UNINIT_MAP_VALUE" || argType == "ARG_PTR_TO_UNINIT_MEM" { + prodCall.ArgMap.removeFlag("BPF_F_RDONLY_PROG") + } else { + prodCall.ArgMap.removeFlag("BPF_F_WRONLY_PROG") + } + } + } + } + return a, ok +} + +func (brf *BpfRuntimeFuzzer) GenBpfProg(r *randGen, opt BrfGenProgOpt) (*BpfProg, bool) { + pt := brf.progTypeMap[BpfProgTypeEnum(r.Intn(int(BPF_PROG_TYPE_TRACING))+1)] + helper := pt.Helpers[r.Intn(len(pt.Helpers))] + p := NewBpfProg(pt, r, opt) + + fmt.Printf("gen prog %v %v\n", pt.Name, helper.Enum) + rd = 0 + hint := newBpfCallGenHint(nil) + _, ok := p.genBpfHelperCall(r, helper, hint, false) + return p, ok +} + +func (brf *BpfRuntimeFuzzer) MutBpfProg(r *randGen, s *BpfProg, opt BrfGenProgOpt) bool { + var calls []*BpfCall + for _, c := range s.Calls { + if len(c.Args) > 0 { + calls = append(calls, c) + } + } + + if len(calls) == 0 { + return false + } + + call := calls[r.Intn(len(calls))] + arg := r.Intn(len(call.Args)) + return s.genBpfHelperCallArg(r, call, arg) +} + +type ObjRef struct { + vars []string + objMap *BpfMap + typ int + count int + calls []*BpfCall +} + +func (call *BpfCall) isRefAcquireCall() int { + refType := -1 + if call.Helper.Enum == "BPF_FUNC_sk_lookup_tcp" || call.Helper.Enum == "BPF_FUNC_sk_lookup_udp" || call.Helper.Enum == "BPF_FUNC_skc_lookup_tcp" || + (call.Helper.Enum == "BPF_FUNC_map_lookup_elem" && (call.ArgMap.MapType == "BPF_MAP_TYPE_SOCKMAP" || call.ArgMap.MapType == "BPF_MAP_TYPE_SOCKHASH")) { + refType = 1 + } + if call.Helper.Enum == "BPF_FUNC_ringbuf_reserve" { + refType = 2 + } + return refType +} + +func (call *BpfCall) isRefReleaseCall() int { + refType := -1 + if call.Helper.Enum == "BPF_FUNC_sk_release" { + refType = 1 + } + if call.Helper.Enum == "BPF_FUNC_ringbuf_submit" || call.Helper.Enum == "BPF_FUNC_ringbuf_discard" { + refType = 2 + } + return refType +} + +func (call *BpfCall) isRefPropagateCall() int { + refType := -1 + if call.Helper.Enum == "BPF_FUNC_tcp_sock" || call.Helper.Enum == "BPF_FUNC_sk_fullsock" || + call.Helper.Enum == "BPF_FUNC_skc_to_tcp_sock" || call.Helper.Enum == "BPF_FUNC_skc_to_tcp6_sock" || + call.Helper.Enum == "BPF_FUNC_skc_to_udp6_sock" || call.Helper.Enum == "BPF_FUNC_skc_to_tcp_timewait_sock" || + call.Helper.Enum == "BPF_FUNC_skc_to_tcp_request_sock" { + refType = 1 + } + return refType +} + +func (s *BpfProg) FixRef(r *randGen) { + objRefMap := make(map[string]*ObjRef) + for i, call := range s.Calls { + if refType := call.isRefAcquireCall(); refType != -1 { + v := call.Ret + if _, ok := objRefMap[v]; !ok { + objRefMap[v] = &ObjRef{vars: []string{v}, objMap: call.ArgMap, typ: refType, count: 0, calls: []*BpfCall{call}} + } + objRefMap[v].count += 1 + fmt.Printf("ref(%v:%v) acquired by call #%v %v\n", v, objRefMap[v].count, i, call.Helper.Enum) + } + if refType := call.isRefReleaseCall(); refType != -1 { + v := call.Args[0].Name + if _, ok := objRefMap[v]; !ok { + objRefMap[v] = &ObjRef{vars: []string{v}, objMap: call.ArgMap, typ: refType, count: 0, calls: []*BpfCall{call}} + } + objRefMap[v].count -= 1 + fmt.Printf("ref(%v:%v) released by call #%v %v\n", v, objRefMap[v].count, i, call.Helper.Enum) + } + if refType := call.isRefPropagateCall(); refType != -1 { + v := call.Args[0].Name + vp := call.Ret + if ref, ok := objRefMap[v]; ok { + ref.calls = append(ref.calls, call) + ref.vars = append(ref.vars, vp) + objRefMap[vp] = ref + fmt.Printf("ref(%v:%v) propagated by call #%v %v\n", v, objRefMap[v].count, i, call.Helper.Enum) + } else { + fmt.Printf("ref(%v:0) propagated by call #%v %v\n", v, i, call.Helper.Enum) + } + } + } + + for _, ref := range objRefMap { + if ref.count < 0 { + // Add a ref-acquire helper + if ref.typ == 1 { + helpers := s.getBpfHelpers([]string{"BPF_FUNC_sk_lookup_tcp", "BPF_FUNC_sk_lookup_udp", "BPF_FUNC_skc_lookup_tcp", "BPF_FUNC_map_lookup_elem"}) + if len(helpers) > 0 { + helper := helpers[r.Intn(len(helpers))] + hint := newBpfCallGenHint(ref.objMap) + if prodCall, ok := s.genBpfHelperCall(r, helper, hint, true); ok {//XXX change to ENUM append, prepend, random + ref.calls[0].Args[0].Name = prodCall.Ret + fmt.Printf("ref: fix releasing invalid ref(%v:%v) by adding %v\n", ref.vars[0], ref.count, helper.Enum) + } else { + fmt.Printf("ref: fix releasing invalid ref(%v:%v) failed since no helper can acquire the reference\n", ref.vars[0], ref.count) + } + } + } + if ref.typ == 2 { + helpers := s.getBpfHelpers([]string{"BPF_FUNC_ringbuf_reserve"}) + if len(helpers) > 0 { + helper := helpers[r.Intn(len(helpers))] + hint := newBpfCallGenHint(ref.objMap) + if prodCall, ok := s.genBpfHelperCall(r, helper, hint, true); ok { + ref.calls[0].Args[0].Name = prodCall.Ret + fmt.Printf("ref: fix releasing invalid ref(%v:%v) by adding %v\n", ref.vars[0], ref.count, helper.Enum) + } else { + fmt.Printf("ref: fix releasing invalid ref(%v:%v) failed since no helper can acquire the reference\n", ref.vars[0], ref.count) + } + } + } + } + if ref.count > 0 { + // Add a ref-release helper + if ref.typ == 1 { + helpers := s.getBpfHelpers([]string{"BPF_FUNC_sk_release"}) + if len(helpers) > 0 { + helper := helpers[r.Intn(len(helpers))] + hint := newBpfCallGenHint(ref.objMap) + //s.genBpfHelperCall(r, h, hint, false) + call := NewBpfCall(helper, hint) + a0 := NewBpfArg(helper, 0) + a0.Name = ref.vars[r.Intn(len(ref.vars))] + call.Args[0] = a0 + ref.calls[0].PostCalls = append(ref.calls[0].PostCalls, call) + //s.Calls = append(s.Calls, call) + ref.count = 0 + fmt.Printf("ref: fixing leaking ref(%v:%v) by adding %v\n", ref.vars[0], ref.count, helper.Enum) + } else { + fmt.Printf("ref: fixing leaking ref(%v:%v) failed since no helper can release the reference\n", ref.vars[0], ref.count) + } + } + if ref.typ == 2 { + helpers := s.getBpfHelpers([]string{"BPF_FUNC_ringbuf_submit", "BPF_FUNC_ringbuf_discard"}) + if len(helpers) > 0 { + helper := helpers[r.Intn(len(helpers))] + hint := newBpfCallGenHint(ref.objMap) + //s.genBpfHelperCall(r, h, hint, false) + call := NewBpfCall(helper, hint) + a0 := NewBpfArg(helper, 0) + a0.Name = ref.vars[r.Intn(len(ref.vars))] + call.Args[0] = a0 + a1 := NewBpfArg(helper, 1) + a1.Name = "0" + a1.IsNotNull = true + call.Args[1] = a1 + s.Calls = append(s.Calls, call) + ref.count = 0 + fmt.Printf("ref: fixing leaking ref(%v:%v) by adding %v\n", ref.vars[0], ref.count, helper.Enum) + } else { + fmt.Printf("ref: fixing leaking ref(%v:%v) failed since no helper can release the reference\n", ref.vars[0], ref.count) + } + } + } + } +} + +func (s *BpfProg) FixSpinLock(r *randGen) { + lockHeld := "" + for i, call := range s.Calls { + if call.Helper.Enum == "BPF_FUNC_spin_unlock" { + if lockHeld == "" { + if helper := s.pt.getHelper("BPF_FUNC_spin_lock"); helper != nil { + hint := newBpfCallGenHint(nil) + call := NewBpfCall(helper, hint) + a0 := NewBpfArg(helper, 0) + a0.Name = s.Calls[i].Args[0].Name + call.Args[0] = a0 + lockHeld = a0.Name + s.Calls = append(s.Calls[:i+1], s.Calls[i:]...) + s.Calls[i] = call + } else { + fmt.Printf("spinlock: fixing spinlock failed since no helper can lock the spinlock\n") + break + } + } else { + if lockHeld == call.Args[0].Name { + lockHeld = "" + } else { + fmt.Printf("spinlock: fixing a mismatch spin_unlock\n") + call.Args[0].Name = lockHeld + } + } + } + if call.Helper.Enum == "BPF_FUNC_spin_lock" { + if i == len(s.Calls)-1 || s.Calls[i+1].Helper.Enum != "BPF_FUNC_spin_unlock" { + if helper := s.pt.getHelper("BPF_FUNC_spin_unlock"); helper != nil { + hint := newBpfCallGenHint(nil) + call := NewBpfCall(helper, hint) + a0 := NewBpfArg(helper, 0) + a0.Name = s.Calls[i].Args[0].Name + call.Args[0] = a0 + lockHeld = a0.Name + s.Calls = append(s.Calls[:i+1], s.Calls[i:]...) + s.Calls[i+1] = call + } else { + fmt.Printf("spinlock: fixing spinlock failed since no helper can unlock the spinlock\n") + break + } + } else { + lockHeld = call.Args[0].Name + } + } + } +} + +//417-program exit +func genRandReturnVal(r *randGen, e BpfProgTypeEnum) int { + retVal := 0 + switch(e) { + case BPF_PROG_TYPE_CGROUP_SOCK_ADDR: + //retVal = r.Intn(4) //(0,3) + retVal = 1 + case BPF_PROG_TYPE_CGROUP_SKB: + //retVal = r.Intn(4) //(0,3) + retVal = r.Intn(2) //(0,1) + case BPF_PROG_TYPE_CGROUP_SOCK: + retVal = r.Intn(2) //(0,1) + case BPF_PROG_TYPE_SOCK_OPS: + retVal = r.Intn(2) //(0,1) + case BPF_PROG_TYPE_CGROUP_DEVICE: + retVal = r.Intn(2) //(0,1) + case BPF_PROG_TYPE_CGROUP_SYSCTL: + retVal = r.Intn(2) //(0,1) + case BPF_PROG_TYPE_CGROUP_SOCKOPT: + retVal = r.Intn(2) //(0,1) + case BPF_PROG_TYPE_RAW_TRACEPOINT: + retVal = 0 + case BPF_PROG_TYPE_TRACING: + retVal = 0 + case BPF_PROG_TYPE_SK_LOOKUP: + retVal = r.Intn(2) //(SK_DROP, SK_PASS) + default: + retVal = r.Intn(1<<32) + } + return retVal +} + +var srcBegin =` +#include "vmlinux.h" +#include + +#define DEFINE_BPF_MAP(the_map, TypeOfMap, MapFlags, TypeOfKey, TypeOfValue, MaxEntries) \ + struct { \ + __uint(type, TypeOfMap); \ + __uint(map_flags, (MapFlags)); \ + __uint(max_entries, (MaxEntries)); \ + __type(key, TypeOfKey); \ + __type(value, TypeOfValue); \ + } the_map SEC(".maps"); + +#define DEFINE_BPF_MAP_IN_MAP(the_map, TypeOfMap, MapFlags, TypeOfKey, TypeOfValue, MaxEntries, innerMap) \ + struct { \ + __uint(type, TypeOfMap); \ + __uint(map_flags, (MapFlags)); \ + __uint(max_entries, (MaxEntries)); \ + __type(key, TypeOfKey); \ + __array(values, typeof(innerMap)); \ + } the_map SEC(".maps") = { .values = {&innerMap}, }; + +#define DEFINE_BPF_MAP_NO_KEY(the_map, TypeOfMap, MapFlags, TypeOfValue, MaxEntries) \ + struct { \ + __uint(type, TypeOfMap); \ + __uint(map_flags, (MapFlags)); \ + __uint(max_entries, (MaxEntries)); \ + __type(value, TypeOfValue); \ + } the_map SEC(".maps"); + +#define DEFINE_BPF_MAP_NO_VAL(the_map, TypeOfMap, MapFlags, TypeOfKey, MaxEntries) \ + struct { \ + __uint(type, TypeOfMap); \ + __uint(map_flags, (MapFlags)); \ + __uint(max_entries, (MaxEntries)); \ + __type(key, TypeOfKey); \ + } the_map SEC(".maps"); + +#define DEFINE_BPF_MAP_NO_KEY_VAL(the_map, TypeOfMap, MapFlags, MaxEntries) \ + struct { \ + __uint(type, TypeOfMap); \ + __uint(map_flags, (MapFlags)); \ + __uint(max_entries, (MaxEntries)); \ + } the_map SEC(".maps"); + +` + +func (p *BpfProg) genCSource() string { + s := new(bytes.Buffer) + s.WriteString(srcBegin) + + for _, t := range p.Structs { + if !t.IsStruct { + continue + } + + fmt.Fprintf(s, "typedef struct %v {\n", t.Name) + for i, m := range t.FieldTypes { + if m == "char [8]" { + fmt.Fprintf(s, " char e%v[8];\n", i) + } else { + fmt.Fprintf(s, " %v e%v;\n", m, i) + } + } + fmt.Fprintf(s, "} %v;\n\n", t.Name) + } + + for v, t := range p.Externs { + fmt.Fprintf(s, "extern const %s %s __ksym;\n\n", t, v) + } + + for _, m := range p.Maps { + if m.Key == nil && m.Val == nil { + fmt.Fprintf(s, "DEFINE_BPF_MAP_NO_KEY_VAL(%s, %s, %s, %d);\n", m.MapName, m.MapType, m.FlagsStr(), m.MaxEntries) + } else if m.Key == nil { + fmt.Fprintf(s, "DEFINE_BPF_MAP_NO_KEY(%s, %s, %s, %s, %d);\n", m.MapName, m.MapType, m.FlagsStr(), m.Val.Name, m.MaxEntries) + } else if m.Val == nil { + fmt.Fprintf(s, "DEFINE_BPF_MAP_NO_VAL(%s, %s, %s, %s, %d);\n", m.MapName, m.MapType, m.FlagsStr(), m.Key.Name, m.MaxEntries) + } else if m.InnerMap == nil { + fmt.Fprintf(s, "DEFINE_BPF_MAP(%s, %s, %s, %s, %s, %d);\n", m.MapName, m.MapType, m.FlagsStr(), m.Key.Name, m.Val.Name, m.MaxEntries) + } else { + fmt.Fprintf(s, "DEFINE_BPF_MAP_IN_MAP(%s, %s, %s, %s, %s, %d, %s);\n", m.MapName, m.MapType, m.FlagsStr(), m.Key.Name, m.Val.Name, m.MaxEntries, m.InnerMap.MapName) + } + } + + fmt.Fprintf(s, "%s", p.SecStr) + fmt.Fprintf(s, "int func(%s *ctx) {\n", p.pt.User) + for field, v := range p.CtxVars { + fmt.Fprintf(s, " %s %s = ctx->%s;\n", p.CtxTypes[field], v, field) + } + for i, call := range p.Calls { + for j, arg := range call.Args { + if arg == nil { + fmt.Printf("debug %v %v %v nil\n", i, call.Helper.Enum, j) + } + if arg.Prepare != "" { + fmt.Fprintf(s, "%s", arg.Prepare) + } + } + if call.RetType != "" { + fmt.Fprintf(s, " %s %s = 0;\n", call.RetType, call.Ret) // XXX see if compiler stop optimize out null check + } + + // Check arguments before calling a helper + indent := "" + constraints := call.getArgConstraints(p) + if len(constraints) != 0 { + fmt.Fprintf(s, " if (") + for i, c := range constraints { + fmt.Fprintf(s, "%v", c) + if i < len(constraints)-1 { + fmt.Fprintf(s, " && ") + } + } + fmt.Fprintf(s, ") {\n") + indent = " " + } + + if call.RetType != "" { + fmt.Fprintf(s, "%s %s = bpf_%s(", indent, call.Ret, call.Helper.Enum[9:]) + } else { + fmt.Fprintf(s, "%s bpf_%s(", indent, call.Helper.Enum[9:]) + } + for i, arg := range call.Args { + fmt.Fprintf(s, "%v", arg.Name) + if i < len(call.Args)-1 { + fmt.Fprintf(s, ", ") + } + } + fmt.Fprintf(s, ");\n") + + for _, pcall := range call.PostCalls { + fmt.Fprintf(s, "%s bpf_%s(", indent, pcall.Helper.Enum[9:]) + for i, arg := range pcall.Args { + fmt.Fprintf(s, "%v", arg.Name) + if i < len(pcall.Args)-1 { + fmt.Fprintf(s, ", ") + } + } + fmt.Fprintf(s, ");\n") + } + + if len(constraints) != 0 { + fmt.Fprintf(s, " }\n") + } + } + + fmt.Fprintf(s, " return %v;\n", p.RetVal) + fmt.Fprintf(s, "}\n\n") + + fmt.Fprintf(s, "char _license[] SEC(\"license\") = \"GPL\";\n") + + fmt.Printf("\n%v\n", s) + + return s.String() +} + diff --git a/prog/brf_prog.go b/prog/brf_prog.go new file mode 100644 index 000000000..f0ec4d57c --- /dev/null +++ b/prog/brf_prog.go @@ -0,0 +1,111 @@ +package prog + +import ( + "encoding/gob" + "fmt" + "os" + "time" +) + +type BpfProg struct { + BasePath string + UseTestSrc bool + + pt *BpfProgTypeDef + TypeEnum BpfProgTypeEnum + VarId int + Maps []*BpfMap + Calls []*BpfCall + Structs []*StructDef + Externs map[string]string + CtxVars map[string]string + CtxTypes map[string]string + RetVal int + SecStr string + Sec SecDef + Path string + AttachOpt BpfAttachOption +} + +type BrfGenProgOpt struct { + genProgAttempt int + useTestSrc bool + basePath string +} + +func newBpfProg(r *randGen, opt BrfGenProgOpt) *BpfProg { + p := &BpfProg {} + + if (opt.useTestSrc) { + p.BasePath = opt.basePath + "/test_prog" + p.UseTestSrc = true + } else { + p.BasePath = fmt.Sprintf("%v/prog_%x", opt.basePath, time.Now().UnixNano()) + } + + return p +} + +func (p *BpfProg) writeCSource() error { + var progSrc string + + if (p.UseTestSrc) { + progSrc = testSrc + } else { + progSrc = p.genCSource() + } + + f, err := os.Create(p.BasePath + ".c") + if err != nil { + return err + } + defer f.Close() + + _, err = f.WriteString(progSrc) + return err +} + +func (p *BpfProg) writeGob() error { + f, err := os.Create(p.BasePath + ".gob") + if err != nil { + return err + } + defer f.Close() + + return gob.NewEncoder(f).Encode(p) +} + +func (p *BpfProg) readGob(path string) error { + file, err := os.Open(path) + if err != nil { + return err + } + defer file.Close() + + return gob.NewDecoder(file).Decode(p) +} + + +var testSrc = ` +#include "vmlinux.h" +#include + +#define DEFINE_BPF_MAP(the_map, TypeOfMap, MapFlags, TypeOfKey, TypeOfValue, MaxEntries) \ + struct { \ + __uint(type, TypeOfMap); \ + __uint(map_flags, (MapFlags)); \ + __uint(max_entries, (MaxEntries)); \ + __type(key, TypeOfKey); \ + __type(value, TypeOfValue); \ + } the_map SEC(".maps"); + +DEFINE_BPF_MAP(array_map, BPF_MAP_TYPE_ARRAY, 0, int, int, 1); + +SEC("cgroup_skb/egress") +int func(struct __sk_buff *ctx) +{ + int *value, key = 0; + value = bpf_map_lookup_elem(&array_map, &key); + return 0; +} +` diff --git a/prog/brf_types.go b/prog/brf_types.go new file mode 100644 index 000000000..774f2f6d8 --- /dev/null +++ b/prog/brf_types.go @@ -0,0 +1,1711 @@ +package prog + +var HelperFuncMap = map[string]*BpfHelperFunc{ + "bpf_map_lookup_elem_proto": &BpfHelperFunc{Num: 1, Enum: "BPF_FUNC_map_lookup_elem", Name: "bpf_map_lookup_elem", Proto: "bpf_map_lookup_elem_proto", Args: []string{"ARG_CONST_MAP_PTR", "ARG_PTR_TO_MAP_KEY"}, Ret: "RET_PTR_TO_MAP_VALUE_OR_NULL", PktAccess: true}, + "bpf_map_update_elem_proto": &BpfHelperFunc{Num: 2, Enum: "BPF_FUNC_map_update_elem", Name: "bpf_map_update_elem", Proto: "bpf_map_update_elem_proto", Args: []string{"ARG_CONST_MAP_PTR", "ARG_PTR_TO_MAP_KEY", "ARG_PTR_TO_MAP_VALUE", "ARG_ANYTHING"}, Ret: "RET_INTEGER", PktAccess: true}, + "bpf_map_delete_elem_proto": &BpfHelperFunc{Num: 3, Enum: "BPF_FUNC_map_delete_elem", Name: "bpf_map_delete_elem", Proto: "bpf_map_delete_elem_proto", Args: []string{"ARG_CONST_MAP_PTR", "ARG_PTR_TO_MAP_KEY"}, Ret: "RET_INTEGER", PktAccess: true}, + "bpf_probe_read_compat_proto": &BpfHelperFunc{Num: 4, Enum: "BPF_FUNC_probe_read", Name: "bpf_probe_read_compat", Proto: "bpf_probe_read_compat_proto", Args: []string{"ARG_PTR_TO_UNINIT_MEM", "ARG_CONST_SIZE_OR_ZERO", "ARG_ANYTHING"}, Ret: "RET_INTEGER", GplOnly: true}, + "bpf_ktime_get_ns_proto": &BpfHelperFunc{Num: 5, Enum: "BPF_FUNC_ktime_get_ns", Name: "bpf_ktime_get_ns", Proto: "bpf_ktime_get_ns_proto", Ret: "RET_INTEGER"}, + "bpf_trace_printk_proto": &BpfHelperFunc{Num: 6, Enum: "BPF_FUNC_trace_printk", Name: "bpf_trace_printk", Proto: "bpf_trace_printk_proto", Args: []string{"ARG_PTR_TO_MEM", "ARG_CONST_SIZE"}, Ret: "RET_INTEGER", GplOnly: true}, + "bpf_get_prandom_u32_proto": &BpfHelperFunc{Num: 7, Enum: "BPF_FUNC_get_prandom_u32", Name: "bpf_get_prandom_u32", Proto: "bpf_get_prandom_u32_proto", Ret: "RET_INTEGER"}, + "bpf_get_smp_processor_id_proto": &BpfHelperFunc{Num: 8, Enum: "BPF_FUNC_get_smp_processor_id", Name: "bpf_get_smp_processor_id", Proto: "bpf_get_smp_processor_id_proto", Ret: "RET_INTEGER"}, + "bpf_get_raw_smp_processor_id_proto": &BpfHelperFunc{Num: 8, Enum: "BPF_FUNC_get_smp_processor_id", Name: "bpf_get_raw_cpu_id", Proto: "bpf_get_raw_smp_processor_id_proto", Ret: "RET_INTEGER"}, + "bpf_skb_store_bytes_proto": &BpfHelperFunc{Num: 9, Enum: "BPF_FUNC_skb_store_bytes", Name: "bpf_skb_store_bytes", Proto: "bpf_skb_store_bytes_proto", Args: []string{"ARG_PTR_TO_CTX", "ARG_ANYTHING", "ARG_PTR_TO_MEM", "ARG_CONST_SIZE", "ARG_ANYTHING"}, Ret: "RET_INTEGER"}, + "bpf_l3_csum_replace_proto": &BpfHelperFunc{Num: 10, Enum: "BPF_FUNC_l3_csum_replace", Name: "bpf_l3_csum_replace", Proto: "bpf_l3_csum_replace_proto", Args: []string{"ARG_PTR_TO_CTX", "ARG_ANYTHING", "ARG_ANYTHING", "ARG_ANYTHING", "ARG_ANYTHING"}, Ret: "RET_INTEGER"}, + "bpf_l4_csum_replace_proto": &BpfHelperFunc{Num: 11, Enum: "BPF_FUNC_l4_csum_replace", Name: "bpf_l4_csum_replace", Proto: "bpf_l4_csum_replace_proto", Args: []string{"ARG_PTR_TO_CTX", "ARG_ANYTHING", "ARG_ANYTHING", "ARG_ANYTHING", "ARG_ANYTHING"}, Ret: "RET_INTEGER"}, + "bpf_tail_call_proto": &BpfHelperFunc{Num: 12, Enum: "BPF_FUNC_tail_call", Name: "NULL", Proto: "bpf_tail_call_proto", Args: []string{"ARG_PTR_TO_CTX", "ARG_CONST_MAP_PTR", "ARG_ANYTHING"}, Ret: "RET_VOID"}, + "bpf_clone_redirect_proto": &BpfHelperFunc{Num: 13, Enum: "BPF_FUNC_clone_redirect", Name: "bpf_clone_redirect", Proto: "bpf_clone_redirect_proto", Args: []string{"ARG_PTR_TO_CTX", "ARG_ANYTHING", "ARG_ANYTHING"}, Ret: "RET_INTEGER"}, + "bpf_get_current_pid_tgid_proto": &BpfHelperFunc{Num: 14, Enum: "BPF_FUNC_get_current_pid_tgid", Name: "bpf_get_current_pid_tgid", Proto: "bpf_get_current_pid_tgid_proto", Ret: "RET_INTEGER"}, + "bpf_get_current_uid_gid_proto": &BpfHelperFunc{Num: 15, Enum: "BPF_FUNC_get_current_uid_gid", Name: "bpf_get_current_uid_gid", Proto: "bpf_get_current_uid_gid_proto", Ret: "RET_INTEGER"}, + "bpf_get_current_comm_proto": &BpfHelperFunc{Num: 16, Enum: "BPF_FUNC_get_current_comm", Name: "bpf_get_current_comm", Proto: "bpf_get_current_comm_proto", Args: []string{"ARG_PTR_TO_UNINIT_MEM", "ARG_CONST_SIZE"}, Ret: "RET_INTEGER"}, + "bpf_get_cgroup_classid_proto": &BpfHelperFunc{Num: 17, Enum: "BPF_FUNC_get_cgroup_classid", Name: "bpf_get_cgroup_classid", Proto: "bpf_get_cgroup_classid_proto", Args: []string{"ARG_PTR_TO_CTX"}, Ret: "RET_INTEGER"}, + "bpf_get_cgroup_classid_curr_proto": &BpfHelperFunc{Num: 17, Enum: "BPF_FUNC_get_cgroup_classid", Name: "bpf_get_cgroup_classid_curr", Proto: "bpf_get_cgroup_classid_curr_proto", Ret: "RET_INTEGER"}, + "bpf_skb_vlan_push_proto": &BpfHelperFunc{Num: 18, Enum: "BPF_FUNC_skb_vlan_push", Name: "bpf_skb_vlan_push", Proto: "bpf_skb_vlan_push_proto", Args: []string{"ARG_PTR_TO_CTX", "ARG_ANYTHING", "ARG_ANYTHING"}, Ret: "RET_INTEGER"}, + "bpf_skb_vlan_pop_proto": &BpfHelperFunc{Num: 19, Enum: "BPF_FUNC_skb_vlan_pop", Name: "bpf_skb_vlan_pop", Proto: "bpf_skb_vlan_pop_proto", Args: []string{"ARG_PTR_TO_CTX"}, Ret: "RET_INTEGER"}, + "bpf_skb_get_tunnel_key_proto": &BpfHelperFunc{Num: 20, Enum: "BPF_FUNC_skb_get_tunnel_key", Name: "bpf_skb_get_tunnel_key", Proto: "bpf_skb_get_tunnel_key_proto", Args: []string{"ARG_PTR_TO_CTX", "ARG_PTR_TO_UNINIT_MEM", "ARG_CONST_SIZE", "ARG_ANYTHING"}, Ret: "RET_INTEGER"}, + "bpf_skb_set_tunnel_key_proto": &BpfHelperFunc{Num: 21, Enum: "BPF_FUNC_skb_set_tunnel_key", Name: "bpf_skb_set_tunnel_key", Proto: "bpf_skb_set_tunnel_key_proto", Args: []string{"ARG_PTR_TO_CTX", "ARG_PTR_TO_MEM", "ARG_CONST_SIZE", "ARG_ANYTHING"}, Ret: "RET_INTEGER"}, + "bpf_perf_event_read_proto": &BpfHelperFunc{Num: 22, Enum: "BPF_FUNC_perf_event_read", Name: "bpf_perf_event_read", Proto: "bpf_perf_event_read_proto", Args: []string{"ARG_CONST_MAP_PTR", "ARG_ANYTHING"}, Ret: "RET_INTEGER", GplOnly: true}, + "bpf_redirect_proto": &BpfHelperFunc{Num: 23, Enum: "BPF_FUNC_redirect", Name: "bpf_redirect", Proto: "bpf_redirect_proto", Args: []string{"ARG_ANYTHING", "ARG_ANYTHING"}, Ret: "RET_INTEGER"}, + "bpf_xdp_redirect_proto": &BpfHelperFunc{Num: 23, Enum: "BPF_FUNC_redirect", Name: "bpf_xdp_redirect", Proto: "bpf_xdp_redirect_proto", Args: []string{"ARG_ANYTHING", "ARG_ANYTHING"}, Ret: "RET_INTEGER"}, + "bpf_get_route_realm_proto": &BpfHelperFunc{Num: 24, Enum: "BPF_FUNC_get_route_realm", Name: "bpf_get_route_realm", Proto: "bpf_get_route_realm_proto", Args: []string{"ARG_PTR_TO_CTX"}, Ret: "RET_INTEGER"}, + "bpf_perf_event_output_proto": &BpfHelperFunc{Num: 25, Enum: "BPF_FUNC_perf_event_output", Name: "bpf_perf_event_output", Proto: "bpf_perf_event_output_proto", Args: []string{"ARG_PTR_TO_CTX", "ARG_CONST_MAP_PTR", "ARG_ANYTHING", "ARG_PTR_TO_MEM", "ARG_CONST_SIZE_OR_ZERO"}, Ret: "RET_INTEGER", GplOnly: true}, + "bpf_event_output_data_proto": &BpfHelperFunc{Num: 25, Enum: "BPF_FUNC_perf_event_output", Name: "bpf_event_output_data", Proto: "bpf_event_output_data_proto", Args: []string{"ARG_PTR_TO_CTX", "ARG_CONST_MAP_PTR", "ARG_ANYTHING", "ARG_PTR_TO_MEM", "ARG_CONST_SIZE_OR_ZERO"}, Ret: "RET_INTEGER", GplOnly: true}, + "bpf_skb_event_output_proto": &BpfHelperFunc{Num: 25, Enum: "BPF_FUNC_perf_event_output", Name: "bpf_skb_event_output", Proto: "bpf_skb_event_output_proto", Args: []string{"ARG_PTR_TO_CTX", "ARG_CONST_MAP_PTR", "ARG_ANYTHING", "ARG_PTR_TO_MEM", "ARG_CONST_SIZE_OR_ZERO"}, Ret: "RET_INTEGER", GplOnly: true}, + "bpf_xdp_event_output_proto": &BpfHelperFunc{Num: 25, Enum: "BPF_FUNC_perf_event_output", Name: "bpf_xdp_event_output", Proto: "bpf_xdp_event_output_proto", Args: []string{"ARG_PTR_TO_CTX", "ARG_CONST_MAP_PTR", "ARG_ANYTHING", "ARG_PTR_TO_MEM", "ARG_CONST_SIZE_OR_ZERO"}, Ret: "RET_INTEGER", GplOnly: true}, + "bpf_perf_event_output_proto_tp": &BpfHelperFunc{Num: 25, Enum: "BPF_FUNC_perf_event_output", Name: "bpf_perf_event_output_tp", Proto: "bpf_perf_event_output_proto_tp", Args: []string{"ARG_PTR_TO_CTX", "ARG_CONST_MAP_PTR", "ARG_ANYTHING", "ARG_PTR_TO_MEM", "ARG_CONST_SIZE_OR_ZERO"}, Ret: "RET_INTEGER", GplOnly: true}, + "bpf_perf_event_output_proto_raw_tp": &BpfHelperFunc{Num: 25, Enum: "BPF_FUNC_perf_event_output", Name: "bpf_perf_event_output_raw_tp", Proto: "bpf_perf_event_output_proto_raw_tp", Args: []string{"ARG_PTR_TO_CTX", "ARG_CONST_MAP_PTR", "ARG_ANYTHING", "ARG_PTR_TO_MEM", "ARG_CONST_SIZE_OR_ZERO"}, Ret: "RET_INTEGER", GplOnly: true}, + "bpf_skb_load_bytes_proto": &BpfHelperFunc{Num: 26, Enum: "BPF_FUNC_skb_load_bytes", Name: "bpf_skb_load_bytes", Proto: "bpf_skb_load_bytes_proto", Args: []string{"ARG_PTR_TO_CTX", "ARG_ANYTHING", "ARG_PTR_TO_UNINIT_MEM", "ARG_CONST_SIZE"}, Ret: "RET_INTEGER"}, + "bpf_flow_dissector_load_bytes_proto": &BpfHelperFunc{Num: 26, Enum: "BPF_FUNC_skb_load_bytes", Name: "bpf_flow_dissector_load_bytes", Proto: "bpf_flow_dissector_load_bytes_proto", Args: []string{"ARG_PTR_TO_CTX", "ARG_ANYTHING", "ARG_PTR_TO_UNINIT_MEM", "ARG_CONST_SIZE"}, Ret: "RET_INTEGER"}, + "sk_reuseport_load_bytes_proto": &BpfHelperFunc{Num: 26, Enum: "BPF_FUNC_skb_load_bytes", Name: "sk_reuseport_load_bytes", Proto: "sk_reuseport_load_bytes_proto", Args: []string{"ARG_PTR_TO_CTX", "ARG_ANYTHING", "ARG_PTR_TO_UNINIT_MEM", "ARG_CONST_SIZE"}, Ret: "RET_INTEGER"}, + "bpf_get_stackid_proto": &BpfHelperFunc{Num: 27, Enum: "BPF_FUNC_get_stackid", Name: "bpf_get_stackid", Proto: "bpf_get_stackid_proto", Args: []string{"ARG_PTR_TO_CTX", "ARG_CONST_MAP_PTR", "ARG_ANYTHING"}, Ret: "RET_INTEGER", GplOnly: true}, + "bpf_get_stackid_proto_pe": &BpfHelperFunc{Num: 27, Enum: "BPF_FUNC_get_stackid", Name: "bpf_get_stackid_pe", Proto: "bpf_get_stackid_proto_pe", Args: []string{"ARG_PTR_TO_CTX", "ARG_CONST_MAP_PTR", "ARG_ANYTHING"}, Ret: "RET_INTEGER"}, + "bpf_get_stackid_proto_tp": &BpfHelperFunc{Num: 27, Enum: "BPF_FUNC_get_stackid", Name: "bpf_get_stackid_tp", Proto: "bpf_get_stackid_proto_tp", Args: []string{"ARG_PTR_TO_CTX", "ARG_CONST_MAP_PTR", "ARG_ANYTHING"}, Ret: "RET_INTEGER", GplOnly: true}, + "bpf_get_stackid_proto_raw_tp": &BpfHelperFunc{Num: 27, Enum: "BPF_FUNC_get_stackid", Name: "bpf_get_stackid_raw_tp", Proto: "bpf_get_stackid_proto_raw_tp", Args: []string{"ARG_PTR_TO_CTX", "ARG_CONST_MAP_PTR", "ARG_ANYTHING"}, Ret: "RET_INTEGER", GplOnly: true}, + "bpf_csum_diff_proto": &BpfHelperFunc{Num: 28, Enum: "BPF_FUNC_csum_diff", Name: "bpf_csum_diff", Proto: "bpf_csum_diff_proto", Args: []string{"ARG_PTR_TO_MEM_OR_NULL", "ARG_CONST_SIZE_OR_ZERO", "ARG_PTR_TO_MEM_OR_NULL", "ARG_CONST_SIZE_OR_ZERO", "ARG_ANYTHING"}, Ret: "RET_INTEGER", PktAccess: true}, + "bpf_skb_get_tunnel_opt_proto": &BpfHelperFunc{Num: 29, Enum: "BPF_FUNC_skb_get_tunnel_opt", Name: "bpf_skb_get_tunnel_opt", Proto: "bpf_skb_get_tunnel_opt_proto", Args: []string{"ARG_PTR_TO_CTX", "ARG_PTR_TO_UNINIT_MEM", "ARG_CONST_SIZE"}, Ret: "RET_INTEGER"}, + "bpf_skb_set_tunnel_opt_proto": &BpfHelperFunc{Num: 30, Enum: "BPF_FUNC_skb_set_tunnel_opt", Name: "bpf_skb_set_tunnel_opt", Proto: "bpf_skb_set_tunnel_opt_proto", Args: []string{"ARG_PTR_TO_CTX", "ARG_PTR_TO_MEM", "ARG_CONST_SIZE"}, Ret: "RET_INTEGER"}, + "bpf_skb_change_proto_proto": &BpfHelperFunc{Num: 31, Enum: "BPF_FUNC_skb_change_proto", Name: "bpf_skb_change_proto", Proto: "bpf_skb_change_proto_proto", Args: []string{"ARG_PTR_TO_CTX", "ARG_ANYTHING", "ARG_ANYTHING"}, Ret: "RET_INTEGER"}, + "bpf_skb_change_type_proto": &BpfHelperFunc{Num: 32, Enum: "BPF_FUNC_skb_change_type", Name: "bpf_skb_change_type", Proto: "bpf_skb_change_type_proto", Args: []string{"ARG_PTR_TO_CTX", "ARG_ANYTHING"}, Ret: "RET_INTEGER"}, + "bpf_skb_under_cgroup_proto": &BpfHelperFunc{Num: 33, Enum: "BPF_FUNC_skb_under_cgroup", Name: "bpf_skb_under_cgroup", Proto: "bpf_skb_under_cgroup_proto", Args: []string{"ARG_PTR_TO_CTX", "ARG_CONST_MAP_PTR", "ARG_ANYTHING"}, Ret: "RET_INTEGER"}, + "bpf_get_hash_recalc_proto": &BpfHelperFunc{Num: 34, Enum: "BPF_FUNC_get_hash_recalc", Name: "bpf_get_hash_recalc", Proto: "bpf_get_hash_recalc_proto", Args: []string{"ARG_PTR_TO_CTX"}, Ret: "RET_INTEGER"}, + "bpf_get_current_task_proto": &BpfHelperFunc{Num: 35, Enum: "BPF_FUNC_get_current_task", Name: "bpf_get_current_task", Proto: "bpf_get_current_task_proto", Ret: "RET_INTEGER", GplOnly: true}, + "bpf_probe_write_user_proto": &BpfHelperFunc{Num: 36, Enum: "BPF_FUNC_probe_write_user", Name: "bpf_probe_write_user", Proto: "bpf_probe_write_user_proto", Args: []string{"ARG_ANYTHING", "ARG_PTR_TO_MEM", "ARG_CONST_SIZE"}, Ret: "RET_INTEGER", GplOnly: true}, + "bpf_current_task_under_cgroup_proto": &BpfHelperFunc{Num: 37, Enum: "BPF_FUNC_current_task_under_cgroup", Name: "bpf_current_task_under_cgroup", Proto: "bpf_current_task_under_cgroup_proto", Args: []string{"ARG_CONST_MAP_PTR", "ARG_ANYTHING"}, Ret: "RET_INTEGER"}, + "bpf_skb_change_tail_proto": &BpfHelperFunc{Num: 38, Enum: "BPF_FUNC_skb_change_tail", Name: "bpf_skb_change_tail", Proto: "bpf_skb_change_tail_proto", Args: []string{"ARG_PTR_TO_CTX", "ARG_ANYTHING", "ARG_ANYTHING"}, Ret: "RET_INTEGER"}, + "sk_skb_change_tail_proto": &BpfHelperFunc{Num: 38, Enum: "BPF_FUNC_skb_change_tail", Name: "sk_skb_change_tail", Proto: "sk_skb_change_tail_proto", Args: []string{"ARG_PTR_TO_CTX", "ARG_ANYTHING", "ARG_ANYTHING"}, Ret: "RET_INTEGER"}, + "bpf_skb_pull_data_proto": &BpfHelperFunc{Num: 39, Enum: "BPF_FUNC_skb_pull_data", Name: "bpf_skb_pull_data", Proto: "bpf_skb_pull_data_proto", Args: []string{"ARG_PTR_TO_CTX", "ARG_ANYTHING"}, Ret: "RET_INTEGER"}, + "sk_skb_pull_data_proto": &BpfHelperFunc{Num: 39, Enum: "BPF_FUNC_skb_pull_data", Name: "sk_skb_pull_data", Proto: "sk_skb_pull_data_proto", Args: []string{"ARG_PTR_TO_CTX", "ARG_ANYTHING"}, Ret: "RET_INTEGER"}, + "bpf_csum_update_proto": &BpfHelperFunc{Num: 40, Enum: "BPF_FUNC_csum_update", Name: "bpf_csum_update", Proto: "bpf_csum_update_proto", Args: []string{"ARG_PTR_TO_CTX", "ARG_ANYTHING"}, Ret: "RET_INTEGER"}, + "bpf_set_hash_invalid_proto": &BpfHelperFunc{Num: 41, Enum: "BPF_FUNC_set_hash_invalid", Name: "bpf_set_hash_invalid", Proto: "bpf_set_hash_invalid_proto", Args: []string{"ARG_PTR_TO_CTX"}, Ret: "RET_INTEGER"}, + "bpf_get_numa_node_id_proto": &BpfHelperFunc{Num: 42, Enum: "BPF_FUNC_get_numa_node_id", Name: "bpf_get_numa_node_id", Proto: "bpf_get_numa_node_id_proto", Ret: "RET_INTEGER"}, + "bpf_skb_change_head_proto": &BpfHelperFunc{Num: 43, Enum: "BPF_FUNC_skb_change_head", Name: "bpf_skb_change_head", Proto: "bpf_skb_change_head_proto", Args: []string{"ARG_PTR_TO_CTX", "ARG_ANYTHING", "ARG_ANYTHING"}, Ret: "RET_INTEGER"}, + "sk_skb_change_head_proto": &BpfHelperFunc{Num: 43, Enum: "BPF_FUNC_skb_change_head", Name: "sk_skb_change_head", Proto: "sk_skb_change_head_proto", Args: []string{"ARG_PTR_TO_CTX", "ARG_ANYTHING", "ARG_ANYTHING"}, Ret: "RET_INTEGER"}, + "bpf_xdp_adjust_head_proto": &BpfHelperFunc{Num: 44, Enum: "BPF_FUNC_xdp_adjust_head", Name: "bpf_xdp_adjust_head", Proto: "bpf_xdp_adjust_head_proto", Args: []string{"ARG_PTR_TO_CTX", "ARG_ANYTHING"}, Ret: "RET_INTEGER"}, + "bpf_probe_read_compat_str_proto": &BpfHelperFunc{Num: 45, Enum: "BPF_FUNC_probe_read_str", Name: "bpf_probe_read_compat_str", Proto: "bpf_probe_read_compat_str_proto", Args: []string{"ARG_PTR_TO_UNINIT_MEM", "ARG_CONST_SIZE_OR_ZERO", "ARG_ANYTHING"}, Ret: "RET_INTEGER", GplOnly: true}, + "bpf_get_socket_cookie_proto": &BpfHelperFunc{Num: 46, Enum: "BPF_FUNC_get_socket_cookie", Name: "bpf_get_socket_cookie", Proto: "bpf_get_socket_cookie_proto", Args: []string{"ARG_PTR_TO_CTX"}, Ret: "RET_INTEGER"}, + "bpf_get_socket_cookie_sock_addr_proto": &BpfHelperFunc{Num: 46, Enum: "BPF_FUNC_get_socket_cookie", Name: "bpf_get_socket_cookie_sock_addr", Proto: "bpf_get_socket_cookie_sock_addr_proto", Args: []string{"ARG_PTR_TO_CTX"}, Ret: "RET_INTEGER"}, + "bpf_get_socket_cookie_sock_proto": &BpfHelperFunc{Num: 46, Enum: "BPF_FUNC_get_socket_cookie", Name: "bpf_get_socket_cookie_sock", Proto: "bpf_get_socket_cookie_sock_proto", Args: []string{"ARG_PTR_TO_CTX"}, Ret: "RET_INTEGER"}, + "bpf_get_socket_cookie_sock_ops_proto": &BpfHelperFunc{Num: 46, Enum: "BPF_FUNC_get_socket_cookie", Name: "bpf_get_socket_cookie_sock_ops", Proto: "bpf_get_socket_cookie_sock_ops_proto", Args: []string{"ARG_PTR_TO_CTX"}, Ret: "RET_INTEGER"}, + "bpf_get_socket_ptr_cookie_proto": &BpfHelperFunc{Num: 46, Enum: "BPF_FUNC_get_socket_cookie", Name: "bpf_get_socket_ptr_cookie", Proto: "bpf_get_socket_ptr_cookie_proto", Args: []string{"ARG_PTR_TO_BTF_ID_SOCK_COMMON"}, Ret: "RET_INTEGER"}, + "bpf_get_socket_uid_proto": &BpfHelperFunc{Num: 47, Enum: "BPF_FUNC_get_socket_uid", Name: "bpf_get_socket_uid", Proto: "bpf_get_socket_uid_proto", Args: []string{"ARG_PTR_TO_CTX"}, Ret: "RET_INTEGER"}, + "bpf_set_hash_proto": &BpfHelperFunc{Num: 48, Enum: "BPF_FUNC_set_hash", Name: "bpf_set_hash", Proto: "bpf_set_hash_proto", Args: []string{"ARG_PTR_TO_CTX", "ARG_ANYTHING"}, Ret: "RET_INTEGER"}, + "bpf_sock_ops_setsockopt_proto": &BpfHelperFunc{Num: 49, Enum: "BPF_FUNC_setsockopt", Name: "bpf_sock_ops_setsockopt", Proto: "bpf_sock_ops_setsockopt_proto", Args: []string{"ARG_PTR_TO_CTX", "ARG_ANYTHING", "ARG_ANYTHING", "ARG_PTR_TO_MEM", "ARG_CONST_SIZE"}, Ret: "RET_INTEGER"}, + "bpf_sk_setsockopt_proto": &BpfHelperFunc{Num: 49, Enum: "BPF_FUNC_setsockopt", Name: "bpf_sk_setsockopt", Proto: "bpf_sk_setsockopt_proto", Args: []string{"ARG_PTR_TO_BTF_ID_SOCK_COMMON", "ARG_ANYTHING", "ARG_ANYTHING", "ARG_PTR_TO_MEM", "ARG_CONST_SIZE"}, Ret: "RET_INTEGER"}, + "bpf_sock_addr_setsockopt_proto": &BpfHelperFunc{Num: 49, Enum: "BPF_FUNC_setsockopt", Name: "bpf_sock_addr_setsockopt", Proto: "bpf_sock_addr_setsockopt_proto", Args: []string{"ARG_PTR_TO_CTX", "ARG_ANYTHING", "ARG_ANYTHING", "ARG_PTR_TO_MEM", "ARG_CONST_SIZE"}, Ret: "RET_INTEGER"}, + "bpf_skb_adjust_room_proto": &BpfHelperFunc{Num: 50, Enum: "BPF_FUNC_skb_adjust_room", Name: "bpf_skb_adjust_room", Proto: "bpf_skb_adjust_room_proto", Args: []string{"ARG_PTR_TO_CTX", "ARG_ANYTHING", "ARG_ANYTHING", "ARG_ANYTHING"}, Ret: "RET_INTEGER"}, + "sk_skb_adjust_room_proto": &BpfHelperFunc{Num: 50, Enum: "BPF_FUNC_skb_adjust_room", Name: "sk_skb_adjust_room", Proto: "sk_skb_adjust_room_proto", Args: []string{"ARG_PTR_TO_CTX", "ARG_ANYTHING", "ARG_ANYTHING", "ARG_ANYTHING"}, Ret: "RET_INTEGER"}, + "bpf_xdp_redirect_map_proto": &BpfHelperFunc{Num: 51, Enum: "BPF_FUNC_redirect_map", Name: "bpf_redirect_map", Proto: "bpf_xdp_redirect_map_proto", Args: []string{"ARG_CONST_MAP_PTR", "ARG_ANYTHING", "ARG_ANYTHING"}, Ret: "RET_INTEGER"}, + "bpf_sk_redirect_map_proto": &BpfHelperFunc{Num: 52, Enum: "BPF_FUNC_sk_redirect_map", Name: "bpf_sk_redirect_map", Proto: "bpf_sk_redirect_map_proto", Args: []string{"ARG_PTR_TO_CTX", "ARG_CONST_MAP_PTR", "ARG_ANYTHING", "ARG_ANYTHING"}, Ret: "RET_INTEGER"}, + "bpf_sock_map_update_proto": &BpfHelperFunc{Num: 53, Enum: "BPF_FUNC_sock_map_update", Name: "bpf_sock_map_update", Proto: "bpf_sock_map_update_proto", Args: []string{"ARG_PTR_TO_CTX", "ARG_CONST_MAP_PTR", "ARG_PTR_TO_MAP_KEY", "ARG_ANYTHING"}, Ret: "RET_INTEGER"}, + "bpf_xdp_adjust_meta_proto": &BpfHelperFunc{Num: 54, Enum: "BPF_FUNC_xdp_adjust_meta", Name: "bpf_xdp_adjust_meta", Proto: "bpf_xdp_adjust_meta_proto", Args: []string{"ARG_PTR_TO_CTX", "ARG_ANYTHING"}, Ret: "RET_INTEGER"}, + "bpf_perf_event_read_value_proto": &BpfHelperFunc{Num: 55, Enum: "BPF_FUNC_perf_event_read_value", Name: "bpf_perf_event_read_value", Proto: "bpf_perf_event_read_value_proto", Args: []string{"ARG_CONST_MAP_PTR", "ARG_ANYTHING", "ARG_PTR_TO_UNINIT_MEM", "ARG_CONST_SIZE"}, Ret: "RET_INTEGER", GplOnly: true}, + "bpf_perf_prog_read_value_proto": &BpfHelperFunc{Num: 56, Enum: "BPF_FUNC_perf_prog_read_value", Name: "bpf_perf_prog_read_value", Proto: "bpf_perf_prog_read_value_proto", Args: []string{"ARG_PTR_TO_CTX", "ARG_PTR_TO_UNINIT_MEM", "ARG_CONST_SIZE"}, Ret: "RET_INTEGER", GplOnly: true}, + "bpf_sock_ops_getsockopt_proto": &BpfHelperFunc{Num: 57, Enum: "BPF_FUNC_getsockopt", Name: "bpf_sock_ops_getsockopt", Proto: "bpf_sock_ops_getsockopt_proto", Args: []string{"ARG_PTR_TO_CTX", "ARG_ANYTHING", "ARG_ANYTHING", "ARG_PTR_TO_UNINIT_MEM", "ARG_CONST_SIZE"}, Ret: "RET_INTEGER"}, + "bpf_sk_getsockopt_proto": &BpfHelperFunc{Num: 57, Enum: "BPF_FUNC_getsockopt", Name: "bpf_sk_getsockopt", Proto: "bpf_sk_getsockopt_proto", Args: []string{"ARG_PTR_TO_BTF_ID_SOCK_COMMON", "ARG_ANYTHING", "ARG_ANYTHING", "ARG_PTR_TO_UNINIT_MEM", "ARG_CONST_SIZE"}, Ret: "RET_INTEGER"}, + "bpf_sock_addr_getsockopt_proto": &BpfHelperFunc{Num: 57, Enum: "BPF_FUNC_getsockopt", Name: "bpf_sock_addr_getsockopt", Proto: "bpf_sock_addr_getsockopt_proto", Args: []string{"ARG_PTR_TO_CTX", "ARG_ANYTHING", "ARG_ANYTHING", "ARG_PTR_TO_UNINIT_MEM", "ARG_CONST_SIZE"}, Ret: "RET_INTEGER"}, + "bpf_override_return_proto": &BpfHelperFunc{Num: 58, Enum: "BPF_FUNC_override_return", Name: "bpf_override_return", Proto: "bpf_override_return_proto", Args: []string{"ARG_PTR_TO_CTX", "ARG_ANYTHING"}, Ret: "RET_INTEGER", GplOnly: true}, + "bpf_sock_ops_cb_flags_set_proto": &BpfHelperFunc{Num: 59, Enum: "BPF_FUNC_sock_ops_cb_flags_set", Name: "bpf_sock_ops_cb_flags_set", Proto: "bpf_sock_ops_cb_flags_set_proto", Args: []string{"ARG_PTR_TO_CTX", "ARG_ANYTHING"}, Ret: "RET_INTEGER"}, + "bpf_msg_redirect_map_proto": &BpfHelperFunc{Num: 60, Enum: "BPF_FUNC_msg_redirect_map", Name: "bpf_msg_redirect_map", Proto: "bpf_msg_redirect_map_proto", Args: []string{"ARG_PTR_TO_CTX", "ARG_CONST_MAP_PTR", "ARG_ANYTHING", "ARG_ANYTHING"}, Ret: "RET_INTEGER"}, + "bpf_msg_apply_bytes_proto": &BpfHelperFunc{Num: 61, Enum: "BPF_FUNC_msg_apply_bytes", Name: "bpf_msg_apply_bytes", Proto: "bpf_msg_apply_bytes_proto", Args: []string{"ARG_PTR_TO_CTX", "ARG_ANYTHING"}, Ret: "RET_INTEGER"}, + "bpf_msg_cork_bytes_proto": &BpfHelperFunc{Num: 62, Enum: "BPF_FUNC_msg_cork_bytes", Name: "bpf_msg_cork_bytes", Proto: "bpf_msg_cork_bytes_proto", Args: []string{"ARG_PTR_TO_CTX", "ARG_ANYTHING"}, Ret: "RET_INTEGER"}, + "bpf_msg_pull_data_proto": &BpfHelperFunc{Num: 63, Enum: "BPF_FUNC_msg_pull_data", Name: "bpf_msg_pull_data", Proto: "bpf_msg_pull_data_proto", Args: []string{"ARG_PTR_TO_CTX", "ARG_ANYTHING", "ARG_ANYTHING", "ARG_ANYTHING"}, Ret: "RET_INTEGER"}, + "bpf_bind_proto": &BpfHelperFunc{Num: 64, Enum: "BPF_FUNC_bind", Name: "bpf_bind", Proto: "bpf_bind_proto", Args: []string{"ARG_PTR_TO_CTX", "ARG_PTR_TO_MEM", "ARG_CONST_SIZE"}, Ret: "RET_INTEGER"}, + "bpf_xdp_adjust_tail_proto": &BpfHelperFunc{Num: 65, Enum: "BPF_FUNC_xdp_adjust_tail", Name: "bpf_xdp_adjust_tail", Proto: "bpf_xdp_adjust_tail_proto", Args: []string{"ARG_PTR_TO_CTX", "ARG_ANYTHING"}, Ret: "RET_INTEGER"}, + "bpf_skb_get_xfrm_state_proto": &BpfHelperFunc{Num: 66, Enum: "BPF_FUNC_skb_get_xfrm_state", Name: "bpf_skb_get_xfrm_state", Proto: "bpf_skb_get_xfrm_state_proto", Args: []string{"ARG_PTR_TO_CTX", "ARG_ANYTHING", "ARG_PTR_TO_UNINIT_MEM", "ARG_CONST_SIZE", "ARG_ANYTHING"}, Ret: "RET_INTEGER"}, + "bpf_get_stack_proto": &BpfHelperFunc{Num: 67, Enum: "BPF_FUNC_get_stack", Name: "bpf_get_stack", Proto: "bpf_get_stack_proto", Args: []string{"ARG_PTR_TO_CTX", "ARG_PTR_TO_UNINIT_MEM", "ARG_CONST_SIZE_OR_ZERO", "ARG_ANYTHING"}, Ret: "RET_INTEGER", GplOnly: true}, + "bpf_get_stack_proto_raw_tp": &BpfHelperFunc{Num: 67, Enum: "BPF_FUNC_get_stack", Name: "bpf_get_stack_raw_tp", Proto: "bpf_get_stack_proto_raw_tp", Args: []string{"ARG_PTR_TO_CTX", "ARG_PTR_TO_MEM", "ARG_CONST_SIZE_OR_ZERO", "ARG_ANYTHING"}, Ret: "RET_INTEGER", GplOnly: true}, + "bpf_get_stack_proto_tp": &BpfHelperFunc{Num: 67, Enum: "BPF_FUNC_get_stack", Name: "bpf_get_stack_tp", Proto: "bpf_get_stack_proto_tp", Args: []string{"ARG_PTR_TO_CTX", "ARG_PTR_TO_UNINIT_MEM", "ARG_CONST_SIZE_OR_ZERO", "ARG_ANYTHING"}, Ret: "RET_INTEGER", GplOnly: true}, + "bpf_get_stack_proto_pe": &BpfHelperFunc{Num: 67, Enum: "BPF_FUNC_get_stack", Name: "bpf_get_stack_pe", Proto: "bpf_get_stack_proto_pe", Args: []string{"ARG_PTR_TO_CTX", "ARG_PTR_TO_UNINIT_MEM", "ARG_CONST_SIZE_OR_ZERO", "ARG_ANYTHING"}, Ret: "RET_INTEGER", GplOnly: true}, + "bpf_skb_load_bytes_relative_proto": &BpfHelperFunc{Num: 68, Enum: "BPF_FUNC_skb_load_bytes_relative", Name: "bpf_skb_load_bytes_relative", Proto: "bpf_skb_load_bytes_relative_proto", Args: []string{"ARG_PTR_TO_CTX", "ARG_ANYTHING", "ARG_PTR_TO_UNINIT_MEM", "ARG_CONST_SIZE", "ARG_ANYTHING"}, Ret: "RET_INTEGER"}, + "sk_reuseport_load_bytes_relative_proto": &BpfHelperFunc{Num: 68, Enum: "BPF_FUNC_skb_load_bytes_relative", Name: "sk_reuseport_load_bytes_relative", Proto: "sk_reuseport_load_bytes_relative_proto", Args: []string{"ARG_PTR_TO_CTX", "ARG_ANYTHING", "ARG_PTR_TO_UNINIT_MEM", "ARG_CONST_SIZE", "ARG_ANYTHING"}, Ret: "RET_INTEGER"}, + "bpf_skb_fib_lookup_proto": &BpfHelperFunc{Num: 69, Enum: "BPF_FUNC_fib_lookup", Name: "bpf_skb_fib_lookup", Proto: "bpf_skb_fib_lookup_proto", Args: []string{"ARG_PTR_TO_CTX", "ARG_PTR_TO_MEM", "ARG_CONST_SIZE", "ARG_ANYTHING"}, Ret: "RET_INTEGER", GplOnly: true}, + "bpf_xdp_fib_lookup_proto": &BpfHelperFunc{Num: 69, Enum: "BPF_FUNC_fib_lookup", Name: "bpf_xdp_fib_lookup", Proto: "bpf_xdp_fib_lookup_proto", Args: []string{"ARG_PTR_TO_CTX", "ARG_PTR_TO_MEM", "ARG_CONST_SIZE", "ARG_ANYTHING"}, Ret: "RET_INTEGER", GplOnly: true}, + "bpf_sock_hash_update_proto": &BpfHelperFunc{Num: 70, Enum: "BPF_FUNC_sock_hash_update", Name: "bpf_sock_hash_update", Proto: "bpf_sock_hash_update_proto", Args: []string{"ARG_PTR_TO_CTX", "ARG_CONST_MAP_PTR", "ARG_PTR_TO_MAP_KEY", "ARG_ANYTHING"}, Ret: "RET_INTEGER"}, + "bpf_msg_redirect_hash_proto": &BpfHelperFunc{Num: 71, Enum: "BPF_FUNC_msg_redirect_hash", Name: "bpf_msg_redirect_hash", Proto: "bpf_msg_redirect_hash_proto", Args: []string{"ARG_PTR_TO_CTX", "ARG_CONST_MAP_PTR", "ARG_PTR_TO_MAP_KEY", "ARG_ANYTHING"}, Ret: "RET_INTEGER"}, + "bpf_sk_redirect_hash_proto": &BpfHelperFunc{Num: 72, Enum: "BPF_FUNC_sk_redirect_hash", Name: "bpf_sk_redirect_hash", Proto: "bpf_sk_redirect_hash_proto", Args: []string{"ARG_PTR_TO_CTX", "ARG_CONST_MAP_PTR", "ARG_PTR_TO_MAP_KEY", "ARG_ANYTHING"}, Ret: "RET_INTEGER"}, + "bpf_lwt_in_push_encap_proto": &BpfHelperFunc{Num: 73, Enum: "BPF_FUNC_lwt_push_encap", Name: "bpf_lwt_in_push_encap", Proto: "bpf_lwt_in_push_encap_proto", Args: []string{"ARG_PTR_TO_CTX", "ARG_ANYTHING", "ARG_PTR_TO_MEM", "ARG_CONST_SIZE"}, Ret: "RET_INTEGER"}, + "bpf_lwt_xmit_push_encap_proto": &BpfHelperFunc{Num: 74, Enum: "BPF_FUNC_lwt_push_encap", Name: "bpf_lwt_xmit_push_encap", Proto: "bpf_lwt_xmit_push_encap_proto", Args: []string{"ARG_PTR_TO_CTX", "ARG_ANYTHING", "ARG_PTR_TO_MEM", "ARG_CONST_SIZE"}, Ret: "RET_INTEGER"}, + "bpf_lwt_seg6_store_bytes_proto": &BpfHelperFunc{Num: 75, Enum: "BPF_FUNC_lwt_seg6_store_bytes", Name: "bpf_lwt_seg6_store_bytes", Proto: "bpf_lwt_seg6_store_bytes_proto", Args: []string{"ARG_PTR_TO_CTX", "ARG_ANYTHING", "ARG_PTR_TO_MEM"}, Ret: "RET_INTEGER"}, + "bpf_lwt_seg6_adjust_srh_proto": &BpfHelperFunc{Num: 76, Enum: "BPF_FUNC_lwt_seg6_adjust_srh", Name: "bpf_lwt_seg6_adjust_srh", Proto: "bpf_lwt_seg6_adjust_srh_proto", Args: []string{"ARG_PTR_TO_CTX", "ARG_ANYTHING", "ARG_ANYTHING"}, Ret: "RET_INTEGER"}, + "bpf_lwt_seg6_action_proto": &BpfHelperFunc{Num: 77, Enum: "BPF_FUNC_lwt_seg6_action", Name: "bpf_lwt_seg6_action", Proto: "bpf_lwt_seg6_action_proto", Args: []string{"ARG_PTR_TO_CTX", "ARG_ANYTHING", "ARG_PTR_TO_MEM", "ARG_CONST_SIZE"}, Ret: "RET_INTEGER"}, + "rc_repeat_proto": &BpfHelperFunc{Num: 78, Enum: "BPF_FUNC_rc_repeat", Name: "bpf_rc_repeat", Proto: "rc_repeat_proto", Args: []string{"ARG_PTR_TO_CTX"}, Ret: "RET_INTEGER", GplOnly: true}, + "rc_keydown_proto": &BpfHelperFunc{Num: 79, Enum: "BPF_FUNC_rc_keydown", Name: "bpf_rc_keydown", Proto: "rc_keydown_proto", Args: []string{"ARG_PTR_TO_CTX", "ARG_ANYTHING", "ARG_ANYTHING", "ARG_ANYTHING"}, Ret: "RET_INTEGER", GplOnly: true}, + "bpf_skb_cgroup_id_proto": &BpfHelperFunc{Num: 80, Enum: "BPF_FUNC_skb_cgroup_id", Name: "bpf_skb_cgroup_id", Proto: "bpf_skb_cgroup_id_proto", Args: []string{"ARG_PTR_TO_CTX"}, Ret: "RET_INTEGER"}, + "bpf_get_current_cgroup_id_proto": &BpfHelperFunc{Num: 81, Enum: "BPF_FUNC_get_current_cgroup_id", Name: "bpf_get_current_cgroup_id", Proto: "bpf_get_current_cgroup_id_proto", Ret: "RET_INTEGER"}, + "bpf_get_local_storage_proto": &BpfHelperFunc{Num: 82, Enum: "BPF_FUNC_get_local_storage", Name: "bpf_get_local_storage", Proto: "bpf_get_local_storage_proto", Args: []string{"ARG_CONST_MAP_PTR", "ARG_ANYTHING"}, Ret: "RET_PTR_TO_MAP_VALUE"}, + "sk_select_reuseport_proto": &BpfHelperFunc{Num: 83, Enum: "BPF_FUNC_sk_select_reuseport", Name: "sk_select_reuseport", Proto: "sk_select_reuseport_proto", Args: []string{"ARG_PTR_TO_CTX", "ARG_CONST_MAP_PTR", "ARG_PTR_TO_MAP_KEY", "ARG_ANYTHING"}, Ret: "RET_INTEGER"}, + "bpf_skb_ancestor_cgroup_id_proto": &BpfHelperFunc{Num: 84, Enum: "BPF_FUNC_skb_ancestor_cgroup_id", Name: "bpf_skb_ancestor_cgroup_id", Proto: "bpf_skb_ancestor_cgroup_id_proto", Args: []string{"ARG_PTR_TO_CTX", "ARG_ANYTHING"}, Ret: "RET_INTEGER"}, + "bpf_sk_lookup_tcp_proto": &BpfHelperFunc{Num: 85, Enum: "BPF_FUNC_sk_lookup_tcp", Name: "bpf_sk_lookup_tcp", Proto: "bpf_sk_lookup_tcp_proto", Args: []string{"ARG_PTR_TO_CTX", "ARG_PTR_TO_MEM", "ARG_CONST_SIZE", "ARG_ANYTHING", "ARG_ANYTHING"}, Ret: "RET_PTR_TO_SOCKET_OR_NULL", PktAccess: true}, + "bpf_xdp_sk_lookup_tcp_proto": &BpfHelperFunc{Num: 85, Enum: "BPF_FUNC_sk_lookup_tcp", Name: "bpf_xdp_sk_lookup_tcp", Proto: "bpf_xdp_sk_lookup_tcp_proto", Args: []string{"ARG_PTR_TO_CTX", "ARG_PTR_TO_MEM", "ARG_CONST_SIZE", "ARG_ANYTHING", "ARG_ANYTHING"}, Ret: "RET_PTR_TO_SOCKET_OR_NULL", PktAccess: true}, + "bpf_sock_addr_sk_lookup_tcp_proto": &BpfHelperFunc{Num: 85, Enum: "BPF_FUNC_sk_lookup_tcp", Name: "bpf_sock_addr_sk_lookup_tcp", Proto: "bpf_sock_addr_sk_lookup_tcp_proto", Args: []string{"ARG_PTR_TO_CTX", "ARG_PTR_TO_MEM", "ARG_CONST_SIZE", "ARG_ANYTHING", "ARG_ANYTHING"}, Ret: "RET_PTR_TO_SOCKET_OR_NULL"}, + "bpf_sk_lookup_udp_proto": &BpfHelperFunc{Num: 85, Enum: "BPF_FUNC_sk_lookup_udp", Name: "bpf_sk_lookup_udp", Proto: "bpf_sk_lookup_udp_proto", Args: []string{"ARG_PTR_TO_CTX", "ARG_PTR_TO_MEM", "ARG_CONST_SIZE", "ARG_ANYTHING", "ARG_ANYTHING"}, Ret: "RET_PTR_TO_SOCKET_OR_NULL", PktAccess: true}, + "bpf_xdp_sk_lookup_udp_proto": &BpfHelperFunc{Num: 85, Enum: "BPF_FUNC_sk_lookup_udp", Name: "bpf_xdp_sk_lookup_udp", Proto: "bpf_xdp_sk_lookup_udp_proto", Args: []string{"ARG_PTR_TO_CTX", "ARG_PTR_TO_MEM", "ARG_CONST_SIZE", "ARG_ANYTHING", "ARG_ANYTHING"}, Ret: "RET_PTR_TO_SOCKET_OR_NULL", PktAccess: true}, + "bpf_sock_addr_sk_lookup_udp_proto": &BpfHelperFunc{Num: 85, Enum: "BPF_FUNC_sk_lookup_udp", Name: "bpf_sock_addr_sk_lookup_udp", Proto: "bpf_sock_addr_sk_lookup_udp_proto", Args: []string{"ARG_PTR_TO_CTX", "ARG_PTR_TO_MEM", "ARG_CONST_SIZE", "ARG_ANYTHING", "ARG_ANYTHING"}, Ret: "RET_PTR_TO_SOCKET_OR_NULL"}, + "bpf_sk_release_proto": &BpfHelperFunc{Num: 86, Enum: "BPF_FUNC_sk_release", Name: "bpf_sk_release", Proto: "bpf_sk_release_proto", Args: []string{"ARG_PTR_TO_BTF_ID_SOCK_COMMON"}, Ret: "RET_INTEGER"}, + "bpf_map_push_elem_proto": &BpfHelperFunc{Num: 87, Enum: "BPF_FUNC_map_push_elem", Name: "bpf_map_push_elem", Proto: "bpf_map_push_elem_proto", Args: []string{"ARG_CONST_MAP_PTR", "ARG_PTR_TO_MAP_VALUE", "ARG_ANYTHING"}, Ret: "RET_INTEGER", PktAccess: true}, + "bpf_map_pop_elem_proto": &BpfHelperFunc{Num: 88, Enum: "BPF_FUNC_map_pop_elem", Name: "bpf_map_pop_elem", Proto: "bpf_map_pop_elem_proto", Args: []string{"ARG_CONST_MAP_PTR", "ARG_PTR_TO_UNINIT_MAP_VALUE"}, Ret: "RET_INTEGER"}, + "bpf_map_peek_elem_proto": &BpfHelperFunc{Num: 89, Enum: "BPF_FUNC_map_peek_elem", Name: "bpf_map_peek_elem", Proto: "bpf_map_peek_elem_proto", Args: []string{"ARG_CONST_MAP_PTR", "ARG_PTR_TO_UNINIT_MAP_VALUE"}, Ret: "RET_INTEGER"}, + "bpf_msg_push_data_proto": &BpfHelperFunc{Num: 90, Enum: "BPF_FUNC_msg_push_data", Name: "bpf_msg_push_data", Proto: "bpf_msg_push_data_proto", Args: []string{"ARG_PTR_TO_CTX", "ARG_ANYTHING", "ARG_ANYTHING", "ARG_ANYTHING"}, Ret: "RET_INTEGER"}, + "bpf_msg_pop_data_proto": &BpfHelperFunc{Num: 91, Enum: "BPF_FUNC_msg_pop_data", Name: "bpf_msg_pop_data", Proto: "bpf_msg_pop_data_proto", Args: []string{"ARG_PTR_TO_CTX", "ARG_ANYTHING", "ARG_ANYTHING", "ARG_ANYTHING"}, Ret: "RET_INTEGER"}, + "rc_pointer_rel_proto": &BpfHelperFunc{Num: 92, Enum: "BPF_FUNC_rc_pointer_rel", Name: "bpf_rc_pointer_rel", Proto: "rc_pointer_rel_proto", Args: []string{"ARG_PTR_TO_CTX", "ARG_ANYTHING", "ARG_ANYTHING"}, Ret: "RET_INTEGER", GplOnly: true}, + "bpf_spin_lock_proto": &BpfHelperFunc{Num: 93, Enum: "BPF_FUNC_spin_lock", Name: "bpf_spin_lock", Proto: "bpf_spin_lock_proto", Args: []string{"ARG_PTR_TO_SPIN_LOCK"}, Ret: "RET_VOID"}, + "bpf_spin_unlock_proto": &BpfHelperFunc{Num: 94, Enum: "BPF_FUNC_spin_unlock", Name: "bpf_spin_unlock", Proto: "bpf_spin_unlock_proto", Args: []string{"ARG_PTR_TO_SPIN_LOCK"}, Ret: "RET_VOID"}, + "bpf_sk_fullsock_proto": &BpfHelperFunc{Num: 95, Enum: "BPF_FUNC_sk_fullsock", Name: "bpf_sk_fullsock", Proto: "bpf_sk_fullsock_proto", Args: []string{"ARG_PTR_TO_SOCK_COMMON"}, Ret: "RET_PTR_TO_SOCKET_OR_NULL"}, + "bpf_tcp_sock_proto": &BpfHelperFunc{Num: 96, Enum: "BPF_FUNC_tcp_sock", Name: "bpf_tcp_sock", Proto: "bpf_tcp_sock_proto", Args: []string{"ARG_PTR_TO_SOCK_COMMON"}, Ret: "RET_PTR_TO_TCP_SOCK_OR_NULL"}, + "bpf_skb_ecn_set_ce_proto": &BpfHelperFunc{Num: 97, Enum: "BPF_FUNC_skb_ecn_set_ce", Name: "bpf_skb_ecn_set_ce", Proto: "bpf_skb_ecn_set_ce_proto", Args: []string{"ARG_PTR_TO_CTX"}, Ret: "RET_INTEGER"}, + "bpf_get_listener_sock_proto": &BpfHelperFunc{Num: 98, Enum: "BPF_FUNC_get_listener_sock", Name: "bpf_get_listener_sock", Proto: "bpf_get_listener_sock_proto", Args: []string{"ARG_PTR_TO_SOCK_COMMON"}, Ret: "RET_PTR_TO_SOCKET_OR_NULL"}, + "bpf_skc_lookup_tcp_proto": &BpfHelperFunc{Num: 99, Enum: "BPF_FUNC_skc_lookup_tcp", Name: "bpf_skc_lookup_tcp", Proto: "bpf_skc_lookup_tcp_proto", Args: []string{"ARG_PTR_TO_CTX", "ARG_PTR_TO_MEM", "ARG_CONST_SIZE", "ARG_ANYTHING", "ARG_ANYTHING"}, Ret: "RET_PTR_TO_SOCK_COMMON_OR_NULL", PktAccess: true}, + "bpf_xdp_skc_lookup_tcp_proto": &BpfHelperFunc{Num: 99, Enum: "BPF_FUNC_skc_lookup_tcp", Name: "bpf_xdp_skc_lookup_tcp", Proto: "bpf_xdp_skc_lookup_tcp_proto", Args: []string{"ARG_PTR_TO_CTX", "ARG_PTR_TO_MEM", "ARG_CONST_SIZE", "ARG_ANYTHING", "ARG_ANYTHING"}, Ret: "RET_PTR_TO_SOCK_COMMON_OR_NULL", PktAccess: true}, + "bpf_sock_addr_skc_lookup_tcp_proto": &BpfHelperFunc{Num: 99, Enum: "BPF_FUNC_skc_lookup_tcp", Name: "bpf_sock_addr_skc_lookup_tcp", Proto: "bpf_sock_addr_skc_lookup_tcp_proto", Args: []string{"ARG_PTR_TO_CTX", "ARG_PTR_TO_MEM", "ARG_CONST_SIZE", "ARG_ANYTHING", "ARG_ANYTHING"}, Ret: "RET_PTR_TO_SOCK_COMMON_OR_NULL"}, + "bpf_tcp_check_syncookie_proto": &BpfHelperFunc{Num: 100, Enum: "BPF_FUNC_tcp_check_syncookie", Name: "bpf_tcp_check_syncookie", Proto: "bpf_tcp_check_syncookie_proto", Args: []string{"ARG_PTR_TO_BTF_ID_SOCK_COMMON", "ARG_PTR_TO_MEM", "ARG_CONST_SIZE", "ARG_PTR_TO_MEM", "ARG_CONST_SIZE"}, Ret: "RET_INTEGER", GplOnly: true, PktAccess: true}, + "bpf_sysctl_get_name_proto": &BpfHelperFunc{Num: 101, Enum: "BPF_FUNC_sysctl_get_name", Name: "bpf_sysctl_get_name", Proto: "bpf_sysctl_get_name_proto", Args: []string{"ARG_PTR_TO_CTX", "ARG_PTR_TO_MEM", "ARG_CONST_SIZE", "ARG_ANYTHING"}, Ret: "RET_INTEGER"}, + "bpf_sysctl_get_current_value_proto": &BpfHelperFunc{Num: 102, Enum: "BPF_FUNC_sysctl_get_current_value", Name: "bpf_sysctl_get_current_value", Proto: "bpf_sysctl_get_current_value_proto", Args: []string{"ARG_PTR_TO_CTX", "ARG_PTR_TO_UNINIT_MEM", "ARG_CONST_SIZE"}, Ret: "RET_INTEGER"}, + "bpf_sysctl_get_new_value_proto": &BpfHelperFunc{Num: 103, Enum: "BPF_FUNC_sysctl_get_new_value", Name: "bpf_sysctl_get_new_value", Proto: "bpf_sysctl_get_new_value_proto", Args: []string{"ARG_PTR_TO_CTX", "ARG_PTR_TO_UNINIT_MEM", "ARG_CONST_SIZE"}, Ret: "RET_INTEGER"}, + "bpf_sysctl_set_new_value_proto": &BpfHelperFunc{Num: 104, Enum: "BPF_FUNC_sysctl_set_new_value", Name: "bpf_sysctl_set_new_value", Proto: "bpf_sysctl_set_new_value_proto", Args: []string{"ARG_PTR_TO_CTX", "ARG_PTR_TO_MEM", "ARG_CONST_SIZE"}, Ret: "RET_INTEGER"}, + "bpf_strtol_proto": &BpfHelperFunc{Num: 105, Enum: "BPF_FUNC_strtol", Name: "bpf_strtol", Proto: "bpf_strtol_proto", Args: []string{"ARG_PTR_TO_MEM", "ARG_CONST_SIZE", "ARG_ANYTHING", "ARG_PTR_TO_LONG"}, Ret: "RET_INTEGER"}, + "bpf_strtoul_proto": &BpfHelperFunc{Num: 106, Enum: "BPF_FUNC_strtoul", Name: "bpf_strtoul", Proto: "bpf_strtoul_proto", Args: []string{"ARG_PTR_TO_MEM", "ARG_CONST_SIZE", "ARG_ANYTHING", "ARG_PTR_TO_LONG"}, Ret: "RET_INTEGER"}, + "bpf_sk_storage_get_proto": &BpfHelperFunc{Num: 107, Enum: "BPF_FUNC_sk_storage_get", Name: "bpf_sk_storage_get", Proto: "bpf_sk_storage_get_proto", Args: []string{"ARG_CONST_MAP_PTR", "ARG_PTR_TO_BTF_ID_SOCK_COMMON", "ARG_PTR_TO_MAP_VALUE_OR_NULL", "ARG_ANYTHING"}, Ret: "RET_PTR_TO_MAP_VALUE_OR_NULL"}, + "bpf_sk_storage_get_cg_sock_proto": &BpfHelperFunc{Num: 107, Enum: "BPF_FUNC_sk_storage_get", Name: "bpf_sk_storage_get", Proto: "bpf_sk_storage_get_cg_sock_proto", Args: []string{"ARG_CONST_MAP_PTR", "ARG_PTR_TO_CTX", "ARG_PTR_TO_MAP_VALUE_OR_NULL", "ARG_ANYTHING"}, Ret: "RET_PTR_TO_MAP_VALUE_OR_NULL"}, + "bpf_sk_storage_get_tracing_proto": &BpfHelperFunc{Num: 107, Enum: "BPF_FUNC_sk_storage_get", Name: "bpf_sk_storage_get_tracing", Proto: "bpf_sk_storage_get_tracing_proto", Args: []string{"ARG_CONST_MAP_PTR", "ARG_PTR_TO_BTF_ID", "ARG_PTR_TO_MAP_VALUE_OR_NULL", "ARG_ANYTHING"}, ArgBtfIds: []string{"struct sock_common"}, Ret: "RET_PTR_TO_MAP_VALUE_OR_NULL"}, + "bpf_sk_storage_delete_proto": &BpfHelperFunc{Num: 108, Enum: "BPF_FUNC_sk_storage_delete", Name: "bpf_sk_storage_delete", Proto: "bpf_sk_storage_delete_proto", Args: []string{"ARG_CONST_MAP_PTR", "ARG_PTR_TO_BTF_ID_SOCK_COMMON"}, Ret: "RET_INTEGER"}, + "bpf_sk_storage_delete_tracing_proto": &BpfHelperFunc{Num: 108, Enum: "BPF_FUNC_sk_storage_delete", Name: "bpf_sk_storage_delete_tracing", Proto: "bpf_sk_storage_delete_tracing_proto", Args: []string{"ARG_CONST_MAP_PTR", "ARG_PTR_TO_BTF_ID"}, ArgBtfIds: []string{"struct sock_common"}, Ret: "RET_INTEGER"}, + "bpf_send_signal_proto": &BpfHelperFunc{Num: 109, Enum: "BPF_FUNC_send_signal", Name: "bpf_send_signal", Proto: "bpf_send_signal_proto", Args: []string{"ARG_ANYTHING"}, Ret: "RET_INTEGER"}, + "bpf_tcp_gen_syncookie_proto": &BpfHelperFunc{Num: 110, Enum: "BPF_FUNC_tcp_gen_syncookie", Name: "bpf_tcp_gen_syncookie", Proto: "bpf_tcp_gen_syncookie_proto", Args: []string{"ARG_PTR_TO_BTF_ID_SOCK_COMMON", "ARG_PTR_TO_MEM", "ARG_CONST_SIZE", "ARG_PTR_TO_MEM", "ARG_CONST_SIZE"}, Ret: "RET_INTEGER", GplOnly: true, PktAccess: true}, + "bpf_skb_output_proto": &BpfHelperFunc{Num: 111, Enum: "BPF_FUNC_skb_output", Name: "bpf_skb_event_output", Proto: "bpf_skb_output_proto", Args: []string{"ARG_PTR_TO_BTF_ID", "ARG_CONST_MAP_PTR", "ARG_ANYTHING", "ARG_PTR_TO_MEM", "ARG_CONST_SIZE_OR_ZERO"}, ArgBtfIds: []string{"struct sk_buff"}, Ret: "RET_INTEGER", GplOnly: true}, + "bpf_probe_read_user_proto": &BpfHelperFunc{Num: 112, Enum: "BPF_FUNC_probe_read_user", Name: "bpf_probe_read_user", Proto: "bpf_probe_read_user_proto", Args: []string{"ARG_PTR_TO_UNINIT_MEM", "ARG_CONST_SIZE_OR_ZERO", "ARG_ANYTHING"}, Ret: "RET_INTEGER", GplOnly: true}, + "bpf_probe_read_kernel_proto": &BpfHelperFunc{Num: 113, Enum: "BPF_FUNC_probe_read_kernel", Name: "bpf_probe_read_kernel", Proto: "bpf_probe_read_kernel_proto", Args: []string{"ARG_PTR_TO_UNINIT_MEM", "ARG_CONST_SIZE_OR_ZERO", "ARG_ANYTHING"}, Ret: "RET_INTEGER", GplOnly: true}, + "bpf_probe_read_user_str_proto": &BpfHelperFunc{Num: 114, Enum: "BPF_FUNC_probe_read_user_str", Name: "bpf_probe_read_user_str", Proto: "bpf_probe_read_user_str_proto", Args: []string{"ARG_PTR_TO_UNINIT_MEM", "ARG_CONST_SIZE_OR_ZERO", "ARG_ANYTHING"}, Ret: "RET_INTEGER", GplOnly: true}, + "bpf_probe_read_kernel_str_proto": &BpfHelperFunc{Num: 115, Enum: "BPF_FUNC_probe_read_kernel_str", Name: "bpf_probe_read_kernel_str", Proto: "bpf_probe_read_kernel_str_proto", Args: []string{"ARG_PTR_TO_UNINIT_MEM", "ARG_CONST_SIZE_OR_ZERO", "ARG_ANYTHING"}, Ret: "RET_INTEGER", GplOnly: true}, + "bpf_tcp_send_ack_proto": &BpfHelperFunc{Num: 116, Enum: "BPF_FUNC_tcp_send_ack", Name: "bpf_tcp_send_ack", Proto: "bpf_tcp_send_ack_proto", Args: []string{"ARG_PTR_TO_BTF_ID", "ARG_ANYTHING"}, Ret: "RET_INTEGER"}, + "bpf_send_signal_thread_proto": &BpfHelperFunc{Num: 117, Enum: "BPF_FUNC_send_signal_thread", Name: "bpf_send_signal_thread", Proto: "bpf_send_signal_thread_proto", Args: []string{"ARG_ANYTHING"}, Ret: "RET_INTEGER"}, + "bpf_jiffies64_proto": &BpfHelperFunc{Num: 118, Enum: "BPF_FUNC_jiffies64", Name: "bpf_jiffies64", Proto: "bpf_jiffies64_proto", Ret: "RET_INTEGER"}, + "bpf_read_branch_records_proto": &BpfHelperFunc{Num: 119, Enum: "BPF_FUNC_read_branch_records", Name: "bpf_read_branch_records", Proto: "bpf_read_branch_records_proto", Args: []string{"ARG_PTR_TO_CTX", "ARG_PTR_TO_MEM_OR_NULL", "ARG_CONST_SIZE_OR_ZERO", "ARG_ANYTHING"}, Ret: "RET_INTEGER", GplOnly: true}, + "bpf_get_ns_current_pid_tgid_proto": &BpfHelperFunc{Num: 120, Enum: "BPF_FUNC_get_ns_current_pid_tgid", Name: "bpf_get_ns_current_pid_tgid", Proto: "bpf_get_ns_current_pid_tgid_proto", Args: []string{"ARG_ANYTHING", "ARG_ANYTHING", "ARG_PTR_TO_UNINIT_MEM", "ARG_CONST_SIZE"}, Ret: "RET_INTEGER"}, + "bpf_xdp_output_proto": &BpfHelperFunc{Num: 121, Enum: "BPF_FUNC_xdp_output", Name: "bpf_xdp_event_output", Proto: "bpf_xdp_output_proto", Args: []string{"ARG_PTR_TO_BTF_ID", "ARG_CONST_MAP_PTR", "ARG_ANYTHING", "ARG_PTR_TO_MEM", "ARG_CONST_SIZE_OR_ZERO"}, ArgBtfIds: []string{"struct xdp_buff"}, Ret: "RET_INTEGER", GplOnly: true}, + "bpf_get_netns_cookie_sock_addr_proto": &BpfHelperFunc{Num: 122, Enum: "BPF_FUNC_get_netns_cookie", Name: "bpf_get_netns_cookie_sock_addr", Proto: "bpf_get_netns_cookie_sock_addr_proto", Args: []string{"ARG_PTR_TO_CTX_OR_NULL"}, Ret: "RET_INTEGER"}, + "bpf_get_netns_cookie_sock_proto": &BpfHelperFunc{Num: 122, Enum: "BPF_FUNC_get_netns_cookie", Name: "bpf_get_netns_cookie_sock", Proto: "bpf_get_netns_cookie_sock_proto", Args: []string{"ARG_PTR_TO_CTX_OR_NULL"}, Ret: "RET_INTEGER"}, + "bpf_get_netns_cookie_sock_ops_proto": &BpfHelperFunc{Num: 122, Enum: "BPF_FUNC_get_netns_cookie", Name: "bpf_get_netns_cookie_sock_ops", Proto: "bpf_get_netns_cookie_sock_ops_proto", Args: []string{"ARG_PTR_TO_CTX_OR_NULL"}, Ret: "RET_INTEGER"}, + "bpf_get_netns_cookie_sk_msg_proto": &BpfHelperFunc{Num: 122, Enum: "BPF_FUNC_get_netns_cookie", Name: "bpf_get_netns_cookie_sk_msg", Proto: "bpf_get_netns_cookie_sk_msg_proto", Args: []string{"ARG_PTR_TO_CTX_OR_NULL"}, Ret: "RET_INTEGER"}, + "bpf_get_netns_cookie_sockopt_proto": &BpfHelperFunc{Num: 122, Enum: "BPF_FUNC_get_netns_cookie", Name: "bpf_get_netns_cookie_sockopt", Proto: "bpf_get_netns_cookie_sockopt_proto", Args: []string{"ARG_PTR_TO_CTX_OR_NULL"}, Ret: "RET_INTEGER"}, + "bpf_get_current_ancestor_cgroup_id_proto": &BpfHelperFunc{Num: 123, Enum: "BPF_FUNC_get_current_ancestor_cgroup_id", Name: "bpf_get_current_ancestor_cgroup_id", Proto: "bpf_get_current_ancestor_cgroup_id_proto", Args: []string{"ARG_ANYTHING"}, Ret: "RET_INTEGER"}, + "bpf_sk_assign_proto": &BpfHelperFunc{Num: 124, Enum: "BPF_FUNC_sk_assign", Name: "bpf_sk_assign", Proto: "bpf_sk_assign_proto", Args: []string{"ARG_PTR_TO_CTX", "ARG_PTR_TO_BTF_ID_SOCK_COMMON", "ARG_ANYTHING"}, Ret: "RET_INTEGER"}, + "bpf_sk_lookup_assign_proto": &BpfHelperFunc{Num: 124, Enum: "BPF_FUNC_sk_assign", Name: "bpf_sk_lookup_assign", Proto: "bpf_sk_lookup_assign_proto", Args: []string{"ARG_PTR_TO_CTX", "ARG_PTR_TO_SOCKET_OR_NULL", "ARG_ANYTHING"}, Ret: "RET_INTEGER"}, + "bpf_ktime_get_boot_ns_proto": &BpfHelperFunc{Num: 125, Enum: "BPF_FUNC_ktime_get_boot_ns", Name: "bpf_ktime_get_boot_ns", Proto: "bpf_ktime_get_boot_ns_proto", Ret: "RET_INTEGER"}, + "bpf_seq_printf_proto": &BpfHelperFunc{Num: 126, Enum: "BPF_FUNC_seq_printf", Name: "bpf_seq_printf", Proto: "bpf_seq_printf_proto", Args: []string{"ARG_PTR_TO_BTF_ID", "ARG_PTR_TO_MEM", "ARG_CONST_SIZE", "ARG_PTR_TO_MEM_OR_NULL", "ARG_CONST_SIZE_OR_ZERO"}, ArgBtfIds: []string{"struct seq_file"}, Ret: "RET_INTEGER", GplOnly: true}, + "bpf_seq_write_proto": &BpfHelperFunc{Num: 127, Enum: "BPF_FUNC_seq_write", Name: "bpf_seq_write", Proto: "bpf_seq_write_proto", Args: []string{"ARG_PTR_TO_BTF_ID", "ARG_PTR_TO_MEM", "ARG_CONST_SIZE_OR_ZERO"}, ArgBtfIds: []string{"struct seq_file"}, Ret: "RET_INTEGER", GplOnly: true}, + "bpf_sk_cgroup_id_proto": &BpfHelperFunc{Num: 128, Enum: "BPF_FUNC_sk_cgroup_id", Name: "bpf_sk_cgroup_id", Proto: "bpf_sk_cgroup_id_proto", Args: []string{"ARG_PTR_TO_BTF_ID_SOCK_COMMON"}, Ret: "RET_INTEGER"}, + "bpf_sk_ancestor_cgroup_id_proto": &BpfHelperFunc{Num: 129, Enum: "BPF_FUNC_sk_ancestor_cgroup_id", Name: "bpf_sk_ancestor_cgroup_id", Proto: "bpf_sk_ancestor_cgroup_id_proto", Args: []string{"ARG_PTR_TO_BTF_ID_SOCK_COMMON", "ARG_ANYTHING"}, Ret: "RET_INTEGER"}, + "bpf_ringbuf_output_proto": &BpfHelperFunc{Num: 130, Enum: "BPF_FUNC_ringbuf_output", Name: "bpf_ringbuf_output", Proto: "bpf_ringbuf_output_proto", Args: []string{"ARG_CONST_MAP_PTR", "ARG_PTR_TO_MEM", "ARG_CONST_SIZE_OR_ZERO", "ARG_ANYTHING"}, Ret: "RET_INTEGER"}, + "bpf_ringbuf_reserve_proto": &BpfHelperFunc{Num: 131, Enum: "BPF_FUNC_ringbuf_reserve", Name: "bpf_ringbuf_reserve", Proto: "bpf_ringbuf_reserve_proto", Args: []string{"ARG_CONST_MAP_PTR", "ARG_CONST_ALLOC_SIZE_OR_ZERO", "ARG_ANYTHING"}, Ret: "RET_PTR_TO_ALLOC_MEM_OR_NULL"}, + "bpf_ringbuf_submit_proto": &BpfHelperFunc{Num: 132, Enum: "BPF_FUNC_ringbuf_submit", Name: "bpf_ringbuf_submit", Proto: "bpf_ringbuf_submit_proto", Args: []string{"ARG_PTR_TO_ALLOC_MEM", "ARG_ANYTHING"}, Ret: "RET_VOID"}, + "bpf_ringbuf_discard_proto": &BpfHelperFunc{Num: 133, Enum: "BPF_FUNC_ringbuf_discard", Name: "bpf_ringbuf_discard", Proto: "bpf_ringbuf_discard_proto", Args: []string{"ARG_PTR_TO_ALLOC_MEM", "ARG_ANYTHING"}, Ret: "RET_VOID"}, + "bpf_ringbuf_query_proto": &BpfHelperFunc{Num: 134, Enum: "BPF_FUNC_ringbuf_query", Name: "bpf_ringbuf_query", Proto: "bpf_ringbuf_query_proto", Args: []string{"ARG_CONST_MAP_PTR", "ARG_ANYTHING"}, Ret: "RET_INTEGER"}, + "bpf_csum_level_proto": &BpfHelperFunc{Num: 135, Enum: "BPF_FUNC_csum_level", Name: "bpf_csum_level", Proto: "bpf_csum_level_proto", Args: []string{"ARG_PTR_TO_CTX", "ARG_ANYTHING"}, Ret: "RET_INTEGER"}, + "bpf_skc_to_tcp6_sock_proto": &BpfHelperFunc{Num: 136, Enum: "BPF_FUNC_skc_to_tcp6_sock", Name: "bpf_skc_to_tcp6_sock", Proto: "bpf_skc_to_tcp6_sock_proto", Args: []string{"ARG_PTR_TO_BTF_ID_SOCK_COMMON"}, Ret: "RET_PTR_TO_BTF_ID_OR_NULL", RetBtfId: "struct tcp6_sock"}, + "bpf_skc_to_tcp_sock_proto": &BpfHelperFunc{Num: 137, Enum: "BPF_FUNC_skc_to_tcp_sock", Name: "bpf_skc_to_tcp_sock", Proto: "bpf_skc_to_tcp_sock_proto", Args: []string{"ARG_PTR_TO_BTF_ID_SOCK_COMMON"}, Ret: "RET_PTR_TO_BTF_ID_OR_NULL", RetBtfId: "struct tcp_sock"}, + "bpf_skc_to_tcp_timewait_sock_proto": &BpfHelperFunc{Num: 138, Enum: "BPF_FUNC_skc_to_tcp_timewait_sock", Name: "bpf_skc_to_tcp_timewait_sock", Proto: "bpf_skc_to_tcp_timewait_sock_proto", Args: []string{"ARG_PTR_TO_BTF_ID_SOCK_COMMON"}, Ret: "RET_PTR_TO_BTF_ID_OR_NULL", RetBtfId: "struct tcp_timewait_sock"}, + "bpf_skc_to_tcp_request_sock_proto": &BpfHelperFunc{Num: 139, Enum: "BPF_FUNC_skc_to_tcp_request_sock", Name: "bpf_skc_to_tcp_request_sock", Proto: "bpf_skc_to_tcp_request_sock_proto", Args: []string{"ARG_PTR_TO_BTF_ID_SOCK_COMMON"}, Ret: "RET_PTR_TO_BTF_ID_OR_NULL", RetBtfId: "struct tcp_request_sock"}, + "bpf_skc_to_udp6_sock_proto": &BpfHelperFunc{Num: 140, Enum: "BPF_FUNC_skc_to_udp6_sock", Name: "bpf_skc_to_udp6_sock", Proto: "bpf_skc_to_udp6_sock_proto", Args: []string{"ARG_PTR_TO_BTF_ID_SOCK_COMMON"}, Ret: "RET_PTR_TO_BTF_ID_OR_NULL", RetBtfId: "struct udp6_sock"}, + "bpf_get_task_stack_proto": &BpfHelperFunc{Num: 141, Enum: "BPF_FUNC_get_task_stack", Name: "bpf_get_task_stack", Proto: "bpf_get_task_stack_proto", Args: []string{"ARG_PTR_TO_BTF_ID", "ARG_PTR_TO_UNINIT_MEM", "ARG_CONST_SIZE_OR_ZERO", "ARG_ANYTHING"}, ArgBtfIds: []string{"struct task_struct"}, Ret: "RET_INTEGER"}, + "bpf_sock_ops_load_hdr_opt_proto": &BpfHelperFunc{Num: 142, Enum: "BPF_FUNC_load_hdr_opt", Name: "bpf_sock_ops_load_hdr_opt", Proto: "bpf_sock_ops_load_hdr_opt_proto", Args: []string{"ARG_PTR_TO_CTX", "ARG_PTR_TO_MEM", "ARG_CONST_SIZE", "ARG_ANYTHING"}, Ret: "RET_INTEGER"}, + "bpf_sock_ops_store_hdr_opt_proto": &BpfHelperFunc{Num: 143, Enum: "BPF_FUNC_store_hdr_opt", Name: "bpf_sock_ops_store_hdr_opt", Proto: "bpf_sock_ops_store_hdr_opt_proto", Args: []string{"ARG_PTR_TO_CTX", "ARG_PTR_TO_MEM", "ARG_CONST_SIZE", "ARG_ANYTHING"}, Ret: "RET_INTEGER"}, + "bpf_sock_ops_reserve_hdr_opt_proto": &BpfHelperFunc{Num: 144, Enum: "BPF_FUNC_reserve_hdr_opt", Name: "bpf_sock_ops_reserve_hdr_opt", Proto: "bpf_sock_ops_reserve_hdr_opt_proto", Args: []string{"ARG_PTR_TO_CTX", "ARG_ANYTHING", "ARG_ANYTHING"}, Ret: "RET_INTEGER"}, + "bpf_inode_storage_get_proto": &BpfHelperFunc{Num: 145, Enum: "BPF_FUNC_inode_storage_get", Name: "bpf_inode_storage_get", Proto: "bpf_inode_storage_get_proto", Args: []string{"ARG_CONST_MAP_PTR", "ARG_PTR_TO_BTF_ID", "ARG_PTR_TO_MAP_VALUE_OR_NULL", "ARG_ANYTHING"}, ArgBtfIds: []string{"struct inode"}, Ret: "RET_PTR_TO_MAP_VALUE_OR_NULL"}, + "bpf_inode_storage_delete_proto": &BpfHelperFunc{Num: 146, Enum: "BPF_FUNC_inode_storage_delete", Name: "bpf_inode_storage_delete", Proto: "bpf_inode_storage_delete_proto", Args: []string{"ARG_CONST_MAP_PTR", "ARG_PTR_TO_BTF_ID"}, ArgBtfIds: []string{"struct inode"}, Ret: "RET_INTEGER"}, + "bpf_d_path_proto": &BpfHelperFunc{Num: 147, Enum: "BPF_FUNC_d_path", Name: "bpf_d_path", Proto: "bpf_d_path_proto", Args: []string{"ARG_PTR_TO_BTF_ID", "ARG_PTR_TO_MEM", "ARG_CONST_SIZE_OR_ZERO"}, ArgBtfIds: []string{"struct path"}, Ret: "RET_INTEGER"}, + "bpf_copy_from_user_proto": &BpfHelperFunc{Num: 148, Enum: "BPF_FUNC_copy_from_user", Name: "bpf_copy_from_user", Proto: "bpf_copy_from_user_proto", Args: []string{"ARG_PTR_TO_UNINIT_MEM", "ARG_CONST_SIZE_OR_ZERO", "ARG_ANYTHING"}, Ret: "RET_INTEGER"}, + "bpf_snprintf_btf_proto": &BpfHelperFunc{Num: 149, Enum: "BPF_FUNC_snprintf_btf", Name: "bpf_snprintf_btf", Proto: "bpf_snprintf_btf_proto", Args: []string{"ARG_PTR_TO_MEM", "ARG_CONST_SIZE", "ARG_PTR_TO_MEM", "ARG_CONST_SIZE", "ARG_ANYTHING"}, Ret: "RET_INTEGER"}, + "bpf_seq_printf_btf_proto": &BpfHelperFunc{Num: 150, Enum: "BPF_FUNC_seq_printf_btf", Name: "bpf_seq_printf_btf", Proto: "bpf_seq_printf_btf_proto", Args: []string{"ARG_PTR_TO_BTF_ID", "ARG_PTR_TO_MEM", "ARG_CONST_SIZE_OR_ZERO", "ARG_ANYTHING"}, ArgBtfIds: []string{"struct seq_file"}, Ret: "RET_INTEGER", GplOnly: true}, + "bpf_skb_cgroup_classid_proto": &BpfHelperFunc{Num: 151, Enum: "BPF_FUNC_skb_cgroup_classid", Name: "bpf_skb_cgroup_classid", Proto: "bpf_skb_cgroup_classid_proto", Args: []string{"ARG_PTR_TO_CTX"}, Ret: "RET_INTEGER"}, + "bpf_redirect_neigh_proto": &BpfHelperFunc{Num: 152, Enum: "BPF_FUNC_redirect_neigh", Name: "bpf_redirect_neigh", Proto: "bpf_redirect_neigh_proto", Args: []string{"ARG_ANYTHING", "ARG_PTR_TO_MEM_OR_NULL", "ARG_CONST_SIZE_OR_ZERO", "ARG_ANYTHING"}, Ret: "RET_INTEGER"}, + "bpf_per_cpu_ptr_proto": &BpfHelperFunc{Num: 153, Enum: "BPF_FUNC_per_cpu_ptr", Name: "bpf_per_cpu_ptr", Proto: "bpf_per_cpu_ptr_proto", Args: []string{"ARG_PTR_TO_PERCPU_BTF_ID", "ARG_ANYTHING"}, Ret: "RET_PTR_TO_MEM_OR_BTF_ID_OR_NULL"}, + "bpf_this_cpu_ptr_proto": &BpfHelperFunc{Num: 154, Enum: "BPF_FUNC_this_cpu_ptr", Name: "bpf_this_cpu_ptr", Proto: "bpf_this_cpu_ptr_proto", Args: []string{"ARG_PTR_TO_PERCPU_BTF_ID"}, Ret: "RET_PTR_TO_MEM_OR_BTF_ID"}, + "bpf_redirect_peer_proto": &BpfHelperFunc{Num: 155, Enum: "BPF_FUNC_redirect_peer", Name: "bpf_redirect_peer", Proto: "bpf_redirect_peer_proto", Args: []string{"ARG_ANYTHING", "ARG_ANYTHING"}, Ret: "RET_INTEGER"}, + "bpf_task_storage_get_proto": &BpfHelperFunc{Num: 156, Enum: "BPF_FUNC_task_storage_get", Name: "bpf_task_storage_get", Proto: "bpf_task_storage_get_proto", Args: []string{"ARG_CONST_MAP_PTR", "ARG_PTR_TO_BTF_ID", "ARG_PTR_TO_MAP_VALUE_OR_NULL", "ARG_ANYTHING"}, ArgBtfIds: []string{"struct task_struct"}, Ret: "RET_PTR_TO_MAP_VALUE_OR_NULL"}, + "bpf_task_storage_delete_proto": &BpfHelperFunc{Num: 157, Enum: "BPF_FUNC_task_storage_delete", Name: "bpf_task_storage_delete", Proto: "bpf_task_storage_delete_proto", Args: []string{"ARG_CONST_MAP_PTR", "ARG_PTR_TO_BTF_ID"}, ArgBtfIds: []string{"struct task_struct"}, Ret: "RET_INTEGER"}, + "bpf_get_current_task_btf_proto": &BpfHelperFunc{Num: 158, Enum: "BPF_FUNC_get_current_task_btf", Name: "bpf_get_current_task_btf", Proto: "bpf_get_current_task_btf_proto", Ret: "RET_PTR_TO_BTF_ID", RetBtfId: "struct task_struct", GplOnly: true}, + "bpf_bprm_opts_set_proto": &BpfHelperFunc{Num: 159, Enum: "BPF_FUNC_bprm_opts_set", Name: "bpf_bprm_opts_set", Proto: "bpf_bprm_opts_set_proto", Args: []string{"ARG_PTR_TO_BTF_ID", "ARG_ANYTHING"}, Ret: "RET_INTEGER"}, + "bpf_ktime_get_coarse_ns_proto": &BpfHelperFunc{Num: 160, Enum: "BPF_FUNC_ktime_get_coarse_ns", Name: "bpf_ktime_get_coarse_ns", Proto: "bpf_ktime_get_coarse_ns_proto", Ret: "RET_INTEGER"}, + "bpf_ima_inode_hash_proto": &BpfHelperFunc{Num: 161, Enum: "BPF_FUNC_ima_inode_hash", Name: "bpf_ima_inode_hash", Proto: "bpf_ima_inode_hash_proto", Args: []string{"ARG_PTR_TO_BTF_ID", "ARG_PTR_TO_UNINIT_MEM", "ARG_CONST_SIZE"}, Ret: "RET_INTEGER"}, + "bpf_sock_from_file_proto": &BpfHelperFunc{Num: 162, Enum: "BPF_FUNC_sock_from_file", Name: "bpf_sock_from_file", Proto: "bpf_sock_from_file_proto", Args: []string{"ARG_PTR_TO_BTF_ID"}, ArgBtfIds: []string{"struct file"}, Ret: "RET_PTR_TO_BTF_ID_OR_NULL", RetBtfId: "struct socket"}, + "bpf_skb_check_mtu_proto": &BpfHelperFunc{Num: 163, Enum: "BPF_FUNC_check_mtu", Name: "bpf_skb_check_mtu", Proto: "bpf_skb_check_mtu_proto", Args: []string{"ARG_PTR_TO_CTX", "ARG_ANYTHING", "ARG_PTR_TO_INT", "ARG_ANYTHING", "ARG_ANYTHING"}, Ret: "RET_INTEGER", GplOnly: true}, + "bpf_xdp_check_mtu_proto": &BpfHelperFunc{Num: 163, Enum: "BPF_FUNC_check_mtu", Name: "bpf_xdp_check_mtu", Proto: "bpf_xdp_check_mtu_proto", Args: []string{"ARG_PTR_TO_CTX", "ARG_ANYTHING", "ARG_PTR_TO_INT", "ARG_ANYTHING", "ARG_ANYTHING"}, Ret: "RET_INTEGER", GplOnly: true}, + "bpf_for_each_map_elem_proto": &BpfHelperFunc{Num: 164, Enum: "BPF_FUNC_for_each_map_elem", Name: "bpf_for_each_map_elem", Proto: "bpf_for_each_map_elem_proto", Args: []string{"ARG_CONST_MAP_PTR", "ARG_PTR_TO_FUNC", "ARG_PTR_TO_STACK_OR_NULL", "ARG_ANYTHING"}, Ret: "RET_INTEGER"}, + "bpf_snprintf_proto": &BpfHelperFunc{Num: 165, Enum: "BPF_FUNC_snprintf", Name: "bpf_snprintf", Proto: "bpf_snprintf_proto", Args: []string{"ARG_PTR_TO_MEM_OR_NULL", "ARG_CONST_SIZE_OR_ZERO", "ARG_PTR_TO_CONST_STR", "ARG_PTR_TO_MEM_OR_NULL", "ARG_CONST_SIZE_OR_ZERO"}, Ret: "RET_INTEGER", GplOnly: true}, + "bpf_sys_bpf_proto": &BpfHelperFunc{Num: 166, Enum: "BPF_FUNC_sys_bpf", Name: "bpf_sys_bpf", Proto: "bpf_sys_bpf_proto", Args: []string{"ARG_ANYTHING", "ARG_PTR_TO_MEM", "ARG_CONST_SIZE"}, Ret: "RET_INTEGER"}, + "bpf_btf_find_by_name_kind_proto": &BpfHelperFunc{Num: 167, Enum: "BPF_FUNC_btf_find_by_name_kind", Name: "bpf_btf_find_by_name_kind", Proto: "bpf_btf_find_by_name_kind_proto", Args: []string{"ARG_PTR_TO_MEM", "ARG_CONST_SIZE", "ARG_ANYTHING", "ARG_ANYTHING"}, Ret: "RET_INTEGER"}, + "bpf_sys_close_proto": &BpfHelperFunc{Num: 168, Enum: "BPF_FUNC_sys_close", Name: "bpf_sys_close", Proto: "bpf_sys_close_proto", Args: []string{"ARG_ANYTHING"}, Ret: "RET_INTEGER"}, + "bpf_timer_init_proto": &BpfHelperFunc{Num: 169, Enum: "BPF_FUNC_timer_init", Name: "bpf_timer_init", Proto: "bpf_timer_init_proto", Args: []string{"ARG_PTR_TO_TIMER", "ARG_CONST_MAP_PTR", "ARG_ANYTHING"}, Ret: "RET_INTEGER", GplOnly: true}, + "bpf_timer_set_callback_proto": &BpfHelperFunc{Num: 170, Enum: "BPF_FUNC_timer_set_callback", Name: "bpf_timer_set_callback", Proto: "bpf_timer_set_callback_proto", Args: []string{"ARG_PTR_TO_TIMER", "ARG_PTR_TO_FUNC"}, Ret: "RET_INTEGER", GplOnly: true}, + "bpf_timer_start_proto": &BpfHelperFunc{Num: 171, Enum: "BPF_FUNC_timer_start", Name: "bpf_timer_start", Proto: "bpf_timer_start_proto", Args: []string{"ARG_PTR_TO_TIMER", "ARG_ANYTHING", "ARG_ANYTHING"}, Ret: "RET_INTEGER", GplOnly: true}, + "bpf_timer_cancel_proto": &BpfHelperFunc{Num: 172, Enum: "BPF_FUNC_timer_cancel", Name: "bpf_timer_cancel", Proto: "bpf_timer_cancel_proto", Args: []string{"ARG_PTR_TO_TIMER"}, Ret: "RET_INTEGER", GplOnly: true}, + "bpf_get_func_ip_proto_kprobe": &BpfHelperFunc{Num: 173, Enum: "BPF_FUNC_get_func_ip", Name: "bpf_get_func_ip_kprobe", Proto: "bpf_get_func_ip_proto_kprobe", Args: []string{"ARG_PTR_TO_CTX"}, Ret: "RET_INTEGER", GplOnly: true}, + "bpf_get_func_ip_proto_tracing": &BpfHelperFunc{Num: 173, Enum: "BPF_FUNC_get_func_ip", Name: "bpf_get_func_ip_tracing", Proto: "bpf_get_func_ip_proto_tracing", Args: []string{"ARG_PTR_TO_CTX"}, Ret: "RET_INTEGER", GplOnly: true}, + "bpf_get_attach_cookie_proto_trace": &BpfHelperFunc{Num: 174, Enum: "BPF_FUNC_get_attach_cookie", Name: "bpf_get_attach_cookie_trace", Proto: "bpf_get_attach_cookie_proto_trace", Args: []string{"ARG_PTR_TO_CTX"}, Ret: "RET_INTEGER"}, + "bpf_get_attach_cookie_proto_pe": &BpfHelperFunc{Num: 174, Enum: "BPF_FUNC_get_attach_cookie", Name: "bpf_get_attach_cookie_pe", Proto: "bpf_get_attach_cookie_proto_pe", Args: []string{"ARG_PTR_TO_CTX"}, Ret: "RET_INTEGER"}, + "bpf_task_pt_regs_proto": &BpfHelperFunc{Num: 175, Enum: "BPF_FUNC_task_pt_regs", Name: "bpf_task_pt_regs", Proto: "bpf_task_pt_regs_proto", Args: []string{"ARG_PTR_TO_BTF_ID"}, ArgBtfIds: []string{"struct task_struct"}, Ret: "RET_PTR_TO_BTF_ID", RetBtfId: "struct pt_regs", GplOnly: true}, +} + +var ProgTypeMap = map[BpfProgTypeEnum]*BpfProgTypeDef{ + BPF_PROG_TYPE_SOCK_OPS: &BpfProgTypeDef{ + Name: "sock_ops", + User: "struct bpf_sock_ops", + Kern: "struct bpf_sock_ops_kern", + Enum: BPF_PROG_TYPE_SOCK_OPS, + SecDefs: []SecDef{ + SecDef{"sockops", nil, false}, + }, + FuncProtos: []string{ + "bpf_sock_ops_setsockopt_proto", "bpf_sock_ops_getsockopt_proto", "bpf_sock_ops_cb_flags_set_proto", "bpf_sock_map_update_proto", + "bpf_sock_hash_update_proto", "bpf_get_socket_cookie_sock_ops_proto", "bpf_get_local_storage_proto", "bpf_event_output_data_proto", + "bpf_sk_storage_get_proto", "bpf_sk_storage_delete_proto", "bpf_get_netns_cookie_sock_ops_proto", "bpf_sock_ops_load_hdr_opt_proto", + "bpf_sock_ops_store_hdr_opt_proto", "bpf_sock_ops_reserve_hdr_opt_proto", "bpf_tcp_sock_proto", + //bpf_sk_base_func_proto + "bpf_skc_to_tcp6_sock_proto", "bpf_skc_to_tcp_sock_proto", "bpf_skc_to_tcp_timewait_sock_proto", "bpf_skc_to_tcp_request_sock_proto", + "bpf_skc_to_udp6_sock_proto", "bpf_ktime_get_coarse_ns_proto", + // bpf_base_func_proto + "bpf_map_lookup_elem_proto", "bpf_map_update_elem_proto", "bpf_map_delete_elem_proto", "bpf_map_push_elem_proto", + "bpf_map_pop_elem_proto", "bpf_map_peek_elem_proto", "bpf_get_prandom_u32_proto", "bpf_get_raw_smp_processor_id_proto", + "bpf_get_numa_node_id_proto", "bpf_tail_call_proto", "bpf_ktime_get_ns_proto", "bpf_ktime_get_boot_ns_proto", + "bpf_ringbuf_output_proto", "bpf_ringbuf_reserve_proto", "bpf_ringbuf_submit_proto", "bpf_ringbuf_discard_proto", + "bpf_ringbuf_query_proto", "bpf_for_each_map_elem_proto", "bpf_spin_lock_proto", "bpf_spin_unlock_proto", + "bpf_jiffies64_proto", "bpf_per_cpu_ptr_proto", "bpf_this_cpu_ptr_proto", "bpf_timer_init_proto", + "bpf_timer_set_callback_proto", "bpf_timer_start_proto", "bpf_timer_cancel_proto", "bpf_trace_printk_proto", + "bpf_get_current_task_proto", "bpf_get_current_task_btf_proto", "bpf_probe_read_user_proto", "bpf_probe_read_kernel_proto", + "bpf_probe_read_user_str_proto", "bpf_probe_read_kernel_str_proto", "bpf_snprintf_btf_proto", "bpf_snprintf_proto", + "bpf_task_pt_regs_proto", + }}, + BPF_PROG_TYPE_LIRC_MODE2: &BpfProgTypeDef{ + Name: "lirc_mode2", + User: "__u32", + Kern: "u32", + Enum: BPF_PROG_TYPE_LIRC_MODE2, + SecDefs: []SecDef{ + SecDef{"lirc_mode2", nil, false}, + }, + FuncProtos: []string{ + "rc_repeat_proto", "rc_keydown_proto", "rc_pointer_rel_proto", "bpf_map_lookup_elem_proto", + "bpf_map_update_elem_proto", "bpf_map_delete_elem_proto", "bpf_map_push_elem_proto", "bpf_map_pop_elem_proto", + "bpf_map_peek_elem_proto", "bpf_ktime_get_ns_proto", "bpf_ktime_get_boot_ns_proto", "bpf_tail_call_proto", + "bpf_get_prandom_u32_proto", + "bpf_trace_printk_proto", + }}, + BPF_PROG_TYPE_SK_REUSEPORT: &BpfProgTypeDef{ + Name: "sk_reuseport", + User: "struct sk_reuseport_md", + Kern: "struct sk_reuseport_kern", + Enum: BPF_PROG_TYPE_SK_REUSEPORT, + SecDefs: []SecDef{ + SecDef{"sk_reuseport/migrate", nil, false}, + SecDef{"sk_reuseport", nil, false}, + }, + FuncProtos: []string{ + "sk_select_reuseport_proto", "sk_reuseport_load_bytes_proto", "sk_reuseport_load_bytes_relative_proto", "bpf_get_socket_ptr_cookie_proto", + "bpf_ktime_get_coarse_ns_proto", + //bpf_base_func_proto + "bpf_map_lookup_elem_proto", "bpf_map_update_elem_proto", "bpf_map_delete_elem_proto", "bpf_map_push_elem_proto", + "bpf_map_pop_elem_proto", "bpf_map_peek_elem_proto", "bpf_get_prandom_u32_proto", "bpf_get_raw_smp_processor_id_proto", + "bpf_get_numa_node_id_proto", "bpf_tail_call_proto", "bpf_ktime_get_ns_proto", "bpf_ktime_get_boot_ns_proto", + "bpf_ringbuf_output_proto", "bpf_ringbuf_reserve_proto", "bpf_ringbuf_submit_proto", "bpf_ringbuf_discard_proto", + "bpf_ringbuf_query_proto", "bpf_for_each_map_elem_proto", "bpf_spin_lock_proto", "bpf_spin_unlock_proto", + "bpf_jiffies64_proto", "bpf_per_cpu_ptr_proto", "bpf_this_cpu_ptr_proto", "bpf_timer_init_proto", + "bpf_timer_set_callback_proto", "bpf_timer_start_proto", "bpf_timer_cancel_proto", "bpf_trace_printk_proto", + "bpf_get_current_task_proto", "bpf_get_current_task_btf_proto", "bpf_probe_read_user_proto", "bpf_probe_read_kernel_proto", + "bpf_probe_read_user_str_proto", "bpf_probe_read_kernel_str_proto", "bpf_snprintf_btf_proto", "bpf_snprintf_proto", + "bpf_task_pt_regs_proto", + }}, + BPF_PROG_TYPE_SK_MSG: &BpfProgTypeDef{ + Name: "sk_msg", + User: "struct sk_msg_md", + Kern: "struct sk_msg", + Enum: BPF_PROG_TYPE_SK_MSG, + SecDefs: []SecDef{ + SecDef{"sk_msg", nil, false}, + }, + FuncProtos: []string{ + "bpf_msg_redirect_map_proto", "bpf_msg_redirect_hash_proto", "bpf_msg_apply_bytes_proto", "bpf_msg_cork_bytes_proto", + "bpf_msg_pull_data_proto", "bpf_msg_push_data_proto", "bpf_msg_pop_data_proto", "bpf_event_output_data_proto", + "bpf_get_current_uid_gid_proto", "bpf_get_current_pid_tgid_proto", "bpf_sk_storage_get_proto", "bpf_sk_storage_delete_proto", + "bpf_get_netns_cookie_sk_msg_proto", "bpf_get_current_cgroup_id_proto", "bpf_get_current_ancestor_cgroup_id_proto", "bpf_get_cgroup_classid_curr_proto", + //bpf_sk_base_func_proto + "bpf_skc_to_tcp6_sock_proto", "bpf_skc_to_tcp_sock_proto", "bpf_skc_to_tcp_timewait_sock_proto", "bpf_skc_to_tcp_request_sock_proto", + "bpf_skc_to_udp6_sock_proto", "bpf_ktime_get_coarse_ns_proto", + // bpf_base_func_proto + "bpf_map_lookup_elem_proto", "bpf_map_update_elem_proto", "bpf_map_delete_elem_proto", "bpf_map_push_elem_proto", + "bpf_map_pop_elem_proto", "bpf_map_peek_elem_proto", "bpf_get_prandom_u32_proto", "bpf_get_raw_smp_processor_id_proto", + "bpf_get_numa_node_id_proto", "bpf_tail_call_proto", "bpf_ktime_get_ns_proto", "bpf_ktime_get_boot_ns_proto", + "bpf_ringbuf_output_proto", "bpf_ringbuf_reserve_proto", "bpf_ringbuf_submit_proto", "bpf_ringbuf_discard_proto", + "bpf_ringbuf_query_proto", "bpf_for_each_map_elem_proto", "bpf_spin_lock_proto", "bpf_spin_unlock_proto", + "bpf_jiffies64_proto", "bpf_per_cpu_ptr_proto", "bpf_this_cpu_ptr_proto", "bpf_timer_init_proto", + "bpf_timer_set_callback_proto", "bpf_timer_start_proto", "bpf_timer_cancel_proto", "bpf_trace_printk_proto", + "bpf_get_current_task_proto", "bpf_get_current_task_btf_proto", "bpf_probe_read_user_proto", "bpf_probe_read_kernel_proto", + "bpf_probe_read_user_str_proto", "bpf_probe_read_kernel_str_proto", "bpf_snprintf_btf_proto", "bpf_snprintf_proto", + "bpf_task_pt_regs_proto", + }}, + BPF_PROG_TYPE_FLOW_DISSECTOR: &BpfProgTypeDef{ + Name: "flow_dissector", + User: "struct __sk_buff", + Kern: "struct bpf_flow_dissector", + Enum: BPF_PROG_TYPE_FLOW_DISSECTOR, + SecDefs: []SecDef{ + SecDef{"flow_dissector", nil, false}, + }, + FuncProtos: []string{ + "bpf_flow_dissector_load_bytes_proto", + //bpf_sk_base_func_proto + "bpf_skc_to_tcp6_sock_proto", "bpf_skc_to_tcp_sock_proto", "bpf_skc_to_tcp_timewait_sock_proto", "bpf_skc_to_tcp_request_sock_proto", + "bpf_skc_to_udp6_sock_proto", "bpf_ktime_get_coarse_ns_proto", + // bpf_base_func_proto + "bpf_map_lookup_elem_proto", "bpf_map_update_elem_proto", "bpf_map_delete_elem_proto", "bpf_map_push_elem_proto", + "bpf_map_pop_elem_proto", "bpf_map_peek_elem_proto", "bpf_get_prandom_u32_proto", "bpf_get_raw_smp_processor_id_proto", + "bpf_get_numa_node_id_proto", "bpf_tail_call_proto", "bpf_ktime_get_ns_proto", "bpf_ktime_get_boot_ns_proto", + "bpf_ringbuf_output_proto", "bpf_ringbuf_reserve_proto", "bpf_ringbuf_submit_proto", "bpf_ringbuf_discard_proto", + "bpf_ringbuf_query_proto", "bpf_for_each_map_elem_proto", "bpf_spin_lock_proto", "bpf_spin_unlock_proto", + "bpf_jiffies64_proto", "bpf_per_cpu_ptr_proto", "bpf_this_cpu_ptr_proto", "bpf_timer_init_proto", + "bpf_timer_set_callback_proto", "bpf_timer_start_proto", "bpf_timer_cancel_proto", "bpf_trace_printk_proto", + "bpf_get_current_task_proto", "bpf_get_current_task_btf_proto", "bpf_probe_read_user_proto", "bpf_probe_read_kernel_proto", + "bpf_probe_read_user_str_proto", "bpf_probe_read_kernel_str_proto", "bpf_snprintf_btf_proto", "bpf_snprintf_proto", + "bpf_task_pt_regs_proto", + }}, + BPF_PROG_TYPE_SOCKET_FILTER: &BpfProgTypeDef{ + Name: "sk_filter", + User: "struct __sk_buff", + Kern: "struct sk_buff", + Enum: BPF_PROG_TYPE_SOCKET_FILTER, + SecDefs: []SecDef{ + SecDef{"socket", nil, false}, + }, + FuncProtos: []string{ + "bpf_skb_load_bytes_proto", + "bpf_skb_load_bytes_relative_proto", + "bpf_get_socket_cookie_proto", + "bpf_get_socket_uid_proto", + "bpf_skb_event_output_proto", + //bpf_sk_base_func_proto + "bpf_skc_to_tcp6_sock_proto", "bpf_skc_to_tcp_sock_proto", "bpf_skc_to_tcp_timewait_sock_proto", "bpf_skc_to_tcp_request_sock_proto", + "bpf_skc_to_udp6_sock_proto", "bpf_ktime_get_coarse_ns_proto", + // bpf_base_func_proto + "bpf_map_lookup_elem_proto", "bpf_map_update_elem_proto", "bpf_map_delete_elem_proto", "bpf_map_push_elem_proto", + "bpf_map_pop_elem_proto", "bpf_map_peek_elem_proto", "bpf_get_prandom_u32_proto", "bpf_get_raw_smp_processor_id_proto", + "bpf_get_numa_node_id_proto", "bpf_tail_call_proto", "bpf_ktime_get_ns_proto", "bpf_ktime_get_boot_ns_proto", + "bpf_ringbuf_output_proto", "bpf_ringbuf_reserve_proto", "bpf_ringbuf_submit_proto", "bpf_ringbuf_discard_proto", + "bpf_ringbuf_query_proto", "bpf_for_each_map_elem_proto", "bpf_spin_lock_proto", "bpf_spin_unlock_proto", + "bpf_jiffies64_proto", "bpf_per_cpu_ptr_proto", "bpf_this_cpu_ptr_proto", "bpf_timer_init_proto", + "bpf_timer_set_callback_proto", "bpf_timer_start_proto", "bpf_timer_cancel_proto", "bpf_trace_printk_proto", + "bpf_get_current_task_proto", "bpf_get_current_task_btf_proto", "bpf_probe_read_user_proto", "bpf_probe_read_kernel_proto", + "bpf_probe_read_user_str_proto", "bpf_probe_read_kernel_str_proto", "bpf_snprintf_btf_proto", "bpf_snprintf_proto", + "bpf_task_pt_regs_proto", + }}, + BPF_PROG_TYPE_CGROUP_SKB: &BpfProgTypeDef{ + Name: "cg_skb", + User: "struct __sk_buff", + Kern: "struct sk_buff", + Enum: BPF_PROG_TYPE_CGROUP_SKB, + SecDefs: []SecDef{ + SecDef{"cgroup_skb/ingress", nil, false}, + SecDef{"cgroup_skb/egress", nil, false}, + SecDef{"cgroup/skb", nil, false}, + }, + FuncProtos: []string{ + "bpf_get_local_storage_proto", "bpf_sk_fullsock_proto", "bpf_sk_storage_get_proto", "bpf_sk_storage_delete_proto", + "bpf_skb_event_output_proto", "bpf_skb_cgroup_id_proto", "bpf_skb_ancestor_cgroup_id_proto", "bpf_sk_cgroup_id_proto", + "bpf_sk_ancestor_cgroup_id_proto", "bpf_sk_lookup_tcp_proto", "bpf_sk_lookup_udp_proto", "bpf_sk_release_proto", + "bpf_skc_lookup_tcp_proto", "bpf_tcp_sock_proto", "bpf_get_listener_sock_proto", "bpf_skb_ecn_set_ce_proto", + //sk_filter_func_proto + "bpf_skb_load_bytes_proto", "bpf_skb_load_bytes_relative_proto", "bpf_get_socket_cookie_proto", "bpf_get_socket_uid_proto", + "bpf_skb_event_output_proto", + // bpf_sk_base_func_proto + "bpf_skc_to_tcp6_sock_proto", "bpf_skc_to_tcp_sock_proto", "bpf_skc_to_tcp_timewait_sock_proto", "bpf_skc_to_tcp_request_sock_proto", + "bpf_skc_to_udp6_sock_proto", "bpf_ktime_get_coarse_ns_proto", + // bpf_base_func_proto + "bpf_map_lookup_elem_proto", "bpf_map_update_elem_proto", "bpf_map_delete_elem_proto", "bpf_map_push_elem_proto", + "bpf_map_pop_elem_proto", "bpf_map_peek_elem_proto", "bpf_get_prandom_u32_proto", "bpf_get_raw_smp_processor_id_proto", + "bpf_get_numa_node_id_proto", "bpf_tail_call_proto", "bpf_ktime_get_ns_proto", "bpf_ktime_get_boot_ns_proto", + "bpf_ringbuf_output_proto", "bpf_ringbuf_reserve_proto", "bpf_ringbuf_submit_proto", "bpf_ringbuf_discard_proto", + "bpf_ringbuf_query_proto", "bpf_for_each_map_elem_proto", "bpf_spin_lock_proto", "bpf_spin_unlock_proto", + "bpf_jiffies64_proto", "bpf_per_cpu_ptr_proto", "bpf_this_cpu_ptr_proto", "bpf_timer_init_proto", + "bpf_timer_set_callback_proto", "bpf_timer_start_proto", "bpf_timer_cancel_proto", "bpf_trace_printk_proto", + "bpf_get_current_task_proto", "bpf_get_current_task_btf_proto", "bpf_probe_read_user_proto", "bpf_probe_read_kernel_proto", + "bpf_probe_read_user_str_proto", "bpf_probe_read_kernel_str_proto", "bpf_snprintf_btf_proto", "bpf_snprintf_proto", + "bpf_task_pt_regs_proto", + }}, + BPF_PROG_TYPE_CGROUP_SOCK: &BpfProgTypeDef{ + Name: "cg_sock", + User: "struct bpf_sock", + Kern: "struct sock", + Enum: BPF_PROG_TYPE_CGROUP_SOCK, + SecDefs: []SecDef{ + SecDef{"cgroup/sock_create", nil, false}, + SecDef{"cgroup/sock_release", nil, false}, + SecDef{"cgroup/sock", nil, false}, + SecDef{"cgroup/post_bind4", nil, false}, + SecDef{"cgroup/post_bind6", nil, false}, + }, + FuncProtos: []string{ + "bpf_get_current_uid_gid_proto", "bpf_get_local_storage_proto", "bpf_get_socket_cookie_sock_proto", "bpf_get_netns_cookie_sock_proto", + "bpf_event_output_data_proto", "bpf_get_current_pid_tgid_proto", "bpf_get_current_comm_proto", "bpf_get_current_cgroup_id_proto", + "bpf_get_current_ancestor_cgroup_id_proto", "bpf_get_cgroup_classid_curr_proto", "bpf_sk_storage_get_cg_sock_proto", + "bpf_ktime_get_coarse_ns_proto", + //bpf_base_func_proto + "bpf_map_lookup_elem_proto", "bpf_map_update_elem_proto", "bpf_map_delete_elem_proto", "bpf_map_push_elem_proto", + "bpf_map_pop_elem_proto", "bpf_map_peek_elem_proto", "bpf_get_prandom_u32_proto", "bpf_get_raw_smp_processor_id_proto", + "bpf_get_numa_node_id_proto", "bpf_tail_call_proto", "bpf_ktime_get_ns_proto", "bpf_ktime_get_boot_ns_proto", + "bpf_ringbuf_output_proto", "bpf_ringbuf_reserve_proto", "bpf_ringbuf_submit_proto", "bpf_ringbuf_discard_proto", + "bpf_ringbuf_query_proto", "bpf_for_each_map_elem_proto", "bpf_spin_lock_proto", "bpf_spin_unlock_proto", + "bpf_jiffies64_proto", "bpf_per_cpu_ptr_proto", "bpf_this_cpu_ptr_proto", "bpf_timer_init_proto", + "bpf_timer_set_callback_proto", "bpf_timer_start_proto", "bpf_timer_cancel_proto", "bpf_trace_printk_proto", + "bpf_get_current_task_proto", "bpf_get_current_task_btf_proto", "bpf_probe_read_user_proto", "bpf_probe_read_kernel_proto", + "bpf_probe_read_user_str_proto", "bpf_probe_read_kernel_str_proto", "bpf_snprintf_btf_proto", "bpf_snprintf_proto", + "bpf_task_pt_regs_proto", + }}, + BPF_PROG_TYPE_LWT_IN: &BpfProgTypeDef{ + Name: "lwt_in", + User: "struct __sk_buff", + Kern: "struct sk_buff", + Enum: BPF_PROG_TYPE_LWT_IN, + SecDefs: []SecDef{ + SecDef{"lwt_in", nil, false}, + }, + FuncProtos: []string{ + "bpf_lwt_in_push_encap_proto", + //lwt_out_func_proto + "bpf_skb_load_bytes_proto", "bpf_skb_pull_data_proto", "bpf_csum_diff_proto", "bpf_get_cgroup_classid_proto", + "bpf_get_route_realm_proto", "bpf_get_hash_recalc_proto", "bpf_skb_event_output_proto", "bpf_get_smp_processor_id_proto", + "bpf_skb_under_cgroup_proto", + // bpf_sk_base_func_proto + "bpf_skc_to_tcp6_sock_proto", "bpf_skc_to_tcp_sock_proto", "bpf_skc_to_tcp_timewait_sock_proto", "bpf_skc_to_tcp_request_sock_proto", + "bpf_skc_to_udp6_sock_proto", "bpf_ktime_get_coarse_ns_proto", + // bpf_base_func_proto + "bpf_map_lookup_elem_proto", "bpf_map_update_elem_proto", "bpf_map_delete_elem_proto", "bpf_map_push_elem_proto", + "bpf_map_pop_elem_proto", "bpf_map_peek_elem_proto", "bpf_get_prandom_u32_proto", "bpf_get_raw_smp_processor_id_proto", + "bpf_get_numa_node_id_proto", "bpf_tail_call_proto", "bpf_ktime_get_ns_proto", "bpf_ktime_get_boot_ns_proto", + "bpf_ringbuf_output_proto", "bpf_ringbuf_reserve_proto", "bpf_ringbuf_submit_proto", "bpf_ringbuf_discard_proto", + "bpf_ringbuf_query_proto", "bpf_for_each_map_elem_proto", "bpf_spin_lock_proto", "bpf_spin_unlock_proto", + "bpf_jiffies64_proto", "bpf_per_cpu_ptr_proto", "bpf_this_cpu_ptr_proto", "bpf_timer_init_proto", + "bpf_timer_set_callback_proto", "bpf_timer_start_proto", "bpf_timer_cancel_proto", "bpf_trace_printk_proto", + "bpf_get_current_task_proto", "bpf_get_current_task_btf_proto", "bpf_probe_read_user_proto", "bpf_probe_read_kernel_proto", + "bpf_probe_read_user_str_proto", "bpf_probe_read_kernel_str_proto", "bpf_snprintf_btf_proto", "bpf_snprintf_proto", + "bpf_task_pt_regs_proto", + }}, + BPF_PROG_TYPE_LWT_SEG6LOCAL: &BpfProgTypeDef{ + Name: "lwt_seg6local", + User: "struct __sk_buff", + Kern: "struct sk_buff", + Enum: BPF_PROG_TYPE_LWT_SEG6LOCAL, + SecDefs: []SecDef{ + SecDef{"lwt_seg6local", nil, false}, + }, + FuncProtos: []string{ + "bpf_lwt_seg6_store_bytes_proto", "bpf_lwt_seg6_action_proto", "bpf_lwt_seg6_adjust_srh_proto", + //lwt_out_func_proto + "bpf_skb_load_bytes_proto", "bpf_skb_pull_data_proto", "bpf_csum_diff_proto", "bpf_get_cgroup_classid_proto", + "bpf_get_route_realm_proto", "bpf_get_hash_recalc_proto", "bpf_skb_event_output_proto", "bpf_get_smp_processor_id_proto", + "bpf_skb_under_cgroup_proto", + // bpf_sk_base_func_proto + "bpf_skc_to_tcp6_sock_proto", "bpf_skc_to_tcp_sock_proto", "bpf_skc_to_tcp_timewait_sock_proto", "bpf_skc_to_tcp_request_sock_proto", + "bpf_skc_to_udp6_sock_proto", "bpf_ktime_get_coarse_ns_proto", + // bpf_base_func_proto + "bpf_map_lookup_elem_proto", "bpf_map_update_elem_proto", "bpf_map_delete_elem_proto", "bpf_map_push_elem_proto", + "bpf_map_pop_elem_proto", "bpf_map_peek_elem_proto", "bpf_get_prandom_u32_proto", "bpf_get_raw_smp_processor_id_proto", + "bpf_get_numa_node_id_proto", "bpf_tail_call_proto", "bpf_ktime_get_ns_proto", "bpf_ktime_get_boot_ns_proto", + "bpf_ringbuf_output_proto", "bpf_ringbuf_reserve_proto", "bpf_ringbuf_submit_proto", "bpf_ringbuf_discard_proto", + "bpf_ringbuf_query_proto", "bpf_for_each_map_elem_proto", "bpf_spin_lock_proto", "bpf_spin_unlock_proto", + "bpf_jiffies64_proto", "bpf_per_cpu_ptr_proto", "bpf_this_cpu_ptr_proto", "bpf_timer_init_proto", + "bpf_timer_set_callback_proto", "bpf_timer_start_proto", "bpf_timer_cancel_proto", "bpf_trace_printk_proto", + "bpf_get_current_task_proto", "bpf_get_current_task_btf_proto", "bpf_probe_read_user_proto", "bpf_probe_read_kernel_proto", + "bpf_probe_read_user_str_proto", "bpf_probe_read_kernel_str_proto", "bpf_snprintf_btf_proto", "bpf_snprintf_proto", + "bpf_task_pt_regs_proto", + }}, + BPF_PROG_TYPE_SK_SKB: &BpfProgTypeDef{ + Name: "sk_skb", + User: "struct __sk_buff", + Kern: "struct sk_buff", + Enum: BPF_PROG_TYPE_SK_SKB, + SecDefs: []SecDef{ + SecDef{"sk_skb/stream_parser", nil, false}, + SecDef{"sk_skb/stream_verdict", nil, false}, + SecDef{"sk_skb", nil, false}, + }, + FuncProtos: []string{ + "bpf_skb_store_bytes_proto", "bpf_skb_load_bytes_proto", "sk_skb_pull_data_proto", "sk_skb_change_tail_proto", + "sk_skb_change_head_proto", "sk_skb_adjust_room_proto", "bpf_get_socket_cookie_proto", "bpf_get_socket_uid_proto", + "bpf_sk_redirect_map_proto", "bpf_sk_redirect_hash_proto", "bpf_skb_event_output_proto", "bpf_sk_lookup_tcp_proto", + "bpf_sk_lookup_udp_proto", "bpf_sk_release_proto", "bpf_skc_lookup_tcp_proto", + //bpf_sk_base_func_proto + "bpf_skc_to_tcp6_sock_proto", "bpf_skc_to_tcp_sock_proto", "bpf_skc_to_tcp_timewait_sock_proto", "bpf_skc_to_tcp_request_sock_proto", + "bpf_skc_to_udp6_sock_proto", "bpf_ktime_get_coarse_ns_proto", + // bpf_base_func_proto + "bpf_map_lookup_elem_proto", "bpf_map_update_elem_proto", "bpf_map_delete_elem_proto", "bpf_map_push_elem_proto", + "bpf_map_pop_elem_proto", "bpf_map_peek_elem_proto", "bpf_get_prandom_u32_proto", "bpf_get_raw_smp_processor_id_proto", + "bpf_get_numa_node_id_proto", "bpf_tail_call_proto", "bpf_ktime_get_ns_proto", "bpf_ktime_get_boot_ns_proto", + "bpf_ringbuf_output_proto", "bpf_ringbuf_reserve_proto", "bpf_ringbuf_submit_proto", "bpf_ringbuf_discard_proto", + "bpf_ringbuf_query_proto", "bpf_for_each_map_elem_proto", "bpf_spin_lock_proto", "bpf_spin_unlock_proto", + "bpf_jiffies64_proto", "bpf_per_cpu_ptr_proto", "bpf_this_cpu_ptr_proto", "bpf_timer_init_proto", + "bpf_timer_set_callback_proto", "bpf_timer_start_proto", "bpf_timer_cancel_proto", "bpf_trace_printk_proto", + "bpf_get_current_task_proto", "bpf_get_current_task_btf_proto", "bpf_probe_read_user_proto", "bpf_probe_read_kernel_proto", + "bpf_probe_read_user_str_proto", "bpf_probe_read_kernel_str_proto", "bpf_snprintf_btf_proto", "bpf_snprintf_proto", + "bpf_task_pt_regs_proto", + }}, + BPF_PROG_TYPE_RAW_TRACEPOINT: &BpfProgTypeDef{ + Name: "raw_tracepoint", + User: "struct bpf_raw_tracepoint_args", + Kern: "u64", + Enum: BPF_PROG_TYPE_RAW_TRACEPOINT, + SecDefs: []SecDef{ + SecDef{"raw_tracepoint/", GenRawTracepointEntry, false}, + SecDef{"raw_tp/", GenRawTracepointEntry, false}, + }, + FuncProtos: []string{ + "bpf_perf_event_output_proto_raw_tp", "bpf_get_stackid_proto_raw_tp", "bpf_get_stack_proto_raw_tp", + //bpf_tracing_func_proto + "bpf_map_lookup_elem_proto", "bpf_map_update_elem_proto", "bpf_map_delete_elem_proto", "bpf_map_push_elem_proto", + "bpf_map_pop_elem_proto", "bpf_map_peek_elem_proto", "bpf_ktime_get_ns_proto", "bpf_ktime_get_boot_ns_proto", + "bpf_tail_call_proto", "bpf_get_current_pid_tgid_proto", "bpf_get_current_task_proto", "bpf_get_current_task_btf_proto", + "bpf_task_pt_regs_proto", "bpf_get_current_uid_gid_proto", "bpf_get_current_comm_proto", "bpf_trace_printk_proto", + "bpf_get_smp_processor_id_proto", "bpf_get_numa_node_id_proto", "bpf_perf_event_read_proto", "bpf_current_task_under_cgroup_proto", + "bpf_get_prandom_u32_proto", "bpf_probe_write_user_proto", "bpf_probe_read_user_proto", "bpf_probe_read_kernel_proto", + "bpf_probe_read_user_str_proto", "bpf_probe_read_kernel_str_proto", "bpf_probe_read_compat_proto", "bpf_probe_read_compat_str_proto", + "bpf_get_current_cgroup_id_proto", "bpf_get_current_ancestor_cgroup_id_proto", "bpf_send_signal_proto", "bpf_send_signal_thread_proto", + "bpf_perf_event_read_value_proto", "bpf_get_ns_current_pid_tgid_proto", "bpf_ringbuf_output_proto", "bpf_ringbuf_reserve_proto", + "bpf_ringbuf_submit_proto", "bpf_ringbuf_discard_proto", "bpf_ringbuf_query_proto", "bpf_jiffies64_proto", + "bpf_get_task_stack_proto", "bpf_copy_from_user_proto", "bpf_snprintf_btf_proto", "bpf_per_cpu_ptr_proto", + "bpf_this_cpu_ptr_proto", "bpf_task_storage_get_proto", "bpf_task_storage_delete_proto", "bpf_for_each_map_elem_proto", + "bpf_snprintf_proto", /*"bpf_get_func_ip_proto_tracing",*/ "bpf_spin_lock_proto", "bpf_spin_unlock_proto", + "bpf_timer_init_proto", "bpf_timer_set_callback_proto", "bpf_timer_start_proto", "bpf_timer_cancel_proto", + }}, + BPF_PROG_TYPE_CGROUP_DEVICE: &BpfProgTypeDef{ + Name: "cg_dev", + User: "struct bpf_cgroup_dev_ctx", + Kern: "struct bpf_cgroup_dev_ctx", + Enum: BPF_PROG_TYPE_CGROUP_DEVICE, + SecDefs: []SecDef{ + SecDef{"cgroup/dev", nil, false}, + }, + FuncProtos: []string{ + "bpf_get_current_uid_gid_proto", "bpf_get_local_storage_proto", "bpf_get_current_cgroup_id_proto", "bpf_event_output_data_proto", + //bpf_base_func_proto + "bpf_map_lookup_elem_proto", "bpf_map_update_elem_proto", "bpf_map_delete_elem_proto", "bpf_map_push_elem_proto", + "bpf_map_pop_elem_proto", "bpf_map_peek_elem_proto", "bpf_get_prandom_u32_proto", "bpf_get_raw_smp_processor_id_proto", + "bpf_get_numa_node_id_proto", "bpf_tail_call_proto", "bpf_ktime_get_ns_proto", "bpf_ktime_get_boot_ns_proto", + "bpf_ringbuf_output_proto", "bpf_ringbuf_reserve_proto", "bpf_ringbuf_submit_proto", "bpf_ringbuf_discard_proto", + "bpf_ringbuf_query_proto", "bpf_for_each_map_elem_proto", "bpf_spin_lock_proto", "bpf_spin_unlock_proto", + "bpf_jiffies64_proto", "bpf_per_cpu_ptr_proto", "bpf_this_cpu_ptr_proto", "bpf_timer_init_proto", + "bpf_timer_set_callback_proto", "bpf_timer_start_proto", "bpf_timer_cancel_proto", "bpf_trace_printk_proto", + "bpf_get_current_task_proto", "bpf_get_current_task_btf_proto", "bpf_probe_read_user_proto", "bpf_probe_read_kernel_proto", + "bpf_probe_read_user_str_proto", "bpf_probe_read_kernel_str_proto", "bpf_snprintf_btf_proto", "bpf_snprintf_proto", + "bpf_task_pt_regs_proto", + }}, + BPF_PROG_TYPE_CGROUP_SOCKOPT: &BpfProgTypeDef{ + Name: "cg_sockopt", + User: "struct bpf_sockopt", + Kern: "struct bpf_sockopt_kern", + Enum: BPF_PROG_TYPE_CGROUP_SOCKOPT, + SecDefs: []SecDef{ + SecDef{"cgroup/getsockopt", nil, false}, + SecDef{"cgroup/setsockopt", nil, false}, + }, + FuncProtos: []string{ + "bpf_get_netns_cookie_sockopt_proto", "bpf_sk_storage_get_proto", "bpf_sk_storage_delete_proto", "bpf_sk_setsockopt_proto", + "bpf_sk_getsockopt_proto", "bpf_tcp_sock_proto", + //cgroup_base_func_proto + "bpf_get_current_uid_gid_proto", "bpf_get_local_storage_proto", "bpf_get_current_cgroup_id_proto", "bpf_event_output_data_proto", + // bpf_base_func_proto + "bpf_map_lookup_elem_proto", "bpf_map_update_elem_proto", "bpf_map_delete_elem_proto", "bpf_map_push_elem_proto", + "bpf_map_pop_elem_proto", "bpf_map_peek_elem_proto", "bpf_get_prandom_u32_proto", "bpf_get_raw_smp_processor_id_proto", + "bpf_get_numa_node_id_proto", "bpf_tail_call_proto", "bpf_ktime_get_ns_proto", "bpf_ktime_get_boot_ns_proto", + "bpf_ringbuf_output_proto", "bpf_ringbuf_reserve_proto", "bpf_ringbuf_submit_proto", "bpf_ringbuf_discard_proto", + "bpf_ringbuf_query_proto", "bpf_for_each_map_elem_proto", "bpf_spin_lock_proto", "bpf_spin_unlock_proto", + "bpf_jiffies64_proto", "bpf_per_cpu_ptr_proto", "bpf_this_cpu_ptr_proto", "bpf_timer_init_proto", + "bpf_timer_set_callback_proto", "bpf_timer_start_proto", "bpf_timer_cancel_proto", "bpf_trace_printk_proto", + "bpf_get_current_task_proto", "bpf_get_current_task_btf_proto", "bpf_probe_read_user_proto", "bpf_probe_read_kernel_proto", + "bpf_probe_read_user_str_proto", "bpf_probe_read_kernel_str_proto", "bpf_snprintf_btf_proto", "bpf_snprintf_proto", + "bpf_task_pt_regs_proto", + }}, + BPF_PROG_TYPE_SK_LOOKUP: &BpfProgTypeDef{ + Name: "sk_lookup", + User: "struct bpf_sk_lookup", + Kern: "struct bpf_sk_lookup_kern", + Enum: BPF_PROG_TYPE_SK_LOOKUP, + SecDefs: []SecDef{ + SecDef{"sk_lookup", nil, false}, + }, + FuncProtos: []string{ + "bpf_event_output_data_proto", "bpf_sk_lookup_assign_proto", "bpf_sk_release_proto", + //bpf_sk_base_func_proto + "bpf_skc_to_tcp6_sock_proto", "bpf_skc_to_tcp_sock_proto", "bpf_skc_to_tcp_timewait_sock_proto", "bpf_skc_to_tcp_request_sock_proto", + "bpf_skc_to_udp6_sock_proto", "bpf_ktime_get_coarse_ns_proto", + // bpf_base_func_proto + "bpf_map_lookup_elem_proto", "bpf_map_update_elem_proto", "bpf_map_delete_elem_proto", "bpf_map_push_elem_proto", + "bpf_map_pop_elem_proto", "bpf_map_peek_elem_proto", "bpf_get_prandom_u32_proto", "bpf_get_raw_smp_processor_id_proto", + "bpf_get_numa_node_id_proto", "bpf_tail_call_proto", "bpf_ktime_get_ns_proto", "bpf_ktime_get_boot_ns_proto", + "bpf_ringbuf_output_proto", "bpf_ringbuf_reserve_proto", "bpf_ringbuf_submit_proto", "bpf_ringbuf_discard_proto", + "bpf_ringbuf_query_proto", "bpf_for_each_map_elem_proto", "bpf_spin_lock_proto", "bpf_spin_unlock_proto", + "bpf_jiffies64_proto", "bpf_per_cpu_ptr_proto", "bpf_this_cpu_ptr_proto", "bpf_timer_init_proto", + "bpf_timer_set_callback_proto", "bpf_timer_start_proto", "bpf_timer_cancel_proto", "bpf_trace_printk_proto", + "bpf_get_current_task_proto", "bpf_get_current_task_btf_proto", "bpf_probe_read_user_proto", "bpf_probe_read_kernel_proto", + "bpf_probe_read_user_str_proto", "bpf_probe_read_kernel_str_proto", "bpf_snprintf_btf_proto", "bpf_snprintf_proto", + "bpf_task_pt_regs_proto", + }}, + BPF_PROG_TYPE_SCHED_CLS: &BpfProgTypeDef{ + Name: "tc_cls", + User: "struct __sk_buff", + Kern: "struct sk_buff", + Enum: BPF_PROG_TYPE_SCHED_CLS, + SecDefs: []SecDef{ + SecDef{"tc", nil, false}, + SecDef{"classifier", nil, false}, + }, + FuncProtos: []string{ + "bpf_skb_store_bytes_proto", "bpf_skb_load_bytes_proto", "bpf_skb_load_bytes_relative_proto", "bpf_skb_pull_data_proto", + "bpf_csum_diff_proto", "bpf_csum_update_proto", "bpf_csum_level_proto", "bpf_l3_csum_replace_proto", + "bpf_l4_csum_replace_proto", "bpf_clone_redirect_proto", "bpf_get_cgroup_classid_proto", "bpf_skb_vlan_push_proto", + "bpf_skb_vlan_pop_proto", "bpf_skb_change_proto_proto", "bpf_skb_change_type_proto", "bpf_skb_adjust_room_proto", + "bpf_skb_change_tail_proto", "bpf_skb_change_head_proto", "bpf_skb_get_tunnel_key_proto", "bpf_skb_set_tunnel_key_proto", + "bpf_skb_get_tunnel_opt_proto", "bpf_skb_set_tunnel_opt_proto", "bpf_redirect_proto", "bpf_redirect_neigh_proto", + "bpf_redirect_peer_proto", "bpf_get_route_realm_proto", "bpf_get_hash_recalc_proto", "bpf_set_hash_invalid_proto", + "bpf_set_hash_proto", "bpf_skb_event_output_proto", "bpf_get_smp_processor_id_proto", "bpf_skb_under_cgroup_proto", + "bpf_get_socket_cookie_proto", "bpf_get_socket_uid_proto", "bpf_skb_fib_lookup_proto", "bpf_skb_check_mtu_proto", + "bpf_sk_fullsock_proto", "bpf_sk_storage_get_proto", "bpf_sk_storage_delete_proto", "bpf_skb_get_xfrm_state_proto", + "bpf_skb_cgroup_classid_proto", "bpf_skb_cgroup_id_proto", "bpf_skb_ancestor_cgroup_id_proto", "bpf_sk_lookup_tcp_proto", + "bpf_sk_lookup_udp_proto", "bpf_sk_release_proto", "bpf_tcp_sock_proto", "bpf_get_listener_sock_proto", + "bpf_skc_lookup_tcp_proto", "bpf_tcp_check_syncookie_proto", "bpf_skb_ecn_set_ce_proto", "bpf_tcp_gen_syncookie_proto", + "bpf_sk_assign_proto", + //bpf_sk_base_func_proto + "bpf_skc_to_tcp6_sock_proto", "bpf_skc_to_tcp_sock_proto", "bpf_skc_to_tcp_timewait_sock_proto", "bpf_skc_to_tcp_request_sock_proto", + "bpf_skc_to_udp6_sock_proto", "bpf_ktime_get_coarse_ns_proto", + // bpf_base_func_proto + "bpf_map_lookup_elem_proto", "bpf_map_update_elem_proto", "bpf_map_delete_elem_proto", "bpf_map_push_elem_proto", + "bpf_map_pop_elem_proto", "bpf_map_peek_elem_proto", "bpf_get_prandom_u32_proto", "bpf_get_raw_smp_processor_id_proto", + "bpf_get_numa_node_id_proto", "bpf_tail_call_proto", "bpf_ktime_get_ns_proto", "bpf_ktime_get_boot_ns_proto", + "bpf_ringbuf_output_proto", "bpf_ringbuf_reserve_proto", "bpf_ringbuf_submit_proto", "bpf_ringbuf_discard_proto", + "bpf_ringbuf_query_proto", "bpf_for_each_map_elem_proto", "bpf_spin_lock_proto", "bpf_spin_unlock_proto", + "bpf_jiffies64_proto", "bpf_per_cpu_ptr_proto", "bpf_this_cpu_ptr_proto", "bpf_timer_init_proto", + "bpf_timer_set_callback_proto", "bpf_timer_start_proto", "bpf_timer_cancel_proto", "bpf_trace_printk_proto", + "bpf_get_current_task_proto", "bpf_get_current_task_btf_proto", "bpf_probe_read_user_proto", "bpf_probe_read_kernel_proto", + "bpf_probe_read_user_str_proto", "bpf_probe_read_kernel_str_proto", "bpf_snprintf_btf_proto", "bpf_snprintf_proto", + "bpf_task_pt_regs_proto", + }}, + BPF_PROG_TYPE_SCHED_ACT: &BpfProgTypeDef{ + Name: "tc_act", + User: "struct __sk_buff", + Kern: "struct sk_buff", + Enum: BPF_PROG_TYPE_SCHED_ACT, + SecDefs: []SecDef{ + SecDef{"action", nil, false}, + }, + FuncProtos: []string{ + "bpf_skb_store_bytes_proto", "bpf_skb_load_bytes_proto", "bpf_skb_load_bytes_relative_proto", "bpf_skb_pull_data_proto", + "bpf_csum_diff_proto", "bpf_csum_update_proto", "bpf_csum_level_proto", "bpf_l3_csum_replace_proto", + "bpf_l4_csum_replace_proto", "bpf_clone_redirect_proto", "bpf_get_cgroup_classid_proto", "bpf_skb_vlan_push_proto", + "bpf_skb_vlan_pop_proto", "bpf_skb_change_proto_proto", "bpf_skb_change_type_proto", "bpf_skb_adjust_room_proto", + "bpf_skb_change_tail_proto", "bpf_skb_change_head_proto", "bpf_skb_get_tunnel_key_proto", "bpf_skb_set_tunnel_key_proto", + "bpf_skb_get_tunnel_opt_proto", "bpf_skb_set_tunnel_opt_proto", "bpf_redirect_proto", "bpf_redirect_neigh_proto", + "bpf_redirect_peer_proto", "bpf_get_route_realm_proto", "bpf_get_hash_recalc_proto", "bpf_set_hash_invalid_proto", + "bpf_set_hash_proto", "bpf_skb_event_output_proto", "bpf_get_smp_processor_id_proto", "bpf_skb_under_cgroup_proto", + "bpf_get_socket_cookie_proto", "bpf_get_socket_uid_proto", "bpf_skb_fib_lookup_proto", "bpf_skb_check_mtu_proto", + "bpf_sk_fullsock_proto", "bpf_sk_storage_get_proto", "bpf_sk_storage_delete_proto", "bpf_skb_get_xfrm_state_proto", + "bpf_skb_cgroup_classid_proto", "bpf_skb_cgroup_id_proto", "bpf_skb_ancestor_cgroup_id_proto", "bpf_sk_lookup_tcp_proto", + "bpf_sk_lookup_udp_proto", "bpf_sk_release_proto", "bpf_tcp_sock_proto", "bpf_get_listener_sock_proto", + "bpf_skc_lookup_tcp_proto", "bpf_tcp_check_syncookie_proto", "bpf_skb_ecn_set_ce_proto", "bpf_tcp_gen_syncookie_proto", + "bpf_sk_assign_proto", + //bpf_sk_base_func_proto + "bpf_skc_to_tcp6_sock_proto", "bpf_skc_to_tcp_sock_proto", "bpf_skc_to_tcp_timewait_sock_proto", "bpf_skc_to_tcp_request_sock_proto", + "bpf_skc_to_udp6_sock_proto", "bpf_ktime_get_coarse_ns_proto", + // bpf_base_func_proto + "bpf_map_lookup_elem_proto", "bpf_map_update_elem_proto", "bpf_map_delete_elem_proto", "bpf_map_push_elem_proto", + "bpf_map_pop_elem_proto", "bpf_map_peek_elem_proto", "bpf_get_prandom_u32_proto", "bpf_get_raw_smp_processor_id_proto", + "bpf_get_numa_node_id_proto", "bpf_tail_call_proto", "bpf_ktime_get_ns_proto", "bpf_ktime_get_boot_ns_proto", + "bpf_ringbuf_output_proto", "bpf_ringbuf_reserve_proto", "bpf_ringbuf_submit_proto", "bpf_ringbuf_discard_proto", + "bpf_ringbuf_query_proto", "bpf_for_each_map_elem_proto", "bpf_spin_lock_proto", "bpf_spin_unlock_proto", + "bpf_jiffies64_proto", "bpf_per_cpu_ptr_proto", "bpf_this_cpu_ptr_proto", "bpf_timer_init_proto", + "bpf_timer_set_callback_proto", "bpf_timer_start_proto", "bpf_timer_cancel_proto", "bpf_trace_printk_proto", + "bpf_get_current_task_proto", "bpf_get_current_task_btf_proto", "bpf_probe_read_user_proto", "bpf_probe_read_kernel_proto", + "bpf_probe_read_user_str_proto", "bpf_probe_read_kernel_str_proto", "bpf_snprintf_btf_proto", "bpf_snprintf_proto", + "bpf_task_pt_regs_proto", + }}, + BPF_PROG_TYPE_CGROUP_SOCK_ADDR: &BpfProgTypeDef{ + Name: "cg_sock_addr", + User: "struct bpf_sock_addr", + Kern: "struct bpf_sock_addr_kern", + Enum: BPF_PROG_TYPE_CGROUP_SOCK_ADDR, + SecDefs: []SecDef{ + SecDef{"cgroup/bind4", nil, false}, + SecDef{"cgroup/bind6", nil, false}, + SecDef{"cgroup/connect4", nil, false}, + SecDef{"cgroup/connect6", nil, false}, + SecDef{"cgroup/sendmsg4", nil, false}, + SecDef{"cgroup/sendmsg6", nil, false}, + SecDef{"cgroup/recvmsg4", nil, false}, + SecDef{"cgroup/recvmsg6", nil, false}, + SecDef{"cgroup/getpeername4", nil, false}, + SecDef{"cgroup/getpeername6", nil, false}, + SecDef{"cgroup/getsockname4", nil, false}, + SecDef{"cgroup/getsockname6", nil, false}, + }, + FuncProtos: []string{ + "bpf_get_current_uid_gid_proto", "bpf_bind_proto", "bpf_get_socket_cookie_sock_addr_proto", "bpf_get_netns_cookie_sock_addr_proto", + "bpf_get_local_storage_proto", "bpf_event_output_data_proto", "bpf_get_current_pid_tgid_proto", "bpf_get_current_comm_proto", + "bpf_get_current_cgroup_id_proto", "bpf_get_current_ancestor_cgroup_id_proto", "bpf_get_cgroup_classid_curr_proto", "bpf_sock_addr_sk_lookup_tcp_proto", + "bpf_sock_addr_sk_lookup_udp_proto", "bpf_sk_release_proto", "bpf_sock_addr_skc_lookup_tcp_proto", "bpf_sk_storage_get_proto", + "bpf_sk_storage_delete_proto", "bpf_sock_addr_setsockopt_proto", "bpf_sock_addr_getsockopt_proto", + //bpf_sk_base_func_proto + "bpf_skc_to_tcp6_sock_proto", "bpf_skc_to_tcp_sock_proto", "bpf_skc_to_tcp_timewait_sock_proto", "bpf_skc_to_tcp_request_sock_proto", + "bpf_skc_to_udp6_sock_proto", "bpf_ktime_get_coarse_ns_proto", + // bpf_base_func_proto + "bpf_map_lookup_elem_proto", "bpf_map_update_elem_proto", "bpf_map_delete_elem_proto", "bpf_map_push_elem_proto", + "bpf_map_pop_elem_proto", "bpf_map_peek_elem_proto", "bpf_get_prandom_u32_proto", "bpf_get_raw_smp_processor_id_proto", + "bpf_get_numa_node_id_proto", "bpf_tail_call_proto", "bpf_ktime_get_ns_proto", "bpf_ktime_get_boot_ns_proto", + "bpf_ringbuf_output_proto", "bpf_ringbuf_reserve_proto", "bpf_ringbuf_submit_proto", "bpf_ringbuf_discard_proto", + "bpf_ringbuf_query_proto", "bpf_for_each_map_elem_proto", "bpf_spin_lock_proto", "bpf_spin_unlock_proto", + "bpf_jiffies64_proto", "bpf_per_cpu_ptr_proto", "bpf_this_cpu_ptr_proto", "bpf_timer_init_proto", + "bpf_timer_set_callback_proto", "bpf_timer_start_proto", "bpf_timer_cancel_proto", "bpf_trace_printk_proto", + "bpf_get_current_task_proto", "bpf_get_current_task_btf_proto", "bpf_probe_read_user_proto", "bpf_probe_read_kernel_proto", + "bpf_probe_read_user_str_proto", "bpf_probe_read_kernel_str_proto", "bpf_snprintf_btf_proto", "bpf_snprintf_proto", + "bpf_task_pt_regs_proto", + }}, + BPF_PROG_TYPE_PERF_EVENT: &BpfProgTypeDef{ + Name: "perf_event", + User: "struct bpf_perf_event_data", + Kern: "struct bpf_perf_event_data_kern", + Enum: BPF_PROG_TYPE_PERF_EVENT, + SecDefs: []SecDef{ + SecDef{"perf_event", nil, false}, + }, + FuncProtos: []string{ + "bpf_perf_event_output_proto_tp", "bpf_get_stackid_proto_pe", "bpf_get_stack_proto_pe", "bpf_perf_prog_read_value_proto", + "bpf_read_branch_records_proto", "bpf_get_attach_cookie_proto_pe", + //bpf_tracing_func_proto + "bpf_map_lookup_elem_proto", "bpf_map_update_elem_proto", "bpf_map_delete_elem_proto", "bpf_map_push_elem_proto", + "bpf_map_pop_elem_proto", "bpf_map_peek_elem_proto", "bpf_ktime_get_ns_proto", "bpf_ktime_get_boot_ns_proto", + "bpf_tail_call_proto", "bpf_get_current_pid_tgid_proto", "bpf_get_current_task_proto", "bpf_get_current_task_btf_proto", + "bpf_task_pt_regs_proto", "bpf_get_current_uid_gid_proto", "bpf_get_current_comm_proto", "bpf_trace_printk_proto", + "bpf_get_smp_processor_id_proto", "bpf_get_numa_node_id_proto", "bpf_perf_event_read_proto", "bpf_current_task_under_cgroup_proto", + "bpf_get_prandom_u32_proto", "bpf_probe_write_user_proto", "bpf_probe_read_user_proto", "bpf_probe_read_kernel_proto", + "bpf_probe_read_user_str_proto", "bpf_probe_read_kernel_str_proto", "bpf_probe_read_compat_proto", "bpf_probe_read_compat_str_proto", + "bpf_get_current_cgroup_id_proto", "bpf_get_current_ancestor_cgroup_id_proto", "bpf_send_signal_proto", "bpf_send_signal_thread_proto", + "bpf_perf_event_read_value_proto", "bpf_get_ns_current_pid_tgid_proto", "bpf_ringbuf_output_proto", "bpf_ringbuf_reserve_proto", + "bpf_ringbuf_submit_proto", "bpf_ringbuf_discard_proto", "bpf_ringbuf_query_proto", "bpf_jiffies64_proto", + "bpf_get_task_stack_proto", "bpf_copy_from_user_proto", "bpf_snprintf_btf_proto", "bpf_per_cpu_ptr_proto", + "bpf_this_cpu_ptr_proto", "bpf_task_storage_get_proto", "bpf_task_storage_delete_proto", "bpf_for_each_map_elem_proto", + "bpf_snprintf_proto", /*"bpf_get_func_ip_proto_tracing",*/ "bpf_spin_lock_proto", "bpf_spin_unlock_proto", + "bpf_timer_init_proto", "bpf_timer_set_callback_proto", "bpf_timer_start_proto", "bpf_timer_cancel_proto", + }}, + BPF_PROG_TYPE_CGROUP_SYSCTL: &BpfProgTypeDef{ + Name: "cg_sysctl", + User: "struct bpf_sysctl", + Kern: "struct bpf_sysctl_kern", + Enum: BPF_PROG_TYPE_CGROUP_SYSCTL, + SecDefs: []SecDef{ + SecDef{"cgroup/sysctl", nil, false}, + }, + FuncProtos: []string{ + "bpf_strtol_proto", "bpf_strtoul_proto", "bpf_sysctl_get_name_proto", "bpf_sysctl_get_current_value_proto", "bpf_sysctl_get_new_value_proto", + "bpf_sysctl_set_new_value_proto", "bpf_ktime_get_coarse_ns_proto", + //cgroup_base_func_proto + "bpf_get_current_uid_gid_proto", "bpf_get_local_storage_proto", "bpf_get_current_cgroup_id_proto", "bpf_event_output_data_proto", + // bpf_base_func_proto + "bpf_map_lookup_elem_proto", "bpf_map_update_elem_proto", "bpf_map_delete_elem_proto", "bpf_map_push_elem_proto", + "bpf_map_pop_elem_proto", "bpf_map_peek_elem_proto", "bpf_get_prandom_u32_proto", "bpf_get_raw_smp_processor_id_proto", + "bpf_get_numa_node_id_proto", "bpf_tail_call_proto", "bpf_ktime_get_ns_proto", "bpf_ktime_get_boot_ns_proto", + "bpf_ringbuf_output_proto", "bpf_ringbuf_reserve_proto", "bpf_ringbuf_submit_proto", "bpf_ringbuf_discard_proto", + "bpf_ringbuf_query_proto", "bpf_for_each_map_elem_proto", "bpf_spin_lock_proto", "bpf_spin_unlock_proto", + "bpf_jiffies64_proto", "bpf_per_cpu_ptr_proto", "bpf_this_cpu_ptr_proto", "bpf_timer_init_proto", + "bpf_timer_set_callback_proto", "bpf_timer_start_proto", "bpf_timer_cancel_proto", "bpf_trace_printk_proto", + "bpf_get_current_task_proto", "bpf_get_current_task_btf_proto", "bpf_probe_read_user_proto", "bpf_probe_read_kernel_proto", + "bpf_probe_read_user_str_proto", "bpf_probe_read_kernel_str_proto", "bpf_snprintf_btf_proto", "bpf_snprintf_proto", + "bpf_task_pt_regs_proto", + }}, + BPF_PROG_TYPE_XDP: &BpfProgTypeDef{ + Name: "xdp", + User: "struct xdp_md", + Kern: "struct xdp_buff", + Enum: BPF_PROG_TYPE_XDP, + SecDefs: []SecDef{ +// SecDef{"xdp.frags/devmap", nil, false}, + //SecDef{"xdp/devmap", nil, false}, //XXX to be supported + //SecDef{"xdp_devmap/", GenXdpEntry, false}, +// SecDef{"xdp.frags/cpumap", nil, false}, + //SecDef{"xdp/cpumap", nil, false}, //XXX to be supported + //SecDef{"xdp_cpumap/", GenXdpEntry, false}, +// SecDef{"xdp.frags", nil, false}, + SecDef{"xdp", nil, false}, + }, + FuncProtos: []string{ + "bpf_xdp_event_output_proto", "bpf_get_smp_processor_id_proto", "bpf_csum_diff_proto", "bpf_xdp_adjust_head_proto", + "bpf_xdp_adjust_meta_proto", "bpf_xdp_redirect_proto", "bpf_xdp_redirect_map_proto", "bpf_xdp_adjust_tail_proto", + "bpf_xdp_fib_lookup_proto", "bpf_xdp_check_mtu_proto", "bpf_xdp_sk_lookup_udp_proto", "bpf_xdp_sk_lookup_tcp_proto", + "bpf_sk_release_proto", "bpf_xdp_skc_lookup_tcp_proto", "bpf_tcp_check_syncookie_proto", "bpf_tcp_gen_syncookie_proto", + //bpf_sk_base_func_proto + "bpf_skc_to_tcp6_sock_proto", "bpf_skc_to_tcp_sock_proto", "bpf_skc_to_tcp_timewait_sock_proto", "bpf_skc_to_tcp_request_sock_proto", + "bpf_skc_to_udp6_sock_proto", "bpf_ktime_get_coarse_ns_proto", + // bpf_base_func_proto + "bpf_map_lookup_elem_proto", "bpf_map_update_elem_proto", "bpf_map_delete_elem_proto", "bpf_map_push_elem_proto", + "bpf_map_pop_elem_proto", "bpf_map_peek_elem_proto", "bpf_get_prandom_u32_proto", "bpf_get_raw_smp_processor_id_proto", + "bpf_get_numa_node_id_proto", "bpf_tail_call_proto", "bpf_ktime_get_ns_proto", "bpf_ktime_get_boot_ns_proto", + "bpf_ringbuf_output_proto", "bpf_ringbuf_reserve_proto", "bpf_ringbuf_submit_proto", "bpf_ringbuf_discard_proto", + "bpf_ringbuf_query_proto", "bpf_for_each_map_elem_proto", "bpf_spin_lock_proto", "bpf_spin_unlock_proto", + "bpf_jiffies64_proto", "bpf_per_cpu_ptr_proto", "bpf_this_cpu_ptr_proto", "bpf_timer_init_proto", + "bpf_timer_set_callback_proto", "bpf_timer_start_proto", "bpf_timer_cancel_proto", "bpf_trace_printk_proto", + "bpf_get_current_task_proto", "bpf_get_current_task_btf_proto", "bpf_probe_read_user_proto", "bpf_probe_read_kernel_proto", + "bpf_probe_read_user_str_proto", "bpf_probe_read_kernel_str_proto", "bpf_snprintf_btf_proto", "bpf_snprintf_proto", + "bpf_task_pt_regs_proto", + }}, + BPF_PROG_TYPE_LWT_OUT: &BpfProgTypeDef{ + Name: "lwt_out", + User: "struct __sk_buff", + Kern: "struct sk_buff", + Enum: BPF_PROG_TYPE_LWT_OUT, + SecDefs: []SecDef{ + SecDef{"lwt_out", nil, false}, + }, + FuncProtos: []string{ + "bpf_skb_load_bytes_proto", "bpf_skb_pull_data_proto", "bpf_csum_diff_proto", "bpf_get_cgroup_classid_proto", + "bpf_get_route_realm_proto", "bpf_get_hash_recalc_proto", "bpf_skb_event_output_proto", "bpf_get_smp_processor_id_proto", + "bpf_skb_under_cgroup_proto", + //bpf_sk_base_func_proto + "bpf_skc_to_tcp6_sock_proto", "bpf_skc_to_tcp_sock_proto", "bpf_skc_to_tcp_timewait_sock_proto", "bpf_skc_to_tcp_request_sock_proto", + "bpf_skc_to_udp6_sock_proto", "bpf_ktime_get_coarse_ns_proto", + // bpf_base_func_proto + "bpf_map_lookup_elem_proto", "bpf_map_update_elem_proto", "bpf_map_delete_elem_proto", "bpf_map_push_elem_proto", + "bpf_map_pop_elem_proto", "bpf_map_peek_elem_proto", "bpf_get_prandom_u32_proto", "bpf_get_raw_smp_processor_id_proto", + "bpf_get_numa_node_id_proto", "bpf_tail_call_proto", "bpf_ktime_get_ns_proto", "bpf_ktime_get_boot_ns_proto", + "bpf_ringbuf_output_proto", "bpf_ringbuf_reserve_proto", "bpf_ringbuf_submit_proto", "bpf_ringbuf_discard_proto", + "bpf_ringbuf_query_proto", "bpf_for_each_map_elem_proto", "bpf_spin_lock_proto", "bpf_spin_unlock_proto", + "bpf_jiffies64_proto", "bpf_per_cpu_ptr_proto", "bpf_this_cpu_ptr_proto", "bpf_timer_init_proto", + "bpf_timer_set_callback_proto", "bpf_timer_start_proto", "bpf_timer_cancel_proto", "bpf_trace_printk_proto", + "bpf_get_current_task_proto", "bpf_get_current_task_btf_proto", "bpf_probe_read_user_proto", "bpf_probe_read_kernel_proto", + "bpf_probe_read_user_str_proto", "bpf_probe_read_kernel_str_proto", "bpf_snprintf_btf_proto", "bpf_snprintf_proto", + "bpf_task_pt_regs_proto", + }}, + BPF_PROG_TYPE_LWT_XMIT: &BpfProgTypeDef{ + Name: "lwt_xmit", + User: "struct __sk_buff", + Kern: "struct sk_buff", + Enum: BPF_PROG_TYPE_LWT_XMIT, + SecDefs: []SecDef{ + SecDef{"lwt_xmit", nil, false}, + }, + FuncProtos: []string{ + "bpf_skb_get_tunnel_key_proto", "bpf_skb_set_tunnel_key_proto", "bpf_skb_get_tunnel_opt_proto", "bpf_skb_set_tunnel_opt_proto", + "bpf_redirect_proto", "bpf_clone_redirect_proto", "bpf_skb_change_tail_proto", "bpf_skb_change_head_proto", + "bpf_skb_store_bytes_proto", "bpf_csum_update_proto", "bpf_csum_level_proto", "bpf_l3_csum_replace_proto", + "bpf_l4_csum_replace_proto", "bpf_set_hash_invalid_proto", "bpf_lwt_xmit_push_encap_proto", + //lwt_out_func_proto + "bpf_skb_load_bytes_proto", "bpf_skb_pull_data_proto", "bpf_csum_diff_proto", "bpf_get_cgroup_classid_proto", + "bpf_get_route_realm_proto", "bpf_get_hash_recalc_proto", "bpf_skb_event_output_proto", "bpf_get_smp_processor_id_proto", + "bpf_skb_under_cgroup_proto", + // bpf_sk_base_func_proto + "bpf_skc_to_tcp6_sock_proto", "bpf_skc_to_tcp_sock_proto", "bpf_skc_to_tcp_timewait_sock_proto", "bpf_skc_to_tcp_request_sock_proto", + "bpf_skc_to_udp6_sock_proto", "bpf_ktime_get_coarse_ns_proto", + // bpf_base_func_proto + "bpf_map_lookup_elem_proto", "bpf_map_update_elem_proto", "bpf_map_delete_elem_proto", "bpf_map_push_elem_proto", + "bpf_map_pop_elem_proto", "bpf_map_peek_elem_proto", "bpf_get_prandom_u32_proto", "bpf_get_raw_smp_processor_id_proto", + "bpf_get_numa_node_id_proto", "bpf_tail_call_proto", "bpf_ktime_get_ns_proto", "bpf_ktime_get_boot_ns_proto", + "bpf_ringbuf_output_proto", "bpf_ringbuf_reserve_proto", "bpf_ringbuf_submit_proto", "bpf_ringbuf_discard_proto", + "bpf_ringbuf_query_proto", "bpf_for_each_map_elem_proto", "bpf_spin_lock_proto", "bpf_spin_unlock_proto", + "bpf_jiffies64_proto", "bpf_per_cpu_ptr_proto", "bpf_this_cpu_ptr_proto", "bpf_timer_init_proto", + "bpf_timer_set_callback_proto", "bpf_timer_start_proto", "bpf_timer_cancel_proto", "bpf_trace_printk_proto", + "bpf_get_current_task_proto", "bpf_get_current_task_btf_proto", "bpf_probe_read_user_proto", "bpf_probe_read_kernel_proto", + "bpf_probe_read_user_str_proto", "bpf_probe_read_kernel_str_proto", "bpf_snprintf_btf_proto", "bpf_snprintf_proto", + "bpf_task_pt_regs_proto", + }}, + BPF_PROG_TYPE_KPROBE: &BpfProgTypeDef{ + Name: "kprobe", + User: "struct bpf_user_pt_regs_t", + Kern: "struct pt_regs", + Enum: BPF_PROG_TYPE_KPROBE, + SecDefs: []SecDef{ + SecDef{"kprobe/", GenKprobeEntry, false}, + SecDef{"uprobe/", GenKprobeEntry, false}, + SecDef{"kretprobe/", GenKprobeEntry, false}, + SecDef{"uretprobe/", GenKprobeEntry, false}, + }, + FuncProtos: []string{ + "bpf_perf_event_output_proto", "bpf_get_stackid_proto", "bpf_get_stack_proto", "bpf_override_return_proto", + "bpf_get_attach_cookie_proto_trace", "bpf_get_func_ip_proto_kprobe", + //bpf_tracing_func_proto + "bpf_map_lookup_elem_proto", "bpf_map_update_elem_proto", "bpf_map_delete_elem_proto", "bpf_map_push_elem_proto", + "bpf_map_pop_elem_proto", "bpf_map_peek_elem_proto", "bpf_ktime_get_ns_proto", "bpf_ktime_get_boot_ns_proto", + "bpf_tail_call_proto", "bpf_get_current_pid_tgid_proto", "bpf_get_current_task_proto", "bpf_get_current_task_btf_proto", + "bpf_task_pt_regs_proto", "bpf_get_current_uid_gid_proto", "bpf_get_current_comm_proto", "bpf_trace_printk_proto", + "bpf_get_smp_processor_id_proto", "bpf_get_numa_node_id_proto", "bpf_perf_event_read_proto", "bpf_current_task_under_cgroup_proto", + "bpf_get_prandom_u32_proto", "bpf_probe_write_user_proto", "bpf_probe_read_user_proto", "bpf_probe_read_kernel_proto", + "bpf_probe_read_user_str_proto", "bpf_probe_read_kernel_str_proto", "bpf_probe_read_compat_proto", "bpf_probe_read_compat_str_proto", + "bpf_get_current_cgroup_id_proto", "bpf_get_current_ancestor_cgroup_id_proto", "bpf_send_signal_proto", "bpf_send_signal_thread_proto", + "bpf_perf_event_read_value_proto", "bpf_get_ns_current_pid_tgid_proto", "bpf_ringbuf_output_proto", "bpf_ringbuf_reserve_proto", + "bpf_ringbuf_submit_proto", "bpf_ringbuf_discard_proto", "bpf_ringbuf_query_proto", "bpf_jiffies64_proto", + "bpf_get_task_stack_proto", "bpf_copy_from_user_proto", "bpf_snprintf_btf_proto", "bpf_per_cpu_ptr_proto", + "bpf_this_cpu_ptr_proto", "bpf_task_storage_get_proto", "bpf_task_storage_delete_proto", "bpf_for_each_map_elem_proto", + "bpf_snprintf_proto", "bpf_get_func_ip_proto_tracing", "bpf_spin_lock_proto", "bpf_spin_unlock_proto", + "bpf_timer_init_proto", "bpf_timer_set_callback_proto", "bpf_timer_start_proto", "bpf_timer_cancel_proto", + }}, + BPF_PROG_TYPE_TRACEPOINT: &BpfProgTypeDef{ + Name: "tracepoint", + User: "__u64", + Kern: "u64", + Enum: BPF_PROG_TYPE_TRACEPOINT, + SecDefs: []SecDef{ + SecDef{"tracepoint/", GenTracepointEntry, false}, + SecDef{"tp/", GenTracepointEntry, false}, + }, + FuncProtos: []string{ + "bpf_perf_event_output_proto_tp", "bpf_get_stackid_proto_tp", "bpf_get_stack_proto_tp", "bpf_get_attach_cookie_proto_trace", + //bpf_tracing_func_proto + "bpf_map_lookup_elem_proto", "bpf_map_update_elem_proto", "bpf_map_delete_elem_proto", "bpf_map_push_elem_proto", + "bpf_map_pop_elem_proto", "bpf_map_peek_elem_proto", "bpf_ktime_get_ns_proto", "bpf_ktime_get_boot_ns_proto", + "bpf_tail_call_proto", "bpf_get_current_pid_tgid_proto", "bpf_get_current_task_proto", "bpf_get_current_task_btf_proto", + "bpf_task_pt_regs_proto", "bpf_get_current_uid_gid_proto", "bpf_get_current_comm_proto", "bpf_trace_printk_proto", + "bpf_get_smp_processor_id_proto", "bpf_get_numa_node_id_proto", "bpf_perf_event_read_proto", "bpf_current_task_under_cgroup_proto", + "bpf_get_prandom_u32_proto", "bpf_probe_write_user_proto", "bpf_probe_read_user_proto", "bpf_probe_read_kernel_proto", + "bpf_probe_read_user_str_proto", "bpf_probe_read_kernel_str_proto", "bpf_probe_read_compat_proto", "bpf_probe_read_compat_str_proto", + "bpf_get_current_cgroup_id_proto", "bpf_get_current_ancestor_cgroup_id_proto", "bpf_send_signal_proto", "bpf_send_signal_thread_proto", + "bpf_perf_event_read_value_proto", "bpf_get_ns_current_pid_tgid_proto", "bpf_ringbuf_output_proto", "bpf_ringbuf_reserve_proto", + "bpf_ringbuf_submit_proto", "bpf_ringbuf_discard_proto", "bpf_ringbuf_query_proto", "bpf_jiffies64_proto", + "bpf_get_task_stack_proto", "bpf_copy_from_user_proto", "bpf_snprintf_btf_proto", "bpf_per_cpu_ptr_proto", + "bpf_this_cpu_ptr_proto", "bpf_task_storage_get_proto", "bpf_task_storage_delete_proto", "bpf_for_each_map_elem_proto", + "bpf_snprintf_proto", /*"bpf_get_func_ip_proto_tracing",*/ "bpf_spin_lock_proto", "bpf_spin_unlock_proto", + "bpf_timer_init_proto", "bpf_timer_set_callback_proto", "bpf_timer_start_proto", "bpf_timer_cancel_proto", + }}, + BPF_PROG_TYPE_RAW_TRACEPOINT_WRITABLE: &BpfProgTypeDef{ + Name: "raw_tracepoint_writable", + User: "struct bpf_raw_tracepoint_args", + Kern: "u64", + Enum: BPF_PROG_TYPE_RAW_TRACEPOINT_WRITABLE, + SecDefs: []SecDef{ + SecDef{"raw_tracepoint.w/", GenRawTracepointEntry, false}, + SecDef{"raw_tp.w/", GenRawTracepointEntry, false}, + }, + FuncProtos: []string{ + "bpf_perf_event_output_proto_raw_tp", "bpf_get_stackid_proto_raw_tp", "bpf_get_stack_proto", + //bpf_tracing_func_proto + "bpf_map_lookup_elem_proto", "bpf_map_update_elem_proto", "bpf_map_delete_elem_proto", "bpf_map_push_elem_proto", + "bpf_map_pop_elem_proto", "bpf_map_peek_elem_proto", "bpf_ktime_get_ns_proto", "bpf_ktime_get_boot_ns_proto", + "bpf_tail_call_proto", "bpf_get_current_pid_tgid_proto", "bpf_get_current_task_proto", "bpf_get_current_task_btf_proto", + "bpf_task_pt_regs_proto", "bpf_get_current_uid_gid_proto", "bpf_get_current_comm_proto", "bpf_trace_printk_proto", + "bpf_get_smp_processor_id_proto", "bpf_get_numa_node_id_proto", "bpf_perf_event_read_proto", "bpf_current_task_under_cgroup_proto", + "bpf_get_prandom_u32_proto", "bpf_probe_write_user_proto", "bpf_probe_read_user_proto", "bpf_probe_read_kernel_proto", + "bpf_probe_read_user_str_proto", "bpf_probe_read_kernel_str_proto", "bpf_probe_read_compat_proto", "bpf_probe_read_compat_str_proto", + "bpf_get_current_cgroup_id_proto", "bpf_get_current_ancestor_cgroup_id_proto", "bpf_send_signal_proto", "bpf_send_signal_thread_proto", + "bpf_perf_event_read_value_proto", "bpf_get_ns_current_pid_tgid_proto", "bpf_ringbuf_output_proto", "bpf_ringbuf_reserve_proto", + "bpf_ringbuf_submit_proto", "bpf_ringbuf_discard_proto", "bpf_ringbuf_query_proto", "bpf_jiffies64_proto", + "bpf_get_task_stack_proto", "bpf_copy_from_user_proto", "bpf_snprintf_btf_proto", "bpf_per_cpu_ptr_proto", + "bpf_this_cpu_ptr_proto", "bpf_task_storage_get_proto", "bpf_task_storage_delete_proto", "bpf_for_each_map_elem_proto", + "bpf_snprintf_proto", /*"bpf_get_func_ip_proto_tracing",*/ "bpf_spin_lock_proto", "bpf_spin_unlock_proto", + "bpf_timer_init_proto", "bpf_timer_set_callback_proto", "bpf_timer_start_proto", "bpf_timer_cancel_proto", + }}, + BPF_PROG_TYPE_TRACING: &BpfProgTypeDef{ + Name: "tracing", + User: "void *", + Kern: "void *", + Enum: BPF_PROG_TYPE_TRACING, + SecDefs: []SecDef{ + SecDef{"tp_btf/", nil, false}, + SecDef{"fentry/", GenBPFTrampoline, false}, + SecDef{"fmod_ret", GenBPFTrampoline, false}, + SecDef{"fexit/", GenBPFTrampoline, false}, + SecDef{"fentry.s/", GenBPFTrampoline, true}, + SecDef{"fmod_ret.s/", GenBPFTrampoline, true}, + SecDef{"fexit.s/", GenBPFTrampoline, true}, + SecDef{"iter/", GenTracingIter, false}, + SecDef{"iter.s/", GenTracingIter, true}, + }, + FuncProtos: []string{ + "bpf_skb_output_proto", "bpf_xdp_output_proto", "bpf_skc_to_tcp6_sock_proto", "bpf_skc_to_tcp_sock_proto", + "bpf_skc_to_tcp_timewait_sock_proto", "bpf_skc_to_tcp_request_sock_proto", "bpf_skc_to_udp6_sock_proto", "bpf_sk_storage_get_tracing_proto", + "bpf_sk_storage_delete_tracing_proto", "bpf_sock_from_file_proto", "bpf_get_socket_ptr_cookie_proto", "bpf_seq_printf_proto", + "bpf_seq_write_proto", "bpf_seq_printf_btf_proto", "bpf_d_path_proto", + //raw_tp_prog_func_proto + "bpf_perf_event_output_proto_raw_tp", "bpf_get_stackid_proto_raw_tp", "bpf_get_stack_proto_raw_tp", + // bpf_tracing_func_proto + "bpf_map_lookup_elem_proto", "bpf_map_update_elem_proto", "bpf_map_delete_elem_proto", "bpf_map_push_elem_proto", + "bpf_map_pop_elem_proto", "bpf_map_peek_elem_proto", "bpf_ktime_get_ns_proto", "bpf_ktime_get_boot_ns_proto", + "bpf_tail_call_proto", "bpf_get_current_pid_tgid_proto", "bpf_get_current_task_proto", "bpf_get_current_task_btf_proto", + "bpf_task_pt_regs_proto", "bpf_get_current_uid_gid_proto", "bpf_get_current_comm_proto", "bpf_trace_printk_proto", + "bpf_get_smp_processor_id_proto", "bpf_get_numa_node_id_proto", "bpf_perf_event_read_proto", "bpf_current_task_under_cgroup_proto", + "bpf_get_prandom_u32_proto", "bpf_probe_write_user_proto", "bpf_probe_read_user_proto", "bpf_probe_read_kernel_proto", + "bpf_probe_read_user_str_proto", "bpf_probe_read_kernel_str_proto", "bpf_probe_read_compat_proto", "bpf_probe_read_compat_str_proto", + "bpf_get_current_cgroup_id_proto", "bpf_get_current_ancestor_cgroup_id_proto", "bpf_send_signal_proto", "bpf_send_signal_thread_proto", + "bpf_perf_event_read_value_proto", "bpf_get_ns_current_pid_tgid_proto", "bpf_ringbuf_output_proto", "bpf_ringbuf_reserve_proto", + "bpf_ringbuf_submit_proto", "bpf_ringbuf_discard_proto", "bpf_ringbuf_query_proto", "bpf_jiffies64_proto", + "bpf_get_task_stack_proto", "bpf_copy_from_user_proto", "bpf_snprintf_btf_proto", "bpf_per_cpu_ptr_proto", + "bpf_this_cpu_ptr_proto", "bpf_task_storage_get_proto", "bpf_task_storage_delete_proto", "bpf_for_each_map_elem_proto", + "bpf_snprintf_proto", "bpf_get_func_ip_proto_tracing", + // bpf_base_func_proto + //"bpf_map_lookup_elem_proto", "bpf_map_update_elem_proto", "bpf_map_delete_elem_proto", "bpf_map_push_elem_proto", + //"bpf_map_pop_elem_proto", "bpf_map_peek_elem_proto", "bpf_get_prandom_u32_proto", "bpf_get_raw_smp_processor_id_proto", + //"bpf_get_numa_node_id_proto", "bpf_tail_call_proto", "bpf_ktime_get_ns_proto", "bpf_ktime_get_boot_ns_proto", + //"bpf_ringbuf_output_proto", "bpf_ringbuf_reserve_proto", "bpf_ringbuf_submit_proto", "bpf_ringbuf_discard_proto", + //"bpf_ringbuf_query_proto", "bpf_for_each_map_elem_proto", "bpf_spin_lock_proto", + "bpf_spin_unlock_proto", + //"bpf_jiffies64_proto", "bpf_per_cpu_ptr_proto", "bpf_this_cpu_ptr_proto", + "bpf_timer_init_proto", "bpf_timer_set_callback_proto", "bpf_timer_start_proto", "bpf_timer_cancel_proto", + //"bpf_trace_printk_proto", "bpf_get_current_task_proto", "bpf_get_current_task_btf_proto", "bpf_probe_read_user_proto", + //"bpf_probe_read_kernel_proto", "bpf_probe_read_user_str_proto", "bpf_probe_read_kernel_str_proto", "bpf_snprintf_btf_proto", + //"bpf_snprintf_proto", "bpf_task_pt_regs_proto", + }}, +// BPF_PROG_TYPE_STRUCT_OPS: &BpfProgTypeDef{ +// Name: "bpf_struct_ops", +// User: "void *", +// Kern: "void *", +// Enum: BPF_PROG_TYPE_STRUCT_OPS, +// SecDefs: []SecDef{ +// SecDef{"struct_ops+", nil, false} +// }, +// FuncProtos: []string{//XXX: why missing this prog type +// }}, +// BPF_PROG_TYPE_EXT: &BpfProgTypeDef{ +// Name: "bpf_extension", +// User: "void *", +// Kern: "void *", +// Enum: BPF_PROG_TYPE_EXT, +// SecDefs: []SecDef{ +// SecDef{"freplace/", nil, false} +// }, +// FuncProtos: []string{//XXX: why missing this prog type +// }}, +// BPF_PROG_TYPE_LSM: &BpfProgTypeDef{ +// Name: "lsm", +// User: "void *", +// Kern: "void *", +// Enum: BPF_PROG_TYPE_LSM, +// SecDefs: []SecDef{ +// SecDef{"lsm/", nil, false}, +// SecDef{"lsm.s/", nil, true}, +// }, +// FuncProtos: []string{//XXX: why missing this prog type +// "bpf_inode_storage_get_proto","bpf_inode_storage_delete_proto","bpf_sk_storage_get_proto", "bpf_sk_storage_delete_proto", +// "bpf_spin_lock_proto", "bpf_spin_unlock_proto", "bpf_bprm_opts_set_proto", "bpf_ima_inode_hash_proto", +// //bpf_tracing_func_proto +// "bpf_map_lookup_elem_proto", "bpf_map_update_elem_proto", "bpf_map_delete_elem_proto", "bpf_map_push_elem_proto", +// "bpf_map_pop_elem_proto", "bpf_map_peek_elem_proto", "bpf_ktime_get_ns_proto", "bpf_ktime_get_boot_ns_proto", +// "bpf_tail_call_proto", "bpf_get_current_pid_tgid_proto", "bpf_get_current_task_proto", "bpf_get_current_task_btf_proto", +// "bpf_task_pt_regs_proto", "bpf_get_current_uid_gid_proto", "bpf_get_current_comm_proto", "bpf_trace_printk_proto", +// "bpf_get_smp_processor_id_proto", "bpf_get_numa_node_id_proto", "bpf_perf_event_read_proto", "bpf_current_task_under_cgroup_proto", +// "bpf_get_prandom_u32_proto", "bpf_probe_write_user_proto", "bpf_probe_read_user_proto", "bpf_probe_read_kernel_proto", +// "bpf_probe_read_user_str_proto", "bpf_probe_read_kernel_str_proto", "bpf_probe_read_compat_proto", "bpf_probe_read_compat_str_proto", +// "bpf_get_current_cgroup_id_proto", "bpf_get_current_ancestor_cgroup_id_proto", "bpf_send_signal_proto", "bpf_send_signal_thread_proto", +// "bpf_perf_event_read_value_proto", "bpf_get_ns_current_pid_tgid_proto", "bpf_ringbuf_output_proto", "bpf_ringbuf_reserve_proto", +// "bpf_ringbuf_submit_proto", "bpf_ringbuf_discard_proto", "bpf_ringbuf_query_proto", "bpf_jiffies64_proto", +// "bpf_get_task_stack_proto", "bpf_copy_from_user_proto", "bpf_snprintf_btf_proto", "bpf_per_cpu_ptr_proto", +// "bpf_this_cpu_ptr_proto", "bpf_task_storage_get_proto", "bpf_task_storage_delete_proto", "bpf_for_each_map_elem_proto", +// "bpf_snprintf_proto", /*"bpf_get_func_ip_proto_tracing",*/ /*"bpf_spin_lock_proto", "bpf_spin_unlock_proto",*/ +// "bpf_timer_init_proto", "bpf_timer_set_callback_proto", "bpf_timer_start_proto", "bpf_timer_cancel_proto", +// }}, +// "bpf_syscall": &BpfProgTypeDef{ +// Name: "bpf_syscall", +// User: "void *", +// Kern: "void *", +// Enum: "BPF_PROG_SYSCALL", +// SecDefs: []SecDef{ +// SecDef{"syscall/", nil} +// }, +// FuncProtos: []string{//XXX: why missing this prog type +// }}, +} + +type TracingIterCtx struct { + Name string + Ctx *StructDef +} + +/* +./kernel/bpf/map_iter.c:DEFINE_BPF_ITER_FUNC(bpf_map, struct bpf_iter_meta *meta, struct bpf_map *map) +./kernel/bpf/map_iter.c:DEFINE_BPF_ITER_FUNC(bpf_map_elem, struct bpf_iter_meta *meta, +./kernel/bpf/prog_iter.c:DEFINE_BPF_ITER_FUNC(bpf_prog, struct bpf_iter_meta *meta, struct bpf_prog *prog) +./kernel/bpf/task_iter.c:DEFINE_BPF_ITER_FUNC(task, struct bpf_iter_meta *meta, struct task_struct *task) +./kernel/bpf/task_iter.c:DEFINE_BPF_ITER_FUNC(task_file, struct bpf_iter_meta *meta, +./kernel/bpf/task_iter.c:DEFINE_BPF_ITER_FUNC(task_vma, struct bpf_iter_meta *meta, +./net/unix/af_unix.c:DEFINE_BPF_ITER_FUNC(unix, struct bpf_iter_meta *meta, +./net/ipv4/udp.c:DEFINE_BPF_ITER_FUNC(udp, struct bpf_iter_meta *meta, +./net/ipv4/tcp_ipv4.c:DEFINE_BPF_ITER_FUNC(tcp, struct bpf_iter_meta *meta, +./net/core/bpf_sk_storage.c:DEFINE_BPF_ITER_FUNC(bpf_sk_storage_map, struct bpf_iter_meta *meta, +./net/core/sock_map.c:DEFINE_BPF_ITER_FUNC(sockmap, struct bpf_iter_meta *meta, +./net/netlink/af_netlink.c:DEFINE_BPF_ITER_FUNC(netlink, struct bpf_iter_meta *meta, struct netlink_sock *sk) +./net/ipv6/route.c:DEFINE_BPF_ITER_FUNC(ipv6_route, struct bpf_iter_meta *meta, struct fib6_info *rt) +*/ +var tracingIterCtxs = []TracingIterCtx{ + TracingIterCtx{Name:"bpf_map", Ctx: nil}, + TracingIterCtx{Name:"bpf_map_elem", Ctx: nil}, + TracingIterCtx{Name:"bpf_prog", Ctx: nil}, + TracingIterCtx{Name:"task", Ctx: nil}, + TracingIterCtx{Name:"task_file", Ctx: nil}, + TracingIterCtx{Name:"task_vma", Ctx: nil}, + TracingIterCtx{Name:"unix", Ctx: nil}, + TracingIterCtx{Name:"udp", Ctx: nil}, + TracingIterCtx{Name:"tcp", Ctx: nil}, + TracingIterCtx{Name:"bpf_sk_storage_map", Ctx: nil}, + TracingIterCtx{Name:"sockmap", Ctx: nil}, + TracingIterCtx{Name:"netlink", Ctx: nil}, + TracingIterCtx{Name:"ipv6_route", Ctx: nil}, +} + +func GenXdpEntry(r *randGen) (string, *StructDef) { + return "", nil +} + +func GenKprobeEntry(r *randGen) (string, *StructDef) { + return "__x64_sys_nanosleep", nil +} + +func GenTracepointEntry(r *randGen) (string, *StructDef) { + return "sched/sched_switch", nil +} + +func GenRawTracepointEntry(r *randGen) (string, *StructDef) { + return "sys_enter", nil +} + +func GenBPFTrampoline(r *randGen) (string, *StructDef) { + return "__x64_sys_getpgid", nil +} + +func GenTracingIter(r *randGen) (string, *StructDef) { + i := r.Intn(len(tracingIterCtxs)) + return tracingIterCtxs[i].Name, nil +} + +var CtxAccessMap = map[BpfProgTypeEnum]*BpfCtxAccess{ + BPF_PROG_TYPE_CGROUP_SOCK_ADDR: &BpfCtxAccess{ + regTypeMap: map[string][][]string{ + "PTR_TO_SOCKET": [][]string{[]string{"offsetof", "struct bpf_sock_addr", "sk", ""}}, + }, + others: map[string]*BpfCtxAccess{}, + accesses: []BpfCtxAccessAttr{ + {rangeInCtx: []string{"user_ip4", "user_ip4"}, canRead: true, defaultSize: 4, narrowAccess: true, attachTypes: []string{ + "BPF_CGROUP_INET4_BIND", "BPF_CGROUP_INET4_CONNECT", "BPF_CGROUP_INET4_GETPEERNAME", "BPF_CGROUP_INET4_GETSOCKNAME", "BPF_CGROUP_UDP4_SENDMSG", "BPF_CGROUP_UDP4_RECVMSG"},}, + {rangeInCtx: []string{"user_ip6[0]", "user_ip6[3]"}, canRead: true, defaultSize: 4, wideAccess: true, narrowAccess: true, attachTypes: []string{ + "BPF_CGROUP_INET6_BIND", "BPF_CGROUP_INET6_CONNECT", "BPF_CGROUP_INET6_GETPEERNAME", "BPF_CGROUP_INET6_GETSOCKNAME", "BPF_CGROUP_UDP6_SENDMSG", "BPF_CGROUP_UDP6_RECVMSG"},}, + {rangeInCtx: []string{"msg_src_ip4", "msg_src_ip4"}, canRead: true, defaultSize: 4, narrowAccess: true, attachTypes: []string{ + "BPF_CGROUP_UDP4_SENDMSG"},}, + {rangeInCtx: []string{"msg_src_ip6[0]", "msg_src_ip6[3]"}, canRead: true, defaultSize: 4, wideAccess: true, narrowAccess: true, attachTypes: []string{ + "BPF_CGROUP_UDP6_SENDMSG"},}, + {rangeInCtx: []string{"user_ip4", "user_ip4"}, canWrite: true, size: 4, attachTypes: []string{ + "BPF_CGROUP_INET4_BIND", "BPF_CGROUP_INET4_CONNECT", "BPF_CGROUP_INET4_GETPEERNAME", "BPF_CGROUP_INET4_GETSOCKNAME", "BPF_CGROUP_UDP4_SENDMSG", "BPF_CGROUP_UDP4_RECVMSG"},}, + {rangeInCtx: []string{"user_ip6[0]", "user_ip6[3]"}, canWrite: true, size: 4, defaultSize: 4, wideAccess: true, attachTypes: []string{ + "BPF_CGROUP_INET6_BIND", "BPF_CGROUP_INET6_CONNECT", "BPF_CGROUP_INET6_GETPEERNAME", "BPF_CGROUP_INET6_GETSOCKNAME", "BPF_CGROUP_UDP6_SENDMSG", "BPF_CGROUP_UDP6_RECVMSG"},}, + {rangeInCtx: []string{"msg_src_ip4", "msg_src_ip4"}, canWrite: true, size: 4, attachTypes: []string{ + "BPF_CGROUP_UDP4_SENDMSG"},}, + {rangeInCtx: []string{"msg_src_ip6[0]", "msg_src_ip6[3]"}, canWrite: true, size: 4, defaultSize: 4, wideAccess: true, attachTypes: []string{ + "BPF_CGROUP_UDP6_SENDMSG"},}, + {rangeInCtx: []string{"sk"}, canRead: true, size: 8, regType: &PtrToSocketRegType{},}, + {rangeInCtx: []string{"default"}, canRead: true, size: 4,}, + }, + }, + BPF_PROG_TYPE_SCHED_CLS: &BpfCtxAccess{ + regTypeMap: map[string][][]string{ + "PTR_TO_SOCK_COMMON_OR_NULL": [][]string{[]string{"offsetof", "struct __sk_buff", "sk", ""}}, + "PTR_TO_PACKET": [][]string{[]string{"bpf_ctx_range", "struct __sk_buff", "data", ""}}, + "PTR_TO_PACKET_META": [][]string{[]string{"bpf_ctx_range", "struct __sk_buff", "data_meta", ""}}, + "PTR_TO_PACKET_END": [][]string{[]string{"bpf_ctx_range", "struct __sk_buff", "data_end", ""}}, + }, + others: map[string]*BpfCtxAccess{}, + accesses: []BpfCtxAccessAttr{ + {rangeInCtx: []string{"family", "local_port"},}, + {rangeInCtx: []string{"mark", "mark"}, canWrite: true, size: 4,}, + {rangeInCtx: []string{"mark", "mark"}, canRead: true, defaultSize: 4, narrowAccess: true,}, + {rangeInCtx: []string{"tc_index", "tc_index"}, canWrite: true, size: 4,}, + {rangeInCtx: []string{"tc_index", "tc_index"}, canRead: true, defaultSize: 4, narrowAccess: true,}, + {rangeInCtx: []string{"priority", "priority"}, canWrite: true, size: 4,}, + {rangeInCtx: []string{"priority", "priority"}, canRead: true, defaultSize: 4, narrowAccess: true,}, + {rangeInCtx: []string{"tc_classid", "tc_classid"}, canWrite: true, size: 4,}, + {rangeInCtx: []string{"tc_classid", "tc_classid"}, canRead: true, defaultSize: 4, narrowAccess: true,}, + {rangeInCtx: []string{"queue_mapping", "queue_mapping"}, canWrite: true, size: 4,}, + {rangeInCtx: []string{"queue_mapping", "queue_mapping"}, canRead: true, defaultSize: 4, narrowAccess: true,}, + {rangeInCtx: []string{"cb[0]", "cb[4]"}, canRead: true, canWrite: true,}, + {rangeInCtx: []string{"remote_ip6[0]", "remote_ip6[3]"}, canRead: true, canWrite: true, size: 4,}, + {rangeInCtx: []string{"local_ip6[0]", "local_ip6[3]"}, canRead: true, canWrite: true, size: 4,}, + {rangeInCtx: []string{"remote_ip4", "remote_ip4"}, canRead: true, canWrite: true, size: 4,}, + {rangeInCtx: []string{"data", "data"}, canRead: true, canWrite: true, size: 4, regType: &PtrToPacketRegType{},}, + {rangeInCtx: []string{"data_meta", "data_meta"}, canRead: true, canWrite: true, size: 4, regType: &PtrToPacketMetaRegType{},}, + {rangeInCtx: []string{"data_end", "data_end"}, canRead: true, canWrite: true, size: 4, regType: &PtrToPacketEndRegType{},}, + {rangeInCtx: []string{"flow_keys", "flow_keys"},}, + {rangeInCtx: []string{"tstamp", "tstamp"}, canRead: true, canWrite: true, size: 8,}, + {rangeInCtx: []string{"sk"}, canRead: true, size: 8, regType: &PtrToSockCommonRegType{},}, + {rangeInCtx: []string{"default"}, canWrite: true, size: 4,}, + {rangeInCtx: []string{"default"}, canRead: true, defaultSize: 4, narrowAccess: true}, + }, + }, + BPF_PROG_TYPE_SCHED_ACT: &BpfCtxAccess{ + regTypeMap: map[string][][]string{ + "PTR_TO_SOCK_COMMON_OR_NULL": [][]string{[]string{"offsetof", "struct __sk_buff", "sk", ""}}, + "PTR_TO_PACKET": [][]string{[]string{"bpf_ctx_range", "struct __sk_buff", "data", ""}}, + "PTR_TO_PACKET_META": [][]string{[]string{"bpf_ctx_range", "struct __sk_buff", "data_meta", ""}}, + "PTR_TO_PACKET_END": [][]string{[]string{"bpf_ctx_range", "struct __sk_buff", "data_end", ""}}, + }, + others: map[string]*BpfCtxAccess{}, + accesses: []BpfCtxAccessAttr{ + {rangeInCtx: []string{"family", "local_port"},}, + {rangeInCtx: []string{"mark", "mark"}, canWrite: true, size: 4,}, + {rangeInCtx: []string{"mark", "mark"}, canRead: true, defaultSize: 4, narrowAccess: true,}, + {rangeInCtx: []string{"tc_index", "tc_index"}, canWrite: true, size: 4,}, + {rangeInCtx: []string{"tc_index", "tc_index"}, canRead: true, defaultSize: 4, narrowAccess: true,}, + {rangeInCtx: []string{"priority", "priority"}, canWrite: true, size: 4,}, + {rangeInCtx: []string{"priority", "priority"}, canRead: true, defaultSize: 4, narrowAccess: true,}, + {rangeInCtx: []string{"tc_classid", "tc_classid"}, canWrite: true, size: 4,}, + {rangeInCtx: []string{"tc_classid", "tc_classid"}, canRead: true, defaultSize: 4, narrowAccess: true,}, + {rangeInCtx: []string{"queue_mapping", "queue_mapping"}, canWrite: true, size: 4,}, + {rangeInCtx: []string{"queue_mapping", "queue_mapping"}, canRead: true, defaultSize: 4, narrowAccess: true,}, + {rangeInCtx: []string{"cb[0]", "cb[4]"}, canRead: true, canWrite: true,}, + {rangeInCtx: []string{"remote_ip6[0]", "remote_ip6[3]"}, canRead: true, canWrite: true, size: 4,}, + {rangeInCtx: []string{"local_ip6[0]", "local_ip6[3]"}, canRead: true, canWrite: true, size: 4,}, + {rangeInCtx: []string{"remote_ip4", "remote_ip4"}, canRead: true, canWrite: true, size: 4,}, + {rangeInCtx: []string{"data", "data"}, canRead: true, canWrite: true, size: 4, regType: &PtrToPacketRegType{},}, + {rangeInCtx: []string{"data_meta", "data_meta"}, canRead: true, canWrite: true, size: 4, regType: &PtrToPacketMetaRegType{},}, + {rangeInCtx: []string{"data_end", "data_end"}, canRead: true, canWrite: true, size: 4, regType: &PtrToPacketEndRegType{},}, + {rangeInCtx: []string{"flow_keys", "flow_keys"},}, + {rangeInCtx: []string{"tstamp", "tstamp"}, canRead: true, canWrite: true, size: 8,}, + {rangeInCtx: []string{"sk"}, canRead: true, size: 8, regType: &PtrToSockCommonRegType{},}, + {rangeInCtx: []string{"default"}, canWrite: true, size: 4,}, + {rangeInCtx: []string{"default"}, canRead: true, defaultSize: 4, narrowAccess: true}, + }, + }, + BPF_PROG_TYPE_LWT_OUT: &BpfCtxAccess{ + regTypeMap: map[string][][]string{ + "PTR_TO_PACKET": [][]string{[]string{"bpf_ctx_range", "struct __sk_buff", "data", ""}}, + "PTR_TO_PACKET_END": [][]string{[]string{"bpf_ctx_range", "struct __sk_buff", "data_end", ""}}, + "PTR_TO_SOCK_COMMON_OR_NULL": [][]string{[]string{"offsetof", "struct __sk_buff", "sk", ""}}, + }, + others: map[string]*BpfCtxAccess{}, + accesses: []BpfCtxAccessAttr{ + {rangeInCtx: []string{"tc_classid"},}, + {rangeInCtx: []string{"family", "local_port"},}, + {rangeInCtx: []string{"data_meta"},}, + {rangeInCtx: []string{"tstamp"},}, + {rangeInCtx: []string{"wire_len"},}, + // + {rangeInCtx: []string{"mark"}, canRead: true, canWrite: true,}, + {rangeInCtx: []string{"priority"}, canRead: true, canWrite: true,}, + {rangeInCtx: []string{"cb[0]", "cb[4]"}, canRead: true, canWrite: true,}, + //bpf_skb_is_valid_access + {rangeInCtx: []string{"remote_ip6[0]", "remote_ip6[3]"}, canRead: true, canWrite: true, size: 4,}, + {rangeInCtx: []string{"local_ip6[0]", "local_ip6[3]"}, canRead: true, canWrite: true, size: 4,}, + {rangeInCtx: []string{"remote_ip4", "remote_ip4"}, canRead: true, canWrite: true, size: 4,}, + {rangeInCtx: []string{"data"}, canRead: true, canWrite: true, size: 4, regType: &PtrToPacketRegType{}}, + {rangeInCtx: []string{"data_meta"}, canRead: true, canWrite: true, size: 4,}, + {rangeInCtx: []string{"data_end"}, canRead: true, canWrite: true, size: 4, regType: &PtrToPacketEndRegType{}}, + {rangeInCtx: []string{"flow_keys"},}, + {rangeInCtx: []string{"tstamp"}, canRead: true, canWrite: true, size: 8,}, + {rangeInCtx: []string{"sk"}, canRead: true, size: 8, regType: &PtrToSockCommonRegType{},}, + {rangeInCtx: []string{"default"}, canWrite: true, size: 4,}, + {rangeInCtx: []string{"default"}, canRead: true, defaultSize: 4, narrowAccess: true,}, + }, + }, + BPF_PROG_TYPE_LWT_XMIT: &BpfCtxAccess{ + regTypeMap: map[string][][]string{ + "PTR_TO_PACKET": [][]string{[]string{"bpf_ctx_range", "struct __sk_buff", "data", ""}}, + "PTR_TO_PACKET_END": [][]string{[]string{"bpf_ctx_range", "struct __sk_buff", "data_end", ""}}, + "PTR_TO_SOCK_COMMON_OR_NULL": [][]string{[]string{"offsetof", "struct __sk_buff", "sk", ""}}, + }, + others: map[string]*BpfCtxAccess{}, + accesses: []BpfCtxAccessAttr{ + {rangeInCtx: []string{"tc_classid"},}, + {rangeInCtx: []string{"family", "local_port"},}, + {rangeInCtx: []string{"data_meta"},}, + {rangeInCtx: []string{"tstamp"},}, + {rangeInCtx: []string{"wire_len"},}, + // + {rangeInCtx: []string{"mark"}, canRead: true, canWrite: true,}, + {rangeInCtx: []string{"priority"}, canRead: true, canWrite: true,}, + {rangeInCtx: []string{"cb[0]", "cb[4]"}, canRead: true, canWrite: true,}, + //bpf_skb_is_valid_access + {rangeInCtx: []string{"remote_ip6[0]", "remote_ip6[3]"}, canRead: true, canWrite: true, size: 4,}, + {rangeInCtx: []string{"local_ip6[0]", "local_ip6[3]"}, canRead: true, canWrite: true, size: 4,}, + {rangeInCtx: []string{"remote_ip4", "remote_ip4"}, canRead: true, canWrite: true, size: 4,}, + {rangeInCtx: []string{"data", "data"}, canRead: true, canWrite: true, size: 4, regType: &PtrToPacketRegType{}}, + {rangeInCtx: []string{"data_meta", "data_meta"}, canRead: true, canWrite: true, size: 4,}, + {rangeInCtx: []string{"data_end", "data_end"}, canRead: true, canWrite: true, size: 4, regType: &PtrToPacketEndRegType{}}, + {rangeInCtx: []string{"flow_keys", "flow_keys"},}, + {rangeInCtx: []string{"tstamp", "tstamp"}, canRead: true, canWrite: true, size: 8,}, + {rangeInCtx: []string{"sk"}, canRead: true, size: 8, regType: &PtrToSockCommonRegType{},}, + {rangeInCtx: []string{"default"}, canWrite: true, size: 4,}, + {rangeInCtx: []string{"default"}, canRead: true, defaultSize: 4, narrowAccess: true,}, + }, + }, + BPF_PROG_TYPE_PERF_EVENT: &BpfCtxAccess{ + regTypeMap: map[string][][]string{}, + others: map[string]*BpfCtxAccess{}, + accesses: []BpfCtxAccessAttr{ + {rangeInCtx: []string{"sample_period", "sample_period"}, canRead: true, defaultSize: 8, narrowAccess: true,}, + {rangeInCtx: []string{"addr", "addr"}, canRead: true, defaultSize: 8, narrowAccess: true,}, + {rangeInCtx: []string{"default"}, canRead: true, size: 4,}, + }, + }, + BPF_PROG_TYPE_KPROBE: &BpfCtxAccess{ + regTypeMap: map[string][][]string{}, + others: map[string]*BpfCtxAccess{}, + accesses: []BpfCtxAccessAttr{ + {rangeInCtx: []string{"default"}, canRead: true,}, + }, + }, + BPF_PROG_TYPE_TRACEPOINT: &BpfCtxAccess{ + regTypeMap: map[string][][]string{}, + others: map[string]*BpfCtxAccess{}, + accesses: []BpfCtxAccessAttr{ + {rangeInCtx: []string{"default"}, canRead: true,}, + }, + }, + BPF_PROG_TYPE_RAW_TRACEPOINT_WRITABLE: &BpfCtxAccess{ + regTypeMap: map[string][][]string{}, + others: map[string]*BpfCtxAccess{}, + accesses: []BpfCtxAccessAttr{ + {rangeInCtx: []string{"default"}, canRead: true,}, + }, + }, + BPF_PROG_TYPE_RAW_TRACEPOINT: &BpfCtxAccess{ + regTypeMap: map[string][][]string{}, + others: map[string]*BpfCtxAccess{}, + accesses: []BpfCtxAccessAttr{ + {rangeInCtx: []string{"default"}, canRead: true,}, + }, + }, + BPF_PROG_TYPE_TRACING: &BpfCtxAccess{ + regTypeMap: map[string][][]string{}, + others: map[string]*BpfCtxAccess{}, + accesses: []BpfCtxAccessAttr{ + {rangeInCtx: []string{"default"}, canRead: true,}, //XXX btf_ctx_access + }, + }, + BPF_PROG_TYPE_CGROUP_SYSCTL: &BpfCtxAccess{ + regTypeMap: map[string][][]string{}, + others: map[string]*BpfCtxAccess{}, + accesses: []BpfCtxAccessAttr{ + {rangeInCtx: []string{"write"}, canRead: true, defaultSize: 4, narrowAccess: true}, + {rangeInCtx: []string{"file_pos"}, canRead: true, defaultSize: 4, narrowAccess: true,}, + {rangeInCtx: []string{"file_pos"}, canWrite: true, size: 4,}, + {rangeInCtx: []string{"default"},}, + }, + }, + BPF_PROG_TYPE_XDP: &BpfCtxAccess{ + regTypeMap: map[string][][]string{ + "PTR_TO_PACKET": [][]string{[]string{"offsetof", "struct xdp_md", "data", ""}}, + "PTR_TO_PACKET_META": [][]string{[]string{"offsetof", "struct xdp_md", "data_meta", ""}}, + "PTR_TO_PACKET_END": [][]string{[]string{"offsetof", "struct xdp_md", "data_end", ""}}, + }, + others: map[string]*BpfCtxAccess{}, + accesses: []BpfCtxAccessAttr{ + {rangeInCtx: []string{"data"}, canRead: true, size: 4, regType: &PtrToPacketRegType{},}, + {rangeInCtx: []string{"data_meta"}, canRead: true, size: 4, regType: &PtrToPacketMetaRegType{},}, + {rangeInCtx: []string{"data_end"}, canRead: true, size: 4, regType: &PtrToPacketEndRegType{},}, + {rangeInCtx: []string{"rx_queue_index"}, canRead: true, canWrite: true, size: 4,}, + {rangeInCtx: []string{"default"}, canRead: true, size: 4,}, + }, + }, + BPF_PROG_TYPE_LIRC_MODE2: &BpfCtxAccess{ + regTypeMap: map[string][][]string{}, + others: map[string]*BpfCtxAccess{}, + accesses: []BpfCtxAccessAttr{ + {rangeInCtx: []string{"default"}, canRead: true, size: 4,}, + }, + }, + BPF_PROG_TYPE_SK_REUSEPORT: &BpfCtxAccess{ + regTypeMap: map[string][][]string{ + "PTR_TO_PACKET_END": [][]string{[]string{"offsetof", "struct sk_reuseport_md", "data_end", ""}}, + "PTR_TO_SOCKET": [][]string{[]string{"offsetof", "struct sk_reuseport_md", "sk", ""}}, + "PTR_TO_SOCK_COMMON_OR_NULL": [][]string{[]string{"offsetof", "struct sk_reuseport_md", "migrating_sk", ""}}, + "PTR_TO_PACKET": [][]string{[]string{"offsetof", "struct sk_reuseport_md", "data", ""}}, + }, + others: map[string]*BpfCtxAccess{}, + accesses: []BpfCtxAccessAttr{ + {rangeInCtx: []string{"data"}, canRead: true, size: 8, regType: &PtrToPacketRegType{},}, + {rangeInCtx: []string{"data_end"}, canRead: true, size: 8, regType: &PtrToPacketEndRegType{},}, + {rangeInCtx: []string{"hash"}, canRead: true, size: 4,}, + {rangeInCtx: []string{"sk", "sk"}, canRead: true, size: 8, regType: &PtrToSocketRegType{},}, + {rangeInCtx: []string{"migrating_sk", "migrating_sk"}, canRead: true, size: 8, regType: &PtrToSockCommonRegType{},}, + {rangeInCtx: []string{"eth_protocol", "eth_protocol"}, canRead: true, defaultSize: 4, narrowAccess: true,}, + {rangeInCtx: []string{"ip_protocol", "ip_protocol"}, canRead: true, defaultSize: 4, narrowAccess: true,}, + {rangeInCtx: []string{"bind_inany", "bind_inany"}, canRead: true, defaultSize: 4, narrowAccess: true,}, + {rangeInCtx: []string{"len", "len"}, canRead: true, defaultSize: 4, narrowAccess: true,}, + {rangeInCtx: []string{"default"},}, + }, + }, + BPF_PROG_TYPE_SOCK_OPS: &BpfCtxAccess{ + regTypeMap: map[string][][]string{ + "PTR_TO_SOCKET_OR_NULL": [][]string{[]string{"offsetof", "struct bpf_sock_ops", "sk", ""}}, + "PTR_TO_PACKET": [][]string{[]string{"offsetof", "struct bpf_sock_ops", "skb_data", ""}}, + "PTR_TO_PACKET_END": [][]string{[]string{"offsetof", "struct bpf_sock_ops", "skb_data_end", ""}}, + }, + others: map[string]*BpfCtxAccess{}, + accesses: []BpfCtxAccessAttr{ + //{rangeInCtx: []string{"reply"}, canWrite: true, size: 4,}, + {rangeInCtx: []string{"args[0]", "args[0]"}, canWrite: true, size: 4,}, + {rangeInCtx: []string{"sk_txhash"}, canWrite: true, size: 4,}, + {rangeInCtx: []string{"bytes_received", "bytes_acked"}, canRead: true, size: 8,}, + {rangeInCtx: []string{"sk"}, canRead: true, size: 8, regType: &PtrToSocketRegType{},}, + {rangeInCtx: []string{"skb_data"}, canRead: true, size: 8, regType: &PtrToPacketRegType{},}, + {rangeInCtx: []string{"skb_data_end"}, canRead: true, size: 8, regType: &PtrToPacketEndRegType{},}, + {rangeInCtx: []string{"default"}, canRead: true, size: 4,}, + }, + }, + BPF_PROG_TYPE_CGROUP_SKB: &BpfCtxAccess{ + regTypeMap: map[string][][]string{ + "PTR_TO_SOCK_COMMON_OR_NULL": [][]string{[]string{"offsetof", "struct __sk_buff", "sk", ""}}, + "PTR_TO_PACKET": [][]string{[]string{"bpf_ctx_range", "struct __sk_buff", "data", ""}}, + "PTR_TO_PACKET_END": [][]string{[]string{"bpf_ctx_range", "struct __sk_buff", "data_end", ""}}, + }, + others: map[string]*BpfCtxAccess{}, + accesses: []BpfCtxAccessAttr{ + {rangeInCtx: []string{"tc_classid"},}, + {rangeInCtx: []string{"data_meta"},}, + {rangeInCtx: []string{"wire_len"},}, +// {rangeInCtx: []string{"data"},}, +// {rangeInCtx: []string{"data_end"},}, + {rangeInCtx: []string{"mark"}, canRead: true, canWrite: true,}, + {rangeInCtx: []string{"priority"}, canRead: true, canWrite: true,}, +// {rangeInCtx: []string{"cb[0]", "cb[4]"}, canRead: true, canWrite: true,}, +// {rangeInCtx: []string{"tstamp"}, canRead: true, canWrite: true,}, + {rangeInCtx: []string{"cb[0]", "cb[4]"}, canRead: true, canWrite: true,}, + {rangeInCtx: []string{"remote_ip6[0]", "remote_ip6[3]"}, canRead: true, canWrite: true, size: 4,}, + {rangeInCtx: []string{"local_ip6[0]", "local_ip6[3]"}, canRead: true, canWrite: true, size: 4,}, + {rangeInCtx: []string{"remote_ip4", "remote_ip4"}, canRead: true, canWrite: true, size: 4,}, + {rangeInCtx: []string{"data", "data"}, canRead: true, canWrite: true, size: 4, regType: &PtrToPacketRegType{}}, + {rangeInCtx: []string{"data_meta", "data_meta"}, canRead: true, canWrite: true, size: 4,}, + {rangeInCtx: []string{"data_end", "data_end"}, canRead: true, canWrite: true, size: 4, regType: &PtrToPacketEndRegType{}}, + {rangeInCtx: []string{"flow_keys", "flow_keys"},}, + {rangeInCtx: []string{"tstamp", "tstamp"}, canRead: true, canWrite: true, size: 8,}, + {rangeInCtx: []string{"sk"}, canRead: true, size: 8, regType: &PtrToSockCommonRegType{},}, + {rangeInCtx: []string{"default"}, canWrite: true, size: 4,}, + {rangeInCtx: []string{"default"}, canRead: true, defaultSize: 4, narrowAccess: true,}, +//bpf_skb_is_valid_access +// {rangeInCtx: []string{"cb[0]", "cb[4]"}, canRead: true, canWrite: true,}, +// {rangeInCtx: []string{"remote_ip6[0]", "remote_ip6[3]"}, canRead: true, canWrite: true, size: 4,}, +// {rangeInCtx: []string{"local_ip6[0]", "local_ip6[3]"}, canRead: true, canWrite: true, size: 4,}, +// {rangeInCtx: []string{"remote_ip4", "remote_ip4"}, canRead: true, canWrite: true, size: 4,}, +// {rangeInCtx: []string{"data", "data"}, canRead: true, canWrite: true, size: 4,}, +// {rangeInCtx: []string{"data_meta", "data_meta"}, canRead: true, canWrite: true, size: 4,}, +// {rangeInCtx: []string{"data_end", "data_end"}, canRead: true, canWrite: true, size: 4,}, +// {rangeInCtx: []string{"flow_keys", "flow_keys"},}, +// {rangeInCtx: []string{"tstamp", "tstamp"}, canRead: true, canWrite: true, size: 8,}, +// {rangeInCtx: []string{"sk"}, canRead: true, size: 8, regType: &PtrToSockCommonRegType{},}, +// {rangeInCtx: []string{"default"}, canWrite: true, size: 4,}, +// {rangeInCtx: []string{"default"}, canRead: true, defaultSize: 4, narrowAccess: true}, + }, + }, + BPF_PROG_TYPE_CGROUP_SOCK: &BpfCtxAccess{ + regTypeMap: map[string][][]string{}, + others: map[string]*BpfCtxAccess{}, + accesses: []BpfCtxAccessAttr{ + {rangeInCtx: []string{"state"}, canRead: true, defaultSize: 4, narrowAccess: true,}, + {rangeInCtx: []string{"family"}, canRead: true, defaultSize: 4, narrowAccess: true,}, + {rangeInCtx: []string{"type"}, canRead: true, defaultSize: 4, narrowAccess: true,}, + {rangeInCtx: []string{"protocol"}, canRead: true, defaultSize: 4, narrowAccess: true,}, + {rangeInCtx: []string{"dst_port"}, canRead: true, defaultSize: 4, narrowAccess: true,}, + {rangeInCtx: []string{"src_port"}, canRead: true, defaultSize: 4, narrowAccess: true,}, + {rangeInCtx: []string{"rx_queue_mapping"}, canRead: true, defaultSize: 4, narrowAccess: true,}, + {rangeInCtx: []string{"src_ip4", "src_ip4"}, canRead: true, defaultSize: 4, narrowAccess: true, attachTypes: []string{"BPF_CGROUP_INET4_POST_BIND"},}, + {rangeInCtx: []string{"src_ip6[0]", "src_ip6[3]"}, canRead: true, defaultSize: 4, narrowAccess: true, attachTypes: []string{"BPF_CGROUP_INET6_POST_BIND"},}, + {rangeInCtx: []string{"dst_ip4", "dst_ip4"}, defaultSize: 4, narrowAccess: true,}, + {rangeInCtx: []string{"dst_ip6[0]", "dst_ip6[3]"}, defaultSize: 4, narrowAccess: true,}, + {rangeInCtx: []string{"bound_dev_if"}, canRead: true, canWrite: true, defaultSize: 4, attachTypes: []string{"BPF_CGROUP_INET_SOCK_CREATE","BPF_CGROUP_INET_SOCK_RELEASE"},}, + {rangeInCtx: []string{"mark"}, canRead: true, canWrite: true, defaultSize: 4, attachTypes: []string{"BPF_CGROUP_INET_SOCK_CREATE","BPF_CGROUP_INET_SOCK_RELEASE"},}, + {rangeInCtx: []string{"priority"}, canRead: true, canWrite: true, defaultSize: 4, attachTypes: []string{"BPF_CGROUP_INET_SOCK_CREATE","BPF_CGROUP_INET_SOCK_RELEASE"},}, + {rangeInCtx: []string{"src_port"}, canRead: true, defaultSize: 4, attachTypes: []string{"BPF_CGROUP_INET4_POST_BIND","BPF_CGROUP_INET6_POST_BIND"},}, + {rangeInCtx: []string{"default"}, canRead: true, defaultSize: 4,}, + }, + }, + BPF_PROG_TYPE_LWT_IN: &BpfCtxAccess{ + regTypeMap: map[string][][]string{ + "PTR_TO_PACKET": [][]string{[]string{"bpf_ctx_range", "struct __sk_buff", "data", ""}}, + "PTR_TO_PACKET_END": [][]string{[]string{"bpf_ctx_range", "struct __sk_buff", "data_end", ""}}, + "PTR_TO_SOCK_COMMON_OR_NULL": [][]string{[]string{"offsetof", "struct __sk_buff", "sk", ""}}, + }, + others: map[string]*BpfCtxAccess{}, + accesses: []BpfCtxAccessAttr{ + {rangeInCtx: []string{"tc_classid"},}, + {rangeInCtx: []string{"family", "local_port"},}, + {rangeInCtx: []string{"data_meta"},}, + {rangeInCtx: []string{"tstamp"},}, + {rangeInCtx: []string{"wire_len"},}, + // + {rangeInCtx: []string{"mark"}, canRead: true, canWrite: true,}, + {rangeInCtx: []string{"priority"}, canRead: true, canWrite: true,}, + {rangeInCtx: []string{"cb[0]", "cb[4]"}, canRead: true, canWrite: true,}, + //bpf_skb_is_valid_access + {rangeInCtx: []string{"remote_ip6[0]", "remote_ip6[3]"}, canRead: true, canWrite: true, size: 4,}, + {rangeInCtx: []string{"local_ip6[0]", "local_ip6[3]"}, canRead: true, canWrite: true, size: 4,}, + {rangeInCtx: []string{"remote_ip4", "remote_ip4"}, canRead: true, canWrite: true, size: 4,}, + {rangeInCtx: []string{"data", "data"}, canRead: true, canWrite: true, size: 4, regType: &PtrToPacketRegType{}}, + {rangeInCtx: []string{"data_meta", "data_meta"}, canRead: true, canWrite: true, size: 4,}, + {rangeInCtx: []string{"data_end", "data_end"}, canRead: true, canWrite: true, size: 4, regType: &PtrToPacketEndRegType{}}, + {rangeInCtx: []string{"flow_keys", "flow_keys"},}, + {rangeInCtx: []string{"tstamp", "tstamp"}, canRead: true, canWrite: true, size: 8,}, + {rangeInCtx: []string{"sk"}, canRead: true, size: 8, regType: &PtrToSockCommonRegType{},}, + {rangeInCtx: []string{"default"}, canWrite: true, size: 4,}, + {rangeInCtx: []string{"default"}, canRead: true, defaultSize: 4, narrowAccess: true,}, +//bpf_skb_is_valid_access +// {rangeInCtx: []string{"cb[0]", "cb[4]"}, canRead: true, canWrite: true,}, +// {rangeInCtx: []string{"remote_ip6[0]", "remote_ip6[3]"}, canRead: true, canWrite: true, size: 4,}, +// {rangeInCtx: []string{"local_ip6[0]", "local_ip6[3]"}, canRead: true, canWrite: true, size: 4,}, +// {rangeInCtx: []string{"remote_ip4", "remote_ip4"}, canRead: true, canWrite: true, size: 4,}, +// {rangeInCtx: []string{"data"}, canRead: true, canWrite: true, size: 4,}, +// {rangeInCtx: []string{"data_meta"}, canRead: true, canWrite: true, size: 4,}, +// {rangeInCtx: []string{"data_end"}, canRead: true, canWrite: true, size: 4,}, +// {rangeInCtx: []string{"flow_keys"},}, +// {rangeInCtx: []string{"tstamp"}, canRead: true, canWrite: true, size: 8,}, +// {rangeInCtx: []string{"sk"}, canRead: true, size: 8, regType: &PtrToSockCommonRegType{},}, +// {rangeInCtx: []string{"default"}, canWrite: true, size: 4,}, +// {rangeInCtx: []string{"default"}, canRead: true, defaultSize: 4, narrowAccess: true}, + }, + }, + BPF_PROG_TYPE_LWT_SEG6LOCAL: &BpfCtxAccess{ + regTypeMap: map[string][][]string{ + "PTR_TO_PACKET_END": [][]string{[]string{"bpf_ctx_range", "struct __sk_buff", "data_end", ""}}, + "PTR_TO_PACKET": [][]string{[]string{"bpf_ctx_range", "struct __sk_buff", "data", ""}}, + "PTR_TO_SOCK_COMMON_OR_NULL": [][]string{[]string{"offsetof", "struct __sk_buff", "sk", ""}}, + }, + others: map[string]*BpfCtxAccess{}, + accesses: []BpfCtxAccessAttr{ + {rangeInCtx: []string{"tc_classid"},}, + {rangeInCtx: []string{"family", "local_port"},}, + {rangeInCtx: []string{"data_meta"},}, + {rangeInCtx: []string{"tstamp"},}, + {rangeInCtx: []string{"wire_len"},}, + // + {rangeInCtx: []string{"mark"}, canRead: true, canWrite: true,}, + {rangeInCtx: []string{"priority"}, canRead: true, canWrite: true,}, + {rangeInCtx: []string{"cb[0]", "cb[4]"}, canRead: true, canWrite: true,}, + //bpf_skb_is_valid_access + {rangeInCtx: []string{"remote_ip6[0]", "remote_ip6[3]"}, canRead: true, canWrite: true, size: 4,}, + {rangeInCtx: []string{"local_ip6[0]", "local_ip6[3]"}, canRead: true, canWrite: true, size: 4,}, + {rangeInCtx: []string{"remote_ip4", "remote_ip4"}, canRead: true, canWrite: true, size: 4,}, + {rangeInCtx: []string{"data", "data"}, canRead: true, canWrite: true, size: 4, regType: &PtrToPacketRegType{}}, + {rangeInCtx: []string{"data_meta", "data_meta"}, canRead: true, canWrite: true, size: 4,}, + {rangeInCtx: []string{"data_end", "data_end"}, canRead: true, canWrite: true, size: 4, regType: &PtrToPacketEndRegType{}}, + {rangeInCtx: []string{"flow_keys", "flow_keys"},}, + {rangeInCtx: []string{"tstamp", "tstamp"}, canRead: true, canWrite: true, size: 8,}, + {rangeInCtx: []string{"sk"}, canRead: true, size: 8, regType: &PtrToSockCommonRegType{},}, + {rangeInCtx: []string{"default"}, canWrite: true, size: 4,}, + {rangeInCtx: []string{"default"}, canRead: true, defaultSize: 4, narrowAccess: true,}, + }, + }, + BPF_PROG_TYPE_SK_SKB: &BpfCtxAccess{ + regTypeMap: map[string][][]string{ + "PTR_TO_PACKET": [][]string{[]string{"bpf_ctx_range", "struct __sk_buff", "data", ""}}, + "PTR_TO_PACKET_END": [][]string{[]string{"bpf_ctx_range", "struct __sk_buff", "data_end", ""}}, + "PTR_TO_SOCK_COMMON_OR_NULL": [][]string{[]string{"offsetof", "struct __sk_buff", "sk", ""}}, + }, + others: map[string]*BpfCtxAccess{}, + accesses: []BpfCtxAccessAttr{ + {rangeInCtx: []string{"tc_classid", "tc_classid"},}, + {rangeInCtx: []string{"data_meta", "data_meta"},}, + {rangeInCtx: []string{"tstamp", "tstamp"},}, + {rangeInCtx: []string{"wire_len", "wire_len"},}, + {rangeInCtx: []string{"tc_index", "tc_index"}, canWrite: true,}, + {rangeInCtx: []string{"priority", "priority"}, canWrite: true,}, + {rangeInCtx: []string{"mark", "mark"},}, +// {rangeInCtx: []string{"data", "data"}, regType}, +// {rangeInCtx: []string{"data_end", "data_end"}, regType}, +//bpf_skb_is_valid_access + {rangeInCtx: []string{"cb[0]", "cb[4]"}, canRead: true, /*canWrite: true,*/}, + {rangeInCtx: []string{"remote_ip6[0]", "remote_ip6[3]"}, canRead: true, /*canWrite: true,*/ size: 4,}, + {rangeInCtx: []string{"local_ip6[0]", "local_ip6[3]"}, canRead: true, /*canWrite: true,*/ size: 4,}, + {rangeInCtx: []string{"remote_ip4", "remote_ip4"}, canRead: true, /*canWrite: true,*/ size: 4,}, + {rangeInCtx: []string{"data", "data"}, canRead: true, /*canWrite: true,*/ size: 4, regType: &PtrToPacketRegType{},}, +// {rangeInCtx: []string{"data_meta", "data_meta"}, canRead: true, /*canWrite: true,*/ size: 4,}, + {rangeInCtx: []string{"data_end", "data_end"}, canRead: true, /*canWrite: true,*/ size: 4, regType: &PtrToPacketEndRegType{},}, + {rangeInCtx: []string{"flow_keys", "flow_keys"},}, + {rangeInCtx: []string{"tstamp", "tstamp"}, canRead: true, /*canWrite: true,*/ size: 8,}, + {rangeInCtx: []string{"sk"}, canRead: true, size: 8, regType: &PtrToSockCommonRegType{},}, + {rangeInCtx: []string{"default"}, canWrite: true, size: 4,}, + {rangeInCtx: []string{"default"}, canRead: true, defaultSize: 4, narrowAccess: true}, + }, + }, + BPF_PROG_TYPE_SK_MSG: &BpfCtxAccess{ + regTypeMap: map[string][][]string{ + "PTR_TO_PACKET": [][]string{[]string{"offsetof", "struct sk_msg_md", "data", ""}}, + "PTR_TO_PACKET_END": [][]string{[]string{"offsetof", "struct sk_msg_md", "data_end", ""}}, + "PTR_TO_SOCKET": [][]string{[]string{"offsetof", "struct sk_msg_md", "sk", ""}}, + }, + others: map[string]*BpfCtxAccess{}, + accesses: []BpfCtxAccessAttr{ + {rangeInCtx: []string{"data", "data"}, canRead: true, size: 8, regType: &PtrToPacketRegType{},}, + {rangeInCtx: []string{"data_end", "data_end"}, canRead: true, size: 8, regType: &PtrToPacketEndRegType{},}, + {rangeInCtx: []string{"sk"}, canRead: true, size: 8, regType: &PtrToSocketRegType{},}, + {rangeInCtx: []string{"family", "family"}, canRead: true, size: 4,}, + {rangeInCtx: []string{"remote_ip4", "remote_ip4"}, canRead: true, size: 4,}, + {rangeInCtx: []string{"local_ip4", "local_ip4"}, canRead: true, size: 4,}, + {rangeInCtx: []string{"remote_ip6[0]", "remote_ip6[3]"}, canRead: true, size: 4,}, + {rangeInCtx: []string{"local_ip6[0]", "local_ip6[3]"}, canRead: true, size: 4,}, + {rangeInCtx: []string{"remote_port", "remote_port"}, canRead: true, size: 4,}, + {rangeInCtx: []string{"local_port", "local_port"}, canRead: true, size: 4,}, + {rangeInCtx: []string{"size", "size"}, canRead: true, size: 4,}, + {rangeInCtx: []string{"default"},}, + }, + }, + BPF_PROG_TYPE_FLOW_DISSECTOR: &BpfCtxAccess{ + regTypeMap: map[string][][]string{ + "PTR_TO_PACKET": [][]string{[]string{"bpf_ctx_range", "struct __sk_buff", "data", ""}}, + "PTR_TO_PACKET_END": [][]string{[]string{"bpf_ctx_range", "struct __sk_buff", "data_end", ""}}, + "PTR_TO_FLOW_KEYS": [][]string{[]string{"bpf_ctx_range_ptr", "struct __sk_buff", "flow_keys", ""}}, + }, + others: map[string]*BpfCtxAccess{}, + accesses: []BpfCtxAccessAttr{ + {rangeInCtx: []string{"data", "data"}, canRead: true, size: 4, regType: &PtrToPacketRegType{},}, + {rangeInCtx: []string{"data_end", "data_end"}, canRead: true, size: 4, regType: &PtrToPacketEndRegType{},}, + {rangeInCtx: []string{"flow_keys", "flow_keys"}, canRead: true, size: 4, regType: &PtrToFlowKeysRegType{},}, + {rangeInCtx: []string{"default"},}, + }, + }, + BPF_PROG_TYPE_SOCKET_FILTER: &BpfCtxAccess{ + regTypeMap: map[string][][]string{ + "PTR_TO_SOCK_COMMON_OR_NULL": [][]string{[]string{"offsetof", "struct __sk_buff", "sk", ""}}, + }, + others: map[string]*BpfCtxAccess{}, + accesses: []BpfCtxAccessAttr{ + {rangeInCtx: []string{"tc_classid", "tc_classid"},}, + {rangeInCtx: []string{"data", "data"},}, + {rangeInCtx: []string{"data_meta", "data_meta"},}, + {rangeInCtx: []string{"data_end", "data_end"},}, + {rangeInCtx: []string{"family", "local_port"},}, + {rangeInCtx: []string{"tstamp", "tstamp"},}, + {rangeInCtx: []string{"wire_len", "wire_len"},}, + {rangeInCtx: []string{"cb[0]", "cb[4]"}, canRead: true, canWrite: true,}, + {rangeInCtx: []string{"remote_ip6[0]", "remote_ip6[3]"}, canRead: true, size: 4,}, + {rangeInCtx: []string{"local_ip6[0]", "local_ip6[3]"}, canRead: true, size: 4,}, + {rangeInCtx: []string{"remote_ip4", "remote_ip4"}, canRead: true, size: 4,}, +// {rangeInCtx: []string{"data", "data"}, canRead: true, size: 4,}, +// {rangeInCtx: []string{"data_meta", "data_meta"}, canRead: true, size: 4,}, +// {rangeInCtx: []string{"data_end", "data_end"}, canRead: true, size: 4,}, + {rangeInCtx: []string{"flow_keys", "flow_keys"},}, +// {rangeInCtx: []string{"tstamp", "tstamp"}, canRead: true, size: 8,}, + {rangeInCtx: []string{"sk"}, canRead: true, size: 8, regType: &PtrToSockCommonRegType{},}, + {rangeInCtx: []string{"default"}, canRead: true, defaultSize: 4, narrowAccess: true,}, +//bpf_skb_is_valid_access +// {rangeInCtx: []string{"cb[0]", "cb[4]"}, canRead: true, canWrite: true,}, +// {rangeInCtx: []string{"remote_ip6[0]", "remote_ip6[3]"}, canRead: true, canWrite: true, size: 4,}, +// {rangeInCtx: []string{"local_ip6[0]", "local_ip6[3]"}, canRead: true, canWrite: true, size: 4,}, +// {rangeInCtx: []string{"remote_ip4", "remote_ip4"}, canRead: true, canWrite: true, size: 4,}, +// {rangeInCtx: []string{"data", "data"}, canRead: true, canWrite: true, size: 4,}, +// {rangeInCtx: []string{"data_meta", "data_meta"}, canRead: true, canWrite: true, size: 4,}, +// {rangeInCtx: []string{"data_end", "data_end"}, canRead: true, canWrite: true, size: 4,}, +// {rangeInCtx: []string{"flow_keys", "flow_keys"},}, +// {rangeInCtx: []string{"tstamp", "tstamp"}, canRead: true, canWrite: true, size: 8,}, +// {rangeInCtx: []string{"sk"}, canRead: true, size: 8, regType: &PtrToSockCommonRegType{},}, +// {rangeInCtx: []string{"default"}, canWrite: true, size: 4,}, +// {rangeInCtx: []string{"default"}, canRead: true, defaultSize: 4, narrowAccess: true}, + }, + }, + BPF_PROG_TYPE_CGROUP_DEVICE: &BpfCtxAccess{ + regTypeMap: map[string][][]string{}, + others: map[string]*BpfCtxAccess{}, + accesses: []BpfCtxAccessAttr{ + {rangeInCtx: []string{"access_type", "access_type"}, canRead: true, defaultSize: 4, narrowAccess: true,}, + {rangeInCtx: []string{"default"}, canRead: true, size: 4,}, + }, + }, + BPF_PROG_TYPE_CGROUP_SOCKOPT: &BpfCtxAccess{ + regTypeMap: map[string][][]string{ + "PTR_TO_SOCKET": [][]string{[]string{"offsetof", "struct bpf_sockopt", "sk", ""}}, + "PTR_TO_PACKET": [][]string{[]string{"offsetof", "struct bpf_sockopt", "optval", ""}}, + "PTR_TO_PACKET_END": [][]string{[]string{"offsetof", "struct bpf_sockopt", "optval_end", ""}}, + }, + others: map[string]*BpfCtxAccess{}, + accesses: []BpfCtxAccessAttr{ + {rangeInCtx: []string{"retval"}, canWrite: true, size: 4, attachTypes: []string{"BPF_CGROUP_GETSOCKOPT"},}, + {rangeInCtx: []string{"optname"}, canWrite: true, size: 4, attachTypes: []string{"BPF_CGROUP_SETSOCKOPT"},}, + {rangeInCtx: []string{"level"}, canWrite: true, size: 4, attachTypes: []string{"BPF_CGROUP_SETSOCKOPT"},}, + {rangeInCtx: []string{"optlen"}, canWrite: true, size: 4,}, + {rangeInCtx: []string{"sk", "sk"}, canRead: true, size: 8, regType: &PtrToSocketRegType{},}, + {rangeInCtx: []string{"optval", "optval"}, canRead: true, size: 8, regType: &PtrToPacketRegType{},}, + {rangeInCtx: []string{"optval_end", "optval_end"}, canRead: true, size: 8, regType: &PtrToPacketEndRegType{},}, + {rangeInCtx: []string{"retval", "retval"}, canRead: true, size: 4, attachTypes: []string{"BPF_CGROUP_GETSOCKOPT"},}, + {rangeInCtx: []string{"default"}, canRead: true, size: 4,}, + }, + }, + BPF_PROG_TYPE_SK_LOOKUP: &BpfCtxAccess{ + regTypeMap: map[string][][]string{ + "PTR_TO_SOCKET_OR_NULL": [][]string{[]string{"offsetof", "struct bpf_sk_lookup", "sk", ""}}, + }, + others: map[string]*BpfCtxAccess{}, + accesses: []BpfCtxAccessAttr{ + {rangeInCtx: []string{"family", "family"}, canRead: true, defaultSize: 4, narrowAccess: true,}, + {rangeInCtx: []string{"protocol", "protocol"}, canRead: true, defaultSize: 4, narrowAccess: true,}, + {rangeInCtx: []string{"remote_ip4", "remote_ip4"}, canRead: true, defaultSize: 4, narrowAccess: true,}, + {rangeInCtx: []string{"local_ip4", "local_ip4"}, canRead: true, defaultSize: 4, narrowAccess: true,}, + {rangeInCtx: []string{"remote_ip6[0]", "remote_ip6[3]"}, canRead: true, defaultSize: 4, narrowAccess: true,}, + {rangeInCtx: []string{"local_ip6[0]", "local_ip6[3]"}, canRead: true, defaultSize: 4, narrowAccess: true,}, + {rangeInCtx: []string{"remote_port", "remote_port"}, canRead: true, defaultSize: 4, narrowAccess: true,}, + {rangeInCtx: []string{"local_port", "local_port"}, canRead: true, defaultSize: 4, narrowAccess: true,}, + {rangeInCtx: []string{"default"},}, + }, + }, +} diff --git a/prog/generation.go b/prog/generation.go index 09240e858..8fbf316b1 100644 --- a/prog/generation.go +++ b/prog/generation.go @@ -15,6 +15,7 @@ func (target *Target) Generate(rs rand.Source, ncalls int, ct *ChoiceTable) *Pro } r := newRand(target, rs) s := newState(target, ct, nil) + target.Brf.GenPrologue(r, s, p) for len(p.Calls) < ncalls { calls := r.generateCall(s, p, len(p.Calls)) for _, c := range calls { diff --git a/sys/linux/bpf.txt b/sys/linux/bpf.txt index c54bb64d3..b278449ec 100644 --- a/sys/linux/bpf.txt +++ b/sys/linux/bpf.txt @@ -92,6 +92,18 @@ type bpf_prog_xdp bpf_prog_t[const[BPF_PROG_TYPE_XDP, int32], const[BPF_XDP, int type bpf_link_create_xdp bpf_link_create_arg_t[fd_bpf_prog_xdp, ifindex, const[BPF_XDP, int32], flags[xdp_flags, int32]] xdp_flags = XDP_FLAGS_UPDATE_IF_NOEXIST, XDP_FLAGS_SKB_MODE, XDP_FLAGS_DRV_MODE, XDP_FLAGS_HW_MODE, XDP_FLAGS_REPLACE +syz_bpf_prog_open(path ptr[in, filename]) +syz_bpf_prog_load(path ptr[in, filename], res ptr[out, bpf_res]) fd_bpf_prog +syz_bpf_prog_attach(path ptr[in, filename]) fd_bpf_link + + +bpf_res { + prog_fds array[fd_bpf_prog, 32] + prog_num len[prog_fds, int32] + map_fds array[fd_bpf_map, 32] + map_num len[map_fds, int32] +} + bpf_map_const_str_freeze { in fd_bpf_const_str out bpf_frozen_const_str (out_overlay) diff --git a/sys/targets/targets.go b/sys/targets/targets.go index 4c840119a..591ed040c 100644 --- a/sys/targets/targets.go +++ b/sys/targets/targets.go @@ -491,6 +491,9 @@ var oses = map[string]osCommon{ "syz_clone3": {"clone3", "exit"}, "syz_clone": {"clone", "exit"}, "syz_pidfd_open": {"pidfd_open"}, + "syz_bpf_prog_open": {"bpf$PROG_LOAD"}, + "syz_bpf_prog_load": {"bpf$PROG_LOAD"}, + "syz_bpf_prog_attach": {"bpf$BPF_PROG_ATTACH"}, }, cflags: []string{"-static-pie"}, }, diff --git a/syz-fuzzer/proc.go b/syz-fuzzer/proc.go index 2ca72107a..fdbcdf323 100644 --- a/syz-fuzzer/proc.go +++ b/syz-fuzzer/proc.go @@ -60,42 +60,42 @@ func newProc(fuzzer *Fuzzer, pid int) (*Proc, error) { } func (proc *Proc) loop() { - generatePeriod := 100 - if proc.fuzzer.config.Flags&ipc.FlagSignal == 0 { - // If we don't have real coverage signal, generate programs more frequently - // because fallback signal is weak. - generatePeriod = 2 - } +// generatePeriod := 1 +// if proc.fuzzer.config.Flags&ipc.FlagSignal == 0 { +// // If we don't have real coverage signal, generate programs more frequently +// // because fallback signal is weak. +// generatePeriod = 2 +// } for i := 0; ; i++ { - item := proc.fuzzer.workQueue.dequeue() - if item != nil { - switch item := item.(type) { - case *WorkTriage: - proc.triageInput(item) - case *WorkCandidate: - proc.execute(proc.execOpts, item.p, item.flags, StatCandidate) - case *WorkSmash: - proc.smashInput(item) - default: - log.SyzFatalf("unknown work type: %#v", item) - } - continue - } +// item := proc.fuzzer.workQueue.dequeue() +// if item != nil { +// switch item := item.(type) { +// case *WorkTriage: +// proc.triageInput(item) +// case *WorkCandidate: +// proc.execute(proc.execOpts, item.p, item.flags, StatCandidate) +// case *WorkSmash: +// proc.smashInput(item) +// default: +// log.SyzFatalf("unknown work type: %#v", item) +// } +// continue +// } ct := proc.fuzzer.choiceTable - fuzzerSnapshot := proc.fuzzer.snapshot() - if len(fuzzerSnapshot.corpus) == 0 || i%generatePeriod == 0 { +// fuzzerSnapshot := proc.fuzzer.snapshot() +// if len(fuzzerSnapshot.corpus) == 0 || i%generatePeriod == 0 { // Generate a new prog. p := proc.fuzzer.target.Generate(proc.rnd, prog.RecommendedCalls, ct) log.Logf(1, "#%v: generated", proc.pid) proc.executeAndCollide(proc.execOpts, p, ProgNormal, StatGenerate) - } else { - // Mutate an existing prog. - p := fuzzerSnapshot.chooseProgram(proc.rnd).Clone() - p.Mutate(proc.rnd, prog.RecommendedCalls, ct, proc.fuzzer.noMutate, fuzzerSnapshot.corpus) - log.Logf(1, "#%v: mutated", proc.pid) - proc.executeAndCollide(proc.execOpts, p, ProgNormal, StatFuzz) - } +// } else { +// // Mutate an existing prog. +// p := fuzzerSnapshot.chooseProgram(proc.rnd).Clone() +// p.Mutate(proc.rnd, prog.RecommendedCalls, ct, proc.fuzzer.noMutate, fuzzerSnapshot.corpus) +// log.Logf(1, "#%v: mutated", proc.pid) +// proc.executeAndCollide(proc.execOpts, p, ProgNormal, StatFuzz) +// } } } diff --git a/vendor/golang.org/x/sync/errgroup/errgroup.go b/vendor/golang.org/x/sync/errgroup/errgroup.go index b18efb743..948a3ee63 100644 --- a/vendor/golang.org/x/sync/errgroup/errgroup.go +++ b/vendor/golang.org/x/sync/errgroup/errgroup.go @@ -4,6 +4,9 @@ // Package errgroup provides synchronization, error propagation, and Context // cancelation for groups of goroutines working on subtasks of a common task. +// +// [errgroup.Group] is related to [sync.WaitGroup] but adds handling of tasks +// returning errors. package errgroup import ( diff --git a/vendor/modules.txt b/vendor/modules.txt index 11af7396b..5ac07dc6e 100644 --- a/vendor/modules.txt +++ b/vendor/modules.txt @@ -861,7 +861,7 @@ golang.org/x/oauth2/jwt golang.org/x/perf/benchstat golang.org/x/perf/internal/stats golang.org/x/perf/storage/benchfmt -# golang.org/x/sync v0.5.0 +# golang.org/x/sync v0.6.0 ## explicit; go 1.18 golang.org/x/sync/errgroup golang.org/x/sync/semaphore diff --git a/vm/qemu/qemu.go b/vm/qemu/qemu.go index bb616af47..ccaf643de 100644 --- a/vm/qemu/qemu.go +++ b/vm/qemu/qemu.go @@ -73,6 +73,8 @@ type Config struct { Snapshot bool `json:"snapshot"` // Magic key used to dongle macOS to the device. AppleSmcOsk string `json:"apple_smc_osk"` + // BPF runtime fuzzer working directory to be shared with the VM + BrfWorkDir string `json:"brf_workdir"` } type Pool struct { @@ -505,6 +507,11 @@ func (inst *instance) boot() error { "-device", "isa-applesmc,osk="+inst.cfg.AppleSmcOsk, ) } + if inst.cfg.BrfWorkDir != "" { + args = append(args, + "-virtfs", "local,path="+inst.cfg.BrfWorkDir+",mount_tag=brf,security_model=mapped,id=brf", + ) + } if inst.debug { log.Logf(0, "running command: %v %#v", inst.cfg.Qemu, args) }