Skip to content

Fix BPF tracepoint attachment failure on kernel 6.12+ (EACCES)#3

Open
ardnew wants to merge 2 commits into
ironsh:mainfrom
ardnew:main
Open

Fix BPF tracepoint attachment failure on kernel 6.12+ (EACCES)#3
ardnew wants to merge 2 commits into
ironsh:mainfrom
ardnew:main

Conversation

@ardnew

@ardnew ardnew commented Mar 29, 2026

Copy link
Copy Markdown

Problem

The sensor fails to start on kernels ≥ 6.12 with:

loading BPF programs: attaching fork tracepoint: cannot create bpf perf link: permission denied

Root cause

Kernel 6.12 made TASK_COMM_LEN configurable, which changed the sched_process_fork tracepoint format. The parent_comm and child_comm fields went from fixed char[16] arrays to __data_loc char[] descriptors (4 bytes each), shrinking the tracepoint data area from 48 to 24 bytes.

Our tp_fork_ctx struct still used char[16] for both fields, so the BPF verifier recorded max_ctx_offset = 48. At attachment time, the kernel checks prog->aux->max_ctx_offset > trace_event_get_offsets() and returns EACCES when the program would read out of bounds.

Fix

Replace the manual tp_fork_ctx struct with CO-RE reads (BPF_CORE_READ) against trace_event_raw_sched_process_fork from vmlinux.h. The CO-RE loader relocates the parent_pid and child_pid field offsets at load time based on the running kernel's BTF, so the same compiled BPF object works on both pre-6.12 and 6.12+ kernels. No vmlinux.h update is required.

Testing

  • All 10 e2e tests pass (TestSensorDetections/*)
  • All unit tests pass, go vet clean
  • Verified all 6 BPF programs attach to their correct tracepoints

Kernel 6.12+ changed the sched_process_fork tracepoint's parent_comm
and child_comm fields from fixed char[16] arrays to __data_loc char[]
(4 bytes each) due to configurable TASK_COMM_LEN. The old struct layout
caused the BPF program to declare context accesses up to byte 48, but
the tracepoint data area is only 24 bytes. The kernel rejects this in
__perf_event_set_bpf_prog() where max_ctx_offset > trace_event_get_offsets()
returns EACCES.

Replace the manual tp_fork_ctx struct with CO-RE reads (BPF_CORE_READ)
against trace_event_raw_sched_process_fork from vmlinux.h. The CO-RE
loader relocates the parent_pid and child_pid field offsets at load time
based on the running kernel's BTF, so the same compiled program works
on both pre-6.12 and 6.12+ kernels.

Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com>
Copilot AI review requested due to automatic review settings March 29, 2026 20:54

Copilot AI left a comment

Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Pull request overview

This PR fixes a BPF tracepoint attachment failure on Linux kernels ≥ 6.12 by avoiding hard-coded sched_process_fork tracepoint context layouts and instead relying on CO-RE field offset relocation at load time.

Changes:

  • Remove the manual tp_fork_ctx struct that no longer matches kernel 6.12+ tracepoint layouts.
  • Update the sched/sched_process_fork tracepoint program to read parent_pid/child_pid via BPF_CORE_READ from trace_event_raw_sched_process_fork.

💡 Add Copilot custom instructions for smarter, more guided reviews. Learn how to get started.

Comment thread bpf/sensor.c Outdated
@mslipper

Copy link
Copy Markdown
Contributor

Hey thanks for this! Will give this a test and get back to you.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

3 participants