
In-memory kernel privilege escalation for Lenovo Legion Y700 2023 (TB320FC) exploiting CVE-2025-21479, a Qualcomm Adreno GPU SMMU flaw, with ReSukiSU root management.
English | 简体中文
In-memory kernel privilege escalation for the Lenovo Legion Y700 2023 (TB320FC), exploiting CVE-2025-21479 (Qualcomm Adreno GPU SMMU vulnerability), with full root management provided by ReSukiSU.
No bootloader unlock. No flashing. No PC required for activation.
⚠️ For authorized security research on devices you own. See Disclaimer.
All offsets and behavior in this project are tuned for the following device. Do not expect it to work on other models/ROMs without retuning (see exploit/device_info.txt).
| Model | Lenovo Legion Y700 2023 (TB320FC) / TB320FC_PRC |
| SoC | Qualcomm SM8475 (Snapdragon 8+ Gen 1, Adreno 730) |
| System | ZUXOS 1.1.350 / Android 15 (SDK 35) |
| Build | AQ3A.240812.002 (TB320FC_CN_OPEN_USER_Q00031.0_V_ZUXOS_1.1.350_ST_250418) |
| Kernel | 5.10.209-android12-9-gef44381c3e04-ab50 |
| Security patch | 2025-03-05 |
| Bootloader | Locked (this project does not unlock it) |
Verified working as of 2026-09 on the above firmware.
| Capability | Implementation |
|---|---|
| Privilege escalation | cheese exploit: KGSL SMMU bug → GPU arbitrary physical R/W → in-memory root (uid 0 + full caps) |
| Root management | ReSukiSU (KernelSU fork) in late-load mode loads kernelsu.ko; su served by an in-kernel hook (u:r:ksu:s0) |
| SELinux | Restored to Enforcing after activation (ReSukiSU policy rules stay applied) |
| One-tap UX | RootActivator APK with embedded exploit + ksud; a single tap after boot |
| Auto-recovery (optional) | Boot-triggered self-healing chain: adaptive load-gated trigger → cheese → root pipeline → optional hosts/Vector. Off by default (com.poc.roottool.CONFIG) |
| Xposed modules | Supported via NeoZygisk (ptrace zygote injection) + Vector |
| Persistence | None by design (in-memory): re-activate after each reboot (~3-4 min; or enable the auto-recovery chain) |
| RootActivator (activated) | ReSukiSU (working, 2 modules) |
|---|---|
![]() | ![]() |
Left: RootActivator after successful activation — SELinux Enforcing, kernelsu loaded, su available.
Right: ReSukiSU manager — LKM mode working with 2 modules (NeoZygisk + Vector).
RootActivator APK
│
├─ libcheese.so ── KGSL SMMU exploit (CVE-2025-21479)
│ 1. Adreno 730 microcode access-check flaw (SDS packet mistaken for RingBuffer)
│ 2. Fake CP_SMMU_TABLE_UPDATE overwrites GPU TTBR0 → arbitrary physical R/W
│ 3. Zero selinux_state.enforcing; dump kernel from fixed PA 0xA8000000,
│ parse kallsyms from the raw image (SM8475 has no physical KASLR)
│ 4. Patch __do_sys_capset with an escalation shellcode
│ (prepare_kernel_cred(0) + commit_creds + clear TIF_SECCOMP);
│ forked child calls capset() → uid 0 + full caps
│
└─ libksud.so (ReSukiSU) ── late-load mode
1. kernelsu.ko loaded from ksud's embedded assets with manual relocation
(does not rely on kernel symbol exports)
2. install → /data/adb/ksu (ksud/busybox/bootctl)
3. su channel online: /system/bin/su → kernel hook redirect → u:r:ksu:s0
4. setenforce 1 — Enforcing restored, policy rules already injected by the ko
Notable engineering points
insmod kernelsu.ko fails. ReSukiSU's late-load resolves symbols itself and loads fine.Build from source (see Building) or grab the APK from the GitHub Releases page (not stored in the repo).
Download from ReSukiSU Releases and install the manager APK.
su -c 'sh /data/adb/modules/zygisksu/post-fs-data.sh'
The repo contains the PoC (the exploit) and its one-tap activator. The custom device layers (debloat scripts, privacy-hosts module, Xposed scope tooling, bring-up helpers) are kept out of tree in a separate private archive — they are deliberately not part of this repository. Details: docs/ARCHITECTURE.md.
├── LICENSE / CHANGELOG.md
├── README.md / README.zh-CN.md
│
├── exploit/ the PoC — root acquisition (CVE-2025-21479)
│ ├── source/ cheese.c / kallsyms_lookup.c / adrenaline.h
│ ├── device_info.txt Target device parameters (offsets, verified facts)
│ ├── build.sh Build script (requires Android NDK)
│ └── README.md Boundary statement, runtime chain, known failure modes
│
├── app/ RootActivator — one-tap activator (all extras OFF by default)
│ ├── src/ BootReceiver / HealGuardService / HealConfig / MainActivity (Kotlin)
│ ├── assets/ selfheal.sh / waiter.sh / xposed-up.sh
│ ├── native/ libcheese.so + libksud.so (built from exploit/; see tools/fetch_assets.py)
│ ├── AndroidManifest.xml
│ ├── debug.keystore debug signing key used by the public APK
│ ├── build.py Build script (kotlinc + d8 + aapt2 + apksigner)
│ └── README.md App documentation
│
├── tools/ Build / inspection helpers
│ ├── fetch_assets.py Host: prepare native assets (exploit + ksud)
│ ├── status_check.sh On-device: root / module snapshot
│ └── check_mods.sh On-device: module inspection helper
├── docs/ Documentation (English)
│ ├── ARCHITECTURE.md Chains, engineering notes, root-cause records
│ ├── TROUBLESHOOTING.md Failure handling, success-rate data
│ └── VECTOR.md Xposed (NeoZygisk + LSPosed/Vector) setup
└── screenshots/ On-device PNG evidence
cd exploit
NDK=/path/to/android-ndk ./build.sh
# Produces ./cheese (arm64) → used as app/native/libcheese.so