Repository navigation
fix: run on RHEL 8 kernels (probe for BPF ring buffers, fix two Go TLS programs) - #383
Conversation
The agent refused any kernel older than 5.8, the release that added BPF ring buffers. RHEL 8 and its rebuilds run 4.18 with ring buffers backported, so they were refused although the programs could load. Probe for the map type instead; kernels without it still get a clear error before the programs fail to load.
RHEL 8 kernels reject go_crypto_tls_read_enter and go_crypto_tls_write_enter with "invalid read from stack": fd is filled in by a helper only on its success path, and the older verifier can't tell the error path returns first.
…rrors The probe runs before the tracer raises RLIMIT_MEMLOCK, so on kernels that still charge BPF maps to it, or without privileges, it can fail for reasons unrelated to ring buffer support. Those now log a warning and leave the error to the program loader.
There was a problem hiding this comment.
Code Review
This pull request adds support for distribution kernels that backport BPF ring buffers (such as RHEL 8) by replacing the hardcoded kernel version check with a feature probe for ebpf.RingBuf support. It also initializes the fd variable in gotls.c to satisfy the RHEL 8 BPF verifier. Feedback suggests raising the RLIMIT_MEMLOCK limit before performing the feature probe to avoid spurious warnings on older kernels.
Kernels before 5.11 charge the probe's map to it, so a low limit made the probe fail with a spurious warning (#383 review).
|
LGTM. Probing for One note: only Rocky 8.10 (4.18.0-553) was tested. RHEL 8 minors differ in their BPF backports. The probe catches missing ring buffers, but verifier differences in older minors (8.4/8.6) would only show at load time. Worth stating the tested release in the README or release notes ("tested on RHEL 8.10 and rebuilds"), so users on older minors know. |
# Conflicts: # ebpftracer/ebpf.go
|
Merged main and regenerated |
Summary
The agent now runs on RHEL 8 and its rebuilds (Rocky, Alma, Oracle Linux 8), whose 4.18 kernels backport BPF ring buffers.
RLIMIT_MEMLOCKis raised before the probe, as the tracer already did before loading, because kernels before 5.11 charge the probe's map to it. Only a definite "not supported" result is fatal; any other probe error (such as missing privileges) logs a warning and leaves the error to the program loader.go_crypto_tls_read_enterandgo_crypto_tls_write_enter("invalid read from stack"). Both read a file descriptor that a helper fills in only when it succeeds. The variable is now zero-initialized. Newer verifiers accepted the code because they track that the error path returns first.Engineering detail
How the failing programs were found: I loaded each program of the 4.16 amd64 object on its own on Rocky 8.10 (kernel 4.18.0-553) and read the verifier log. Before the fix, 2 of 42 programs failed (the two above); after it, 0 of 42.
Other kernels: with the regenerated objects, every program still loads on 6.1 (5.12 variant, with and without ctx padding, 40 of 40 programs) and on 5.10 (5.6 variant, 40 of 40).
Memlock and the probe: 5.10 still charges BPF maps to
RLIMIT_MEMLOCK, and the tracer only raised it later, at load time. WithLimitMEMLOCK=0:ebpf.go: regenerated withmake buildinebpftracer. Only the embedded objects changed (every variant, both architectures).CI: gofmt, goimports, vet, golangci-lint,
go test(excluding/containers) and the build all pass in a Linux container with Go 1.26.5.Local e2e: I ran agent binaries built from this branch as systemd services on local VMs.
crypto/tlsclients against local HTTP and HTTPS servers:go_crypto_tls_read_enterverifier error.LimitMEMLOCK=0: the probe-only version exited with the false "does not support BPF ring buffers" error. The final version logs no probe warning, starts, and serves container metrics.