
Amazon Fire 7(Fire OS 7.3.3.1)において、Mali kbase JIT use-after-free CVE-2022-38181を利用し、modprobe_path overwriteチェーンを用いて一時的なrootを取得するカーネルエクスプロイト研究。
AI支援プロジェクト。 この研究、エクスプロイト開発、およびドキュメントは、 モデル GLM-5.3 と DeepSeek V4.1 Flash を使用したAI支援によって作成されました。
最終ファームウェア — Fire OS 7.3.3.1、PS7331.4463N、カーネル 4.9.117(ビルド 2025-05-03、SPL 2024-08-01) における Amazon Fire 7 第9世代(mustang、MT8163、Mali-T720) のルートエクスプロイト研究。
目標: LineageOS。このユニットではブートローダーパスは死んでいる(パッチ済みブートROM — CMDショートによるpreloaderのみ)ため、 残された唯一の経路はソフトウェアカーネルエクスプロイトである。
nix-shell -p android-tools --run './run.sh' # add -p zig too if no zig
成功時:```
/data/metrics/su id # run a command as root
/data/metrics/su # interactive root shell
reclaim はおよそ 3 回に 1 回の起動で成功し、失敗するとタブレットはパニック/再起動します。
run.sh は再起動を待ってリトライするだけです。SELinux はエクスプロイトの一環として
強制的に Permissive にされるため、root は 実行時のみ です — 再起動すると
ストック状態に戻り、run.sh を再実行する必要があります。
ビルド済みの st3 と su (armv7 静的) がコミットされているため、実行に
ツールチェーンは不要です。zig があれば ./run.sh --build で poc/*.c から
再ビルドできます。
GhostLock (下記) は保留中です: MTK の BUG_ON rtmutex 変種 + シェルからの カーネルアドレス開示ゼロ = このビルドではアーキテクチャ上の行き止まり (セッション 2-4)。 kbase JIT UAF は再診断され (destroy-worker の「無条件パニック」は JIT_FREE の 逆参照であり、ログはパニック途中の adbd 死亡により失われた)、ステージ 2 は 現在オラクル実証済みです — SESSION 5 のセクションを参照。
rtmutex remove_waiter() futex-PI スタック UAF (NebuSec 開示 2026-07、修正 3bfdc63936dd
は 2026-04 に着地)。脆弱な範囲 2.6.39–7.1 → 我々の 4.9.117 (2025 年 5 月) は影響を受ける。
我々の正確なビルドで検証済み:
CONFIG_FUTEX=y、rtmutex はコンパイル済み、バグはそのまま存在:
rtmutex.c:1108-1111 は current->pi_lock/current->pi_blocked_on を使用 (本来は
waiter->task であるべき); バグのある呼び出し箇所 rtmutex.c:1723 (rt_mutex_start_proxy_lock エラーパス)WAIT_REQUEUE_PI/CMP_REQUEUE_PI)、デバイスノード不要、
SELinux でゲートされるものは何もない — kbase パスの致命的な障害はここには存在しないsched_setattr → __sched_setscheduler → rt_mutex_adjust_pi(p) が
sched/core.c:4706 で — 古い pi_blocked_on を逆参照 ✓futex.c:1975 が this->rt_waiter を渡し、
これは futex.c:2880 の futex_wait_requeue_pi で宣言) → waiter は arm32 select (nr 142) fd_sets を
通じて自身の解放済みフレームを刻印するDEBUG_RT_MUTEXES オフ
→ コンパクトな 48 バイト rt_mutex_waiter (tree_entry@0, pi_tree_entry@0xc, task@0x18,
lock@0x1c, prio@0x20, deadline@0x28)modprobe_path @ 0xc111488c (文字列は
vmlinux 内で自己位置特定; KALLSYMS_ALL オフのためデータシンボルにはこのトリックが必要) → 未知の binfmt exec → root
スクリプト (setenforce 0, OTA 無効化, su)refs/ 内の参照: NebuSec/CyberMeowfia (オリジナル)、GhostLock-5.10 (Fire OS 8 移植、
src/exp32/ に完全な 32 ビット ARM トリガー)、ghostlock-...-4.19-k40 (Qualcomm 4.19 Android 移植)exp32/main.c の移植rt_waiter フレームオフセット vs do_sys_select fd_set 領域 — 我々の vmlinux を
逆アセンブル (do_sys_select の stack_fds vs futex_wait_requeue_pi フレーム)、
STAMP_NFDS/STAMP_WAITER_OFF を調整可能パラメータとして公開Failed critical init step 3/dev/mali0 ワールド RW + SELinux gpu_device、kbase r26p0-01rel0selroot 2 パケットチェーン: selinux_state.enforcing をゼロ化、
偽エントリを commit_creds(&init_cred) に書き換え。uid=0、SELinux Permissive。mustang、Fire OS 7.3.3.1 PS7331.4463N/00315758630404.9.117-g08fe75b-dirty、ビルド日時 Sat May 3 01:25:15 UTC 2025 (Linaro GCC 6.3-2017.05)/dev/kb、/dev/dkb (Amazon カーネルバックアップパーティション) root:drmrpc 0660 — ロック済みmali_kbase r26p0-01rel0 (Midgard, Mali-T720)、NVD の影響範囲 r4p0–r31p0 内mali_kbase_mem.c:2721 kbase_jit_destroy_worker が領域を解放、kctx->jit_alloc[id] を決してクリアしないmali_kbase_softjobs.c:1270 kbase_jit_free_finish が古い jit_alloc[ids[j]] を逆参照mali_kbase_mem.c:3138 kbase_jit_backing_lost → destroy パス (reclaim 中に発火)0xc0008000 VA / 0x40080000 PA)ARM_SW_DOMAIN_PAN なし → ret2usr が可能; CONFIG_PANIC_ON_OOPS=y (失敗した試行 = 再起動)SLAB_FREELIST_RANDOM/HARDENED なし、CONFIG_USER_NS/USERFAULTFD/NF_TABLES なしCONFIG_MODULES=y、STATIC_USERMODEHELPER なし → modprobe_path 上書き = root_IOC_TYPE 0x80)MEM_ALLOC union は 32 バイト (in は extent を含む 4 × u64)BASE_MEM_PROT_GPU_RD|WR (ビット 2|3) を含める必要があり、レガシーな R|W ではないmmap(fd, offset=3<<12, PROT_NONE)JOB_SUBMIT のストライドは sizeof(base_jd_atom_v2) = 48 と等しくなければならない (base_jd_prio/base_jd_dep_type は u8 typedef)MEM_JIT_INIT (nr 14, v2 構造体)、alloc/free は JOB_SUBMIT 経由の ソフトジョブ
(BASE_JD_REQ_SOFT_JIT_ALLOC=0x209, ...FREE=0x20a; jc=ユーザーポインタ, nr_extres=カウント)info->gpu_alloc_addr を通じて書き込む (事前に確保して渡す必要がある GPU VA)| 退避可能オブジェクト | プレッシャー | 結果 |
|---|---|---|
| なし | 900 MB | 生存 |
| なし | 1300 MB | パニック (システム lowmem バグ — 無関係) |
| 通常領域 + DONT_NEED | 700 MB | 生存 |
| JIT 領域 + DONT_NEED | 700 MB | reclaim パスでパニック |
パニックは eviction 自体の間に発生する (evictable_reclaim_scan_objects → backing_lost →
destroy worker) — ぶら下がり参照 (jit_alloc[]、evict リスト) は、我々が JIT_FREE を
submit する前に走査される。ステージ 2 はレースに勝つ必要がある: プレッシャーがまだ
実行中の間に、解放された kbase_va_region を我々自身の MEM_ALLOC スプレーで再確保する。
poc/stage2.c — ステージ 2 エクスプロイト (モード: step/uaf/spstep/spfree/spray/keys)
— spray 700 = 完全オラクル実行; 生存して一時停止 (クリーンアップには kill)poc/mustang_jit_uaf.c — ステージ 1 PoC (モード: jit N / control N / pressure N)poc/build.sh — zig クロスビルド (静的 musl armv7)kernel/vmlinux — 正確な OTA ビルドから復元したシンボル (vmlinux-to-elf)kernel/config-* — 実行中デバイスからの /proc/config.gz ダンプksrc/ — Amazon OSS ソース (platform.tar + 展開済み midgard-r26p0 ツリー)/tmp/opencode/mustang_ota.bin (sha256 6068515a… は fireos-archive と一致)
および 2.2 GB のカーネルソース tarball を ~/Desktop/amazon-mustang/ に保管ksrc/kernel/mediatek/mt8163/4.9/drivers/misc/mediatek/gpu/gpu_mali/mali_midgard/midgard-r26p0/