CVE-2024-36925 - How Uninitialized Pool Lists in Linux Kernel DMA Handling Could Crash Your System (with Fix, Analysis, and Exploit Insight)

In the world of Linux kernels, Direct Memory Access (DMA) is critical for efficient hardware communication. Special configs—like dynamic SWIOTLB and restricted DMA pools—help manage memory in secure, high-performance systems. But sometimes, when two clever features meet, they create unexpected chaos. This is the story behind CVE-2024-36925, where a tiny initialization bug could take down your kernel.

What is CVE-2024-36925?

CVE-2024-36925 is a vulnerability in the Linux kernel that relates to the way the kernel initializes memory pool lists when both dynamic SWIOTLB (CONFIG_SWIOTLB_DYNAMIC=y) and restricted DMA pools (CONFIG_DMA_RESTRICTED_POOL=y) options are turned on. When these configs are combined, you can hit a crash right at boot.

If you boot a machine with these settings, you might see a crash like

Unable to handle kernel NULL pointer dereference at virtual address 0000000000000008
Internal error: Oops: 0000000096000005 [#1] PREEMPT SMP
pc : rmem_swiotlb_device_init+xfc/x1ec
...

This basically means the kernel tried to access memory it shouldn't, right as it was starting up — worst timing!

Where is the Bug? Technical Breakdown

Let’s walk through the actual code bug and why it happens.

Key Files Involved

- kernel/dma/swiotlb.c
- include/linux/list.h
- include/linux/rculist.h

The Failing Code Path

At boot, rmem_swiotlb_device_init() tries to initialize a memory pool and calls add_mem_pool(). But if the list head for mem->pools wasn’t set up, this line:

list_add_rcu(&pool->list, &mem->pools);

...would then try to add to a list head that wasn’t initialized—essentially a null pointer. In C, that leads straight to a crash.

Example from Crash Stack

kernel/dma/swiotlb.c:306
kernel/dma/swiotlb.c:1695

Here’s a rough snippet showing where the error happens

// buggy code snippet before the fix
void rmem_swiotlb_device_init(…) {
    // other initializations
    add_mem_pool(mem);   // mem->pools wasn't initialized!
}

- Upstream Linux commit with the fix
- Mainline Kernel Patch (kernel.org)
- CVE Details entry (when available)

Impact

- Privilege Escalation / Denial-of-Service: While the bug occurs at boot and would mostly just crash the machine, if a malicious actor could trigger reserved-memory DMA pool at runtime (e.g., with custom device tree overlays or kernel modules), they could potentially cause a controlled crash (DoS) or worse, depending on system architecture.
- Affected systems: Any Linux systems with both CONFIG_SWIOTLB_DYNAMIC and CONFIG_DMA_RESTRICTED_POOL enabled (common in virtualized/cloud and ARM server environments).

Exploit Example

While this isn't a classic remote code execution hole, it can be exploited to forcibly crash systems—impacting uptime-hungry environments.

A simplified local DoS (Denial of Service) exploit would look like

// This code won't run outside the kernel, but illustrates the logic
// Pseudo-exploit: Simulate device init with uninitialized mem->pools
struct restricted_mem *mem = kmalloc(sizeof(*mem), GFP_KERNEL);
// 'mem->pools' not initialized
add_mem_pool(mem); // Triggers crash (list_add_rcu derefs NULL)

Again: In most cases, exploiting this requires low-level access (e.g., custom kernel builds, driver modifications, or special device overlays). But in some cloud or embedded scenarios, these configs *do* get turned on by accident.

How To Fix (Code Sample)

The official fix: Initialize the mem->pools list head before using it.

Corrected Code Snippet

#include <linux/list.h>

// In kernel/dma/swiotlb.c
void rmem_swiotlb_device_init(struct restricted_mem *mem)
{
    INIT_LIST_HEAD(&mem->pools);  // <-- THIS IS THE CRUCIAL LINE!
    add_mem_pool(mem);            // Safe now!
}

This one line prevents a nasty crash by making sure the linked list is correctly set up before adding to it.

Conclusion

CVE-2024-36925 is a perfect example of the kind of subtle, systemic bugs that can wreak havoc in complex system software. By simply forgetting to initialize a list head, the Linux kernel could crash right at boot if certain features are combined.

Follow upstream Linux kernel mailing lists for security announcements.

Takeaways for sysadmins: If you run kernels with restricted DMA pools and dynamic SWIOTLB, *patch now* or make sure your distributions have rolled out this fix.

References

- Upstream Fix on GitHub
- Linux Kernel Mainline Patch
- CVE Database

For technical folks and kernel maintainers: Always read your boot logs—and remember: that one call to INIT_LIST_HEAD() can save your bacon!

Timeline

Published on: 05/30/2024 16:15:15 UTC
Last modified on: 06/10/2024 19:21:01 UTC