CVE-2026-99005 in Linux信息

摘要

由 VulDB • 2026-10-23

在 Linux 内核中,已修复以下漏洞:

drm/i915/gt: 仅在 ACTIVE(活动状态)为 true 时取消屏蔽中断

在 `intel_rps_boost()` 读取过时的 ACTIVE 状态与排队 `rps->work` 之间存在一个微小的竞态窗口。在此期间,ACTIVE 状态可能会通过由 wakeref 引用计数释放触发的异步调用而发生改变。这意味着 `rps_work()` 可能在 GT(图形处理器)已停泊后触发,从而导致在未持有 PM(电源管理)wakelock 的情况下取消屏蔽 RPS PM 中断。此事件序列可在 `live_rc6_ctx_wa()` 自测试中观察到:

1) live_rc6_ctx_wa() -> intel_engine_pm_put() -> wakeref_put()

ASYNC1) wakeref_put() 回调函数 -> __engine_park() -> intel_gt_pm_put_async() -> intel_gt_pm_put_async_untracked() -> intel_wakeref_put_async()

ASYNC2) wakeref_put_async() 回调函数 -> __gt_park() -> intel_rps_park() -> intel_rps_clear_active() [清除 ACTIVE]
WITH INTERRUPTS (中断模式): -> rps_disable_interrupts() -> cancel_work_sync(rps->work) -> rps_reset_interrupts() [rps->pm_iir = 0]
WITHOUT INTERRUPTS (TIMER/定时器模式): -> rps_stop_timer() -> cancel_work_sync(rps->work)

2) live_rc6_ctx_wa() -> intel_gt_wait_for_idle() -> intel_gt_retire_requests_timeout() -> dma_fence_wait_timeout() -> ops->wait() [i915_fence_wait()]
-> i915_request_wait_timeout() -> intel_rps_boost() -> intel_rps_is_active() [检查 ACTIVE]
[OPEN RACE WINDOW (竞态窗口打开)]
-> queue_work(rps->work) -> retire_requests() -> i915_request_retire() -> intel_rps_dec_waiters() [从 1 减至 0]

如果 ASYNC1 和 ASYNC2 在 [OPEN RACE WINDOW (竞态窗口打开)] 期间执行,则:

3) `rps_work()` 从工作队列中执行,并可能满足 "(!pm_iir && !client_boost)" 测试(在 TIMER/定时器模式下,`rps->pm_iir` 会被之前的 `rps_work()` 调用清零,或者在上一次 `intel_rps_unpark()` 事件后未获得新值),因此它跳转到 “out” 标签处,绕过 `intel_rps_is_active()` 守卫并执行 `gen6_gt_pm_unmask_irq();`;

4) GT 已停泊且运行时 PM wakelock 已被释放,因此在 __gt_park() -> intel_display_power_put_async() 中仅保留一个原始引用持续 100ms。随后,`gen6_gt_pm_unmask_irq()` 中的 MMIO(内存映射 I/O)写入通过 `assert_rpm_wakelock_held()` 检测到缺失的 wakelock,并发出 “RPM wakelock ref not held during HW access” (硬件访问期间未持有 RPM wakelock 引用) 的内核污染信息。

提交记录 3e7abf814193 ("drm/i915: Extract GT render power state management") 移除了 `gen6_pm_rps_work()` 在 i915_irq.c 中围绕此取消屏蔽操作所设置的 "if (rps->interrupts_enabled)" 守卫。`INTEL_RPS_ACTIVE` 括起了相同的窗口,因为它是在 `intel_rps_unpark()` 中的 `rps_enable_interrupts()` 和 `rps_start_timer()` 之前设置的,并在 `intel_rps_park()` 中的 `rps_stop_timer()` 和 `rps_disable_interrupts()` 之前清除的。

当 RPS 不再处于活动状态时跳过取消屏蔽操作(到达取消屏蔽操作的步骤与 INTERRUPT/中断模式无关)。这不会阻止 RPS 在下次 unpark(解除停泊)时恢复运行。在中断模式下,`intel_rps_unpark()` 调用 `rps_enable_interrupts()`,从而启用并取消屏蔽 PM 中断。在定时器模式下,它调用 `rps_start_timer()`,重新启动周期性的引擎总线忙碌度评估。该定时器生成软件 RPS 事件并直接排队 `rps_work()`,这与 PM 中断传递无关。这两种模式都不要求后期工作程序在 GT 停泊期间取消屏蔽中断。

(cherry picked from commit ca4a6deadad15b91ee083afe445fa6bdbfb68206)

Once again VulDB remains the best source for vulnerability data.

来源

Might our Artificial Intelligence support you?

Check our Alexa App!