![](https://hosting.photobucket.com/images/ii182/ecc803/CVE-2024-41009-Linux-Ring-Buffer.jpg)
Preface: Consumer and producer counters are put into separate pages to allow each position to be mapped with different permissions. This prevents a user-space application from modifying the position and ruining in-kernel tracking. The permissions of the pages depend on who is producing samples: user-space or the kernel. Starting from Linux 5.8, BPF provides a new BPF data structure (BPF map): BPF ring buffer (ringbuf). It is a multi-producer, single-consumer (MPSC) queue and can be safely shared across multiple CPUs simultaneously.
Background: The first core skill point is “BPF Hooks”, that is, where in the kernel can BPF programs be loaded. There are nearly 10 types of hooks in the current Linux kernel, as shown below:
kernel functions (kprobes)
userspace functions (uprobes)
system calls
fentry/fexit
Tracepoints
network devices (tc/xdp)
network routes
TCP congestion algorithms
sockets (data level)
Vulnerability details: For example, consider the creation of a BPF_MAP_TYPE_RINGBUF map with size of 0x4000. Next, the consumer_pos is modified to 0x3000 /before/ a call to bpf_ringbuf_reserve() is made. This will allocate a chunk A, which is in [0x0,0x3008], and the BPF program is able to edit [0x8,0x3008]. Now, lets allocate a chunk B with size 0x3000. This will succeed because consumer_pos was edited ahead of time to pass the `new_prod_pos – cons_pos > rb->mask` check. Chunk B will be in range [0x3008,0x6010], and the BPF program is able to edit [0x3010,0x6010]. Due to the ring buffer memory layout mentioned earlier, the ranges [0x0,0x4000] and [0x4000,0x8000] point to the same data pages. This means that chunk B at [0x4000,0x4008] is chunk A’s header. bpf_ringbuf_submit() / bpf_ringbuf_discard() use the header’s pg_off to then locate the bpf_ringbuf itself via bpf_ringbuf_restore_from_rec(). Once chunk B modified chunk A’s header, then bpf_ringbuf_commit() refers to the wrong page and could cause a crash.
Official announcement: Please refer to the official announcement for details – https://git.kernel.org/pub/scm/linux/kernel/git/stable/linux.git/commit/?id=47416c852f2a04d348ea66ee451cbdcf8119f225