Ship Magisk like GOLDEN; KernelSU optional recycle only; parallel to sunfish-a16-rom standby.
270 lines
13 KiB
Markdown
270 lines
13 KiB
Markdown
# Feature Specification: KernelSU-Next on sunfish (LAB)
|
||
|
||
**Feature Branch**: `007-kernelsu-sunfish`
|
||
**Created**: 2026-09-15
|
||
**Status**: In progress (LAB)
|
||
**Session handoff**: `docs/session-20260916-handoff.md` (2026-09-16)
|
||
**Input**: After `005` first Google-compat stack works on LAB, skip forcing a
|
||
rootless Yuh green gate. Prioritize **ReSukiSU** (not Magisk; KSU-Next only as
|
||
history) on the LineageOS 23.2 sunfish kernel, verified hide for banking UIDs,
|
||
then SusFS / TEESimulator-class LAB experiments aimed at Yuh KeyMint/RKP
|
||
failures already logged in `002`. LAB only; never GOLDEN. Personal stock
|
||
handset for banks remains an optional operator fallback outside this feature.
|
||
|
||
**Spine reminder:** product path is **our** LOS 23.2 (`003`→`004`/`005` bacon)
|
||
then `007`. Community abu/torukk ROMs and Downloads boots are reference only.
|
||
|
||
## Context / sequencing vs `006`
|
||
|
||
Constitution originally ordered a **rootless** banking baseline (`006`) before
|
||
root (`007`). Evidence already shows:
|
||
|
||
| Device | Stack | Swissquote | Yuh |
|
||
|--------|-------|------------|-----|
|
||
| GOLDEN | AXP + Magisk DenyList | PASS (owner) | FAIL — HA / “certificate invalid”; KeyMint/`HARDWARE_TYPE_UNAVAILABLE` |
|
||
| LAB (iodé A16) | No Magisk; BL locked | — | FAIL — same KeyMint/RKP class |
|
||
|
||
So a “rootless Yuh must pass” gate is **not** a credible start condition.
|
||
This feature **absorbs** the banking regression that `006` would have owned:
|
||
measure owner + Island UIDs on **our** ROM with root hidden. A separate `006`
|
||
spec may stay deferred or become a thin historical note — it must not block
|
||
`007` work.
|
||
|
||
**Explicitly later (do not pull into this feature):** call recording (`008`),
|
||
`FLAG_SECURE` (`009`), AXP UX leftovers (`010`), project signing/AVB (`011`),
|
||
incremental Graphene/AXP/Divest **hardening** ports (`012`–`013`).
|
||
|
||
## User Scenarios & Testing *(mandatory)*
|
||
|
||
### User Story 1 - Bootable rooted LAB image (Priority: P1)
|
||
|
||
As the developer, I can flash a LAB build whose kernel includes KernelSU-Next
|
||
compatible with non-GKI Linux 4.14 / sunfish, boot to the lock screen, and
|
||
confirm root is available only through the KernelSU manager to apps I approve.
|
||
|
||
**Why this priority**: Without a working integrated root path, hide/SusFS/banking
|
||
experiments cannot run on *our* ROM.
|
||
|
||
**Independent Test**: Flash LAB only; manager shows installed; `su` works for one
|
||
approved test app and fails for an unapproved app.
|
||
|
||
**Acceptance Scenarios**:
|
||
|
||
1. **Given** a `007` LAB flash, **When** the device boots, **Then** telephony,
|
||
Wi‑Fi, and basic UI work at least as well as the last `005` image.
|
||
2. **Given** KernelSU manager, **When** root is granted to a single debug app,
|
||
**Then** that app can obtain root and an unapproved app cannot.
|
||
3. **Given** documentation, **When** reviewed, **Then** the exact KernelSU-Next
|
||
revision (tag/commit) used for the accepted POC is recorded for reproducibility.
|
||
|
||
---
|
||
|
||
### User Story 2 - Banking apps never get root; mounts hidden (Priority: P1)
|
||
|
||
As the developer, Yuh and Swissquote (owner and Island/work profile UIDs) are
|
||
configured so they **never** receive root, and module/overlay mounts that would
|
||
expose root or custom ROM fingerprints to those UIDs are removed or hidden —
|
||
verified by a real check, not only a UI toggle.
|
||
|
||
**Why this priority**: Constitution root architecture; Magisk DenyList on GOLDEN
|
||
is oracle-only, not our production model.
|
||
|
||
**Independent Test**: Per-UID checks (process view of mounts / root binaries)
|
||
for banking packages on user 0 and work profile; screenshots/logs stored under
|
||
artifacts.
|
||
|
||
**Acceptance Scenarios**:
|
||
|
||
1. **Given** Yuh and Swissquote installed (Aurora → Island workflow preferred),
|
||
**When** root grant lists are reviewed, **Then** those packages are denied
|
||
root on every relevant user ID.
|
||
2. **Given** a module or overlay that would be visible to a normal app,
|
||
**When** the banking UID is inspected, **Then** that mount is absent or
|
||
otherwise hidden per the verified umount/profile mechanism.
|
||
3. **Given** only a manager “hide” toggle without mount evidence, **When**
|
||
validation runs, **Then** the story is **not** marked pass.
|
||
|
||
---
|
||
|
||
### User Story 3 - SusFS after profiles work (Priority: P2)
|
||
|
||
As the developer, once KernelSU profiles and verified hide work, I can enable a
|
||
SusFS-capable kernel/config on LAB and confirm the device still boots and that
|
||
selected path-hiding behaviours are measurable for banking UIDs.
|
||
|
||
**Why this priority**: Needed for hard banks on community sunfish reports; must
|
||
not destabilize before basic KSU works. Constitution: SusFS only after KernelSU
|
||
and application profiles work.
|
||
|
||
**Independent Test**: LAB boot + documented SusFS enablement + before/after
|
||
visibility check for at least one sensitive path from a banking or probe UID.
|
||
|
||
**Acceptance Scenarios**:
|
||
|
||
1. **Given** US1–US2 green, **When** SusFS is enabled on LAB, **Then** the
|
||
device boots and KernelSU manager still functions.
|
||
2. **Given** SusFS on, **When** a probe from a denied banking UID runs,
|
||
**Then** at least one previously visible root/custom indicator is hidden
|
||
(evidence logged).
|
||
3. **Given** SusFS causes repeated spontaneous reboot or severe thermal
|
||
instability, **When** triage completes, **Then** SusFS is reverted or pinned
|
||
to a known-good revision before continuing banking claims.
|
||
|
||
---
|
||
|
||
### User Story 4 - Attestation / KeyMint experiment track (Priority: P1)
|
||
|
||
As the developer, I can run a **LAB-only** attestation-compatibility experiment
|
||
(TrickyStore-class or equivalent, plus any required microG hardware-attestation
|
||
toggles) aimed at the Yuh failure mode already captured in `002` (KeyMint /
|
||
`HARDWARE_TYPE_UNAVAILABLE` / “certificate invalid”), without modifying GOLDEN.
|
||
|
||
**Why this priority**: Root hide alone did not fix Yuh on GOLDEN or iodé LAB;
|
||
attestation is the open hypothesis. **Yuh PASS is mandatory** for feature
|
||
acceptance — otherwise root is not worth carrying vs NeoBackup + native
|
||
`008`/`009` and a stock banking phone.
|
||
|
||
**Independent Test**: Reproduce Yuh launch with logcat focused on `keystore2` /
|
||
KeyMint / RKP; compare to `002` baselines; diagnostic results required with artifact paths; US5 owns PASS.
|
||
|
||
**Acceptance Scenarios**:
|
||
|
||
1. **Given** `002` Yuh failure signatures, **When** the experiment stack is
|
||
applied on LAB, **Then** a new log capture exists that either shows the same
|
||
class of error or a clear change.
|
||
2. **Given** a candidate experiment, **When** the same attestation probe and
|
||
bank attempt are repeated, **Then** record the before/after result, limitations
|
||
and rollback outcome. US4 owns diagnostic evidence, not banking acceptance.
|
||
3. **Given** persistent KeyMint/RKP messages, **When** results are interpreted,
|
||
**Then** do not infer causality or failure from those messages alone. US5
|
||
exclusively owns the end-to-end banking acceptance decision.
|
||
|
||
---
|
||
|
||
### User Story 5 - Banking regression on our ROM (Priority: P1)
|
||
|
||
As the project owner, after hide (and any accepted SusFS/attestation experiments)
|
||
I have a written regression for **Swissquote** and **Yuh** inside Island on the
|
||
`007` LAB image: install path, profile UIDs, biometrics if used, and outcome.
|
||
Revolut/N26 remain non-blocking.
|
||
|
||
**Why this priority**: Compatibility hard-gates; replaces the deferred `006`
|
||
oracle for “does banking work on our stack”.
|
||
|
||
**Independent Test**: End-to-end on LAB only; evidence under
|
||
`/srv/rom/artifacts/007-…` (and optional laptop rsync). No GOLDEN flash/wipe.
|
||
|
||
**Acceptance Scenarios**:
|
||
|
||
1. **Given** Island (or documented equivalent), **When** Swissquote is used in
|
||
the work profile with root denied + hide verified, **Then** Swissquote MUST PASS with a usable authenticated session, date and build id.
|
||
2. **Given** the same setup for Yuh, **When** login/attestation is attempted,
|
||
**Then** the session MUST **PASS**; an unusable session means
|
||
`007` is not accepted.
|
||
3. **Given** Magisk, **When** proposed as production root, **Then** it is
|
||
rejected; Magisk A/B diagnostic builds are allowed only as temporary
|
||
reference per constitution.
|
||
|
||
---
|
||
|
||
### Edge Cases
|
||
|
||
- KernelSU-Next revision incompatible with 4.14 → evaluate alternate pin /
|
||
ReSukiSU only as documented POC fork, not silent default change.
|
||
- Work-profile UIDs differ from owner → hide/root denial must be tested on both.
|
||
- `path_umount` missing/broken on 4.14 → story 2 fails until backport/verify.
|
||
- Attestation modules break Play/microg → revert experiment; keep iterating
|
||
until both banks PASS or declare `007` blocked/cancelled.
|
||
- Operator chooses a separate stock phone for banks → interim fallback only;
|
||
does **not** satisfy the Yuh hard-gate on LAB.
|
||
|
||
## Requirements *(mandatory)*
|
||
|
||
### Functional Requirements
|
||
|
||
- **FR-001**: Project MUST integrate KernelSU-Next into the LineageOS
|
||
23.2–compatible sunfish kernel built with the ROM (not Magisk as production
|
||
root).
|
||
- **FR-002**: Root MUST be grantable only to explicitly approved apps; banking
|
||
packages (at least Yuh and Swissquote) MUST never receive root on owner or
|
||
work-profile user IDs used in the regression.
|
||
- **FR-003**: Module/overlay mounts MUST be removable or hidden from selected
|
||
app processes, with verification beyond manager UI toggles; `path_umount` (or
|
||
equivalent) support on this kernel MUST be confirmed or explicitly failed.
|
||
- **FR-004**: The accepted KernelSU-Next revision MUST be pinned and recorded
|
||
(tag/commit) for reproducible builds.
|
||
- **FR-005**: SusFS MUST only be enabled after FR-001–FR-003 work on LAB; if
|
||
enabled, boot stability and at least one measurable hide effect MUST be
|
||
evidenced.
|
||
- **FR-006**: Evaluate an attestation candidate with exact source URL, immutable
|
||
revision or release plus binary hash, dependencies, auditability, baseline,
|
||
before/after evidence and rollback. KeyMint/RKP causality remains a hypothesis.
|
||
Banking acceptance is owned solely by FR-007 / US5.
|
||
- **FR-007**: Both Yuh and Swissquote MUST PASS usable authenticated sessions in
|
||
the LAB managed profile on the same accepted stack with root denied and hide
|
||
verified. Failure of either bank leaves `007` incomplete or cancelled.
|
||
N26/Revolut are non-blocking.
|
||
- **FR-008**: All flashing, kernel experiments, and attestation modules MUST
|
||
target LAB (`11231JEC207477`) only; GOLDEN MUST remain read-only oracle.
|
||
- **FR-009**: Zygisk/LSPosed MUST NOT be introduced as the initial architecture
|
||
unless a later feature proves no native alternative (out of default `007`
|
||
scope).
|
||
- **FR-010**: Feature docs MUST state that deferred `006` rootless-Yuh-pass is
|
||
not a prerequisite, and must link `002` Yuh/Swissquote evidence paths.
|
||
|
||
### Key Entities
|
||
|
||
- **LAB device**: Experimental sunfish; only flash target for `007`.
|
||
- **KernelSU profile**: Per-app (and per-user) root grant / umount policy.
|
||
- **Banking target apps**: Yuh (`com.yuh`), Swissquote (`com.swissquote.android`).
|
||
- **Managed profile**: Island (or equivalent) work user hosting banking apps.
|
||
- **Attestation experiment stack**: Optional LAB modules/toggles aimed at
|
||
hardware attestation / KeyMint behaviour.
|
||
- **Pinned root revision**: Exact KernelSU-Next (and SusFS, if used) identifiers.
|
||
|
||
## Success Criteria *(mandatory)*
|
||
|
||
### Measurable Outcomes
|
||
|
||
- **SC-001**: LAB boots a `007` image with working selective root within one
|
||
flash cycle after the accepted kernel build.
|
||
- **SC-002**: For Yuh and Swissquote on every tested user ID, root grant is
|
||
denied and mount-hide is evidenced (not toggle-only) for every applicable contract checklist row, for both packages and every tested user ID; no failed or unverified mandatory row is allowed.
|
||
- **SC-003**: **Yuh PASS** on LAB Island under the `007` stack (root denied +
|
||
verified hide + accepted SusFS/attestation experiments), with build id and
|
||
evidence — required to close the feature.
|
||
- **SC-004**: Swissquote MUST PASS a usable authenticated session on the same
|
||
image/stack as SC-003, with dated evidence; both are required for acceptance.
|
||
- **SC-005**: If SusFS is claimed in the release notes for this phase, LAB
|
||
completes ≥24h soak without SusFS-driven reboot loops, or SusFS is withdrawn
|
||
from the claim.
|
||
- **SC-006**: Artifact package contains before/after attestation probe results
|
||
and correlated banking logs, including unresolved messages and limitations.
|
||
Absence of a log string alone is not proof of successful attestation.
|
||
- **SC-007**: No Magisk-based production image is published as the project
|
||
default root path.
|
||
|
||
## Assumptions
|
||
|
||
- `005` stack (microG + patched Phonesky + restricted spoofing) remains the
|
||
userspace base on LAB before/while bringing up `007`.
|
||
- Island (already used on LAB/GOLDEN) remains the managed-profile vehicle unless
|
||
a documented substitute is chosen during implementation planning.
|
||
- If EOL sunfish cannot satisfy Yuh even with SusFS/TrickyStore-class stacks,
|
||
**`007` stays incomplete** (or is explicitly cancelled) — not “done with Yuh
|
||
documented FAIL”. Rationale: without Yuh, root adds little over NeoBackup +
|
||
native `008`/`009`; a stock handset becomes the banking plan instead.
|
||
- Operator may still use a separate stock phone as interim fallback; that does
|
||
not count as `007` acceptance.
|
||
- Full GrapheneOS/AXP/Divest kernel hardening ports remain `013`, not this
|
||
feature — `007` only changes the kernel as needed for KSU/SusFS/umount.
|
||
- Community sunfish LOS+KSU+SusFS reports are inspiration, not a drop-in base.
|
||
|
||
## Out of scope
|
||
|
||
- Flashing or modifying GOLDEN.
|
||
- Magisk/Magia as default project root.
|
||
- Making Revolut/N26 hard-gates.
|
||
- Call recording, FLAG_SECURE, WebView provider work, project AVB lock.
|
||
- Purchasing or provisioning a second physical phone (operator choice).
|