Volume-header CRC (vol_crc) is never verified β hammer_crc_test_volume has zero callers; all mount-time header consumption is integrity-unchecked
| Field | Value |
|---|---|
| ID | DF-3042 |
| Status | new |
| Severity | Info |
| CVSS 3.1 | CVSS:3.1/AV:L/AC:L/PR:H/UI:N/S:U/C:N/I:N/A:N |
| CWE | CWE-345 |
| File | sys/vfs/hammer/hammer_ondisk.c |
| Lines | 180-213 |
| Area | vfs/hammer |
| Confidence | certain |
| Discovered | 2026-09-02 |
| Pass | 2 (GLM 5.3 second pass) |
| Bucket | base:vfs |
| Reported | pending |
| Known CVE | none |
| CVE match | novel |
Summary
hammer_install_volume validates only vol_signature, fsid match, duplicate vol_no and root vol_no; the root volume's vol_crc field is loaded into kernel memory but never checked β hammer_crc_test_volume() is defined and referenced nowhere else in the kernel (tree-wide grep). Everything downstream of mount β vol_no, vol_count, vol_version, vol_buf_beg/vol_buf_end, vol0_blockmap[] (including the undo map that feeds DF-3040), vol0_undo_array[], vol0_btree_root, vol0_stat_* β is consumed with zero integrity gate. For a malicious crafter this changes nothing (CRC is forgeable), but for the corruption/robustness threat model the missing gate means random media corruption is interpreted as trusted metadata instead of failing the mount; it is also the reason the DF-3040 PoC needed no CRC fixup. Layer1 freemap CRCs are verified on blockmap paths and B-Tree nodes at load β the volume header is the one unchecked anchor structure. Fix: verify the header CRC after the signature check (row diff). Not applicable to Phase V (hardening).
Timeline
- 2026-09-02 Discovered during pass-2 audit of hammer_ondisk.c (GLM 5.3).
Discussion (0)
PoC verification
Evidence pack
findings/poc/DF-3042 Β· 6 files| File | Type | Description | Size | |
|---|---|---|---|---|
| README.md | β | 217 B | β raw | |
| corrupt3042.c | β | 3.1 KB | view raw | |
| fix.diff | β | 774 B | view raw | |
| manifest.json | β | 429 B | view raw | |
| run.log | β | 529 B | view raw | |
| verdict.json | β | 2.2 KB | view raw |
DF-3042 evidence pack
What
hammer volume-header CRC never verified at mount
Verdict
status=reproduced impact=none confidence=certain
See VERDICT.md for the full narrative and fix.diff for the verified fix.
Fix verification
fixedA/B complete: stock mounts any corrupted header (vol_crc never checked); F40FIX refuses an image whose stored vol_crc is nonzero-and-wrong (console: HAMMER: volume has an invalid header CRC, mount EINVAL) while fresh newfs_hammer images (vol_crc==0) still mount - compat retained. Fix verified end to end.
Confirmed kernel references
Detail
Evidence (decisive lines)
VERDICT.md with path:line citations; run.log where a live demo exists; fix.diff
PoC changes
corruptor computes CRC32C locally (userland has no iscsi_crc32) to prove stored-vs-computed mismatch; also discovered vol_crc==0 on fresh images
Verified recommended fix
verify vol_crc after the signature check when vol_crc != 0 (newfs_hammer leaves it 0)
Verdict
Reproduced on the stock INVARIANTS guest: a newfs_hammer image whose volume header byte (vol_reserved[7], covered by vol_crc) was flipped WITHOUT fixing vol_crc mounted successfully (mount_hammer /dev/vn1 /mnt -> OK) - tree-wide hammer_crc_test_volume() has zero callers, so vol_no, vol_count, vol_version, vol0_blockmap[] etc. are consumed integrity-unchecked (hammer_ondisk.c:199-247 validates only signature/fsid/dup-vol_no/root vol_no). IMPORTANT fix-design discovery recorded by the corruptor: newfs_hammer leaves vol_crc == 0 on fresh images (two independent images verified), so a naive always-enforce fix would reject every new volume; the fix enforces the CRC only when vol_crc != 0. Post-fix A/B on F40FIX: image with a forged non-zero vol_crc is rejected with invalid header CRC/EFTYPE while a vol_crc==0 image still mounts (compat).
No comments yet.