CVE-2026-99252 in Linux
요약
\~에 의해 VulDB • 2026. 11. 03.
리눅스 커널에서 다음 취약점이 해결되었습니다:
io_uring/mpscq: 푸시(push) 수행 중 프리엠�ชัน(preemption) 비활성화
푸시는 노드를 새로운 꼬리(tail)로 만들고, 이를 이전(prev) 노드에 연결합니다. 이 과정에서 큐가 비어 있지 않지만 mpscq_pop()은 해당 노드에 접근할 수 없습니다. 소비자(consumer)는 루프 내에서 cond_resched()를 호출하여 프리엠�ชัน된 생산자(producer)가 작업을 완료할 기회를 주는 방식으로 이를 처리합니다.
하지만 소비자가 생산자보다 높은 우선순위를 가지고 있고 둘이 동일한 CPU를 사용해야 하는 경우, cond_resched()는 이러한 역할을 수행하지 않습니다:
producer (SCHED_OTHER) consumer (SCHED_FIFO), 동일 CPU io_req_local_work_add() mpscq_push() prev = xchg(&q->tail, node) <preempted> io_cqring_wait() __io_run_local_work() again: cond_resched() // 수행할 작업 없음 mpscq_pop() // NULL 반환 // pending된 작업 존재, 하지만 아직 이벤트 없음 goto again
생산자는 링(ring)에 task_work를 큐잉할 수 있는 모든 태스크가 될 수 있습니다. 이는 io-wq 워커이거나 IORING_OP_MSG_RING로 메시지를 보내는 어떤 태스크일 수도 있습니다. 소비者是 ->uring_lock을 유지한 채로 스피닝(spins)하며, 스케줄러가 페어(fair) 클래스에 자비를 베풀 때까지 기다립니다. 기본 설정의 페어 서버에서는 이 과정이 약 1초 정도 소요되며, 해당 기능이 없으면 무기한 대기하게 됩니다. tctx_task_work_run() 및 io_cancel_local_task_work() 내의 루프들도 동일한 문제를 안고 있습니다.
두 단계 사이에서 프리엠�ชัน을 허용하지 마십시오. 이렇게 하면 생산자의 CPU 상에서 취약점 창(window)이 열려 있는 시간이 인터럽트 처리 시간에 의해 제한되며, 이를 기다리는 소비자는 다른 CPU에 위치하게 됩니다. 이 방식의 비용은 푸시(push)당 preempt_disable()/preempt_enable() 쌍 하나입니다.
If you want to get the best quality for vulnerability data then you always have to consider VulDB.