[!CAUTION] 本项目尚未完成——目前尚不可用。 截至 2026-10-06,任何设备上均没有可用的 root。请不要期望 下方的快速开始能够成功。在构建或运行任何内容之前,请先阅读当前状态。
[!WARNING] 状态:进行中——ring 1 尚未落地
- 未达成: 在 SM-T878U 上获得持久甚至一次性的
root。- 最近一次验证的失败: 栈回收载荷从未到达内核的写入路径。在约 470 次插桩运行中,伪造的锁从未被观察到在
rtmutex.c:585处被获取,因此存储操作*(ASHMEM_MISC_FOPS) = fake_fops从未执行。- 此前的阻塞问题,现已解决: 崩溃取证过去对
uid 2000 shell不可用(/proc/kmsg、/proc/last_kmsg、/sys/fs/pstore、dmesg→ 全部EACCES)。现在一个持久的write()+fsync()日志镜像 (IONSTACK_LOG_MIRROR)可在CONFIG_PANIC_ON_OOPS=y下存活,因此发生 panic 的 运行仍会留下完整的记录。- 完整证据链见
docs/RTMUTEX_WEAPONIZATION.md§15.16–§15.18。
针对 Samsung Galaxy Tab S7(SM-T878U / gts7l)、利用 CVE-2026-43499(IonStack / GhostLock)的纯 C、主机辅助的重新 root 概念验证。
运行时链仅使用原生 C/ELF 组件。它不需要在 Android 目标上使用
Python、Java、DEX、app_process 或 JVM。ADB 用于
部署和验证。
尚未获得 root。 本节是关于该链当前进展的权威、最新
说明(最后修订于 2026-10-06)。以下所有内容均在真实硬件上实测
(SM-T878U,T878USQS8DXE1,内核
4.19.113-27114284),而非理论推测。
| 阶段 | 状态 | 证据 |
|---|---|---|
| 目标识别 + KASLR 泄露 | 可用 | [reroot] LEAK_OK kaslr_base=… task=…(perf 侧信道) |
CVE 触发:FUTEX_CMP_REQUEUE_PI → -EDEADLK | 可用 | [*] requeue ret=-1 errno=35 — 在 Linux 上 EDEADLK == 35 |
有缺陷的回滚留下悬空的 pi_blocked_on | 与上游修复一致 | 上游 3bfdc63936dd 将 current->pi_blocked_on 改为 waiter->task->pi_blocked_on |
struct rt_mutex_waiter 布局(4.19) | 已从源码验证 | tree_entry@0x00 pi_tree_entry@0x18 task@0x30 lock@0x38 prio@0x40 deadline@0x48 |
栈几何关系 paint == rt_waiter + 0x28 | 已验证 4 次,含 objdump | rt_waiter = do_futex_sp+0xC0;address = ___sys_sendmsg_sp+0xB8 |
| 持久崩溃取证 | 可用 | IONSTACK_LOG_MIRROR 的 write()+fsync() 记录可在 panic 重启后存活 |
| 每条消息的 frag 页身份标记 | 可用 | reclaim-scan tag=1 sent=8201 range=1..8201 ok=8192 bad=0 dup=0 undecoded=0 absent=9 |
| 队列扫描:内核向 8192 个已入队 frag 页写入 0 字节 | 已验证 | 256 MB 与载荷逐字节比对,hits=0 |
rt_mutex_adjust_prio_chain 到达写入路径 | 已从反汇编验证 | top_waiter == NULL ⇒ requeue 保持为 true ⇒ 664/682/685/716-725 在结构上可达 |
page-dump 和 45 次 ring1-page 观测都报告
first_diff=8000 (pristine)、owner_cpu=00000000、case1_gate=0,并且
lock_root/lock_leftmost 与 payload 值完全相等。该遍历
从未被观察到在 rtmutex.c:585 处获取 fake_lock->wait_lock,因此
664/682/685/716-725——唯一能向
*(ASHMEM_MISC_FOPS) 写入的分支——从未运行。
注意,_raw_spin_trylock()/_raw_spin_unlock() 经由
外部辅助函数路由,且此厂商内核树没有 arm64 queued_spin_unlock
覆盖,因此 wait_lock.val == 1 是可靠的 585 见证,
而 owner_cpu != 0 只是次要见证。prctl(PR_SET_MM, PR_SET_MM_MAP, …) 回收该帧。此内核附带
# CONFIG_CHECKPOINT_RESTORE is not set,因此该 syscall 被编译排除。
它也从未使用 sendmsg——我们的载体——这极可能是 (1) 的根本
原因。ring1-read 从未运行。 对 ring 1 的唯一用户态回读
(configfs_read_once(fd, data_addr(ASHMEM_MISC_FOPS), …))位于
队列扫描门控之后,且位于 harness MARKER 默认值之后,后者会提前 8 秒
在 ring1-page 处停止。每一次到达该门控的运行都死在
page-dump tag=pre-arm 与 page-dump tag=post-arm 之间。664/682/685 在我们
自己的页内完成 的配置——IONSTACK_FOPS_WAIT_LOCK_WORD=0 配合
IONSTACK_PAINT_WAITER_TASK_MODE=fake-task——并读取
page-dump tag=post-arm / ring1-lock585 以检查 wait_lock=00000001。ring1-read 执行:在未设置 IONSTACK_RECLAIM_SCAN_QUEUE 且
MARKER='ring1-read|…' 的情况下运行,使 harness 不会在 ring1-page 处停止。IONSTACK_RECLAIM_TAG=1 运行,并在
page-dump 中比较 pipe_tag 与 msg_tag。所有 frag 页都是 payload 的逐字节相同
副本,因此仅凭 first_diff 无法区分它们。IONSTACK_FOPS_WAIT_LOCK_WORD 问题——
保持 IONSTACK_RECLAIM_TAG 不变,比较 wlw=0 与 wlw=1。此前的
相关性因两个变量同时变动而受到混杂影响。res_in/res_out 的 pselect6 绘制表面。fops.c:3157 reason=selinux_write ret=-1 errno=22 EINVAL——仍未解决。
| 文档 | 内容 |
|---|---|
docs/RTMUTEX_WEAPONIZATION.md | rtmutex 链的完整证据链(最大的文档) |
docs/ROOT_CHAIN_THEORY.md | 端到端 ring 0→4 root 链设计 |
docs/PAINT_ORACLE_ANALYSIS.md | 栈绘制 oracle 为何如此读取 |
docs/PSELECT_GEOMETRY_FINDINGS.md | pselect6 作为替代绘制载体 |
docs/RING1_RECLAIM_IDENTITY_2026-10-06.md | 逐消息 frag 页身份标签;队列扫描验证 |
docs/RING1_585_NEVER_SUCCEEDED_2026-10-06.md | 证明 rtmutex.c:585 从未成功 |
docs/RING1_ORACLE_FIX_2026-10-05.md | Oracle 修正 |
docs/RING1_ORACLE_WRONG_FRAGMENT_2026-10-06.md | 为何被持有的 fragment 被错误识别 |
target-artifacts/ 包含分析此目标所需的全部内容,
无需设备:
/proc/config.gz(原始 + 解压后),src/exploit/offset.h 中每个类地址常量与 ELF 自身符号表进行机械验证,核心结果:ELF 内嵌的 linux_banner 与设备逐字节匹配(因此确认 T878USQS8DXE1 / 4.19.113-27114284),该 ELF 未被剥离符号,并且 27 个类地址 offset.h 常量中有 24 个与符号完全匹配,0 个无法解析。完整报告见 target-artifacts/README.md,其中包括一个命名陷阱:CONFIGFS_READ_FILE_OFF 实际指向 configfs_read_bin_file,而非 configfs_read_file。
本 POC 有意采用失败关闭策略,除非所有配置文件检查均匹配:
device: gts7l
Android: 13 / SDK 33
fingerprint: samsung/gts7lsqwnc/gts7l:13/TP1A.220624.014/T878USQS8DXE1:user/release-keys
kernel: 4.19.113
build: T878USQS8DXE1
不受支持或失败的运行可能导致设备 panic 或重启。请保留可用的恢复路径。
本仓库的范围严格限定于上述固件配置。它并非通用 root 工具,其中的偏移量或假设不得在未经独立验证的情况下复用于其他设备。
adb devices -l
然后:
./build/smt878u-ionstack-reroot -s SERIAL --preflight-only
./build/smt878u-ionstack-reroot -s SERIAL --validate-only
./build/smt878u-ionstack-reroot -s SERIAL
主机报告成功后,验证 root 权限并打开 shell:
adb -s SERIAL shell /data/local/tmp/su -c id
adb -s SERIAL shell /data/local/tmp/su
当恰好连接一个 ADB 设备时,-s SERIAL 是可选的。
要求:
clang、make 和 adb 的 macOS 或 Linux 主机make -j4
需要时覆盖发现:
make NDK_ROOT=/path/to/android-ndk API=35 -j4
所有产物均输出到 build/ 下。
宿主控制器支持 macOS arm64、Linux x86_64 和 Windows x86_64。 Android 设备产物在各宿主平台之间完全相同。
# native host controller only
make host
# Windows x86_64 controller with LLVM-MinGW
make host-windows \
WINDOWS_CC=/path/to/llvm-mingw/bin/x86_64-w64-mingw32-clang
先进行非漏洞利用的 profile 检查,然后进行验证,最后执行完整链条:
./build/smt878u-ionstack-reroot -s SERIAL --preflight-only
./build/smt878u-ionstack-reroot -s SERIAL --validate-only
./build/smt878u-ionstack-reroot -s SERIAL
默认情况下,日志写入 results/YYYY-MM-DD/ 目录下。
./tools/collect_reboot_artifacts.sh SERIAL
su受支持的用户端客户端安装在 /data/local/tmp/su。它通过
/data/local/tmp/temp_su.sock 连接到临时 root 守护进程。不要将其移动到
/system/bin,也不要指望它在重启后仍然存在。