A serious vulnerability, CVE-2024-27010, was found and resolved in the Linux kernel affecting the net/sched code base. This bug could cause a kernel deadlock if certain traffic control (tc) configurations are used—most notably, when redirecting or mirroring packets back to the originating interface (device). This post breaks down the vulnerability, demonstrates simple reproduction steps, examines the patch, and provides links and context for deeper understanding.
What Is the Issue?
The vulnerability lies in the Linux kernel’s “mirred” action, commonly used for redirecting (or mirroring) traffic between interfaces using tc. When using a classful egress queuing discipline (qdisc) and redirecting packets to the same device (“device recursion”), a recursive locking can occur, leading to a hard kernel deadlock.
In plainer terms: if a network packet is redirected from eth back to eth, or between two interfaces which redirect back to each other, internal kernel locks are reacquired ("double locked") by the same CPU, causing the system to hang. This can halt network operations or even freeze the entire system.
Example 1: Loop on a Single Device
This rule will redirect every packet on eth right back to eth. It’s all it takes to potentially deadlock your system:
tc qdisc add dev eth root handle 1: htb default 30
tc filter add dev eth handle 1: protocol ip prio 2 matchall \
action mirred egress redirect dev eth
If you have two interfaces, you can build a redirection loop between them
tc qdisc add dev eth root handle 1: htb default 30
tc filter add dev eth handle 1: protocol ip prio 2 matchall \
action mirred egress redirect dev eth1
tc qdisc add dev eth1 root handle 1: htb default 30
tc filter add dev eth1 handle 1: protocol ip prio 2 matchall \
action mirred egress redirect dev eth
Now, packets will ping-pong between eth and eth1, with each device’s qdisc trying to lock itself again.
When this bug is hit, you’ll see something like this in the kernel logs (dmesg)
WARNING: possible recursive locking detected
ping/418 is trying to acquire lock:
(&sch->q.lock){+.-.}-{3:3}, at: __dev_queue_xmit+x1778/x355
but task is already holding lock:
(&sch->q.lock){+.-.}-{3:3}, at: __dev_queue_xmit+x1778/x355
* DEADLOCK *
This means the kernel noticed the same CPU tried to lock the queue discipline structure (q.lock) twice while handling the same packet chain, which is a classic deadlock pattern.
Why Did It Happen?
- Cause: The “mirred action” did not track if the current operation had already entered the root qdisc via the current CPU, leading to repeated locking when recursion happened.
- Effect: If a mirrored/redirected traffic rule sent packets back into an egress qdisc (on self or via a loop), the lock would be acquired again by the same CPU/task—resulting in a deadlock.
The Patch: Owner Field to the Rescue
The vulnerability was fixed in kernel commit 7e8eafc36374 (and backported to appropriate maintained series). The fix is simple but effective:
A new field, owner, is added to the Qdisc structure.
- When a softirq (the kernel context where network packet processing happens) enters a root qdisc, this owner (set to the CPU’s ID) is marked.
- If the qdisc is re-entered by the same CPU (indicating recursion), the packet is dropped, breaking the loop and preventing the deadlock.
Simplified Code Snippet from the Patch
struct Qdisc {
// ... existing fields ...
int owner; // newly added
};
// In enqueueing code:
int cpu = smp_processor_id();
if (qdisc->owner == cpu) {
// Detected recursion: drop the packet!
kfree_skb(skb);
return NET_XMIT_DROP;
}
qdisc->owner = cpu;
// continue normal processing...
Linux kernel 6.8 and possibly other versions before the patch
- Custom routers, servers, or firewalls using advanced tc/mirred setups
Update Your Kernel
- Make sure your system runs a kernel version that includes the fix (see this commit).
Avoid Known-Bad tc Patterns
- Until upgraded, avoid setting up mirred rules that mirror or redirect packets back to their originating interface or into loops.
References
- CVE-2024-27010 @ NVD
- Upstream Patch: net/sched: Fix mirred deadlock on device recursion
- Linux Kernel Traffic Control (TC) Docs
In Summary
CVE-2024-27010 was a classic kernel deadlock caused by not tracking which CPU owned a qdisc lock during packet redirection. If you’re running a router, gateway, or server with unusual tc mirroring/redirect rules—and especially if you’re using classful qdiscs—make sure you apply this kernel fix. This keeps your networking stack reliable and prevents hard-to-diagnose system freezes.
Timeline
Published on: 05/01/2024 06:15:19 UTC
Last modified on: 12/23/2024 14:05:34 UTC