--- a/sys/bus/firewire/fwcrom.c 2026-10-15 22:16:23.771424969 +0000 +++ b/sys/bus/firewire/fwcrom.c 2026-10-15 22:16:37.355250103 +0000 @@ -77,6 +77,19 @@ cc->depth = -1; return; } + if (hdr->info_len > 4) { + /* + * The bus info block is at most 4 quadlets in a 1024-byte + * CSR ROM. A larger info_len pushes the root directory + * past the buffer and pushes CROM_END() (~root+1003) up to + * ~999 bytes beyond it, neutralizing every later bounds + * check. Reject the ROM instead. (DF-2290) + */ + kprintf("crom_init_context: info_len %d out of range\n", + hdr->info_len); + cc->depth = -1; + return; + } if (hdr->info_len == 1) { /* minimum ROM */ cc->depth = -1; @@ -204,7 +217,10 @@ } textleaf = (struct csrtext *)(reg + reg->val); - if ((vm_offset_t)textleaf + textleaf->crc_len > CROM_END(cc)) { + /* crc_len is a QUADLET count: bound the leaf's full byte extent + * (header + text), not the quadlet count as a byte offset. (DF-2291) */ + if ((vm_offset_t)textleaf + + (textleaf->crc_len + 1) * sizeof(u_int32_t) > CROM_END(cc)) { strncpy(buf, nullstr, len); return; }