HIGH Introduced in 2.6.33
sch_teql LowerQdisc UAF
CVE-2026-99282
CVSS:3.1/AV:L/AC:L/PR:L/UI:N/S:U/C:H/I:H/A:H
01Description
In the Linux kernel, the following vulnerability has been resolved: net/sched: sch_teql: fix use-after-free on lower qdisc drop The issue: teql_master_xmit() tests the slave's ndo_start_xmit() return value against NETDEV_TX_OK alone. A slave that consumes the skb but returns an error code (rc < NET_XMIT_MASK, e.g. NET_XMIT_DROP) is treated as if the skb were still owned, so the loop restores skb->dev and calls __skb_pull() on it. A VLAN slave returns the result of dev_queue_xmit() from its ndo_start_xmit() (propagated since cbbef5e18307), and when the lower qdisc drops the packet that value is NET_XMIT_DROP after the skb has been freed, giving a use-after-free in teql_master_xmit(). The Fix: test for consumption with dev_xmit_complete(), which accepts NETDEV_TX_OK and every rc < NET_XMIT_MASK, matching other callers that need to distinguish consumed results from busy. Only NETDEV_TX_OK keeps the packet counted in tx_packets/tx_bytes and advances the slave; a consumed result that is neither a success nor NET_XMIT_CN ends the attempt and is charged to tx_dropped, so lower-qdisc drops are no longer reported as good transmits. NET_XMIT_CN is counted like success because it can accompany acceptance of the current packet: pfifo_head_drop drops the old head, enqueues the current skb and returns NET_XMIT_CN. Conditions to recreate the bug: With CONFIG_NET_SCH_TEQL, CONFIG_VLAN_8021Q and CONFIG_DUMMY enabled, add lkrdummy0 (dummy) and lkrvlan0 (VLAN id 37 on lkrdummy0); set a pfifo limit 0 root on lkrdummy0 and a teql0 root on lkrvlan0; bring teql0 up with an address and send one UDP packet to it. The VLAN xmit returns NET_XMIT_DROP from the lower qdisc while holding a freed skb.
02KernelScan AI Analysis
Risk summary
A local attacker with CAP_NET_ADMIN (obtainable in a user namespace) can trigger a use-after-free in the TEQL qdisc by configuring a VLAN slave over a dummy interface with a zero-limit pfifo qdisc and transmitting a packet. This leads to kernel memory corruption, enabling privilege escalation to root or kernel code execution. The bug is reachable on any system with the TEQL, VLAN, and DUMMY kernel modules enabled.
Vulnerability analysis
The TEQL qdisc's transmit function incorrectly assumes that a slave device's ndo_start_xmit() returns NETDEV_TX_OK only when the packet was successfully transmitted and the skb is still owned. In reality, a VLAN slave propagates the return value from dev_queue_xmit(), which can be NET_XMIT_DROP when a lower qdisc drops the packet after consuming (freeing) the skb. The original code treated this error as if the skb were still valid, restoring skb->dev and calling __skb_pull() on freed memory. The fix replaces the equality check with dev_xmit_complete(), which correctly identifies all consumption return codes (NETDEV_TX_OK and any rc < NET_XMIT_MASK). Consumed-but-dropped packets are now counted in tx_dropped and the transmit returns success to the caller, preventing the use-after-free. Only NETDEV_TX_OK and NET_XMIT_CN advance the slave and count as successful transmits. An attacker needs local access and CAP_NET_ADMIN to configure the required qdisc hierarchy, which is achievable inside a user namespace.
Lifecycle
03Fix Versions
| Branch | Introduced | Fixed in | Patch commit |
|---|---|---|---|
| 6.18 | 2.6.33 | 6.18.61 | fc55d92ae6a4 |
| 7.3 | 2.6.33 | 7.3.2 | 2702ae318630 |
| mainline | 2.6.33 | 7.4-rc1 | 782d6bb8f9b8 |
04CIP Kernels
State of the newest release of each Civil Infrastructure Platform SLTS tree, from CIP's own fix records.
| CIP tree | State |
|---|---|
| cip/6.12 | Affected — no CIP fix yet (latest 6.12.114-cip34) |
| cip/6.1 | Affected — no CIP fix yet (latest 6.1.190-cip62) |
| cip/6.1-rt | Affected — no CIP fix yet (latest 6.1.189-cip61-rt32) |
| cip/5.10 | Affected — no CIP fix yet (latest 5.10.272-cip79) |
| cip/5.10-rt | Affected — no CIP fix yet (latest 5.10.272-cip79-rt35) |
| cip/4.19 | Affected — no CIP fix yet (latest 4.19.325-cip136) |
| cip/4.19-rt | Affected — no CIP fix yet (latest 4.19.325-cip136-rt50) |
| cip/4.4 | Affected — no CIP fix yet (latest 4.4.302-cip115) |
| cip/4.4-rt | Affected — no CIP fix yet (latest 4.4.302-cip115-rt63) |