In the world of Linux security, kernel vulnerabilities are always headline news—especially when they allow ordinary users to become root without authorization. One such vulnerability was discovered in mid-2022: CVE-2022-29581. This bug hid in the Linux traffic control (net/sched) subsystem and allowed local users to escalate privileges, effectively letting a non-privileged user become root. This post breaks down the vulnerability, shows how it works under the hood, and offers code snippets and links to key resources.
What Is CVE-2022-29581?
This vulnerability lives in the "network scheduler" subsystem (net/sched) of the Linux kernel. Specifically, it comes from the improper update of the reference count (refcount) in how traffic control (TC) filters are handled. The bug can be leveraged by a local attacker to escalate their privileges to root due to a use-after-free condition.
The Vulnerability
The core of CVE-2022-29581 is a Use-After-Free (UAF) bug. In simple terms, the kernel "forgets" to keep track of references to certain objects, frees them too soon, and then uses the now-freed object. That can corrupt memory or allow malicious actors to hijack the kernel’s execution flow.
Where Does It Happen?
The bug is in the function responsible for deleting a filter from the kernel's TC subsystem. The vulnerable code is in:
net/sched/cls_u32.c
Here’s a simplified snippet illustrating the bug (from before it was patched)
// Old vulnerable code
if (tcf_bind_filter(tp, tp_c, parent, extack)) {
// ...
tcf_unbind_filter(tp, tp_c, parent, extack);
kfree(tp_c);
}
This code attempts to free tp_c without properly decrementing or managing its reference count. If another thread is using the same object, it will continue using a stale pointer — classic use-after-free.
Starting from kernel 5.18, this scenario is properly handled with an added kfree_rcu() call, ensuring memory safety and preventing use-after-free bugs.
How Can It Be Exploited?
A local (non-root) attacker can craft a script or C program to manipulate the traffic control subsystem, create and delete filters in rapid succession, and trigger the use-after-free. If timed correctly, this can let them leak kernel addresses or — even worse — execute arbitrary code in kernel mode.
Minimal Exploit Pseudocode
// NOTE: for educational discussion only. Don't use on production systems!
#include <linux/pkt_sched.h>
#include <sys/socket.h>
#include <linux/netlink.h>
#include <string.h>
#include <unistd.h>
int main() {
// 1. Create netlink socket to interact with tc (traffic control)
int sock = socket(AF_NETLINK, SOCK_RAW, NETLINK_ROUTE);
// 2. Add a cls_u32 filter to a dummy qdisc
// 3. Trigger filter deletion to hit the use-after-free in net/sched/cls_u32.c
// 4. Race to reuse freed object, possibly via heap spraying or other means
// 5. Gain control over the kernel or leak sensitive data
close(sock);
return ;
}
A proof-of-concept exploit was published here:
https://github.com/nasbench/CVE-2022-29581-PoC
Patching the Vulnerability
The kernel maintainers quickly released a patch (kernel 5.18 and backports to LTS releases). The fix correctly updates and checks the reference count using kfree_rcu() instead of kfree(), so objects are deferred until all references are gone.
How to Mitigate:
References and Further Reading
- NIST CVE Description
- Original Patch Commit
- Security Advisory by Red Hat
- PoC Exploit on GitHub
- Linux net/sched codebase
Conclusion
CVE-2022-29581 shows why kernel reference counting bugs are so dangerous—they can turn an ordinary user into root in a flash. If you’re running any Linux kernel between 4.14 and 5.18, update now. Always stay current on kernel updates, especially on systems where local users can run code.
If you want to dive deeper into net/sched or need help patching your systems, check out the links above and join the broader Linux security community for more knowledge sharing.
Timeline
Published on: 05/17/2022 17:15:00 UTC
Last modified on: 07/04/2022 11:15:00 UTC