⬢ DragonFlyBSD Kernel Audit
DF-2291 / fix.diff
← back to finding ↓ download raw
--- 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;
 	}