PT-2026-117016 · Linux · Linux

CVE-2026-98797

·

Publicado

2026-10-18

·

Atualizado

2026-10-18

Nenhuma

Não há classificações de severidade ou métricas disponíveis. Quando houver, atualizaremos as informações correspondentes na página.
In the Linux kernel, the following vulnerability has been resolved:
net: cap skb->queue mapping when the tx queue is picked
skbedit can set skb->queue mapping and raise the per-CPU skip txqueue flag so dev queue xmit() honours the mapping. dev queue xmit() cleared the flag before sch handle egress() and only read it afterwards, so the flag was not confined to the xmit that set it: a nested xmit (mirred redirect or mirror, or a drop after skbedit) could set the flag and the outer xmit would consume it for an skb that never went through skbedit.
A forwarded packet still carries the ingress NIC's rx queue + 1 in skb->queue mapping, so the outer device then indexes its tx queue state with that stale value. Taprio's child array q->qdiscs[] is sized to the device's queue count, so taprio enqueue() indexes past its allocation and dereferences the result as a struct Qdisc *.
We (ab)use the skb->nf skip egress which means "skip netfilter egress for this packet" to tag to "am I in tc egress?". Despite the overload I dont see it as a conflict since the marker is set only around the single sch handle egress() call and ingress path is guarded by tc at ingress. I will send a followup(net-next) patch once this hits net-next to rename the skb->nf skip egress bit/flag to skb->skip egress
Arm the flag only from the egress classifier that can use it: raise skip txqueue from tcf skbedit act() only when it runs inside sch handle egress(), thanks to skb->nf skip egress. An egress qdisc classifier runs in q->enqueue(), after the tx queue has been picked, so a mapping it sets cannot affect the current packet; arming the flag there only pollutes it for a later xmit. Then own the flag for the xmit frame the egress hook runs in: save the incoming value and clear it just before sch handle egress(), and restore it after the hook - on the consumed (drop) path, or, in the same call that reads it, on the surviving path. The save and the restores stay inside the egress needed key static branch, so a packet pays for them only when egress hooks are active (2f1e85b1aee4).
Store the value netdev cap txqueue() selected back into skb->queue mapping in netdev tx queue mapping(), as netdev core pick tx() already does, so the skip txqueue path never hands a later reader on the xmit path a mapping the device cannot serve. A store made still later in the same frame, by a tc BPF program attached to a transmit qdisc, is outside this path and is not re-capped; a separate followup will resolve that path.
netdev xmit skip txqueue() returns the previous flag value so the save-and-clear is one call, and a no-op stub is provided when CONFIG NET EGRESS is disabled. skb->nf skip egress is compiled under CONFIG NET EGRESS rather than CONFIG NETFILTER SKIP EGRESS, so skb at tc egress() is valid whenever the egress path is built.
A local user in a network namespace can redirect a packet from a device with more TX queues to one with fewer after setting a mapping valid only on the larger device. That reaches these reads and, under KASAN, faults with "slab-out-of-bounds in taprio enqueue".
Conditions to recreate the bug: the report's own trigger is a local user with CAP NET ADMIN in a network namespace, so no eBPF program is needed. With CONFIG NET SCH TAPRIO=y, CONFIG NET ACT SKBEDIT=y, CONFIG NET ACT MIRRED=y, CONFIG NET CLS MATCHALL=y, CONFIG NET SCH PRIO=y and KASAN enabled, create qa (3 queues), qb (2 queues) and qc (1 queue) as dummy devices; put a taprio root on qb (num tc 1, queues 2@0) and clsact on all three; then add an egress matchall filter on every device. On qa: "action skbedit queue mapping 2 pipe action mirred egress redirect dev qb". On qb: "action mirred egress mirror dev qc". On qc: "action skbedit queue mapping 0 pipe". Send one packet out qa. qc's skbedit sets the flag while qb's outer xmit is in flight; without the fix qb consumes it and reads its two-entry taprio child array with the forwarded packet's stale mapping. A qc whose skb ---truncated---
Encontrou algum problema na descrição? Tem algo a acrescentar? Fique à vontade para nos escrever 👾

Identificadores relacionados

CVE-2026-98797

Produtos afetados

Linux