Skip to content
KitploitKITPLOIT
도구블로그
제출
도구블로그
제출

해킹, 침투 테스트 및 사이버 보안 도구를 당신의 보안 무기고에!

Kitploit은 해킹, 사이버 보안 및 침투 테스트 도구 디렉토리입니다. 최신 프로젝트 업데이트를 발견하여 취약점을 찾고, 시스템을 분석하고, 테스트를 자동화하고, 보안을 강화하세요.

··피드·문의·개인정보·© 2026 Kitploit

도구 디렉토리

카테고리

모든 카테고리 보기
Loading categories
도구/GitHubGitHub/villager1314/cve-2026-64560-analysis
Android SecurityVulnerability AnalysisExploitationMobile SecurityLearning & EducationBinary Exploitation
GitHubvillager1314/cve-2026-64560-analysis

CVE-2026-64560-Analysis

리눅스 커널 UAF 분석: CVE-2026-64560에 대한 경쟁 조건(race) 트리거 PoC, 패치 리뷰, 영향받는 LTS/Android 버전 매트릭스, 패치된 기기 자가 점검.

인기

모두 보기 →

커뮤니티에서 가장 많이 사용되는 도구를 찾아보세요.

모든 도구 탐색

도구 컬렉션을 둘러보세요

모든 도구 보기 →
공유
저장소 보기
1161개월 전Kitploit 검토 완료

CVE-2026-64560 — Linux Kernel posix-cpu-timers non-leader exec() 경쟁 조건 UAF

Reproducer / PoC(트리거 검증형): Linux & Android (NDK) 본 저장소는 자체 테스트 기기에서 패치 상태를 검증하고 연구/학습 목적으로만 제공되며, 권한 상승/익스플로잇 프리미티브를 포함하지 않습니다.

CVSS 3.1 CVSS 4.0 (SUSE) CWE-416 Fix


1. 취약점 개요

필드내용
CVE IDCVE-2026-64560
제목posix-cpu-timers: Prevent UAF caused by non-leader exec() race
유형Use-After-Free(CWE-416), 경쟁 조건
CNAkernel.org(Linux CNA)
CVSS v3.17.8 High — CVSS:3.1/AV:L/AC:L/PR:L/UI:N/S:U/C:H/I:H/A:H
CVSS v4.0 (SUSE)8.5 High — CVSS:4.0/AV:L/AC:L/AT:N/PR:L/UI:N/VC:H/VI:H/VA:H/SC:N/SI:N/SA:N
EPSS~0.12%(2nd percentile, 2026-08 시점)
CISA KEV미등재
공개 날짜2026-07-29
수정 커밋(mainline)920f893f735e92ba3a1cd9256899a186b161928d
문제 유발 커밋(Fixes:)55e8c8eb2c7b (v5.7, 2020) — "posix-cpu-timers: Store a reference to a pid not a task"
수정자Thomas Gleixner <[email protected]>
보고자Wongi Lee <[email protected]>, Jungwoo Lee <[email protected]>
영향 파일kernel/exit.c, kernel/signal.c, kernel/time/posix-cpu-timers.c

영향을 받는 버전

취약점은 v5.7(2020-05)에서 도입되었으며, 수정 사항은 각 stable 브랜치에 백포트되었습니다:

Android 관련 사항

Android GKI 커널은 5.10 / 5.15 / 6.1 / 6.6 / 6.12 LTS를 기반으로 하며 모두 영향을 받는 범위에 속합니다. 메인라인 수정 커밋이 2026-07-29에 공개되었으므로, SPL(보안 패치 수준)이 2026-08-01 이하인 Android 기기는 대부분 이 수정 사항이 반영되지 않았습니다. 기기에서 adb shell cat /proc/version 및 getprop ro.build.version.security_patch로 커널 버전과 SPL을 확인할 수 있습니다.


2. 기술 세부 사항

2.1 배경: posix CPU 타이머와 sighand

