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

crom_init_context() trusts attacker-controlled info_len, allowing root-directory pointer to land past the csrrom buffer

Summary

info_len is an 8-bit field read from device-supplied ConfigROM (fwcrom.c:67) and used without upper-bound check to advance data pointer past the bus-info block (p += 1 + hdr->info_len at :84). MAX_ROM at :59 is hardcoded 1004, not derived from actual buffer size. CROM_END at :60 is computed from attacker-influenced stack[0].dir + MAX_ROM. For info_len=255, p advances 256 quads (1024 bytes) past start of 1024-byte csrrom buffer. With info_len>=254 parser dereferences kernel memory past csrrom into fw_device rommax/rcnt/fc/status/link fields (firewirereg.h:44-62) including kernel heap pointers. csrrom populator firewire.c:1473-1558 only validates WRITE index, not info_len VALUE stored at csrrom[0]. Reachable from any FireWire device at attach via sbp_alloc_lun. Info leak via sbp_probe_lun -> crom_parse_text -> sdev->vendor -> SCSI INQUIRY at sbp.c:1527 OR kernel panic. Fix: reject info_len > 254.

Discussion (0)

No comments yet.

PoC verification

Evidence pack

findings/poc/1084 Β· 8 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 201 B view raw
run.log run-log baseline: dir=0x403660 (quad 256, OOB) 1.3 KB view raw
fix_harness_run.log run-log patched parser: info_len rejected, dir=NULL 924 B view raw
fix.diff suggested-fix reject info_len > 254 in crom_init_context 797 B view raw
env.txt environment uname, cc version 232 B view raw
VERDICT.md verdict full narrative 2.6 KB ↓ raw
VERDICT.md verdict full narrative
↓ download raw

DF-1084 β€” crom_init_context trusts attacker-controlled info_len (OOB read)

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

crom_init_context() (sys/bus/firewire/fwcrom.c:62-94) reads hdr->info_len β€” an 8-bit field taken directly from device-supplied ConfigROM (fwcrom.c:67) β€” and uses it to advance the data pointer past the bus-info block with no upper-bound check:

fwcrom.c:84    p += 1 + hdr->info_len;

MAX_ROM (:59) is a hardcoded 1004 and CROM_END (:60) is computed from the advanced stack[0].dir, not the buffer origin, so a malicious info_len pushes the root-directory pointer out of the buffer. With info_len = 255, p advances by 1 + 255 = 256 quads = 1024 bytes, i.e. exactly past the 1024-byte (256-quad) csrrom buffer. The very next line (fwcrom.c:87, ((struct csrdirectory *)p)->crc_len) already dereferences out-of-bounds memory.

Reproduction (no FireWire hardware needed)

fwcrom.c ships a userland -DTEST mode, so the harness links against the real kernel parser (its demo main() renamed away) and feeds it a crafted ROM backed by a poisoned region, with only the first 256 quads treated as the logical csrrom:

hdr->info_len        = 255
logical csrrom range = quads [0 .. 256)  (1024 bytes)
&rom[256] (OOB start)= 0x403660
cc.depth             = 0
cc.stack[0].dir      = 0x403660          <- root-directory pointer
crom_get()           = 0x403664          <- derefs OOB memory
  OOB reg->crc_len   = 0x00004242        <- read from quad 256 (OOB)
[+] DF-1084 CONFIRMED: root-directory pointer 0x403660 is at quad 256, PAST
    the 1024-byte csrrom end.

The parser proceeds (depth=0) and crom_get()/crom_parse_text() then operate entirely on OOB memory β€” in the kernel this is the adjacent fw_device fields (firewirereg.h:44-62) holding kernel heap pointers, yielding an info leak / panic.

Reachability

FireWire is compiled into the GENERIC kernel (per DF-1083) and the parser is exercised at device attach via sbp_alloc_lun/crom_parse_text. The audit guest has no FireWire controller, so the live device path is not triggerable here; the bug is demonstrated against the actual parser code instead, which is the authoritative reproduction for this class. Impact ceiling: kernel info-leak of adjacent fw_device pointers (KASLR-bypass) or panic.

Fix (validated at harness level)

fix.diff adds if (hdr->info_len > 254) { reject } before the pointer advance. Re-linking the harness against the patched parser yields crom_init_context: info_len 255 too large, cc.depth = -1, cc.stack[0].dir = NULL β€” the OOB read is eliminated.

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_init_context info_len no bounds -> root-dir past 1024B csrrom.