Skip to content

docs(corpus): record the node-type fixtures and the macOS minting recipe - #17

Merged
h4x0r merged 1 commit into
mainfrom
docs/node-type-corpus
Aug 24, 2026
Merged

docs(corpus): record the node-type fixtures and the macOS minting recipe#17
h4x0r merged 1 commit into
mainfrom
docs/node-type-corpus

Conversation

@h4x0r

@h4x0r h4x0r commented Aug 24, 2026

Copy link
Copy Markdown
Contributor

Catalogues the three fixtures minted for the node-type work, and writes down two constraints that cost real time — both of which point at the wrong culprit.

Catalog entries

fixture tier
B9b udf_all_node_types.img — all five types via ICB file_type T2
C1b ntfs_all_node_types.zip — all five, in both Interix and WSL encodings T2
C1c ntfs_windows_reparse.zip — classic tags, Windows-authored, fsutil answer key committed alongside T2 (strong)

Each with MD5, oracle, consuming test, and an explicit tier justification. C1c is deliberately not labelled T1: neither the bytes nor the expected values were authored here, but the scenario was chosen, and T1 would need a real-world installation image where Windows Setup made the junctions.

Minting recipe

Rootless podman cannot mknod a device even with --privilegedcap_mknod shows in CapEff and it still fails, because the capability is namespaced. mkfifo succeeds in the same container, which makes it read like a filesystem-driver limitation. Four ntfs-3g mount-option sets were tried before running the control that settles it in one command: mknod on tmpfs. The fix is a rootful container inside the podman VM.

Plus the loop-device gotcha (/dev carries only loop0, so losetup -f names a device that doesn't exist).

What each filesystem can express

A table, because the assumption that a format records a type just because the OS has one is wrong twice here:

  • Interix cannot express a FIFO or socket distinguishably — zero-length and one-byte $DATA with no magic. libntfs-3g/dir.c's own comment reads "FIFO or regular file." A reader must report File; inferring otherwise fabricates an observation.
  • No Linux tool writes classic 0xA000000C/0xA0000003 — but ntfs-3g reads them. "Cannot create X" and "cannot validate X" are different claims, and most format libraries read far more than they write. Checking the read path separately avoided standing up a VM for validation.

Paired with SecurityRonin/ntfs-forensic#15 and SecurityRonin/udf-forensic#18.

Three new fixtures enter the catalog: udf_all_node_types.img,
ntfs_all_node_types.zip (both Linux encodings) and
ntfs_windows_reparse.zip (classic tags, Windows-authored with fsutil as
the answer key). Each with tier, MD5, oracle and consuming test.

Adds a minting section to the corpus standard, because two constraints
cost real time and both point at the wrong culprit:

- Rootless podman cannot mknod a device even with --privileged and
  cap_mknod present in CapEff. mkfifo succeeds in the same container,
  which reads like a filesystem-driver limitation; the control that
  settles it is mknod on tmpfs. Four ntfs-3g mount-option sets were
  tried before that control was run.
- No Linux tool writes the classic 0xA000000C / 0xA0000003 tags, but
  ntfs-3g READS them. "Cannot create X" and "cannot validate X" are
  different claims, and most format libraries read more than they write.

Also tabulates which node types each filesystem can actually express:
the Interix encoding cannot represent a FIFO or a socket
distinguishably, so a reader must report File there rather than infer a
type the volume never recorded.

Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>
@h4x0r
h4x0r merged commit 8141844 into main Aug 24, 2026
2 checks passed
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