Ebpf Security Model
What We Load
| Program | Type | Attach |
|---|---|---|
oom_kill.bpf.c | tracepoint | oom:mark_victim |
page_fault.bpf.c | tracepoint | exceptions:page_fault_user/kernel |
block_io.bpf.c | tracepoint | block:block_rq_complete |
tcp_retransmit.bpf.c | tracepoint | tcp:tcp_retransmit_skb |
gpu_process.bpf.c | uprobe | libcuda.so cudaLaunchKernel/Memcpy/StreamSync |
nccl_socket.bpf.c | uprobe | libnccl.so ncclCommInitRank/AllReduce/Bcast/CommDestroy |
Why This is OK
1. Verifier
All programs pass the kernel verifier before being loaded. Any unbounded loops or unbounded memory access is rejected.
2. No PII / No Process Memory Dump
Our programs emit only:
- PIDs, comm (process name) — already public via
/proc. - Latencies, addresses — already public via
/proc/vmstat,/proc/<pid>/wchan.
We never read full instructions, full instruction pointers, or sensitive kernel struct fields beyond what the tracepoint already exposes.
3. Bounded Ringbuffers
Each program uses a 4MB ringbuffer (BPF_MAP_TYPE_RINGBUF). The user-space consumer caps at 1,000 events/sec with drop+counter on overflow. The maps have no unprivileged read.
4. Pinning
Pinned to /sys/fs/bpf/denpex/<program> with BPF_F_PIN_GLOBAL so a privileged re-attach doesn't lose history, but a malicious unprivileged user can't read or write the maps.
5. Signed Loader
denpex-bpf-loader is signed at build time and verified at boot via cosign / sigstore. A tampered loader refuses to load.
6. No Network Probes
The eBPF programs only emit events via the ringbuffer. They do not initiate network communication.
What We DON'T Load
- Network XDP/TC programs.
- kprobes into kernel modules outside the allow-list.
- USDT probes anywhere outside the libc/libm allow-list.
- LSM hooks (no BPF-LSM).
CI Test Path
For CI / non-Linux runners, the loader reports a capability_missing event for every program, and the agent falls back to journald-only collection. Tests still pass.