CVE-2025-39677

net/sched: Fix backlog accounting in qdisc_dequeue_internal

State
Published
Severity
7.8 High
Published
Sep 5, 2025
Updated
Oct 30, 2026
Reserved
Apr 16, 2025

Read the record on cve.org

Description

In the Linux kernel, the following vulnerability has been resolved:

net/sched: Fix backlog accounting in qdisc_dequeue_internal

This issue applies for the following qdiscs: hhf, fq, fq_codel, and fq_pie, and occurs in their change handlers when adjusting to the new limit. The problem is the following in the values passed to the subsequent qdisc_tree_reduce_backlog call given a tbf parent:

When the tbf parent runs out of tokens, skbs of these qdiscs will be placed in gso_skb. Their peek handlers are qdisc_peek_dequeued, which accounts for both qlen and backlog. However, in the case of qdisc_dequeue_internal, ONLY qlen is accounted for when pulling from gso_skb. This means that these qdiscs are missing a qdisc_qstats_backlog_dec when dropping packets to satisfy the new limit in their change handlers.

One can observe this issue with the following (with tc patched to support a limit of 0):

export TARGET=fq tc qdisc del dev lo root tc qdisc add dev lo root handle 1: tbf rate 8bit burst 100b latency 1ms tc qdisc replace dev lo handle 3: parent 1:1 $TARGET limit 1000 echo ''; echo 'add child'; tc -s -d qdisc show dev lo ping -I lo -f -c2 -s32 -W0.001 127.0.0.1 2>&1 >/dev/null echo ''; echo 'after ping'; tc -s -d qdisc show dev lo tc qdisc change dev lo handle 3: parent 1:1 $TARGET limit 0 echo ''; echo 'after limit drop'; tc -s -d qdisc show dev lo tc qdisc replace dev lo handle 2: parent 1:1 sfq echo ''; echo 'post graft'; tc -s -d qdisc show dev lo

The second to last show command shows 0 packets but a positive number (74) of backlog bytes. The problem becomes clearer in the last show command, where qdisc_purge_queue triggers qdisc_tree_reduce_backlog with the positive backlog and causes an underflow in the tbf parent's backlog (4096 Mb instead of 0).

To fix this issue, the codepath for all clients of qdisc_dequeue_internal has been simplified: codel, pie, hhf, fq, fq_pie, and fq_codel. qdisc_dequeue_internal handles the backlog adjustments for all cases that do not directly use the dequeue handler.

The old fq_codel_change limit adjustment loop accumulated the arguments to the subsequent qdisc_tree_reduce_backlog call through the cstats field. However, this is confusing and error prone as fq_codel_dequeue could also potentially mutate this field (which qdisc_dequeue_internal calls in the non gso_skb case), so we have unified the code here with other qdiscs.

Scores

CVSSScoreVectorSource
3.17.8 HighCVSS:3.1/AV:L/AC:L/PR:L/UI:N/S:U/C:H/I:H/A:HLinux

Weaknesses

The record names no weakness.

Affected Products

ProductVersions
LinuxLinux
  • 4b549a2ef4bef9965d97cbd992ba67930cd3e0fe to before 65d1b5d84a0d697e9cfcdd0e07aad1bf1cb96295Affected
  • 4b549a2ef4bef9965d97cbd992ba67930cd3e0fe to before dcfed7251e23cd71d32c4ecc444ff97992087e46Affected
  • 4b549a2ef4bef9965d97cbd992ba67930cd3e0fe to before 38cdf8d1f5f3ee133f6e48dd422df4057fa9bfcbAffected
  • 4b549a2ef4bef9965d97cbd992ba67930cd3e0fe to before a225f44d84b8900d679c5f5a9ea46fe9c0cc7802Affected
  • 4b549a2ef4bef9965d97cbd992ba67930cd3e0fe to before 52bf272636bda69587952b35ae97690b8dc89941Affected
LinuxLinux
  • 3.5Affected
  • before 3.5Not affected
  • 6.1.191 through 6.1.*Not affected
  • 6.6.160 through 6.6.*Not affected
  • 6.12.114 through 6.12.*Not affected
  • 6.16.4 through 6.16.*Not affected
  • 6.17 and laterNot affected

References

Every record here comes from the CVE Program’s CVE List. © 1999–2026 The MITRE Corporation. CVE is a registered trademark of The MITRE Corporation. The records are reproduced under the CVE Program terms of use.