
GhostLock (CVE-2026-43499) アダプター(4.19.152-perf+ Android カーネル用)
ブートローダーがロックされたOnePlus/OPPO/realmeデバイス向けのカーネルエクスプロイト。ブートローダーのロック解除やブートイメージの改変なしに、root権限の取得とKernelSUのインストールを実現します。複数デバイスのオフセットテーブルにより、カーネルバージョンを実行時に自動検出します。
CVE-2026-43499 — Futex PI(優先度継承)Use-After-Free
影響を受けるLinuxカーネル: 2.6.39〜7.1。メインライン7.1で修正済み(コミット3bfdc63936dd)。Android GKI 6.12.xは依然として脆弱です。
pselect6システムコールは、fd_setデータをカーネルスタック上にコピーします。futex PIウェイター機構と組み合わせると、解放されたスタックフレームがrt_mutex_waiter構造体として再利用される可能性があります。その後、PIチェーン走査中のrbツリーのリバランスによって、制御された値が任意のカーネルアドレスに書き込まれます。
| デバイス | SoC | カーネル | 状態 |
|---|---|---|---|
| OnePlus Ace 6T (PLR110) | SM8845 | 6.12.38-...-ab14275539 | 動作確認済み |
| OnePlus Ace 6T (PLR110) | SM8845 | 6.12.38-...-ab14552068 | 動作確認済み |
| OnePlus 15 (CPH2749) | SM8850 | 6.12.23-...-ab14541642 | 動作確認済み |
| Xiaomi 17 (pudding) | SM8850 | 6.12.23-...-abogki463945075 | 動作確認済み |
| Xiaomi 17 (pudding) | SM8850 | 6.12.69-...-abogki514973465 | 動作確認済み(2026年8月アップデート) |
| OnePlus 13 (IN2060) | SM8750 | 6.6.89-...-abogki446052083 | 動作確認済み(PSELECT_SHIFT=-2) |
| OPPO Pad 4 Pro | SM8750 | 6.6.89-...-ab14358676 | 動作確認済み(PSELECT_SHIFT=-2) |
| デバイス | SoC | カーネル | 備考 |
|---|---|---|---|
| OnePlus 15T (PLZ110) | SM8845 | 6.12.38-...-ab14552068 | Ace 6Tと同じカーネル。QEMUでSP diff=-64を検証済み。 |
pselectスタックオーバーレイは、解放されたrt_mutex_waiterがstack_fdsバッファのユーザー制御可能な領域内に配置された場合にのみ機能します。ウェイターの配置場所はカーネルバージョンではなく、コンパイラの出力(PGO + LTO)によって決まります。詳細はスタックレイアウトを参照してください。
| デバイス | SoC | カーネル | 理由 |
|---|---|---|---|
| OPPO Find X9 Ultra | SM8750 | 6.12.58-android16-6 | PGOによりdo_futexフレームが消滅 → SP diff=+32、ウェイターword=14。安全なシフトは存在しません。 |
| OPPO Find X7 | — | 6.1.157 | 6.1 GKI: ウェイターはword 13(6.1の全OPLUS/GKIデバイス) |
| realme RMX5070 | SM6650 | 6.1.141 | 6.1 GKI: ウェイターはword 13 |
| realme RMX3852 | SM8635 | 6.1.141 | RMX5070と同じ6.1ブランチ |
| OnePlus 13R / Ace 5 | SM8650 | 6.1.x | 同じ6.1ブランチ |
| OnePlus 12 | SM8650 | 6.1.141 | 6.1 GKI: do_futexがPGOによりインライン化、ウェイターword=13/19 |
| OPPO Pad 5 (OPD2502) | MT6878 | 6.1.134 | 同じ6.1ブランチ |
| OPPO PKW110 | — | 5.15.180 | do_futexフレーム0x140(通常の4.5倍)→ ウェイターword=-29、到達不能 |
| Motorola Edge 60 Fusion | MT6878 | 6.1.145 | 6.1 GKI: ウェイターはword 13(OPLUS以外でも同じ結果) |
| iQOO Z9 5G | — | 5.15.178 | do_futexフレームが大きすぎるためウェイターに到達不能。OPLUSデバイスではない(vivo)。 |
デバイスの機能に応じて自動選択される2つのrootパス:
off_ashmem_misc_fops != 0であること(BSSに静的miscdeviceを持つC ashmem)が必要です。
PI write (mode=4) → redirect miscdevice fops to fake fops (via W0 pi_tree)
configfs r/w established
→ pipe physrw (1-byte precise kernel r/w)
→ SELinux enforcing = 0 (single byte, no policycap corruption)
→ UMH: inject work_struct into system_unbound_wq
kernel executes /data/local/tmp/a/e --umh as UID 0
→ root script → ksud late-load → KSU installed
パスBに対する利点:
selinux_state.policycapを破損しない(OnePlus 13のネットワーク問題を修正)現在利用可能なデバイス: OnePlus 13(カーネル6.6、C ashmem)。 Rust ashmem搭載デバイス(6.12 GKI)では利用不可 — miscdeviceがヒープ割り当てされ、コンパイル時にアドレスを予測できないためです。
UMHオフセットまたはC ashmemのmisc_fopsが利用できない場合に使用されます。
Write 1 (mode=1) → SELinux enforcing = 0
(low byte of kernel ptr = 0x00, 8-byte write)
Write 2 (mode=2) → task->cred = init_cred
(uid=0, all capabilities)
Root shell → ksud late-load (KernelSU LKM)
→ su -c load_policy (fix SELinux policycap)
→ dynamic manager registration
App (seccomp) → Write 1 (no perf needed)
→ mini-adb connect TCP (port from /data/local/tmp/a/adb_port, default 5555)
→ adb shell: full exploit (perf works, no seccomp)
→ root → KSU → network fix
BOOT_COMPLETED → BootCompletedReceiver
├─ su available → skip (soft reboot / already rooted)
└─ no root → GhostlockService → setsid exploit --bootstrap
NFDS=320の場合、カーネルのcore_sys_selectは256バイトのstack_fdsバッファを割り当てます:
stack_fds: 0 5 10 14 | 15 20 25 29
├─in─┤─out─┤─ex──┤ ├res_in┤res_out┤res_ex┤
◄── USER CONTROLLED ──►│◄── KERNEL ZEROED ──►
エクスプロイトは、偽のウェイターフィールド(task、lock)をfd_set入力ビットマップに書き込みます。これが機能するには、ウェイターのtaskフィールドとlockフィールドが制御可能ゾーン(word 0〜14)内に位置する必要があります。
Ace 6T ✅ (waiter at word 2):
░░████████████████░░│░░░░░░░░░░░░░░░░░░
▲waiter t l │
task/lock controllable
RMX5070 ❌ (waiter at word 13):
░░░░░░░░░░░░░████│██████████████░░░░░░
▲ │ t l
waiter task/lock ZEROED
実現可能性のルール: ウェイターword + 11(rt_waiter_node内のlockオフセット)は14以下でなければなりません。実現可能な最大ウェイターwordは3です。
ウェイターの位置は、コンパイラのスタックフレームレイアウト(PGO + LTO + BOLT最適化プロファイル)によって決まり、SoCブランチごとに異なります。同じカーネルバージョンでも、SoCが異なればレイアウトも異なる場合があります。
すべてのカーネル書き込みは、イメージのリニアマップエイリアスを経由します:
data_addr(x) = PAGE_OFFSET + (kernel_phys_load - PHYS_OFFSET) + (x - KIMAGE_TEXT_BASE)
ブートローダーがkernel_phys_loadを選択するため、SoCごとに異なり、boot.imgやDTには含まれません。struct kernel_offsets内のデバイス別フィールド。0の場合はtarget.hのデフォルトを使用します。
| SoC | kernel_phys_load |
|---|---|
| SM8845 (Ace 6T, 15T) | 0xa8000000 |
| SM8750 (OnePlus 13, OPPO Pad 4 Pro) | 0xa8000000 |
| SM8850 (OnePlus 15, Xiaomi 17) | 0xc7800000 |
誤った値は静かに失敗します — 書き込みは依然としてマップ済みRAMに到達するため、クラッシュも効果も発生しません。PSELECT_SHIFTの問題と混同しないでください。同じモデルのroot化済み端末で値を読み取ってください(Kernel codeは_stextから始まり、_textは0x10000低い位置にあります):
su -c 'grep -i "Kernel code" /proc/iomem' # c7810000-... -> 0xc7800000
カーネルによって、ウェイターは制御可能ゾーン内の異なる位置に配置されます。PSELECT_SHIFTを使用して調整してください:
# Default (Ace 6T + OnePlus 15, 6.12): shift=0
/data/local/tmp/a/e
# OnePlus 13 (6.6): shift=-2
PSELECT_SHIFT=-2 /data/local/tmp/a/e
# Override kernel_phys_load for new SoCs (when /proc/iomem is not accessible):
KPHYS=0xc7800000 /data/local/tmp/a/e
check_feasibility.pyのウェイターwordは信頼できません。フレームの演算は正しいものの、ゼロストアから推測される構造体オフセットが正しくありません(OnePlus 15ではword 3と算出されますが、実測値はword 2です)。誤ったシフトは推測のたびにカーネルパニックを招くため、代わりにroot化済み端末で実測してください:
echo 'p:ds do_select fdsin=+0(%x1)' >> /sys/kernel/tracing/kprobe_events
echo 'p:rw rt_mutex_wait_proxy_lock waiter=%x2' >> /sys/kernel/tracing/kprobe_events
# trigger FUTEX_CMP_REQUEUE_PI, then:
# PSELECT_SHIFT = ((waiter & 0x3fff) - (fdsin & 0x3fff)) / 8 - 2
NDK=/path/to/android-ndk
$NDK/toolchains/llvm/prebuilt/linux-x86_64/bin/aarch64-linux-android35-clang \
-O2 -Wall -Isrc/core -Isrc/devices -DTARGET_CONFIG_H="target.h" \
src/core/main.c src/core/util.c src/core/slide.c \
src/core/fops.c src/core/pipe_physrw.c src/core/root.c \
src/core/miniadb.c src/core/umh_root.c \
-o ghostlock -fPIE -pie -pthread
GhostLockはroot権限のみを提供します。KernelSUのインストールはksudに依存します — 各KMIバージョン向けのkernelsu.koモジュールを内蔵したバイナリです。rootスクリプトはデバイス上のksudを検索し、ksud late-load --kmi android16-6.12を実行します。
| 方法 | 手順 |
|---|---|
| ReSukiSU APK(推奨) | ReSukiSUまたはこのフォークをインストール。公式リリースにはlibksud.soが同梱されています。 |
| CIリリース | ReSukiSU CIからksud-aarch64-linux-android.zipをダウンロード |