summaryrefslogtreecommitdiff
path: root/internal/generate/bpfhandler.go
diff options
context:
space:
mode:
authorPaul Buetow <paul@buetow.org>2026-05-02 10:01:15 +0300
committerPaul Buetow <paul@buetow.org>2026-05-02 10:01:15 +0300
commit0528557ee9f14ed292de49be09e65b8662185c38 (patch)
tree42b6d3ccd45f975cc9fa4f282a0813a81a707e0b /internal/generate/bpfhandler.go
parent0dc3dc4e0c8367bc8399d3987251015a0e135fd9 (diff)
fix BPF tracepoint context type for RHEL 9 stock kernel
The BPF handler generator emitted struct trace_event_raw_sys_enter/ trace_event_raw_sys_exit (the BTF-blessed aliases). RHEL 9 carries an rt-tree backport that adds preempt_lazy_count to struct trace_entry, which widens those aliases by 8 bytes and shifts args/ret. The actual tracepoint context the kernel hands the program is still syscall_trace_enter / syscall_trace_exit, where the offsets did not move. Programs typed against the wider alias read past max_ctx_offset and the verifier rejects the attach with EACCES. Switching the generator to emit syscall_trace_enter/exit lines up with the real context on RHEL 9 (and is identical on every other distro, since the two structs only diverge there). Same fix bcc shipped in iovisor/bcc#4920 and inspektor-gadget did in inspektor-gadget#2546. Field accesses (ctx->args[N], ctx->ret) are unchanged. Verified end-to-end on Rocky Linux 9.7 stock 5.14.0-611.5.1.el9_7 (no kernel-ml needed) and Fedora 6.19. README rewritten accordingly: drops the elrepo kernel-ml step and the trailing 'permission denied' troubleshooting paragraph; adds a historical note explaining why the old workaround existed. Co-Authored-By: Claude Opus 4.7 <noreply@anthropic.com>
Diffstat (limited to 'internal/generate/bpfhandler.go')
-rw-r--r--internal/generate/bpfhandler.go12
1 files changed, 10 insertions, 2 deletions
diff --git a/internal/generate/bpfhandler.go b/internal/generate/bpfhandler.go
index 2c0d648..3d76ac4 100644
--- a/internal/generate/bpfhandler.go
+++ b/internal/generate/bpfhandler.go
@@ -9,9 +9,17 @@ func generateBPFHandler(tp GeneratedTracepoint) string {
f := tp.Format
isEnter := strings.Split(f.Name, "_")[1] == "enter"
- ctxStruct := "trace_event_raw_sys_exit"
+ // Use the kernel's actual tracepoint context structs (syscall_trace_enter/exit)
+ // rather than the BTF-emitted trace_event_raw_sys_enter/exit aliases. On RHEL 9
+ // kernels (5.14 with the rt-merge backport that added preempt_lazy_count to
+ // trace_entry) the two diverge: trace_event_raw_sys_* grows by 8 bytes and
+ // the args/ret offsets shift, but the real context handed to the BPF program
+ // is still syscall_trace_*. Reading via the wider alias trips the verifier's
+ // max_ctx_offset check and the attach fails with EACCES. The two structs are
+ // identical on non-RHEL kernels, so this is a no-op everywhere else.
+ ctxStruct := "syscall_trace_exit"
if isEnter {
- ctxStruct = "trace_event_raw_sys_enter"
+ ctxStruct = "syscall_trace_enter"
}
eventStruct := eventStructName(tp.Classification.Kind)