Skip to content

feat(controller): rootfs integrity verification (iiab-tree-sha256-v1) + device-backup manifest#37

Merged
luisguzman-adfa merged 3 commits into
mainfrom
feat/rootfs-import-restore-integrity
Jun 24, 2026
Merged

feat(controller): rootfs integrity verification (iiab-tree-sha256-v1) + device-backup manifest#37
luisguzman-adfa merged 3 commits into
mainfrom
feat/rootfs-import-restore-integrity

Conversation

@luisguzman-adfa

Copy link
Copy Markdown
Collaborator

Follow-up to #31. Part 2 of the rootfs import/restore validation series.

What

On-device integrity verification for manually imported rootfs/backups, plus a backup writer that stamps a manifest. No new dependencies.

Verifier (consumer)

  • deploy/domain/RootfsTreeHash — pure-JVM iiab-tree-sha256-v1 (norm + per-member digest + order-independent, domain-separated combine). Byte-parity with tools/iiab_tree_hash.py proven by tests.
  • deploy/data/RootfsIntegrity — one-pass, dependency-free tar reader (ustar + GNU long-name + pax path/linkpath) that recomputes the treehash (excluding the integrity member) and reads the declaration → ABSENT / DECLARED_NONE / MATCH / MISMATCH / ERROR.
  • No Apache Commons Compress on purpose: minSdk 24 has no core-library desugaring and CC reaches into java.nio.file (API 26+). We hand-parse the tar the way RootfsManifest already does + GZIPInputStream.

Wiring (matrix)

case result
no manifest OK_NO_MANIFEST (soft alert)
origin:device-backup / algo:none OK_NO_CHECKSUM (proceed + transparency)
real treehash matches OK
real treehash mismatch / unreadable CORRUPT → blocks (like WRONG_ARCH)

Integrity runs only at the import gate and rides identity: device backups are recognized from the first tar header (no full pass); the restore path does not re-verify. Block-on-mismatch is safe because the CI parity test retires the false-positive risk.

Writer (producer)

  • App backups embed installed-rootfs/iiab/.iiab-rootfs.json with kind/arch/built/builder + origin:device-backup, staged in a temp tree and packed first (a second tar -C). No treehash is computed on the device — we don't turn the phone into a builder; origin:device-backup is the explicit "no checksum" declaration.

Tests

RootfsTreeHashTest (golden parity) + RootfsIntegrityTest over checked-in ustar / GNU long-name / pax / mismatch / none / absent fixtures. Verifier + writer were also validated end-to-end locally against the Python reference.

Deferred (documented)

Interactive "restore without checksum?" gate; strict-on-absence; >10 GB → suggest Share/rsync. Folding the rare builder-rootfs-manual-import verify into the import copy (it currently costs one extra pass for that path only).

Contract addendum to relay to the build task

origin:"device-backup" in the identity member = "no checksum by design" (and algo:"none" in the integrity member). Backward-compatible; docs/ROOTFS_MANIFEST.md should record it.

Part 2 of the rootfs import/restore validation series (follow-up to #31).

- deploy/domain/RootfsTreeHash: pure-JVM treehash (norm + per-member digest +
  order-independent domain-separated combine), byte-parity with
  tools/iiab_tree_hash.py. Streaming Accumulator for single-pass tar.
- deploy/data/RootfsIntegrity: one-pass, dependency-free tar reader (ustar + GNU
  long-name + pax path/linkpath) that recomputes the treehash (excluding the
  integrity member) and reads the integrity declaration -> ABSENT / DECLARED_NONE
  / MATCH / MISMATCH / ERROR. No Apache Commons Compress: minSdk 24 has no
  core-library desugaring and CC reaches into java.nio.file (API 26+); we hand
  parse the tar like RootfsManifest does.
- Tests: RootfsTreeHashTest (golden parity) + RootfsIntegrityTest over checked-in
  ustar/GNU/pax/mismatch/none/absent fixtures.

Wiring (Result.CORRUPT + gates) and the backup writer come in the next commits.
…dator + import gate

- RootfsManifest.Identity gains 'origin' (cheap device-backup signal from the
  first tar header — no full pass for app-made backups).
- RootfsArchiveValidator: Result.CORRUPT + OK_NO_CHECKSUM; new checkIntegrity
  overload. Import gate (checkIntegrity=true) recomputes the treehash for builder
  rootfs and fails closed on MISMATCH/ERROR; device backups (origin) and the
  restore path skip the full pass. Matrix: absent->OK_NO_MANIFEST(soft);
  origin/none->OK_NO_CHECKSUM; match->OK; mismatch->CORRUPT(block).
- DeployFragment import gate: CORRUPT blocks+deletes like WRONG_ARCH;
  OK_NO_CHECKSUM proceeds with a transparency snackbar.
- strings (en/es): install_error_corrupt, install_warn_no_checksum.
App-created backups now embed installed-rootfs/iiab/.iiab-rootfs.json declaring
kind/arch + origin=device-backup (and builder=knowledgetogo-app). Staged in a
temp tree and packed FIRST (a second tar -C) so the validator reads it from the
first header — no full decompress, no java.nio, flag-agnostic. NO treehash is
computed on the device (we don't make the phone a builder); origin=device-backup
is the explicit no-checksum declaration the verifier maps to OK_NO_CHECKSUM.
@luisguzman-adfa luisguzman-adfa merged commit 8a59ee8 into main Jun 24, 2026
1 check passed
@luisguzman-adfa luisguzman-adfa deleted the feat/rootfs-import-restore-integrity branch June 24, 2026 02:09
luisguzman-adfa added a commit that referenced this pull request Jun 24, 2026
- Status banner: Phase 0 done + Phase 1 core-complete; Phase 2 not started
  (~37 raw threads); Phase 3 partial (slices land but god classes grew —
  DeployFragment ~3022, MainActivity ~2384); M15 done, M8/M9 open.
- Phase 1 line: F15 A+B (#30/#32) + rootfs validation (#31) + integrity (#37) done.
- Integrity/writer entry: marked DONE via #37 (was 'next PR').
- F4 + M7: confirmed mitigated by inspection (onPause teardown + remove-before-post).
- Lint workaround: added root-cause analysis with concrete carve targets
  (addNewTerminalSession ~727 LOC; DeployFragment bind* methods) for D1/F1.

Docs only; no code change.
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant