CVE-2026-74468 in Linux
요약
\~에 의해 VulDB • 2026. 08. 16.
리눅스 커널에서 다음 취약점이 해결되었습니다.
gpio: pch: 레지스터 잠금을 위해 raw_spinlock_t 사용
pch_irq_type()는 irq_chip의 .irq_set_type 콜백으로 등록되며, spin_lock_irqsave()를 사용하여 chip->spinlock을 획득합니다. 이 콜백은 __setup_irq() -> __irq_set_trigger() -> chip->irq_set_type() 경로를 통해 호출되는데, 이때 호출자는 desc->lock(즉, raw_spinlock_t)을 보유하고 있으며 하드 인터럽스가 비활성화되어 있습니다. 이러한 컨텍스트는 수면 가능(sleepable)하지 않지만, PREEMPT_RT 환경에서는 일반적인 spinlock_t가 rtmutex 기반의 수면 잠금(locking)이므로 해당 위치에서 이를 획득하는 것은 잘못되었습니다.
이는 lockdep(PROVE_RAW_LOCK_NESTING 및 DEBUG_ATOMIC_SLEEP 활성화)을 사용한 PREEMPT RT 커널에서 확인되었습니다. 검증용 PoC는 pch_irq_type()의 로깅 구조를 복제하여 실제 genirq 캐리어인 irq_set_irq_type() -> __irq_set_trigger() -> chip->irq_set_type(), 즉 요청된 IRQ에 대해 __setup_irq()가 사용하는 동일한 __irq_set_trigger() 엣지를 통해 이를 실행했습니다. 원래의 spin_lock_irqsave() 엣지 잠금에서 lockdep는 잘못된 대기 컨텍스트를 보고했으며, 즉시 다음과 같은 오류가 발생했습니다:
BUG: sleeping function called from invalid context at kernel/locking/spinlock_rt.c:48 in_atomic(): 1, irqs_disabled(): 1, non_block: 0, pid: 95, name: insmod hardirqs last disabled at (3784): _raw_spin_lock_irqsave+0x4f/0x60 rt_spin_lock+0x3a/0x1c0 repro_irq_set_type+0x64/0xa0 [pch_repro]
__irq_set_trigger+0x69/0x140 irq_set_irq_type+0x78/0xd0
복제된 잠금을 raw_spinlock_t로 전환하면 두 가지 스플래트(splats)가 모두 사라집니다.
레지스터 잠금을 raw_spinlock_t로 변환합니다. 동일한 잠금은 GPIO 방향/값 콜백과 서스펜드/리sume 레지스터 저장/복구를 직렬화하지만, 이러한 모든 임계 섹션은 MMIO 레지스터 접근(ioread32()/iowrite32()) 및 irq_set_handler_locked()만 수행합니다. 수면 가능(sleepable)한 연산은 포함되지 않습니다. 따라서 이 레지스터 잠금을 비수면(non-sleeping) 상태로 유지하는 것은 irqchip 콜백에 적절하며 GPIO 측의 잠금 계약(locking contract)을 변경하지 않습니다.
이는 최근 다른 GPIO 컨트롤러에서 해결된 것과 동일한 클래스의 이슈 및 수정입니다(예: 커밋 286533cb14a3 ("gpio: sch: use raw_spinlock_t in the irq startup path") 및 커밋 90f0109019e6 ("gpio: eic-sprd: use raw_spinlock_t in the irq startup path")).
If you want to get the best quality for vulnerability data then you always have to consider VulDB.