
LinuxカーネルのCVE-2026-64560に関するUAF分析:競合条件を誘発するPoC、パッチレビュー、影響を受けるLTS/Androidバージョンのマトリクス、およびパッチ適用済みデバイスの自己チェック
Reproducer / PoC(トリガー検証型):Linux & Android (NDK) 本リポジトリは、自身が所有するテストデバイス上でパッチ状態を検証し、研究・学習する目的のみに使用されます。権限昇格やエクスプロイトプリミティブは一切含みません。
| フィールド | 内容 |
|---|---|
| CVE ID | CVE-2026-64560 |
| タイトル | posix-cpu-timers: Prevent UAF caused by non-leader exec() race |
| 種別 | Use-After-Free(CWE-416)、競合状態 |
| CNA | kernel.org(Linux CNA) |
| CVSS v3.1 | 7.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 GKI カーネルは 5.10 / 5.15 / 6.1 / 6.6 / 6.12 LTS に基づいており、すべて影響範囲内です。mainline の修正コミットは 2026-07-29 に公開されたため、2026-08-01 以前の SPL(セキュリティパッチレベル)の Android デバイスはほぼすべてこの修正を適用していません。デバイス上で adb shell cat /proc/version と getprop ro.build.version.security_patch を使用して、カーネルバージョンと SPL を確認できます。
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) でその task の sighand->siglock を取得し、timerqueue を保護する必要があります。
2020 年のコミット 55e8c8eb2c7b は、タイマーにキャッシュされていた task ポインタを pid 参照に置き換え(2010 年の workaround e0a70217107e が導入した問題を修正するため)、操作のたびに pid_task(pid, type) で検索する方式にしました。この変更が本 CVE の競合ウィンドウを残しました。
execve() が非リーダースレッドによって実行されると、de_thread() → switch_leader() によって TGID が旧リーダーから新リーダーに移動し、旧リーダーは release_task() → __exit_signal() の経路をたどります。この中で old_leader->sighand = NULL が設定され、unhash_task(old_leader) が実行されます。
一方、別の CPU で実行されている sys_timer_delete() → posix_cpu_timer_del():
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 は旧リーダーであり、この時点で p->sighand == NULL のため、関数は「タスクが終了処理中であり、exit パスがキューからの削除を担当する」と判断し、何もせずに成功を返します。その後、free_posix_timer() が k_itimer を解放します。
要点:exec() は exit() とは異なります——exec() 時には TGID が変わらないため、プロセスレベル(p->signal->cpu_timers)に登録されている armed タイマーは継承され、キューに入ったままになります。その結果:
run_posix_cpu_timers()(tick 内で timerqueue を走査)が解放済みオブジェクトの timerqueue_node にアクセス → UAF 読み取り/書き込み;同種の問題は以下にも存在します:
posix_cpu_timer_set():通常のタイマーは一時的に -ESRCH を返すだけですが、カーネル内部の do_cpu_nanosleep() はスタック上に割り当てた k_itimer を使用しており、同様の UAF となります。posix_cpu_timer_rearm():rearm が静かに失敗するため、タイマーが以後満了しなくなります(機能的なバグ)。Frederic Weisbecker 氏は次のように指摘しています:__exit_signal() 内の tsk->sighand = NULL は通常のストアであり、ARM64 などの弱順序アーキテクチャでは、posix_cpu_timer_del() が sighand == NULL を観測した時点で、posix_cpu_timers*_exit() より前のキューからの削除書き込みを観測できる保証はありません。これにより、WARN_ON_ONCE(timer_queued(tmr)) が誤検出される可能性があります。
__exit_signal() 内を smp_store_release(&tsk->sighand, NULL) に変更;lock_task_sighand() の !sighand パスに smp_acquire__after_ctrl_dep() を追加;timer_lock_sighand() を追加:task の検索 + sighand のロックを行い、sighand == NULL の場合は戻らずに検索を再試行——exec シナリオでは新しいリーダーがヒットし、exit シナリオでは検索が失敗した場合にのみ断念します;_del / _set / _rearm)をすべてこのヘルパーに統一します。完全な diff は patches/920f893f735e.patch を参照してください。
poc/ には競合トリガーが用意されています。2 つのスレッドがそれぞれ高強度でループします:
timer_create(CLOCK_PROCESS_CPUTIME_ID) → arm(非常に短い初期満了時間)→ ビジーウェイトで発火待ち → timer_delete() を繰り返します;fork() を繰り返し、子プロセス内で非リーダースレッドを作成し、そのスレッドが execve() を呼び出します(非リーダー 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 制御などのエクスプロイトプリミティブは一切含みません。これを権限昇格 exploit にするには、さらなる多大な作業(ヒープ風水(heap feng shui)、
k_itimerが存在する slab cache のプレースホルダオブジェクト、KASLR/CFI の回避など)が必要であり、特定のカーネルビルドに強く依存します。本リポジトリはこの部分を意図的に含めていません。
├── README.md ← 本文
├── patches/
│ └── 920f893f735e.patch ← mainline 修复补丁全文
└── poc/
├── cve_2026_64560_poc.c ← 触发器源码(Linux/Android 通用)
├── Makefile ← Linux / NDK 交叉编译
└── Android.mk ← NDK ndk-build(可选)
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'
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* 查看
デバイスには以下の要件が必要です:
CLOCK_PROCESS_CPUTIME_ID タイマーは TGID を対象とする → signal->cpu_timers に登録され、exec 後も継承される —— これが UAF の前提です(CLOCK_THREAD_CPUTIME_ID では不可);switch_leader() により pid_task(TGID) が返す旧リーダーが直後に sighand = NULL となる —— これが競合の必要条件です;timer_create/arm/delete と高頻度の fork/exec を並行させ、posix_cpu_timer_del() がウィンドウ内に収まる確率を最大化します。タイマー満了処理(run_posix_cpu_timers)自体もダングリングノードに触れるため、追加のトリガーは不要です。# 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 モードがあります)。
本リポジトリはセキュリティ研究と防御検証のみを対象としています。所有している、または書面による許可を得たデバイス上でのみ実行してください。PoC はカーネルの不安定化、さらには panic を引き起こす可能性があるため、本番デバイスでは実行しないでください。作者は、不正使用によって生じたいかなる結果についても責任を負いません。
| ブランチ | 影響範囲 | 修正バージョン(≥) | Stable 修正コミット |
|---|
| 5.10 LTS | 5.7 ~ 5.10.261 | 5.10.262 | 67aa823e3e8c |
| 5.15 LTS | ~ 5.15.212 | 5.15.213 | d8bcb28abad8 |
| 6.1 LTS | ~ 6.1.179 | 6.1.180 | cc35ddbc4973 |
| 6.6 LTS | ~ 6.6.146 | 6.6.147 | 12a891c773ae |
| 6.12 LTS | ~ 6.12.99 | 6.12.100 | e74443f5db00 |
| 6.18 | ~ 6.18.40 | 6.18.41 | 6a7ecc25abe6 |
| 7.1 | ~ 7.1.4 | 7.1.5 | ad1cafa1bdaa |
| mainline | < 7.2-rc3 | 7.2-rc3 | 920f893f735e |