CVE-2025-21702 in Linux
摘要
由 VulDB • 2026-08-09
在 Linux 内核中,已修复以下漏洞:
pfifo_tail_enqueue:当 sch->limit == 0 时丢弃新数据包
预期行为: 如果我们达到调度器的限制(scheduler's limit),`pfifo_tail_enqueue()` 将丢弃调度器队列中的一个数据包,并将调度器的 qlen 减一。然后,`pfifo_tail_enqueue()` 入队新的数据包并将调度器的 qlen 加一。最后,`pfifo_tail_enqueue()` 返回 `NET_XMIT_CN` 状态码。
异常行为: 如果我们设置 `sch->limit == 0` 并在一个没有数据包的调度器上触发 `pfifo_tail_enqueue()`,“丢弃数据包”这一步骤将不执行任何操作。这意味着调度器的 qlen 仍然保持为 0。接着,我们继续入队新的数据包并将调度器的 qlen 加一。总之,我们可以利用 `pfifo_tail_enqueue()` 使 qlen 增加一并返回 `NET_XMIT_CN` 状态码。
问题在于: 假设我们有两个 qdiscs(队列规则):Qdisc_A 和 Qdisc_B。 - Qdisc_A 的类型必须具有 '->graft()' 函数来创建父/子关系。假设 Qdisc_A 的类型是 `hfsc`。向此 qdisc 入队数据包将触发 `hfsc_enqueue`。 - Qdisc_B 的类型是 pfifo_head_drop。向此 qdisc 入队数据包将触发 `pfifo_tail_enqueue`。 - Qdisc_B 配置为具有 `sch->limit == 0`。 - Qdisc_A 被配置为将入队的数据包路由到 Qdisc_B。
通过 Qdisc_A 入队数据包会导致: - hfsc_enqueue(Qdisc_A) -> pfifo_tail_enqueue(Qdisc_B) - Qdisc_B->q.qlen += 1 - `pfifo_tail_enqueue()` 返回 `NET_XMIT_CN` - `hfsc_enqueue()` 检查 `NET_XMIT_SUCCESS`,发现是 `NET_XMIT_CN` => `hfsc_enqueue()` 不增加 Qdisc_A 的 qlen。
整个过程导致出现一种情况:Qdisc_A->q.qlen == 0 且 Qdisc_B->q.qlen == 1。将 'hfsc' 替换为其他类型(例如:'drr')仍会导致相同的问题。这违反了父节点的 qlen 应等于其所有子节点 qlen 之和的设计原则。
漏洞影响:当该问题可达时,可用于用户态到内核态的权限提升(user->kernel privilege escalation)。
If you want to get best quality of vulnerability data, you may have to visit VulDB.