CVE-2024-26581: Linux Kernel netfilter UAF — Container Escape via nf_tables
A use-after-free vulnerability in the Linux kernel's netfilter nf_tables subsystem allowed local attackers to achieve kernel code execution and container escape through crafted Netlink messages in unprivileged network namespaces.

TL;DR
A race condition in nf_tables batch processing led to use-after-free when destroying tables with active sets, allowing local privilege escalation from unprivileged user namespaces. The vulnerability enabled container escapes and affects kernels from 5.2 through 6.8-rc2.
Affected versions
Linux kernel versions 5.2 through 6.8-rc2 (prior to 6.8-rc3, released February 2024) are vulnerable. This includes:
- RHEL 8.x and 9.x
- Ubuntu 20.04 LTS through 23.10
- Debian 11 (Bullseye) and 12 (Bookworm)
- SUSE/SLES 15.x
- Any distribution running kernel versions in the affected range
The vulnerability was introduced in kernel 5.2 when nf_tables anonymous sets were added (commit 958bee14d071). Containerized environments (Docker, Kubernetes, LXC) using affected kernels are particularly at risk since unprivileged users can create network namespaces with CAP_NET_ADMIN and manipulate nf_tables.
Root cause
The vulnerability exists in the nf_tables subsystem's transaction batching mechanism in net/netfilter/nf_tables_api.c. nf_tables uses a complex transaction system to apply multiple operations atomically through Netlink messages.
The specific issue occurs during table deletion when sets (data structures for efficient packet matching) are still referenced:
- Transaction handling: nf_tables batches multiple operations (create/delete/modify) before committing
- Reference counting flaw: When destroying a table (
NFT_MSG_DELTABLE), the code releases table resources during commit phase - Race window: If a set bound to the table is being accessed simultaneously (e.g., during packet processing or another transaction), references become invalid
- Premature free: The transaction code in
nft_commit_release()frees table structures while set elements may still hold pointers
The problematic code path:
cnft_commit_release() └─> nft_table_destroy() └─> kfree(table) // Frees table while sets may reference it
Meanwhile, concurrent operations might access:
cnft_set_destroy() └─> table->... // Accesses freed table memory
The core issue is insufficient synchronization between transaction commit and set element cleanup, particularly when tables are destroyed while sets contain elements that hold references to table metadata.
Exploitation primitive
Exploitation requires triggering the UAF through precise timing and leveraging kernel heap grooming:
- Namespace creation: Create unprivileged user+network namespace pair (requires
CONFIG_USER_NS=y) - nf_tables setup: Within namespace, use CAP_NET_ADMIN to create nf_tables chains and sets
- Race preparation:
- Create a table with multiple sets containing elements
- Prepare Netlink messages to delete the table
- Simultaneously prepare operations that access set elements
- Trigger UAF: Send concurrent Netlink messages to:
- Delete the table (triggering
nft_commit_release()) - Access/modify set elements (accessing freed table pointer)
- Delete the table (triggering
- Heap spray: Spray kernel heap with controlled data to reclaim freed table memory
- Corrupt function pointers: The freed table structure contains function pointers (e.g., for set operations); overwriting these provides RIP control
- Kernel exploitation:
- Pivot to arbitrary kernel read/write using physmap spray
- Modify creds structure to gain root (
commit_creds(prepare_kernel_cred(0))) - Bypass SMEP/SMAP using ROP or modprobe_path overwrite
- Escape container by accessing host filesystem/namespaces
The exploit is reliable in containerized environments because:
- Unprivileged user namespaces are commonly enabled
- Network namespaces grant CAP_NET_ADMIN automatically
- Container kernel is shared with host, so kernel exploitation = host root
Mitigation
Immediate action required:
-
Patch kernels to 6.8-rc3 or later, or apply backported fixes from distribution vendors (RHEL: RHSA-2024:1248, Ubuntu: USN-6625-1)
-
Disable unprivileged user namespaces if not required:
bashsysctl -w kernel.unprivileged_userns_clone=0 # Or via kernel parameter: user_namespace.enable=0 -
Runtime protection:
- Apply SELinux/AppArmor policies denying CAP_NET_ADMIN in containers
- Use seccomp profiles blocking
nftablesNetlink operations - Enable kernel.yama.ptrace_scope=1 at minimum
-
Container hardening:
- Drop CAP_NET_ADMIN from container capabilities unless absolutely necessary
- Use user namespace remapping (Docker
userns-remap) - Deploy Kubernetes with restricted PSPs/PSAs preventing privileged operations
-
Detection:
- Monitor for unusual nf_tables operations in containers:
auditctl -a always,exit -F arch=b64 -S socket -F a0=0x10 -k netfilter - Alert on unprivileged namespace creation patterns
- Watch for kernel crashes in nf_tables code paths
- Monitor for unusual nf_tables operations in containers:
The kernel patch adds proper reference counting and synchronization in nft_commit_release() to ensure tables aren't freed while referenced by sets, and enhances locking around transaction cleanup phases.
Comments (0)
// go deeper
- Practice this in a legal lab: Container Escape via /proc
- Read the writeup: CVE-2024-26581: Linux Kernel netfilter UAF — Exploiting nft_set_desc Reference Counting
- Read the writeup: CVE-2024-1086: Linux kernel nf_tables use-after-free enabling container escape
- Read the writeup: CVE-2024-26581: Linux Kernel netfilter UAF — Root Through Connection Tracking