Skip to content

feat(ubifs): recover orphaned inodes into lost+found on rootless captures - #42

Merged
nmatt0 merged 1 commit into
masterfrom
feat/ubifs-orphan-recovery
Sep 19, 2026
Merged

nmatt0 merged 1 commit into
masterfrom
feat/ubifs-orphan-recovery

Conversation

@nmatt0

@nmatt0 nmatt0 commented Sep 19, 2026

Copy link
Copy Markdown
Owner

Problem

When a UBIFS capture is missing its root LEB (common in raw flash dumps: the superblock/root LEB simply isn't in the captured region), there is no root inode 1 and no dentry parented at root. moria's tree walk starts at root inode 1, so it recovers nothing from that volume even though valid inode, dentry, and data nodes for real files are present and CRC-valid. This mirrors the failure mode of ubireader/fsck on damaged images: return nothing rather than what could be recovered.

Change

Add an orphan-recovery pass that runs after the normal root walk and re-roots everything unreachable from root inode 1 under a synthetic lost+found/:

  1. Named orphan subtrees — dentry parents the root walk never reached and that no dentry names as a child (the top of a dangling tree) → lost+found/inode_<pino>/…, full subtree with original filenames and structure.
  2. Parent-link cycles — clusters where every member is a child of another member, so none qualifies as a subtree top, are still walked (a cycle can't make a whole subtree vanish).
  3. Data-bearing lone inodes — a file/symlink with content but no dentry anywhere → lost+found/inode_<n>. Lone inodes require real content, so a metadata-only inode whose data nodes didn't survive is not emitted as a zero-filled shell.

The pass is gated (no lost+found/ when there are no orphans). Extraction status is marked partial only when the root inode was genuinely absent.

Human-view fixes (folded in)

The recovery signal was reaching the JSON manifest but not the human view, due to two pre-existing gaps:

  • A finding's own extraction status/warning was only rendered on descendant rows, never on the finding row itself.
  • The extraction-tree renderer linked a finding to its subtree by offset and type, so a ubi finding (whose top extraction entry is labelled ubifs) never linked and its whole volume subtree was dropped from the human view.

Fixed both, and routed extraction warnings/hard statuses into the diagnostics table so the NOTES column stays terse (→ lost+found) while the full detail lives in one scannable place. The errors-only banner moved to just above the footer.

Testing

  • New self-contained regression test_ubifs_orphan_recovery: a hand-built raw UBIFS (no mkfs tools) with no root inode, exercising a named subtree, a parent-link cycle, a data-bearing lone inode, the zero-shell gate, partial status, and that the recovery surfaces in the human -e output.
  • Full extraction suite green (22/22 CTest), all existing mkfs.ubifs round-trips unchanged.
  • ASan/UBSan clean on the fixture and on a real partial multi-volume UBI image; warning-free build. JSON manifest schema unchanged.

…ures

A partial UBIFS capture missing its root LEB has no root inode 1 and no
dentry parented at root, so the tree-only walk from root yields nothing
even when valid inode/dentry/data nodes for real files are present. Add
an orphan pass that re-roots everything unreachable from root inode 1
under a synthetic lost+found/: named subtrees, parent-link cycles, and
data-bearing lone inodes. Lone inodes require real content so a
metadata-only inode can't extract as a zero-filled shell. Status is
marked partial only when the root inode was absent.

Surface extraction status/warnings the human view was dropping: render a
finding's own manifest-node status/warning on its row, link a finding to
its extraction subtree by a unique offset when the type differs (a `ubi`
finding's entry is labelled `ubifs`), and route extraction warnings and
hard statuses into the diagnostics table so the NOTES column stays terse.
Move the errors-only banner to just above the footer.
@nmatt0
nmatt0 merged commit 30e4038 into master Sep 19, 2026
4 checks passed
@nmatt0
nmatt0 deleted the feat/ubifs-orphan-recovery branch September 19, 2026 05:46
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