POSIX CPU 타이머(timer_create(CLOCK_PROCESS_CPUTIME_ID, ...) / timer_create(CLOCK_THREAD_CPUTIME_ID, ...))는 커널에서 kernel/time/posix-cpu-timers.c에 의해 관리됩니다. 각 k_itimer는 it.cpu.pid를 통해 대상 태스크를 기억하며, 타이머를 조작할 때는 lock_task_sighand(p, &flags)로 해당 태스크의 sighand->siglock을 획득하여 timerqueue를 보호해야 합니다.

2020년 커밋 55e8c8eb2c7b는 타이머에 캐시되던 task 포인터를 pid 참조로 교체했고(2010년 워크어라운드 e0a70217107e가 도입한 문제를 수정하기 위해), 매 작업 전에 pid_task(pid, type) 조회를 수행합니다. 이 변경으로 인해 본 CVE의 경쟁 조건 창(race window)이 남게 되었습니다.

2.2 경쟁 조건 시나리오(non-leader 스레드 exec)

execve()가 non-leader 스레드에 의해 실행되면, de_thread() → switch_leader()가 TGID를 기존 leader에서 새 leader로 이전하고, 기존 leader는 release_task() → __exit_signal() 경로를 거치며, 이 과정에서 old_leader->sighand = NULL로 설정되고 unhash_task(old_leader)가 호출됩니다.

한편, 다른 CPU에서 실행 중이던 sys_timer_delete() → posix_cpu_timer_del():

root@kitploit:~
 sys_timer_delete()                        exec()
   posix_cpu_timer_del()
   // 观察到旧 leader
   p = pid_task(pid, pid_type);            de_thread()
                                             switch_leader();
                                             release_task(old_leader)
                                               __exit_signal(old_leader)
                                                 sighand = lock(old_leader, sighand);
                                                 posix_cpu_timers*_exit();
   sighand = lock_task_sighand(p)            unhash_task(old_leader);
     sh = lock(p, sighand)                   old_leader->sighand = NULL;
                                               unlock(sighand);
     (p->sighand == NULL)
       unlock(sh)
       return NULL;

   // 直接返回,没有摘链!
   if (!sighand)
      return 0;
   free_posix_timer();   // ← k_itimer 被释放

posix_cpu_timer_del()이 조회한 p는 기존 leader이며, 이때 p->sighand == NULL이므로 함수는 "태스크가 종료 중이고 exit 경로가 연결 해제(unlink)를 처리할 것"이라고 판단하여 아무것도 하지 않고 성공을 반환합니다. 이후 free_posix_timer()가 k_itimer를 해제합니다.

핵심 포인트: exec()는 exit()와 다릅니다. exec() 시 TGID는 변경되지 않으므로 프로세스 레벨(p->signal->cpu_timers)에 걸려 있는 armed 타이머는 상속되어 여전히 큐에 남아 있습니다. 따라서:

  • run_posix_cpu_timers()(tick에서 timerqueue를 순회)가 해제된 객체의 timerqueue_node에 접근 → UAF 읽기/쓰기;
  • 다른 타이머의 add/delete 작업도 댕글링 노드가 포함된 이 rbtree를 순회하게 됨 → UAF.

동일한 유형의 문제는 다음에도 존재합니다:

  • posix_cpu_timer_set(): 일반 타이머는 단지 일시적으로 -ESRCH를 반환할 뿐입니다. 그러나 커널 내부의 do_cpu_nanosleep()은 스택에 할당된 k_itimer를 사용하므로 동일한 UAF가 발생합니다.
  • posix_cpu_timer_rearm(): rearm이 조용히 실패하여 타이머가 더 이상 만료되지 않습니다(기능적 버그).

2.3 약한 메모리 순서(weak ordering) 아키텍처의 부차적 문제

Frederic Weisbecker가 지적했듯이, __exit_signal()에서 tsk->sighand = NULL은 일반(ordinary) 저장이므로 ARM64와 같은 약한 메모리 순서 아키텍처에서는 posix_cpu_timer_del()이 sighand == NULL을 관찰하더라도 posix_cpu_timers*_exit() 이전의 연결 해제 쓰기를 관찰할 수 있음이 보장되지 않아, WARN_ON_ONCE(timer_queued(tmr))가 오탐(false positive)을 낼 수 있습니다.

