Skip to content

feat: AFF4 mounting (logical + disk) — supersedes the aff4-mount scaffold#4

Merged
h4x0r merged 7 commits into
mainfrom
feat/aff4-mount
Jul 1, 2026
Merged

feat: AFF4 mounting (logical + disk) — supersedes the aff4-mount scaffold#4
h4x0r merged 7 commits into
mainfrom
feat/aff4-mount

Conversation

@h4x0r

@h4x0r h4x0r commented Jul 1, 2026

Copy link
Copy Markdown
Contributor

Summary

Mount AFF4 (Advanced Forensic Format 4) images. Implemented fully with strict TDD, replacing the scaffold-only aff4-mount branch (which declared only the dep + a plan).

Upstream first — added aff4::container_kind() (published aff4 0.2.1): AFF4 is a ZIP with no magic bytes, so this reads information.turtle once to classify Disk/Logical/Encrypted. Validated tier-1 (real Evimetry Base-Linear.aff4 → Disk, encrypted-linear-password.aff4 → Encrypted) + tier-2 (testutil).

4n6mount

  • Detection (RED→GREEN): FsType::Aff4Disk/Aff4Logical; detect_aff4 refines an auto-detected ZIP via container_kind.
  • Backend fs_aff4 (RED→GREEN): Aff4ForensicFs mounts AFF4-Logical (AD1-like) over ArchiveTree, validated byte-identical against aff4::testutil.
  • Dispatch: Logical opens directly from path; Disk opens Aff4Reader (Read+Seek) → re-detects inner FS → build_filesystem (EWF/VMDK-like). Encrypted refused loudly.
  • Smoke: AFF4-Logical added to the matrix (FUSE + Dokan). Disk shape relies on the aff4 crate's tier-1 validation + EWF glue (the test writer is single-chunk; can't wrap a real FS) — documented.
  • ADR 0002 records the design; the handoff is superseded.

Test

Local: 208 lib + 10 integration green; clippy -D warnings + fmt clean; cargo deny green with aff4 0.2.1.

🤖 Generated with Claude Code

h4x0r and others added 7 commits July 1, 2026 14:16
Declare the aff4 0.2 dep + feature (default) and its test-helpers dev-dep.
Add FsType::Aff4Disk / Aff4Logical (+ Display/FromStr) and a stubbed
detect_aff4(&Path) that refines a ZIP-detected file into its AFF4 shape
(AFF4 has no magic bytes). Three tests (disk, logical, non-AFF4) driven by
aff4::testutil fail (unimplemented); implementation follows.

Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
detect_aff4 calls aff4::container_kind and maps Disk/Encrypted →
FsType::Aff4Disk (encrypted refused at open) and Logical →
FsType::Aff4Logical; non-AFF4 files return None. All three detection
tests pass; clippy/fmt clean.

Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
New fs_aff4 module: Aff4ForensicFs skeleton (stubbed) over ArchiveTree,
plus three tests driven by aff4::testutil's test_aff4_logical fixture
builder (list + read a file byte-identical, a sliced range read, fs_info).
map_err handles Aff4Error's non_exhaustive variants. All three fail
(unimplemented); implementation follows.

Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
Aff4ForensicFs::open enumerates LogicalContainer entries into an
ArchiveTree (splitting each original_file_name, trimming the "./" prefix,
synthesising parent dirs); read_range resolves the entry and slices the
inflated bytes (AFF4-Logical has no positioned read). All three
testutil-oracle tests pass; clippy/fmt clean.

Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
Auto-detected ZIP files are refined via detect_aff4 (AFF4 has no magic).
Two arms: Aff4Logical opens Aff4ForensicFs directly from the path (AD1-like);
Aff4Disk opens aff4::Aff4Reader (Read+Seek), re-detects the inner
filesystem, and mounts it via build_filesystem (EWF/VMDK-like). A forced
--fs is respected as-is. Binary builds; clippy/fmt clean.

Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
Commit an 863-byte AFF4-Logical fixture (aff4::testutil, verified to read
back through Aff4ForensicFs), copied by gen-fixtures.sh and asserted by the
`aff4` row (hello.txt = "hello from aff4"). The AFF4 disk shape isn't
smoke-fixtured — the test writer is single-chunk and can't wrap a real
inner FS; its Aff4Reader is tier-1 validated in the aff4 crate and its
mount path is the EWF/VMDK glue. Provenance in tests/data/README.md.

Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
ADR 0002 captures why AFF4 mounts as two shapes (Logical via Aff4ForensicFs,
Disk via Aff4Reader→inner FS), why detection uses the new upstream
aff4::container_kind (AFF4 has no magic bytes), how encryption is refused,
and why the disk shape relies on tier-1 upstream validation rather than a
synthetic smoke fixture. Supersedes the aff4-integration handoff.

Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
@socket-security

Copy link
Copy Markdown

Review the following changes in direct dependencies. Learn more about Socket for GitHub.

Diff Package Supply Chain
Security
Vulnerability Quality Maintenance License
Addedaff4@​0.2.19910093100100

View full report

@h4x0r h4x0r merged commit 0d3d9d6 into main Jul 1, 2026
12 checks passed
@h4x0r h4x0r deleted the feat/aff4-mount branch July 1, 2026 06:43
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