// SPDX-License-Identifier: GPL-2.0 /* Copyright (c) 2020 Facebook */ #include "vmlinux.h" #include <bpf/bpf_helpers.h> #include <bpf/bpf_core_read.h> #include <bpf/bpf_tracing.h> char _license[] SEC("license") = "GPL"; struct bpf_testmod_test_read_ctx { /* field order is mixed up */ size_t len; char *buf; loff_t off; } __attribute__((preserve_access_index)); struct { char in[256]; char out[256]; bool skip; uint64_t my_pid_tgid; } data = {}; struct core_reloc_module_output { long long len; long long off; int read_ctx_sz; bool read_ctx_exists; bool buf_exists; bool len_exists; bool off_exists; /* we have test_progs[-flavor], so cut flavor part */ char comm[sizeof("test_progs")]; int comm_len; }; SEC("raw_tp/bpf_testmod_test_read") int BPF_PROG(test_core_module_probed, struct task_struct *task, struct bpf_testmod_test_read_ctx *read_ctx) { #if __has_builtin(__builtin_preserve_enum_value) struct core_reloc_module_output *out = (void *)&data.out; __u64 pid_tgid = bpf_get_current_pid_tgid(); __u32 real_tgid = (__u32)(pid_tgid >> 32); __u32 real_pid = (__u32)pid_tgid; if (data.my_pid_tgid != pid_tgid) return 0; if (BPF_CORE_READ(task, pid) != real_pid || BPF_CORE_READ(task, tgid) != real_tgid) return 0; out->len = BPF_CORE_READ(read_ctx, len); out->off = BPF_CORE_READ(read_ctx, off); out->read_ctx_sz = bpf_core_type_size(struct bpf_testmod_test_read_ctx); out->read_ctx_exists = bpf_core_type_exists(struct bpf_testmod_test_read_ctx); out->buf_exists = bpf_core_field_exists(read_ctx->buf); out->off_exists = bpf_core_field_exists(read_ctx->off); out->len_exists = bpf_core_field_exists(read_ctx->len); out->comm_len = BPF_CORE_READ_STR_INTO(&out->comm, task, comm); #else data.skip = true; #endif return 0; } SEC("tp_btf/bpf_testmod_test_read") int BPF_PROG(test_core_module_direct, struct task_struct *task, struct bpf_testmod_test_read_ctx *read_ctx) { #if __has_builtin(__builtin_preserve_enum_value) struct core_reloc_module_output *out = (void *)&data.out; __u64 pid_tgid = bpf_get_current_pid_tgid(); __u32 real_tgid = (__u32)(pid_tgid >> 32); __u32 real_pid = (__u32)pid_tgid; if (data.my_pid_tgid != pid_tgid) return 0; if (task->pid != real_pid || task->tgid != real_tgid) return 0; out->len = read_ctx->len; out->off = read_ctx->off; out->read_ctx_sz = bpf_core_type_size(struct bpf_testmod_test_read_ctx); out->read_ctx_exists = bpf_core_type_exists(struct bpf_testmod_test_read_ctx); out->buf_exists = bpf_core_field_exists(read_ctx->buf); out->off_exists = bpf_core_field_exists(read_ctx->off); out->len_exists = bpf_core_field_exists(read_ctx->len); out->comm_len = BPF_CORE_READ_STR_INTO(&out->comm, task, comm); #else data.skip = true; #endif return 0; }