🇰🇷 한글 설명
Linux 커널의 futex 메커니즘에서 requeue-PI 동작 중 신호 또는 타임아웃 발생 시 데드락(Lockup)이 발생할 수 있는 취약점입니다. 특정 레이스 컨디션 상황에서 우선순위가 높은 태스크가 락을 계속 점유하려고 시도하면서 시스템이 응답하지 않는 라이브락(Livelock) 상태에 빠질 수 있습니다.
💡 쉬운 설명
컴퓨터 내부의 작업들이 서로의 순서를 기다리는 과정에서 충돌이 발생하여 시스템이 멈춰버리는 문제입니다. 특히 특정 작업이 우선순위가 높을 때 다른 작업이 끼어들지 못해 전체 시스템이 무한 루프에 빠지게 됩니다.
🇺🇸 원문 (English)
In the Linux kernel, the following vulnerability has been resolved:
futex: Prevent lockup in requeue-PI during signal/ timeout wakeup
During wait-requeue-pi (task A) and requeue-PI (task B) the following
race can happen:
Task A Task B
futex_wait_requeue_pi()
futex_setup_timer()
futex_do_wait()
futex_requeue()
CLASS(hb, hb1)(&key1);
CLASS(hb, hb2)(&key2);
*timeout*
futex_requeue_pi_wakeup_sync()
requeue_state = Q_REQUEUE_PI_IGNORE
*blocks on hb->lock*
futex_proxy_trylock_atomic()
futex_requeue_pi_prepare()
Q_REQUEUE_PI_IGNORE => -EAGAIN
double_unlock_hb(hb1, hb2)
*retry*
Task B acquires both hb locks and attempts to acquire the PI-lock of the
top most waiter (task B). Task A is leaving early due to a signal/
timeout and started removing itself from the queue. It updates its
requeue_state but can not remove it from the list because this requires
the hb lock which is owned by task B.
Usually task A is able to swoop the lock after task B unlocked it.
However if task B is of higher priority then task A may not be able to
wake up in time and acquire the lock before task B gets it again.
Especially on a UP system where A is never scheduled.
As a result task A blocks on the lock and task B busy loops, trying to
make progress but live locks the system instead. Tragic.
This can be fixed by removing the top most waiter from the list in this
case. This allows task B to grab the next top waiter (if any) in the
next iteration and make progress.
Remove the top most waiter if futex_requeue_pi_prepare() fails.
Let the waiter conditionally remove itself from the list in
handle_early_requeue_pi_wakeup().
📍 영향받는 시스템
Linux Kernel (futex requeue-PI 관련 기능 사용 시)
⚔️ 공격 벡터
로컬 사용자가 특수하게 설계된 멀티스레드 프로그램을 실행하여 커널 내 레이스 컨디션을 유도함으로써 시스템 서비스 거부(DoS) 유발
🛡️ 대응 방법
Linux 커널을 최신 보안 패치가 적용된 버전으로 업데이트하여 futex_requeue_pi_prepare() 실패 시 대기자를 목록에서 제거하도록 수정된 패치를 적용해야 함
🔧 검증 코드
출력된 커널 버전이 해당 취약점이 해결된 패치 버전 이후인지 확인