🇰🇷 한글 설명
Linux 커널의 RDMA/rxe 구성 요소에서 do_task() 함수가 반복 횟수 제한에 도달할 때 발생하는 레이스 컨디션 취약점입니다. 작업 상태를 TASK_STATE_IDLE로 잘못 설정하여 TASK_STATE_DRAINING 상태를 덮어쓸 수 있으며, 이로 인해 정리 로직이 진행되는 동안 작업이 재스케줄링되어 Use-After-Free 오류를 유발할 수 있습니다.
💡 쉬운 설명
컴퓨터가 작업을 정리하는 도중에 다른 명령이 끼어들어 작업 상태를 엉뚱하게 바꿔버리는 문제입니다. 이로 인해 이미 끝난 줄 알고 삭제된 데이터를 다시 사용하려다가 시스템 오류나 보안 문제가 발생할 수 있습니다.
🇺🇸 원문 (English)
In the Linux kernel, the following vulnerability has been resolved:
RDMA/rxe: Fix race in do_task() when draining
When do_task() exhausts its iteration budget (!ret), it sets the state
to TASK_STATE_IDLE to reschedule, without a secondary check on the
current task->state. This can overwrite the TASK_STATE_DRAINING state
set by a concurrent call to rxe_cleanup_task() or rxe_disable_task().
While state changes are protected by a spinlock, both rxe_cleanup_task()
and rxe_disable_task() release the lock while waiting for the task to
finish draining in the while(!is_done(task)) loop. The race occurs if
do_task() hits its iteration limit and acquires the lock in this window.
The cleanup logic may then proceed while the task incorrectly
reschedules itself, leading to a potential use-after-free.
This bug was introduced during the migration from tasklets to workqueues,
where the special handling for the draining case was lost.
Fix this by restoring the original pre-migration behavior. If the state is
TASK_STATE_DRAINING when iterations are exhausted, set cont to 1 to
force a new loop iteration. This allows the task to finish its work, so
that a subsequent iteration can reach the switch statement and correctly
transition the state to TASK_STATE_DRAINED, stopping the task as intended.
📍 영향받는 시스템
RDMA/rxe를 사용하는 Linux 커널 (tasklet에서 workqueue로 마이그레이션된 이후 버전)
⚔️ 공격 벡터
로컬 공격자가 특정 RDMA 작업의 정리 과정을 유도하여 메모리 레이스 컨디션을 발생시킴
🛡️ 대응 방법
Linux 커널을 최신 보안 패치가 적용된 버전으로 업데이트하여 do_task()의 상태 체크 로직을 수정해야 함
🔧 검증 코드
출력된 커널 버전이 해당 취약점이 수정된 최신 패치 버전인지 확인