🇰🇷 한글 설명
Linux 커널의 x86/efi 구성 요소에서 FPU softirq 변경 사항으로 인해 발생하는 결함입니다. EFI 런타임 서비스 호출 중 페이지 폴트가 발생할 경우, 시스템이 이를 인터럽트 상황으로 오인하여 정상적인 복구 대신 시스템 전체가 멈추는 하드 프리징 현상이 발생합니다.
💡 쉬운 설명
컴퓨터의 핵심 소프트웨어가 특정 작업을 처리하는 도중 오류가 발생하면, 이를 안전하게 처리하지 못하고 시스템이 완전히 멈춰버리는 문제입니다. 특히 특정 하드웨어 설정에서 시스템이 재부팅되지 않고 먹통이 될 수 있습니다.
🇺🇸 원문 (English)
In the Linux kernel, the following vulnerability has been resolved:
x86/efi: Fix graceful fault handling after FPU softirq changes
Since commit d02198550423 ("x86/fpu: Improve crypto performance by
making kernel-mode FPU reliably usable in softirqs"), kernel_fpu_begin()
calls fpregs_lock() which uses local_bh_disable() instead of the
previous preempt_disable(). This sets SOFTIRQ_OFFSET in preempt_count
during the entire EFI runtime service call, causing in_interrupt() to
return true in normal task context.
The graceful page fault handler efi_crash_gracefully_on_page_fault()
uses in_interrupt() to bail out for faults in real interrupt context.
With SOFTIRQ_OFFSET now set, the handler always bails out, leaving EFI
firmware page faults unhandled. This escalates to die() which also sees
in_interrupt() as true and calls panic("Fatal exception in interrupt"),
resulting in a hard system freeze. On systems with buggy firmware that
triggers page faults during EFI runtime calls (e.g., accessing unmapped
memory in GetTime()), this causes an unrecoverable hang instead of the
expected graceful EFI_ABORTED recovery.
Fix by replacing in_interrupt() with !in_task(). This preserves the
original intent of bailing for interrupts or NMI faults, while no longer
falsely triggering from the FPU code path's local_bh_disable().
[ardb: Sashiko spotted that using 'in_hardirq() || in_nmi()' leaves a
window where a softirq may be taken before fpregs_lock() is
called, but after efi_rts_work.efi_rts_id has been assigned,
and any page faults occurring in that window will then be
misidentified as having been caused by the firmware. Instead,
use !in_task(), which incorporates in_serving_softirq(). ]
📍 영향받는 시스템
FPU softirq 관련 커밋(d02198550423)이 적용된 이후의 Linux 커널 (x86 아키텍처)
⚔️ 공격 벡터
직접적인 공격보다는 버그가 있는 EFI 펌웨어가 실행되는 환경에서 시스템 가용성을 침해하는 방식 (DoS)
🛡️ 대응 방법
커널 패치를 통해 in_interrupt() 호출을 !in_task()로 교체하여 페이지 폴트 핸들러를 수정해야 합니다.
🔧 검증 코드
출력된 커널 버전이 해당 취약점이 수정된 패치 버전 이후인지 확인합니다.