Repository navigation
feat(preflight): check capabilities and kernel before loading BPF - #191
Merged
Merged
Conversation
dodoazzurro
reviewed
Sep 12, 2026
dodoazzurro
left a comment
Collaborator
There was a problem hiding this comment.
Reviewed #191 (adds internal/preflight — kernel version advisory + capability check before BPF load).
Logic checks out:
ParseReleasehandles distro suffixes correctly (6.12.0-1-amd64→ 6.12,6.18.44-r0-gcp-6.18→ 6.18), and the test table covers the tricky cases (6.6-rc1, non-numeric major/minor, empty string, bare"6").- Kernel check is advisory-only (logs a warning, never blocks) — correct, since backports (RHEL 9.4/5.14) can't be detected from the version string alone.
- Capability check is the actual gate:
CAP_SYS_ADMINalone short-circuits as sufficient, otherwise bothCAP_BPFandCAP_PERFMONare required — matches how the perfmon/bpf cap split works (pre-5.8 kernels only hadCAP_SYS_ADMINfor bpf()). --userspace-bpfcorrectly implies skipping preflight (no kernel BPF path involved there).
One thing worth a second look: daemonize() calls o.preflight() once in the parent (to fail fast before forking) and then the re-exec'd daemon calls it again via Run() → setup() → preflight(). Not wrong, just means the check — and any kernel advisory warning — fires twice when detaching. Harmless (cheap syscalls) but slightly redundant logging in the daemon's log file.
Nothing blocking.
… BPF On kernels older than 6.6 (no BPF_TRACE_UPROBE_MULTI) or without the needed privileges, xcover failed with libbpf's bare "invalid argument" or an EPERM deep in the attach path. Add internal/preflight with a kernel release parser tolerant of distro suffixes, a comparison against the 6.6 minimum, and an effective capability check that accepts CAP_SYS_ADMIN or CAP_BPF plus CAP_PERFMON. Both checks return sentinel errors with actionable messages. The version check is a heuristic, so the error names the skip flag. The capability check reads the caller's effective set and cannot see user-namespace confinement.
Run the kernel and capability checks after setup in the foreground path and before forking in --detach mode, so the error reaches the user instead of only the daemon log. --userspace-bpf implies skipping, since bpftime needs neither kernel uprobe_multi nor privileges.
Distribution kernels backport uprobe_multi: RHEL 9.4 ships it on 5.14. A hard uname-based gate refused hosts where xcover works. Warn when the release looks older than 6.6, naming the backport case and the skip flag, and keep the capability check as the only hard failure.
Kernel row: 6.6 upstream or a distribution backport, checked with a warning at start. Privileges row: the effective capability set is checked and cannot see user-namespace confinement. Regenerate the run command page for --skip-preflight.
Kernel row: 6.6 upstream or a distribution backport, checked with a warning at start. Privileges row: the effective capability set is checked and cannot see user-namespace confinement.
maxgio92
force-pushed
the
feat/preflight
branch
from
September 12, 2026 21:01
ca40ccd to
a5ccf19
Compare
The capability check fails before any BPF load, so its error matched none of the runtime-environment markers and an unprivileged run failed instead of skipping. Match the sentinel and cover the matcher.
The parent ran preflight to fail fast and the re-exec'd daemon ran it again through setup, so the kernel advisory landed twice in the log. Forward --skip-preflight to the child unless the user set it.
… CLI The setcap hint named no file and did not mention that file capabilities do not apply under go run or on nosuid mounts. The kernel advisory recommended --skip-preflight, which also disables the hard capability check, so the checker no longer mentions the flag.
Attach failures are still only warned about on this branch, so the limitation still holds until the lifecycle fix lands.
Owner
Author
|
Fixed: preflight now runs once when detaching. The child gets Also on this branch:
|
The capability check reads the namespace-local effective set, so inside a rootless container it can pass and the BPF load then fails with libbpf's bare EPERM. xcover now warns when /proc/self/uid_map is not the identity map. The troubleshooting page and the README lead with the preflight message as the missing-privilege symptom and keep the libbpf error for --skip-preflight, user namespaces and seccomp or LSM denials.
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Add this suggestion to a batch that can be applied as a single commit.This suggestion is invalid because no changes were made to the code.Suggestions cannot be applied while the pull request is closed.Suggestions cannot be applied while viewing a subset of changes.Only one suggestion per line can be applied in a batch.Add this suggestion to a batch that can be applied as a single commit.Applying suggestions on deleted lines is not supported.You must change the existing code in this line in order to create a valid suggestion.Outdated suggestions cannot be applied.This suggestion has been applied or marked resolved.Suggestions cannot be applied from pending reviews.Suggestions cannot be applied on multi-line comments.Suggestions cannot be applied while the pull request is queued to merge.Suggestion cannot be applied right now. Please check back later.
xcover runchecks its environment before loading any BPF object so unsupported hosts get an actionable error instead of libbpf's bare "invalid argument". MissingCAP_BPFandCAP_PERFMON(orCAP_SYS_ADMIN) in the effective set is a hard failure that names the missing capabilities. A kernel release older than 6.6 is an advisory only, because distribution kernels backportuprobe_multi(RHEL 9.4 ships it on 5.14).--skip-preflightbypasses both checks and--userspace-bpfimplies it.Table tests cover the release parser, the capability decision and the skip paths.