Cyber Posture

CVE-2025-21702

High

Published: 18 February 2025

Published
18 February 2025
Modified
02 April 2026
KEV Added
Patch
CVSS Score 7.8 CVSS:3.1/AV:L/AC:L/PR:L/UI:N/S:U/C:H/I:H/A:H
EPSS Score 0.0003 9.7th percentile
Risk Priority 16 60% EPSS · 20% KEV · 20% CVSS

Description

In the Linux kernel, the following vulnerability has been resolved: pfifo_tail_enqueue: Drop new packet when sch->limit == 0 Expected behaviour: In case we reach scheduler's limit, pfifo_tail_enqueue() will drop a packet in scheduler's queue and decrease scheduler's qlen by one. Then, pfifo_tail_enqueue() enqueue new packet and increase scheduler's qlen by one. Finally, pfifo_tail_enqueue() return `NET_XMIT_CN` status code. Weird behaviour: In case we set `sch->limit == 0` and trigger pfifo_tail_enqueue() on a scheduler that has no packet, the 'drop a packet' step will do nothing. This means the scheduler's qlen still has value equal 0. Then, we continue to enqueue new packet and increase scheduler's qlen by one. In summary, we can leverage pfifo_tail_enqueue() to increase qlen by one and return `NET_XMIT_CN` status code. The problem is: Let's say we have two qdiscs: Qdisc_A and Qdisc_B. - Qdisc_A's type must have '->graft()' function to create parent/child relationship. Let's say Qdisc_A's type is `hfsc`. Enqueue packet to this qdisc will trigger `hfsc_enqueue`. - Qdisc_B's type is pfifo_head_drop. Enqueue packet to this qdisc will trigger `pfifo_tail_enqueue`. - Qdisc_B is configured to have `sch->limit == 0`. - Qdisc_A is configured to route the enqueued's packet to Qdisc_B. Enqueue packet through Qdisc_A will lead to: - hfsc_enqueue(Qdisc_A) -> pfifo_tail_enqueue(Qdisc_B) - Qdisc_B->q.qlen += 1 - pfifo_tail_enqueue() return `NET_XMIT_CN` - hfsc_enqueue() check for `NET_XMIT_SUCCESS` and see `NET_XMIT_CN` => hfsc_enqueue() don't increase qlen of Qdisc_A. The whole process lead to a situation where Qdisc_A->q.qlen == 0 and Qdisc_B->q.qlen == 1. Replace 'hfsc' with other type (for example: 'drr') still lead to the same problem. This violate the design where parent's qlen should equal to the sum of its childrens'qlen. Bug impact: This issue can be used for user->kernel privilege escalation when it is reachable.

Security Summary

CVE-2025-21702 is a vulnerability in the Linux kernel's pfifo_tail_enqueue function within the queueing discipline (qdisc) subsystem. The issue arises when a child qdisc, such as pfifo_head_drop configured with sch->limit == 0, is enqueued to via a parent qdisc like hfsc or drr that supports grafting. In the expected behavior, reaching the scheduler's limit drops a packet and enqueues a new one, returning NET_XMIT_CN. However, with limit == 0 and an empty queue, no packet is dropped, allowing the new packet to enqueue anyway, incrementing the child qdisc's qlen to 1 while the parent qdisc's qlen remains 0. This violates the design invariant that a parent's qlen equals the sum of its children's qlen.

A local attacker with low privileges (PR:L) can exploit this by configuring a parent qdisc (e.g., hfsc) to route packets to a pfifo_head_drop child qdisc with limit == 0, then enqueuing packets through the parent. The enqueue triggers pfifo_tail_enqueue on the child, causing the qlen discrepancy without incrementing the parent's qlen due to the NET_XMIT_CN return code. When reachable, this enables user-to-kernel privilege escalation, with a CVSS v3.1 base score of 7.8 (AV:L/AC:L/PR:L/UI:N/S:U/C:H/I:H/A:H).

Mitigation involves applying upstream kernel patches, as detailed in the referenced stable commit fixes: https://git.kernel.org/stable/c/020ecb76812a0526f4130ab5aeb6dc7c773e7ab9, https://git.kernel.org/stable/c/647cef20e649c576dff271e018d5d15d998b629d, https://git.kernel.org/stable/c/78285b53266d6d51fa4ff504a23df03852eba84e, https://git.kernel.org/stable/c/79a955ea4a2e5ddf4a36328959de0de496419888, and https://git.kernel.org/stable/c/7a9723ec27aff5674f1fd4934608937f1d650980. These resolve the pfifo_tail_enqueue logic to properly handle limit == 0 cases and maintain qlen consistency.

Details

CWE(s)
NVD-CWE-noinfo

Affected Products

linux
linux kernel
6.14 · 2.6.34 — 5.4.291 · 5.5 — 5.10.235 · 5.11 — 5.15.179

References