2.4 수정 방안

  1. __exit_signal()에서 smp_store_release(&tsk->sighand, NULL)로 변경;
  2. lock_task_sighand()의 !sighand 경로에 smp_acquire__after_ctrl_dep() 추가;
  3. 새 helper timer_lock_sighand() 도입: task 조회 + sighand 잠금. sighand == NULL이면 반환하지 않고 조회를 재시도 — exec 시나리오에서는 새 leader를 찾게 되고, exit 시나리오에서는 조회가 실패해야 비로소 포기;
  4. 영향을 받는 세 함수(_del / _set / _rearm)가 모두 이 helper를 사용하도록 통일.

전체 diff는 patches/920f893f735e.patch를 참조하세요.


3. PoC 설명(트리거 검증용, 권한 상승 익스플로잇 아님)

poc/ 아래에 경쟁 트리거(race trigger) 가 제공됩니다. 두 스레드가 각각 고강도로 다음을 반복합니다:

  • 스레드 A(타이머 스레드): timer_create(CLOCK_PROCESS_CPUTIME_ID) → arm(매우 짧은 초기 만료 시간) → busy-wait로 만료 대기 → timer_delete()를 반복;
  • 스레드 B(exec 스레드): fork()를 반복 → 자식 프로세스에서 non-leader 스레드를 만든 뒤 해당 스레드가 execve() 호출(non-leader exec는 이 취약점의 필요 조건), 부모 프로세스는 즉시 waitpid()로 회수.

timer_delete()가 마침 de_thread()/__exit_signal()과의 경쟁에 적중하면, 패치되지 않은 커널에서는 해제된 k_itimer가 여전히 signal->cpu_timers의 rbtree에 남아 있게 되고, 이후 run_posix_cpu_timers()나 다른 timerqueue 작업이 댕글링 노드에 접근하게 됩니다. KASAN 커널과 함께 사용하면 BUG: KASAN: use-after-free in run_posix_cpu_timers / timerqueue_del 등의 보고를 안정적으로 관찰할 수 있으며, KASAN이 없을 때는 보통 산발적인 커널 경고나 panic으로 나타납니다.

성격 설명: 이것은 순수 C로 작성된 race 트리거이며, heap spray, 객체 점유, RIP 제어 등 어떤 익스플로잇 프리미티브도 포함하지 않습니다. 이를 권한 상승 익스플로잇으로 만들려면 추가로 많은 작업(힙 풍수(heap feng shui), k_itimer가 속한 slab cache의 점유 객체, KASLR/CFI 우회 등)이 필요하고, 특정 커널 빌드와 강하게 연관됩니다. 본 저장소는 의도적으로 이 부분을 포함하지 않습니다.

디렉터리 구조

root@kitploit:~
├── README.md                ← 本文
├── patches/
│   └── 920f893f735e.patch   ← mainline 修复补丁全文
└── poc/
    ├── cve_2026_64560_poc.c ← 触发器源码(Linux/Android 通用)
    ├── Makefile             ← Linux / NDK 交叉编译
    └── Android.mk           ← NDK ndk-build(可选)

3.1 Linux x86_64 컴파일 및 실행

root@kitploit:~
cd poc
make                 # 生成 cve_2026_64560_poc
sudo ./cve_2026_64560_poc -d 60
# 观察 dmesg: sudo dmesg -wH | grep -iE 'kasan|use-after|BUG|WARNING'

3.2 Android(NDK 크로스 컴파일, adb 푸시)

root@kitploit:~
cd poc
export ANDROID_NDK_HOME=/path/to/ndk
make android         # 生成 cve_2026_64560_poc_arm64(static, pie)

adb push cve_2026_64560_poc_arm64 /data/local/tmp/cvepoc
adb shell chmod 755 /data/local/tmp/cvepoc
adb shell /data/local/tmp/cvepoc -d 120

# 观察内核日志:
adb shell su 0 dmesg -w | grep -iE 'kasan|use-after|BUG|WARNING|timer'
# 无 root 时也可在触发崩溃后用 adb shell cat /sys/fs/pstore/console-ramoops* 查看

