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!
}
Reference Links & Upstream Details
- 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