
CVE-2026-43499 Google TV搭載Chromecast(sabrina)向けGhostLock rootエクスプロイト
Chromecast with Google TV(sabrina)向けのrootエクスプロイト。CVE-2026-43499 -- Linuxカーネルのfutex PI(優先度継承)サブシステムにおけるuse-after-freeを悪用する。
Android 14、カーネル5.15.170(PGO+BOLT+LTO、clang 17)を実行するロックされたブートローダーのデバイスでrootを取得する。
GhostLockは、rt_mutex_start_proxy_lock()内の-EDEADLKロールバックパスから呼び出されるremove_waiter()のバグを悪用する。この関数は、waiterタスクのものではなく(requeuerのもので、すでにNULLである)current->pi_blocked_onをクリアする。waiterのpi_blocked_onは決してクリアされず、カーネルスタック上の解放済みrt_mutex_waiterへのダングリングポインタが残る。
その後のsched_setattrがrt_mutex_adjust_pi -> rt_mutex_adjust_prio_chainをトリガーし、これがダングリングポインタを辿り、再利用されたヒープページ上の攻撃者制御データを介してPIチェーンを走査する -- rb_eraseを介した任意書き込みプリミティブを与える。
ucounts = NULLを持つ -- cap_capableは最初の反復で一致し、inc_rlimit_ucountsは1回のループで終了するため、&init_user_nsをリークする必要がなくなるPERF_SAMPLE_TIDフィルタにより、呼び出しスレッドのレジスタスナップショットのみがカウントされ、ホットなシステムサービスが最頻値投票を支配するのを防ぐ5.15.170-android14-11-gf4a1f03072af(aarch64、PGO+BOLT+LTO、clang 17.0.2)CONFIG_FUTEX_PI=y、CONFIG_IO_URING=y、perf_event_paranoid=-1、SELinux enforcing、panic_on_oops=1、ユーザー名前空間なしexport ANDROID_NDK_HOME=/path/to/android-ndk
make -j$(nproc)
Android NDKが必要(r27でテスト済み)。静的にリンクされたaarch64バイナリを生成する。
adb push ghostlock /data/local/tmp/
adb shell "cd /data/local/tmp && ./ghostlock --cred"
エクスプロイトは約20秒かかる(ヒープスプレー + KernelSnitchブルートフォース)。成功すると、プロセスはuid=0の資格情報で/system/bin/shをexecする。
このエクスプロイトは、Claude Opus 4.6(Anthropic)によってポーティングおよび開発され、GLM-5.3(Z.ai)がカーネルエクスプロイトコンサルタントを務めた。
kernel/futex/、kernel/locking/rtmutex.c、lib/rbtree.cこのエクスプロイトはセキュリティ研究および教育目的で公開されている。研究者が所有するデバイスを対象としている。所有していないデバイス、または許可なく使用しないこと。
MIT
| ステージ | 手法 |
|---|
| KASLRリーク | perf_event_openとPERF_SAMPLE_IP(TIDゲート付き) |
| タスク構造体リーク | perf_event_openとPERF_SAMPLE_REGS_INTR(TIDゲート付き、線形マップアドレスの最頻値) |
| mm_structリーク | KernelSnitch -- futexハッシュ衝突タイミングサイドチャネル |
| ヒープスプレー | SLUB破棄の振り付け(memfd-close、CPU部分オーバーフロー)+ io_uring_setup(256)による次数2ページ回収 |
| スタックオーバーレイ | AF_UNIX SOCK_SEQPACKET sendmsg -- move_addr_to_kernelが128バイトのsockaddrをカーネルスタックにコピーし、ダングリングwaiterのtask/lock/prioフィールドを上書きする |
| 走査トリガー | 単調なniceラダー(7 -> 14 -> 19)を伴うsched_setattrがPIチェーン走査を発火させる |
| 書き込みプリミティブ | rb_eraseのCase 1aがchild(fake_cred)をparent->rb_right = task->credに書き込む |
| 資格情報スワップ | task->cred = fake_cred(uid=0、全capability、スプレーページ上の自己完結型fake user_namespace) |
| rootシェル | execve("/system/bin/sh") -- execパス内のcommit_credsがfake_credをクリーンなslab資格情報にコピーする |