β¬’ DragonFlyBSD Kernel Audit
← triage Β· dashboard
1086

crom_parse_text() CROM_END check treats crc_len as bytes instead of quadlets, allowing OOB read past csrrom

Summary

Bounds check at fwcrom.c:207 is (vm_offset_t)textleaf + textleaf->crc_len > CROM_END(cc), but crc_len counts 32-bit quadlets not bytes (compare its use at :215,:218 where text[i] indexed as u_int32_t and qlen=crc_len-2 looped as quadlets). Check too permissive by ~4x. With info_len=4 stack[0].dir=&csrrom[5], CROM_END=&csrrom[5]+1003. textleaf at offset 983 with crc_len=20: check 983+20>1003 false (passes), but textleaf->text[7] at byte offset 983+12+28=1023..1026 crosses csrrom/rommax boundary. Bytes copied to sdev->vendor[0..31] then bcopy to SCSI INQUIRY response (sbp.c:1527) exposing leaked rommax/rcnt kernel values to any userland CAM inquiry. Fix: multiply crc_len by sizeof(u_int32_t) and account for full leaf size.

Discussion (0)

No comments yet.

PoC verification

Evidence pack

findings/poc/1086 Β· 7 files
FileTypeDescriptionSize
poc_firewire.c trigger-source shared fwcrom OOB harness (real parser, TEST mode) 5.9 KB view raw
build.sh build-script compile real fwcrom.c (TEST) + harness, link 581 B view raw
run.sh run-script ./poc_firewire 188 B view raw
run.log run-log baseline: 60+ bytes OOB poison copied by crom_parse_text 1.3 KB view raw
fix.diff suggested-fix scale crc_len bound by sizeof(u_int32_t) 646 B view raw
env.txt environment uname, cc version 232 B view raw
VERDICT.md verdict full narrative 1.9 KB ↓ raw
VERDICT.md verdict full narrative
↓ download raw

DF-1086 β€” crom_parse_text CROM_END check treats crc_len as bytes (OOB read)

Verdict: REPRODUCED (out-of-bounds read past the 1024-byte csrrom)

crom_parse_text() (sys/bus/firewire/fwcrom.c:187-225) bounds-checks the text leaf with:

fwcrom.c:207   if ((vm_offset_t)textleaf + textleaf->crc_len > CROM_END(cc)) ...

but crc_len counts 32-bit quadlets, not bytes β€” the loop immediately below indexes textleaf->text[i] as u_int32_t with qlen = crc_len - 2 (:215-219). The check is therefore ~4Γ— too lax: a text leaf whose crc_len fits the byte bound still reads text[i] quadlets far past the csrrom buffer.

Concrete: root dir at quad 5 (info_len=4), text leaf at quad 250, crc_len = 20. - byte-check (:207): textleaf(1000) + 20 = 1020 <= 1023 β†’ PASSES - quad loop (:218): qlen = 18, reads text[0..17] = quads 253..270 β†’ quads 256..270 are out-of-bounds (15 quads = 60 bytes OOB).

Reproduction (no FireWire hardware needed)

Same harness as DF-1084 (links the real -DTEST parser):

crom_parse_text output bytes (hex): 42424242 ... (60+ bytes of 0x42 OOB poison)
[+] DF-1086 CONFIRMED: crom_parse_text copied 60+ bytes of OOB memory via the
    byte-vs-quad crc_len check bug at fwcrom.c:207.

In the kernel these OOB bytes are adjacent fw_device/ConfigROM fields exposed to userland via sdev->vendor β†’ SCSI INQUIRY (sbp.c:1527), i.e. an info leak of kernel heap values to any CAM inquiry.

Reachability

Same as DF-1084: FireWire in GENERIC (DF-1083), parser exercised at device attach; no FW controller on the audit guest, so demonstrated against the real parser code. Impact ceiling: kernel info-leak / panic.

Fix (validated at harness level)

fix.diff scales the bound by sizeof(u_int32_t): if ((vm_offset_t)textleaf + (size_t)textleaf->crc_len * sizeof(u_int32_t) > CROM_END(cc)). Re-linked harness returns the "(null)" fallback with 0 OOB bytes copied.

Fix verification

fixed

validated

see evidence pack
↓ fix.diffDragonFly 6.5-DEVELOPMENT #1: Fri Jul 17 14:28:56 UTC 2026

Confirmed kernel references

β€”

Detail

Exploit chain

none

Evidence (decisive lines)

β€”

Verdict

REPRODUCED (harness, real parser). crom_parse_text crc_len bytes-vs-quads -> 60B OOB read.