CVE-2023-31248 - Linux Kernel nftables Use-After-Free Local Privilege Escalation Explained
In May 2023, a serious security issue was disclosed in the Linux kernel's nftables subsystem. Identified as CVE-2023-31248, this vulnerability enables local attackers to escalate their privileges via a use-after-free (UAF) bug. The problem arises from improper checks in the nft_chain_lookup_byid() function. Specifically, it doesn't verify whether a chain is active, and doesn't properly gate powerful actions behind the appropriate network admin capabilities (CAP_NET_ADMIN) within user or network namespaces.
In this article, I'll break down what happened, why it's dangerous, and show you code snippets to help you understand the bug. We'll also look at references and even talk about exploitation—so you know what to watch out for.
What Is nftables?
nftables is the modern packet filtering framework in the Linux kernel, replacing iptables as of kernel version 3.13 (2014). It's used for controlling network traffic, performing Network Address Translation (NAT), and enforcing policy through chains and tables.
The Vulnerability: Use-After-Free in nft_chain_lookup_byid()
In short, the function nft_chain_lookup_byid() is responsible for looking up a chain object via its ID. A chain is an ordered list of rules that nftables uses for packet filtering. For safe operation, the function must ensure that the chain is “active”, meaning it exists and hasn’t been deleted by another thread/user.
The core issue?
nft_chain_lookup_byid() failed to check if the chain was still active. Attackers could exploit a race condition by deleting a chain, then immediately performing actions via its ID. This causes the kernel to access freed memory—a classic use-after-free situation. Worse, nftables actions were not always properly protected with capability checks, especially in the context of user namespaces or nested network namespaces.
Implication:
A regular (unprivileged) user in any user or network namespace could exploit this bug to gain escalated (root) privileges.
Vulnerable Code Snippet
Here’s a simplified representation of the vulnerable code from the kernel commit diff:
// net/netfilter/nf_tables_api.c
static struct nft_chain *nft_chain_lookup_byid(struct net *net, u32 chain_id)
{
struct nft_chain *chain;
/* ... */
list_for_each_entry(chain, &net->nft.chains, list) {
if (chain->id == chain_id)
return chain; // <-- No check whether the chain is still active!
}
return NULL;
}
The function grabs the chain by ID—but does not check if the chain is still active (i.e., it might already have been deleted by another thread). Once it returns a dangling pointer, anything could happen.
Create and delete a chain:
A malicious user creates a chain in their namespace, then quickly deletes it—freeing the structure.
Race to access freed memory:
By exploiting the lack of an “active” check, the attacker issues a command (like nft get or another update) targeting the same chain ID just after deletion, causing the kernel to act on the now-freed memory.
Privilege Escalation:
The attacker can corrupt kernel memory structures, usually by exploiting the UAF to write controlled data, eventually allowing for code execution as root.
This is a highly simplified logic and not a full exploit—just a minimal demonstration:
// User 1: quickly create and delete a chain
system("nft add table ip testtable");
system("nft add chain ip testtable testchain { type filter hook input priority ; }");
system("nft delete chain ip testtable testchain");
// User 2 or a second thread: race to lookup the chain by id
// (in real exploit, would use netlink calls and rapid forking/threading)
system("nft get chain ip testtable testchain"); // may access freed memory
The attacker would automate and synchronize this using threads or processes to maximize the race condition window.
References
- Linux Kernel Commit (fix)
- CVE-2023-31248 on NVD
- Red Hat Security Advisory
- Linux kernel bugzilla bug #217350
Mitigation
- Upgrade your kernel: Apply an updated kernel version with the fix backported. Most enterprise distributions have released patches.
- Limit unprivileged access: Limit who can create namespaces and use nftables features, especially on shared systems.
Conclusion
CVE-2023-31248 highlights the complexity and risk of subtle bugs in low-level kernel code. Even a small missed check can open the door to root-level exploits by any local user. Always keep your systems updated, and be aware of who can run privileged operations inside user or network namespaces.
Stay safe—and, as always, keep an eye out for future kernel advisories!
*If you found this helpful, please share or leave a comment. For more deep-dives into Linux security, follow this blog!*
Timeline
Published on: 07/05/2023 19:15:00 UTC
Last modified on: 08/02/2023 17:15:00 UTC