Files
AXP-Resurection/docs/007-susfs-source-audit.md
T
sunfish-adminandCursor 2d145c2878 009: Polish bacon fixes, OTA host scripts, and migration docs.
Restore disable_configstore, EuiccDisabler and thermal CDEV guards, branding
and rebuild/sync helpers; document device roles, laptop migration, and Gitea.

Co-authored-by: Cursor <cursoragent@cursor.com>
2026-10-16 21:06:45 +02:00

7.4 KiB

Status: parallel KernelSU / SusFS track (kept). Bridge to current Magisk ROM: 007-parallel-on-009.md. Magisk ship resume: 009-handoff-20261008.md.

SUSFS bring-up: source and artifact audit, 2026-09-16

Status: superseded for boot outcome by 007-lab-results-20260916.md — matched DEBUG boot + vendor (correct SELinux) booted; SusFS v1.5.5 + Manager 35153 verified. This audit retains the ABI / stub / UAF analysis. Banking PASS still FAIL. LAB only; GOLDEN was not accessed.

Verified baseline and build

LAB reports 23.2-20260915-UNOFFICIAL-sunfish, slot _a, kernel 4.14.357-openela-g28f9290ae067-dirty #1 ... Sep 15 18:06:17 UTC 2026. Approved shell root works. The installed vibrator module probes successfully on this kernel. The DEBUG build started at 2026-09-16T11:51:15Z and was still linking with ld.lld using a full CPU at 12:18Z. Ninja's idle-output warning alone is not a stalled-build diagnosis. Its inputs were not edited during this audit.

Confirmed incompatible vendor module

The installed /vendor/lib/modules/drv2624.ko imports module_layout with CRC 0xbce8f094. The SUSFS sigfix build's Module.symvers exports it as 0xf9adc508. There are 31 mismatches among 56 imports. The matching module in the host output passes all 56 checks against that same symvers.

Evidence was captured before DEBUG replaced these outputs:

  • Host symvers mtime: 2026-09-16 11:44:39 UTC.
  • Host vendor module mtime: 2026-09-16 11:45:48 UTC.
  • Kernel config: CONFIG_MODVERSIONS=y, module force loading disabled.
  • Device module loading list: device/google/sunfish/init.insmod.sunfish.cfg includes drv2624.ko alongside audio, touch and WLAN modules.
  • Local evidence: .local-artifacts/007-kernelsu/rca-20260916/, including Module.symvers-sigfix, drv2624-installed.ko, drv2624-built.ko and CRCs.

Reproduce with python3 scripts/check-module-abi.py <Module.symvers> <module.ko>. Exit 1 means incompatible or unverified; exit 0 verifies CRCs only, not full ABI/CFI/firmware compatibility or device behaviour.

Implication: flashing a SUSFS boot while retaining these installed vendor modules is an invalid release combination. Rebuilding modules on the host does not update the phone's vendor partition. The older vibrator watchdog is consistent with this defect, but historical dmesg or a controlled test is still needed to prove that particular attempt's cause. This result does not prove the cause of the subsequent early panics.

SUSFS currently changes task_struct and vfsmount; those changes can affect layouts and transitive exported symbol CRCs. Do not bypass version checks. Package a consistent kernel/modules set and verify all imports before testing. After vendor changes, the old boot alone is not necessarily a valid rollback; preserve the corresponding old vendor/ROM and slot state too.

Confirmed filename lifetime defect

Our fs/exec.c:do_execveat_common() calls __do_execve_file(), which calls putname(filename) on both successful and failed exec paths. The wrapper then calls ksu_handle_post_execveat(); ReSukiSU dereferences filename->name. This is a use-after-free in the integration. It also exists in the root-only path, so its existence does not establish why only SUSFS panics in the recorded trials.

Prepared patch: vendor/sunfish/patches/007-kernelsu/0001-exec-avoid-post-hook-filename-uaf.patch. It calls ksu_handle_post_execve() with NULL filename, which that handler explicitly supports for its LSM adapter. The patch is staged locally, not applied to the running build, and still needs compilation and LAB validation.

Confirmed incomplete and mismatched SUSFS API

The active kernel advertises SUSFS v1.5.5, based on upstream kernel-4.14 at 77905b5a071e6f3669e3b1814cea30147c0801da (February 2025), plus local compatibility wrappers. It is not a complete modern backport.

The active fs/susfs.c contains:

  • susfs_add_sus_map(): reports success without implementing map hiding.
  • susfs_set_avc_log_spoofing(): reports success without the SELinux hook.
  • susfs_add_sus_path_loop(): aliases a one-time addition, with no loop list.
  • susfs_run_extra_works() and susfs_start_sdcard_monitor_fn(): no-op.
  • susfs_get_enabled_features(): returns only the generic KSU_SUSFS string.

The local st_susfs_sus_path starts with err, then target_ino, then a pathname. Modern upstream v2.3.0 starts with the pathname, then err. Sharing command numbers or converting a pointer type does not make those wire formats compatible. Do not interpret compile/link success or a manager feature badge as proof that the commands work.

ReSukiSU integration documentation explicitly directs non-GKI SUSFS integrators to backport the 5.10 patches. Its separate SUSFS hook mode is deliberate; the Kconfig choice is not in itself an upstream bug. Missing manual hooks when selecting SUSFS means the SUSFS integration must provide its own complete hook path.

Upstream freshness checked without changing live inputs

Remote refs were queried directly on 2026-09-16:

  • Latest ReSukiSU tag seen: v4.2.0-rc2, 3576e6a5255fc880c00f6a3175d89268a6d942be.
  • Active ReSukiSU: 6d674e50a022a85076dcfe4498af9a8bfead2cf9, nine commits after that tag, non-shallow, rev-list count 4453, computed version 35153, with local patches. Manager binary matching still requires independent verification; the filename is not sufficient.
  • Latest observed SUSFS 5.10 branch: e466df60670eab2847ea76940be2f8a125c8adc9, advertising v2.3.0.
  • Remote 4.14 branch still points to the old v1.5.5 commit above.
  • Abu reference checkout ksu-susfs-23.0 is 8c604af9d3d97a8b1b2da1b663a4e39b32697e5a, with SUSFS v1.5.12. This checkout is not proof of the exact source/configuration of the owner's working L22 binary. Do not conflate the two.

Before a new build, fetch tags, record full revisions and version codes, and use a matching manager and userspace tool. A v2.3.0 port must include actual implementations, correct struct layouts and all call-site adaptations.

Panic evidence remains missing

The known-good dmesg shows the ramoops script exits 0, but inspection shows that the script returns the final key-generation command's status, not the earlier decrypt status. LAB has vendor.ramoops.decryption.error=1, use_alt=0, and empty pstore. No private key contents were read or copied. Therefore neither successful script exit nor an empty directory proves that the failed kernel produced no backtrace.

Framebuffer console config does not guarantee a visible panic: display registration and panic timing must also permit output. panic=0 does not by itself disable every independent hardware watchdog.

Next diagnostic work

  1. Preserve DEBUG as a named experiment with hashes/config/source snapshot.
  2. Fix the lifetime defect in a subsequent isolated change.
  3. Obtain panic trace or instrument milestones; distinguish kernel init, module load, init and zygote failures rather than infer timing from logo.
  4. Use a matched kernel/vendor-module deployment and rollback. Never compare different system slots as though only boot changed.
  5. Complete a modern SUSFS backport with the intended hook model, then verify real command responses, root denial, per-UID hiding and hardware behaviour. Boot success alone does not meet the requested result or feature gates.