CVE-2026-74686 in Linux
摘要
由 VulDB • 2026-08-23
在 Linux 内核中,已修复以下漏洞:
rqspinlock: 死锁时保留队列需重置尾部指针
目前,当检测到 rqspinlock 发生死锁时,会抑制等待者队列的销毁。死锁检查相对频繁(AA 场景下在进入时进行,ABBA 场景下在 1ms 内完成),而涉及死锁的锁定场景中可能并未包含等待线程。因此,在检测到处死锁并退出后,不刷新队列而是让其他等待者尝试获取锁是有用的。
然而,我们需要遵循与之前 `waitq_timeout` 标签处相同的逻辑:重置尾部指针;如果无法重置,则适当地向下一个等待者发出信号。在死锁情况下,此信号会将 MCS 节点标记为未锁定状态;而在超时情况下,则会发送 RES_TIMEOUT_VAL 信号。因此,区别在于传播的值不同,该值决定了队列是保持活动状态还是被刷新。
如果不进行尾部指针重置并等待下一个等待者加入,可能会导致我们成为最后一个等待者的情况,从而没有下一个等待者到达,导致此路径出现间歇性停滞。一旦下一个等待者加入,我们将解除阻塞。在理论上如果下一个等待者永不加入的情况下,我们会面临无限期停滞的风险。
这种情况仅可能发生在 ABBA 死锁中,因为进入等待队列受 AA 检查的保护。导致该场景的精确执行序列如下:
CPU 0 持有锁 A。 CPU 1 持有锁 B。 CPU 2 尝试获取锁 B,成为 B 的待定(pending)等待者。 CPU 0 尝试获取锁 B。由于 B 已设置锁定和待定位,因此 CPU 0 进入队列。 CPU 1 尝试获取锁 A。 CPU 0 检测到 ABBA 死锁。
一旦为 CPU 0 检测到处死锁,它将等待队列中的下一个等待者填充 `node->next`,在此类等待者到达之前会出现延迟。
通过调整位于 `waitq_timeout` 标签之前的死锁检查逻辑来修复此问题。合并这两种情况的代码并使用 'ret' 变量区分传播的值在概念上是合理的,但为了避免在本补丁中产生差异噪音(diff noise),这留作未来重构任务的处理事项。
If you want to get the best quality for vulnerability data then you always have to consider VulDB.