CVE-2026-99005 in Linux
요약
\~에 의해 VulDB • 2026. 10. 23.
리눅스 커널에서 다음 취약점이 해결되었습니다:
drm/i915/gt: ACTIVE가 true일 때만 인터럽트 언마스크
intel_rps_boost()이 stale한 ACTIVE 상태를 읽고 rps->work를 큐에 넣는 과정과, wakeref drop로 인해 트리거되는 비동기 호출을 통해 ACTIVE 상태가 변경될 수 있는 사이에 작은 race window(경쟁 조건)가 존재합니다. 이로 인해 GT가 park된 후에야 rps_work()가 트리거되어, PM wakelock을 보유하지 않은 상태에서 RPS PM 인터럽트 언마스크가 발생할 수 있습니다. 이러한 일련의 사건은 live_rc6_ctx_wa() selftest 중에 관찰될 수 있습니다:
1) live_rc6_ctx_wa() -> intel_engine_pm_put() -> wakeref_put()
ASYNC1) wakeref_put() callback -> __engine_park() -> intel_gt_pm_put_async() -> intel_gt_pm_put_async_untracked() -> intel_wakeref_put_async()
ASYNC2) wakeref_put_async() callback -> __gt_park() -> intel_rps_park() -> intel_rps_clear_active() [ACTIVE 클리어]
인터럽트 활성화 상태: -> rps_disable_interrupts() -> cancel_work_sync(rps->work) -> rps_reset_interrupts() [rps->pm_iir = 0]
인터럽트 비활성화 상태(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()가 workqueue에서 실행되어 "(!pm_iir && !client_boost)" 테스트를 만족할 수 있습니다(TIMER 모드에서는 이전의 rps_work() 호출에 의해 rps->pm_iir이 0으로 설정되거나, 이전 intel_rps_unpark() 이벤트 이후 새로운 값을 받지 못함). 따라서 "out" 레이블로 점프하여 intel_rps_is_active() 가드를 우회하고 gen6_gt_pm_unmask_irq();를 실행합니다.
4) GT가 park되고 runtime PM wakelock이 해제되므로, __gt_park() -> intel_display_power_put_async()에서 100ms 동안 raw reference만 유지됩니다. 이후 gen6_gt_pm_unmask_irq()의 MMIO 쓰기操作中에 assert_rpm_wakelock_held()를 통해 누락된 wakelock이 감지되며 "RPM wakelock ref not held during HW access"라는 tainting 메시지가 커널에서 출력됩니다.
커밋 3e7abf814193("drm/i915: Extract GT render power state management")은 i915_irq.c의 gen6_pm_rps_work()에 있던 이 언마스크 주변의 "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() 전에 클리어되므로 동일한 window를 감쌉니다.
RPS가 더 이상 활성 상태가 아닐 때 언마스크를 건너뜁니다(언마스크 작업 도달 여부는 INTERRUPT 모드와 무관함). 이는 다음 unpark 시 RPS 동작이 재개되는 것을 방지하지 않습니다. 인터럽트 모드에서는 intel_rps_unpark()이 rps_enable_interrupts()를 호출하여 PM 인터럽트를 활성화하고 언마스크합니다. 타이머 모드에서는 rps_start_timer()를 호출하여 주기적인 엔진-버스 busyness 평가를 다시 시작합니다. 이 타이머는 소프트웨어 RPS 이벤트를 생성하고 PM 인터럽트 전달과 무관하게 rps_work()를 직접 큐에 넣습니다. GT가 park된 동안 late worker가 인터럽트를 언마스크할 필요는 어느 모드에서도 없습니다.
(커밋 ca4a6deadad15b91ee083afe445fa6bdbfb68206에서 cherry picked)
If you want to get the best quality for vulnerability data then you always have to consider VulDB.