
Target-specific Android CVE-2026-98260 research port for Xiaomi popsicle
An Android AArch64 exploit chain built for a precise kernel build: starting from an ordinary ADB shell, it sequentially verifies SELinux Permissive, UID/GID 0, and full Linux capabilities, and provides a root shell service within the current boot cycle.
| Item | Measured Scope |
|---|---|
| Device | Xiaomi 17 Pro Max, codename popsicle |
| System | Xiaomi HyperOS 4 OS4.0.4.0.XPBCNXM, Android 17 |
| Kernel | 6.12.69-android16-6-g43b5ab7e247d-abogki558343811-4k |
The android16 in the kernel version string is an identifier for that kernel branch and must not be used to infer the Android system version running on the device; the system version of this target is Android 17.
| Starting Point | Authorized ordinary ADB shell, UID 2000 |
| Successful Result | UID/GID 0, SELinux Permissive, CapPrm/CapEff/CapBnd=000001ffffffffff |
| Lifecycle | The root service is available to subsequent ADB shells during this boot; it must be run again after the phone reboots |
This is a precise target port that has succeeded on a real device, not a universal Android root. Page reclamation on the target is nondeterministic, and the credential stage may fail; the repository does not claim a 100% success rate, nor does it implement offline automatic root after reboot. See Validation Record and Evidence Boundaries for details.
flowchart LR
A[普通 ADB shell] --> B[核对机型 / 构建 / 内核]
B --> C[CVE-2026-98260 定时器 UAF]
C --> D[SELinux Permissive]
D --> E[私有 cred 的 UID/GID 归零]
E --> F[cred / real_cred 与 capabilities 阶段]
F --> G[当前开机的 root 服务]
G --> H[新 ADB shell 获得 root]
This vulnerability occurs on the abnormal exit path where exec() is executed on a non-main thread: after the thread identity swap, the POSIX CPU timer object may have been freed, but its node remains in the timerqueue of a live task. When that task is subsequently reclaimed, the kernel operates on the already-freed node again. This port establishes an observable timer slab and page-reuse flow for the target device, using this condition for three independent state transitions. For the relationship between the specific implementation and the original research, see Technical Implementation and Upstream Provenance.
| Stage | On-device Program | Pass Condition |
|---|---|---|
| 1. SELinux | exploit-android-perf | getenforce is Permissive, and the status-word-related fields are verified |
| 2. Identity | exploit-android-perf-chain | The same process's UID/GID become 0, then the next stage is launched |
| 3. Full Privileges | exploit-android-key-ptr and pc98260_rootd.c | UID/GID 0, full capabilities, and the root service is accessible from a new ADB shell |
UID 0 does not equal full root. In an earlier successful UID 0 record, CapEff was still 0, so the repository lists full capabilities and independent ADB shell verification as the final success conditions.
On Windows, install Android NDK r28.2 (28.2.13676358) and Android platform-tools. The build script looks for %LOCALAPPDATA%\Android\Sdk\ndk\28.2.13676358 by default; if the NDK is located elsewhere, specify -NdkHome.
git clone https://github.com/quyicheng03-boop/CVE-2026-98260-popsicle-android.git
cd CVE-2026-98260-popsicle-android
powershell -NoProfile -ExecutionPolicy Bypass -File .\build.ps1 -VerifyReference
build.ps1 uses aarch64-linux-android35-clang -std=gnu11 -O2 -pthread to generate four device-side programs in build\bin\. -VerifyReference compares each new artifact against the SHA-256 of the verified binaries in bin\ one by one. Before uploading, all four checks pass; the complete hashes are recorded in bin/SHA256SUMS.txt. The build does not connect to the phone or write to the device.
| Artifact | Input source |
|---|---|
exploit-android-perf | src/exploit-android-perf.c |
exploit-android-perf-chain | src/exploit-android-perf-chain.c |
exploit-android-key-ptr | src/exploit-android-key-ptr.c + src/pc98260_rootd.c |
pc98260-su-client | src/pc98260_su.c |
The bin/ in the repository is only applicable to the exact target builds listed in the table above. Successfully compiling from source for another kernel does not mean that kernel can be exploited.
Connect a target device with USB debugging enabled and authorized, add platform-tools to PATH, then run:
.\开始98260临时ROOT.bat
Or explicitly select an ADB device:
powershell -NoProfile -ExecutionPolicy Bypass -File .\run_98260.ps1 -Serial <ADB序列号> -Reboot
The host script verifies the device, system incremental version, full kernel string, binary hash, and the phone's boot ID; if multiple ADB devices are online at the same time and no serial number is specified, it stops. The output of each stage is saved locally in logs/, which is ignored by Git. The script only runs the temporary root chain and does not write to the boot partition.
After success, a newly opened ADB shell within the same boot session can run:
adb shell -t /data/local/tmp/pc98260-su
The final verification focuses on three independent facts: id shows UID/GID 0, getenforce shows Permissive, and CapEff in /proc/self/status is 000001ffffffffff. The script will not misreport merely "SELinux is permissive" or "UID has become 0" as the entire chain succeeding.
The exploit chain requires reclaiming the page where the target timer resides. The source code correlates the object, RCU callback, free_slab event, and subsequent mapping hits; if the same target page cannot be observed, or if verification after the pointer write is inconsistent, the program retains the relevant zombie/mapping and stops, avoiding blind reclamation while the dangling node is still referenced by the kernel. In this case, a fresh phone boot should be used as the boundary for the next attempt. In historical runs, there have indeed been cases where the SELinux stage succeeded but the credential stage did not hit.
This repository does not upload device backups, boot images, partition images, raw run logs, or bootloader unlock materials. The four binaries and source code here belong to a temporary privilege escalation chain; they will not cause a locked device to automatically retain root after a phone reboot.