In February 2024, a new security flaw and its patch emerged in the Linux kernel's network filtering subsystem, nf_tables. Identified as CVE-2024-26643, this bug revolved around a subtle race condition that could cause elements in anonymous sets, with timeouts enabled, to be incorrectly removed. In the wrong hands, this could have unpredictable security consequences. In this article, we’ll examine the vulnerability, show affected code, explain the impact, and walk through how it’s mitigated.
Background: What Are nf_tables and Anonymous Sets?
nf_tables is a framework inside the Linux kernel for packet classification, filtering, and NAT (Network Address Translation). It’s widely used for firewall operations.
The Problem: A Race Condition in gc of Anonymous Sets
A key internal operation is the rhashtable set garbage collector (gc), which runs asynchronously to clean up timed-out set elements. A *race* appears when:
At the same time, the garbage collector is running and also clearing elements.
The bug:
Because the gc is running asynchronously, it might process and free set elements *while* the commit path is still cleaning up, causing a double-free or collection of elements that should have stayed alive a bit longer. This race risks crashing the kernel or creating logic bugs.
Who Reported This?
Mingi Cho spotted anomalous behavior in Linux 6.1.x, especially when using a “pipapo” set with low timeouts. Later kernel versions had hardened this path, but the risk persisted for some scenarios until the recent mainline fix.
Original Risky Code
The problem arises because the garbage collector checks if a set is “dead” after it starts work—not before. Here’s a simplified view:
// set->flags didn't have DEAD flag at the right time!
if (!test_bit(NFT_SET_DEAD, &set->flags)) {
// proceed to gc and free elements
}
Meanwhile, the commit (release) path didn't set the DEAD flag early enough, so the gc could still run on that set’s elements.
The Fix
The patch ensures that any relevant set is marked as *dead* right when it starts being removed or aborted, telling the garbage collector to skip it:
// Before unbinding or aborting, set the DEAD flag
set_bit(NFT_SET_DEAD, &set->flags);
// Now gc will see this and NOT touch the set anymore
if (!test_bit(NFT_SET_DEAD, &set->flags)) {
// gc proceeds
}
This simple flag prevents concurrent access and double deletion.
Exploitability & Impact
- Denial of Service (DoS): An attacker with Netfilter rule privileges (e.g., root or CAP_NET_ADMIN) could potentially crash the kernel, triggering instability or a reboot.
- Data Races/State Leaks: The same race could allow improper garbage collecting or leaking of state about firewall sets.
Note: There’s no indication of privilege escalation from this alone, as the attacker requires a high privilege to use nf_tables, but server reliability is critical!
Exploit Example (Hypothetical)
Suppose you control netfilter rules and repeatedly create and destroy anonymous sets with very short timeouts:
nft add set inet filter anonset { type ipv4_addr\; timeout 1ms\; }
nft add element inet filter anonset { 1.2.3.4 }
nft delete set inet filter anonset
# Repeat quickly in a loop
On affected kernels, this script could trigger the race, potentially leading to a crash.
Patch fixing code:
netfilter: nf_tables: mark set as dead when unbinding anonymous set with timeout
More Reading
- CVE Page: CVE-2024-26643 at NVD
- Original bug report/discussion:
Mingi Cho’s report and patch discussion
- Netfilter project
Conclusion
CVE-2024-26643 is a good example of how concurrency bugs can creep into performance-optimized kernel code. It would be hard to exploit for non-privileged users, but system operators and distribution maintainers should keep firewalls patched against such DoS vectors.
Action: If you administer Linux servers with nftables, update as soon as the patch lands in your distro.
Timeline
Published on: 03/21/2024 11:15:28 UTC
Last modified on: 03/13/2025 21:20:19 UTC