⬢ DragonFlyBSD Kernel Audit
DF-2427 / fix.diff
← back to finding ↓ download raw
--- sys/dev/disk/amd/amd.c	2026-10-19 12:13:07.621619884 +0000
+++ sys/dev/disk/amd/amd.c	2026-10-19 12:13:21.173446528 +0000
@@ -1828,6 +1828,23 @@
 	/* get ID */
 	amd->cur_target = amd_read8(amd, SCSIFIFOREG);
 	amd->cur_target ^= amd->HostID_Bit;
+	if (amd->cur_target == 0
+	 || (amd->cur_target & (amd->cur_target - 1)) != 0) {
+		/*
+		 * A valid reselection ID byte is the initiator ID bit
+		 * ORed with exactly one target ID bit, so after masking
+		 * our own bit off, exactly one bit must remain.  A zero
+		 * remainder decodes to no target (ffs(0)-1 == -1 indexes
+		 * tinfo/untagged_srbs/disc_count out of bounds); a
+		 * multi-bit remainder decodes to the WRONG target.  Reject
+		 * both and reset the bus.
+		 */
+		kprintf("amd%d: Invalid reselection ID, resetting bus\n",
+			amd->unit);
+		amd_ResetSCSIBus(amd);
+		amd->ACBFlag = 0;
+		return;
+	}
 	amd->cur_target = ffs(amd->cur_target) - 1;
 	amd->cur_lun = amd_read8(amd, SCSIFIFOREG) & 7;
 	tinfo = &amd->tinfo[amd->cur_target];