🇰🇷 한글 설명
Linux 커널 PCI 슬롯 잠금에서 bridge device 위임 후 실패 경로 처리 누락으로 인한 버그. pci_bus_trylock() 실패 시 필요 없는 pci_dev_unlock()을 호출하여 lock이 중복 해제되거나 다른 스레드의 lock이 잘못 해제될 수 있음.
💡 쉬운 설명
Linux 커널의 PCI 장치 잠금 메커니즘에서 열고 닫는 순서가 잘못되어 같은 자물쇠를 두 번 열려 하거나 다른 프로세스의 자물쇠를 열어버리는 문제입니다. 시스템 멈춤이나 보안 결함을 초래할 수 있습니다.
🇺🇸 원문 (English)
In the Linux kernel, the following vulnerability has been resolved:
PCI: Fix pci_slot_trylock() error handling
Commit a4e772898f8b ("PCI: Add missing bridge lock to pci_bus_lock()")
delegates the bridge device's pci_dev_trylock() to pci_bus_trylock() in
pci_slot_trylock(), but it forgets to remove the corresponding
pci_dev_unlock() when pci_bus_trylock() fails.
Before a4e772898f8b, the code did:
if (!pci_dev_trylock(dev)) /* <- lock bridge device */
goto unlock;
if (dev->subordinate) {
if (!pci_bus_trylock(dev->subordinate)) {
pci_dev_unlock(dev); /* <- unlock bridge device */
goto unlock;
}
}
After a4e772898f8b the bridge-device lock is no longer taken, but the
pci_dev_unlock(dev) on the failure path was left in place, leading to the
bug.
This yields one of two errors:
1. A warning that the lock is being unlocked when no one holds it.
2. An incorrect unlock of a lock that belongs to another thread.
Fix it by removing the now-redundant pci_dev_unlock(dev) on the failure
path.
[Same patch later posted by Keith at
https://patch.msgid.link/
[email protected]]
📍 영향받는 시스템
Linux kernel 커밋 a4e772898f8b 이후 버전 (PCI 서브시스템 활성화된 시스템)
⚔️ 공격 벡터
로컬 공격자가 PCI 장치 접근을 통해 경합 조건(race condition) 유발 또는 kernel deadlock 발생
🛡️ 대응 방법
Linux 커널을 pci_dev_unlock() 제거 패치가 포함된 버전으로 업데이트
🔧 검증 코드
Linux 소스 코드에서 pci_slot_trylock 함수의 실패 경로에 pci_dev_unlock()이 없는지 확인 (있으면 패치 미적용)
grep -r 'pci_slot_trylock' /usr/src/linux-*/drivers/pci/ 2>/dev/null | head -1