CVE-2025-39677

Severity CVSS v4.0:
Pending analysis
Type:
Unavailable / Other
Publication date:
05/09/2025
Last modified:
08/09/2025

Description

In the Linux kernel, the following vulnerability has been resolved:<br /> <br /> net/sched: Fix backlog accounting in qdisc_dequeue_internal<br /> <br /> This issue applies for the following qdiscs: hhf, fq, fq_codel, and<br /> fq_pie, and occurs in their change handlers when adjusting to the new<br /> limit. The problem is the following in the values passed to the<br /> subsequent qdisc_tree_reduce_backlog call given a tbf parent:<br /> <br /> When the tbf parent runs out of tokens, skbs of these qdiscs will<br /> be placed in gso_skb. Their peek handlers are qdisc_peek_dequeued,<br /> which accounts for both qlen and backlog. However, in the case of<br /> qdisc_dequeue_internal, ONLY qlen is accounted for when pulling<br /> from gso_skb. This means that these qdiscs are missing a<br /> qdisc_qstats_backlog_dec when dropping packets to satisfy the<br /> new limit in their change handlers.<br /> <br /> One can observe this issue with the following (with tc patched to<br /> support a limit of 0):<br /> <br /> export TARGET=fq<br /> tc qdisc del dev lo root<br /> tc qdisc add dev lo root handle 1: tbf rate 8bit burst 100b latency 1ms<br /> tc qdisc replace dev lo handle 3: parent 1:1 $TARGET limit 1000<br /> echo &amp;#39;&amp;#39;; echo &amp;#39;add child&amp;#39;; tc -s -d qdisc show dev lo<br /> ping -I lo -f -c2 -s32 -W0.001 127.0.0.1 2&gt;&amp;1 &gt;/dev/null<br /> echo &amp;#39;&amp;#39;; echo &amp;#39;after ping&amp;#39;; tc -s -d qdisc show dev lo<br /> tc qdisc change dev lo handle 3: parent 1:1 $TARGET limit 0<br /> echo &amp;#39;&amp;#39;; echo &amp;#39;after limit drop&amp;#39;; tc -s -d qdisc show dev lo<br /> tc qdisc replace dev lo handle 2: parent 1:1 sfq<br /> echo &amp;#39;&amp;#39;; echo &amp;#39;post graft&amp;#39;; tc -s -d qdisc show dev lo<br /> <br /> The second to last show command shows 0 packets but a positive<br /> number (74) of backlog bytes. The problem becomes clearer in the<br /> last show command, where qdisc_purge_queue triggers<br /> qdisc_tree_reduce_backlog with the positive backlog and causes an<br /> underflow in the tbf parent&amp;#39;s backlog (4096 Mb instead of 0).<br /> <br /> To fix this issue, the codepath for all clients of qdisc_dequeue_internal<br /> has been simplified: codel, pie, hhf, fq, fq_pie, and fq_codel.<br /> qdisc_dequeue_internal handles the backlog adjustments for all cases that<br /> do not directly use the dequeue handler.<br /> <br /> The old fq_codel_change limit adjustment loop accumulated the arguments to<br /> the subsequent qdisc_tree_reduce_backlog call through the cstats field.<br /> However, this is confusing and error prone as fq_codel_dequeue could also<br /> potentially mutate this field (which qdisc_dequeue_internal calls in the<br /> non gso_skb case), so we have unified the code here with other qdiscs.

Impact