CVE-2026-64560
posix-cpu-timers: 리더가 아닌 exec() 경쟁 조건으로 인한 UAF 방지
- 게시됨
- 2026. 7. 29.
- 업데이트됨
- 2026. 9. 8.
- CNA 할당 중
- Linux
- 증거 관찰됨
- 2026. 8. 10.
기본 CVSS
nvd · CVSS 3.1
CVSS:3.1/AV:L/AC:L/PR:L/UI:N/S:U/C:H/I:H/A:H낮음 · 다음 30일
- 백분위수
- 35.5%
- 모델 날짜
- 2026. 9. 21.
EPSS는 통계적 추정치이지 확실성이나 영향의 척도가 아닙니다. 이를 CVSS, KEV 상태, 노출 및 환경과 결합하세요.
요약
리눅스 커널에서 다음 취약점이 해결되었습니다: posix-cpu-timers: 비리더 exec() 경쟁 조건으로 인한 UAF 방지 Wongi와 Jungwoo가 비리더 exec() 관련 경쟁 조건을 해독하고 보고했으며, 이로 인해 UAF(Use-After-Free)가 발생할 수 있습니다: ```c sys_timer_delete() exec() de_thread() switch_leader(); release_task(old_leader) __exit_signal(old_leader) sighand = lock(old_leader, sighand); posix_cpu_timers*_exit(); posix_cpu_timer_del() // Observes old leader p = pid_task(pid, pid_type); unhash_task(old_leader); sighand = lock_task_sighand(p) sh = lock(p, sighand) old_leader->sighand = NULL; unlock(sighand); (p->sighand == NULL) unlock(sh) return NULL; // Returns without action if(!sighand) return 0; free_posix_timer(); ``` 삭제된 타이머가 p->signal에 설정(armed)되고 대기열에 추가(enqueued)된 경우가 아니라면 이는 "무해(harmless)"합니다. exec() 시 TGID 대상 타이머는 상속되기 때문입니다. sys_timer_delete()가 기본 posix 타이머 객체를 해제했으므로, run_posix_cpu_timers() 또는 다른 타이머에 대한 timerqueue 관련 추가/삭제 작업은 해제된 객체의 timerqueue 노드에 접근하게 되어 UAF가 발생합니다. posix_cpu_timer_set()에도 유사한 문제가 있습니다. 일반 posix 타이머의 경우 사용자 공간에 일시적으로 -ESRCH를 반환할 뿐이지만, do_cpu_nanosleep()의 사용 사례에서는 k_itimer가 스택에 할당되어 있다는 점만 다를 뿐 동일한 UAF입니다. 또한 posix_cpu_timer_rearm()은 타이머를 재설정(rearm)하지 못하므로 타이머가 만료되지 않게 됩니다. 해결 방안을 논의하는 동안 Frederic이 또 다른 문제를 지적했습니다: ```c posix_cpu_timer_del(tmr) __exit_signal(p) posix_cpu_timers*_exit(p); unhash_task(p); p->sighand = NULL; sh = lock_task_sighand(p) sighand = p->sighand; if (!sighand) return NULL; lock(sighand); if (!sh) WARN_ON_ONCE(timer_queued(tmr)); ``` 약한 메모리 순서(weakly ordered) 아키텍처에서는 p->sighand가 NULL로 관찰될 때 posix_cpu_timer_del()이 posix_cpu_timers*_exit()의 저장(store)을 반드시 관찰한다는 보장이 없으므로, WARN()이 오탐(false positive)일 수 있습니다. 다음과 같은 방법으로 이러한 문제를 해결합니다: 1) __exit_signal()의 저장을 smp_store_release()로 변경합니다. 2) lock_task_sighand()의 !sighand 경로에 smp_acquire__after_ctrl_dep()을 추가합니다. 3) 작업(task)을 조회하고 sighand를 잠그는 헬퍼 함수를 생성하되, sighand == NULL일 때 반환하지 않도록 합니다. 대신 작업 조회를 재시도하고, 그래도 실패할 경우에만 포기합니다. 4) 영향을 받는 세 함수에서 해당 헬퍼를 사용합니다. #1/#2는 sighand == NULL을 관찰하는 읽기 측이 모든 선행 저장, 즉 posix_cpu_timers*_exit()의 저장과 unhash_task()의 저장도 모두 관찰하도록 보장합니다. #3은 위에서 설명한 비리더 exec() 상황이 정상적으로 처리되도록 보장합니다. 작업 조회가 이전 리더를 반환하지만 sighand == NULL이면 재시도합니다. 비리더 exec()의 경우 후속 작업 조회는 #1/#2로 인해 새 리더를 관찰합니다. 일반적인 exit() 시나리오에서는 후속 조회가 실패합니다. 작업 조회가 실패하면 함수는 타이머가 여전히 대기열에 있는지도 확인하고, 그럴 경우 경고를 발생시킵니다. 안타깝게도 이에 대해 할 수 있는 조치는 없지만, 작업이 더 이상 표시되지 않으므로 타이머에 더 이상 접근해서는 안 됩니다. 이 확인에는 메모리 순서도 필요하지만, 첫 번째 조회가 실패할 경우에는 제공되지 않습니다. 이를 위해 확인 앞에 smp_rmb()를 배치하며, 이는 __exit_signal()의 write_seqlock()에 있는 smp_wmb()와 짝을 이룹니다. 이는 posix_cpu_timers*_exit()의 저장이 표시되도록 보장합니다. 비리더 exec() 문제의 역사는 posix CPU 타이머 초기 시절로 거슬러 올라갑니다. 당시 타이머에 그룹 리더 작업에 대한 포인터가 저장되었습니다. 비리더 exec()가 리더를 전환하면 이는 당연히 실패합니다. commit e0a70217107e ("posix-cpu-timers: workaround to suppress the problems with mt exec")는 2010년에 이에 대한 임시 해결책을 추가했지만, 이는 ---잘림---
책임 있는 사용
귀하가 소유하고 있거나 테스트할 권한이 있는 시스템에 대해서만 취약점 정보를 사용하십시오. Kitploit은 공개 연구 메타데이터에 연결되며 익스플로잇 코드나 악성 페이로드를 저장하지 않습니다.