β¬’ DragonFlyBSD Kernel Audit
← triage Β· dashboard
DF-3155

ext2 extent-block checksum verification is dead code β€” metadata_csum extent blocks are never verified, and the dormant implementation carries a latent eh_max-driven ~768KB OOB read

Summary

ext2_extent_blk_csum_verify()/set() have zero callers in the tree (ext2_extents.c contains no csum logic), so extent-tree blocks on metadata_csum filesystems are accepted without checksum verification. The dormant ext2_extent_blk_csum() derives its crc length from EXT4_EXTENT_TAIL_OFFSET(ehp) = 12 + 12*eh_max with eh_max raw on-disk: a crafted eh_max=65535 would read 786,432 bytes from a bsize buffer (worse than DF-0877) the moment anyone wires the verification in (upstream FreeBSD calls these from ext4_ext_find_extent). None today (unreachable); latent + integrity-detection gap vs ext4. Fix: if wired, check eh_magic and bound eh_max <= (bsize-16)/sizeof(ext4_extent); otherwise delete.

Discussion (0)

No comments yet.

PoC verification

Evidence pack

findings/poc/DF-3155 Β· 3 files
FileTypeDescriptionSize
README.md β€” 1.6 KB ↓ raw
manifest.json β€” 629 B view raw
verdict.json β€” 1.5 KB view raw

DF-3155 β€” ext2 extent-block checksums are dead code (+ latent eh_max OOB)

ext2_extent_blk_csum_verify() / ext2_extent_blk_csum_set() (sys/vfs/ext2fs/ext2_csum.c:387-433) have zero callers in the tree (only the prototypes at ext2_extern.h:120-121; grep -rn extent_blk_csum sys/ shows no call sites β€” ext2_extents.c contains no checksum logic at all).

Two consequences:

  1. Verification gap: on a metadata_csum filesystem, extent-tree blocks are accepted without any checksum verification β€” corruption or tampering of extent metadata that Linux/ext4 would reject is silently honored by this port.

  2. Latent OOB if ever wired up: ext2_extent_blk_csum() computes size = EXT4_EXTENT_TAIL_OFFSET(ehp) + offsetof(...et_checksum); EXT4_EXTENT_TAIL_OFFSET(hdr) = 12 + 12 * le16toh(hdr->eh_max) /* ext2_extents.h:113-114 */ crc = calculate_crc32c(crc, (uint8_t*)ehp, size); with eh_max taken raw from the on-disk extent header (u16). A crafted eh_max = 65535 would crc 786,432 bytes from a bsize buffer β€” an immediate ~768 KB OOB heap read (worse than DF-0877) the moment anyone calls the function (upstream FreeBSD calls it from ext4_ext_find_extent).

Not verified in-kernel (dead code β€” unreachable today). Recorded so the landmine is documented and the gap is a conscious decision.

Recommended fix (if the verification is wired up): validate eh_magic == EXT4_EXT_MAGIC and bound eh_max <= (bsize - 12 - sizeof(tail)) / sizeof(ext4_extent) before computing the tail offset, or delete the dead functions.

Fix verification

not_testable
per-fix-DF-3155

Confirmed kernel references

Detail

Evidence (decisive lines)

['findings/poc/DF-3155/README.md', 'sys/vfs/ext2fs/ext2_extents.h:113-114', 'grep -rn extent_blk_csum sys/ (definitions + prototypes only)']

PoC changes

n/a β€” no runtime path exists to test

Verified recommended fix

Bound eh_max by the block size and check eh_magic before computing the extent tail offset, or remove the dead verification functions

Verdict

NOT RUNTIME-TESTABLE (dead code). ext2_extent_blk_csum_verify/set (ext2_csum.c:387-433) have zero callers in the tree; extent-tree blocks on metadata_csum filesystems are never checksum-verified by this port (ext2_extents.c contains no csum logic). The dormant ext2_extent_blk_csum() computes its crc length from EXT4_EXTENT_TAIL_OFFSET(ehp) = 12 + 12*eh_max (ext2_extents.h:113-114) with eh_max raw on-disk u16 β€” a crafted eh_max=65535 would read 786,432 bytes from a bsize buffer (worse than DF-0877) the moment anyone wires the verification in (FreeBSD calls these from ext4_ext_find_extent).