필요한 기기 조건:

  1. 커널 버전이 영향 범위(5.7 ~ 위 표의 수정 버전 이전)에 있고, SPL ≤ 2026-08-01인 기기는 대부분 영향을 받습니다;
  2. 해당 패치가 적용되지 않아야 합니다(패치 적용 후에는 PoC가 빈 루프만 돌다가 종료됨);
  3. 명확한 KASAN 보고를 확인하려면 KASAN 커널이 필요합니다(직접 컴파일한 GKI/boot.img면 충분). 제조사 기본 커널에서 트리거에 성공하면 보통 watchdog/panic 또는 조용한 손상(silent corruption)으로 나타납니다.

3.3 적중 원리(왜 이렇게 설계했는가)

  • CLOCK_PROCESS_CPUTIME_ID 타이머는 TGID를 대상으로 함 → signal->cpu_timers에 연결되고 exec 후에도 상속됨 — 이것이 UAF의 전제 조건(CLOCK_THREAD_CPUTIME_ID로는 불가);
  • non-leader 스레드 exec → switch_leader()로 인해 pid_task(TGID)가 반환한 기존 leader가 곧바로 sighand = NULL이 됨 — 이것이 경쟁 조건의 필요 조건;
  • 고빈도 timer_create/arm/delete + 고빈도 fork/exec 병렬 실행으로 posix_cpu_timer_del()이 경쟁 창(window) 안에 들어갈 확률을 극대화. 타이머 만료 처리(run_posix_cpu_timers) 자체도 댕글링 노드를 건드리므로 별도의 트리거가 필요 없음.

4. 자가 점검: 내 기기가 패치되었는가?

root@kitploit:~
# Android:
adb shell cat /proc/version            # 内核版本是否 >= 上表修复版本
adb shell getprop ro.build.version.security_patch   # SPL 是否 > 2026-08
# Linux:
uname -r
# 或直接检查源码是否包含 timer_lock_sighand:
grep -r timer_lock_sighand /usr/src/linux/kernel/time/posix-cpu-timers.c

PoC를 수 분간 실행해도 KASAN/panic이 전혀 발생하지 않고 커널 버전이 수정 버전 이상이면 패치된 것으로 간주합니다(PoC 자체에도 --check 모드가 있어 가벼운 스모크 테스트를 수행합니다).


5. 참고 링크

  • CVE 레코드: https://www.cve.org/CVERecord?id=CVE-2026-64560
  • GitHub Advisory: https://github.com/advisories/GHSA-78ph-mc3q-52vv
  • mainline 수정 커밋: https://github.com/torvalds/linux/commit/920f893f735e92ba3a1cd9256899a186b161928d
  • 문제를 유발한 커밋 (v5.7): https://github.com/torvalds/linux/commit/55e8c8eb2c7b6bf30e99423ccfe7ca032f498f59
  • 2010년 워크어라운드: https://github.com/torvalds/linux/commit/e0a70217107e
  • SUSE 추적(Bugzilla 1273004/1273007 포함): https://www.suse.com/security/cve/CVE-2026-64560

면책 조항 / Disclaimer

본 저장소는 보안 연구 및 방어 검증만을 위한 것입니다. 소유한 기기 또는 서면 승인을 받은 기기에서만 실행하세요. PoC는 커널 불안정 또는 panic을 유발할 수 있으므로 프로덕션 기기에서 실행하지 마십시오. 저자는 오용으로 인한 어떠한 결과에도 책임을 지지 않습니다.

도구 다운로드
브랜치영향 범위수정 버전(≥)Stable 수정 커밋
5.10 LTS5.7 ~ 5.10.2615.10.26267aa823e3e8c
5.15 LTS~ 5.15.2125.15.213d8bcb28abad8
6.1 LTS~ 6.1.1796.1.180cc35ddbc4973
6.6 LTS~ 6.6.1466.6.14712a891c773ae
6.12 LTS~ 6.12.996.12.100e74443f5db00
6.18~ 6.18.406.18.416a7ecc25abe6
7.1~ 7.1.47.1.5ad1cafa1bdaa
mainline< 7.2-rc37.2-rc3920f893f735e