Description
In the Linux kernel, the following vulnerability has been resolved: net/sched: sch_hfsc: Don't make class passive twice update_vf() is called from two places for the same class during a single dequeue when the class's child qdisc (e.g. codel/fq_codel) drops its last packets while dequeuing: 1. The child calls qdisc_tree_reduce_backlog(), which, now that the child is empty, invokes hfsc_qlen_notify() -> update_vf(cl, 0, 0) and turns the class passive (cl_nactive is decremented up the hierarchy). 2. hfsc_dequeue() then calls update_vf(cl, qdisc_pkt_len(skb), cur_time) to charge the dequeued bytes. On the second call the class is already passive, but its child qdisc is still empty, so update_vf() arms go_passive again: if (cl->qdisc->q.qlen == 0 && cl->cl_flags & HFSC_FSC) go_passive = 1; The leaf is then skipped by the cl_nactive == 0 check inside the loop, which does not clear go_passive, so the stale go_passive propagates to the parent and decrements its cl_nactive a second time. A parent that still has other active children is driven to cl_nactive == 0 and removed from the vttree, even though those siblings are still backlogged. They are never dequeued again and the qdisc stalls. Fix this by only arming go_passive when the class is actually active, so an already-passive class no longer triggers a second passive transition. The byte accounting (cl->cl_total += len) still runs for every ancestor, so dequeued bytes continue to be counted exactly once.
Affected products
Version statuses are supplied by the assigning organization. Consult the original record for detailed ranges and platform conditions.
Linux Linux
Default version status: unaffected
72c61ffbeeb8c50f6d4d70c65d3283aa1bac57a7 to < a425c82ff06cda5165e0de3de8c2a445ec1f863eaffecteda5efc95a33bd4fcb879250852828cc58c7862970 to < fc973ecd1a079b9a87c360478542f3a56dea085baffected0475c85426b18eccdcb7f9fb58d8f8e9c6c58c87 to < 15720cd8fa3fc625146128f89a8e11b0449a20a7affected9030a91235ae4845ec71902c3e0cecfc9ed1f2df to < b2a017bfcf565721918ec7355a373911d2f2a227affectedd06476714d2819b550e0cc39222347e2c8941c9d to < 9221a594c72a1446137926d4c2aa04e345f798dcaffected51eb3b65544c9efd6a1026889ee5fb5aa62da3bb to < 66dbb13eeb2fc339f8f548a9076be4c1a94857b0affected51eb3b65544c9efd6a1026889ee5fb5aa62da3bb to < 3a49bbae676fef1ffe548971e6229ae2adeb9d10affected51eb3b65544c9efd6a1026889ee5fb5aa62da3bb to < 90b662ea25f5e83bb3b8ccec5b93ced810b92fb8affected9a5fd5c2f4d4afdd5e405083ee53e0789ce76956affectedc1175c4ad01dbc9c979d099861fa90a754f72059affected5.10.241 to < 5.10.261affected5.15.190 to < 5.15.212affected6.1.138 to < 6.1.178affected6.6.90 to < 6.6.145affected6.12.28 to < 6.12.97affected5.4.297 to < 5.5affected6.14.6 to < 6.15affected
Linux Linux
Default version status: affected
6.15affected0 to < 6.15unaffected5.10.261 to ≤ 5.10.*unaffected5.15.212 to ≤ 5.15.*unaffected6.1.178 to ≤ 6.1.*unaffected6.6.145 to ≤ 6.6.*unaffected6.12.97 to ≤ 6.12.*unaffected6.18.40 to ≤ 6.18.*unaffected7.1.5 to ≤ 7.1.*unaffected7.2 to ≤ *unaffected
References
- https://git.kernel.org/stable/c/a425c82ff06cda5165e0de3de8c2a445ec1f863e ↗
- https://git.kernel.org/stable/c/fc973ecd1a079b9a87c360478542f3a56dea085b ↗
- https://git.kernel.org/stable/c/15720cd8fa3fc625146128f89a8e11b0449a20a7 ↗
- https://git.kernel.org/stable/c/b2a017bfcf565721918ec7355a373911d2f2a227 ↗
- https://git.kernel.org/stable/c/9221a594c72a1446137926d4c2aa04e345f798dc ↗
- https://git.kernel.org/stable/c/66dbb13eeb2fc339f8f548a9076be4c1a94857b0 ↗
- https://git.kernel.org/stable/c/3a49bbae676fef1ffe548971e6229ae2adeb9d10 ↗
- https://git.kernel.org/stable/c/90b662ea25f5e83bb3b8ccec5b93ced810b92fb8 ↗