⬢ DragonFlyBSD Kernel Audit
DF-4241 / fix.diff
← back to finding ↓ download raw
diff --git a/sys/dev/raid/dpt/dpt_scsi.c b/sys/dev/raid/dpt/dpt_scsi.c
index ebc9e1a..2288962 100644
--- a/sys/dev/raid/dpt/dpt_scsi.c
+++ b/sys/dev/raid/dpt/dpt_scsi.c
@@ -1537,6 +1537,18 @@ dpt_intr(void *arg)
 		}
 		dpt->sp->EOC = 0;
 
+		/* The ccb_busaddr in the status packet is controller-fed.  A
+		 * duplicate or fabricated packet names a CCB that is no longer
+		 * in flight; completing it again would double-free the CCB onto
+		 * the free list and double-xpt_done() a CAM ccb that may already
+		 * be recycled.  Drop it. */
+		if ((dccb->state & DCCB_ACTIVE) == 0) {
+			kprintf("dpt%d: status packet for inactive CCB ignored\n",
+			       dpt->unit);
+			status = dpt_inb(dpt, HA_RSTATUS);	/* clear IRQ */
+			continue;
+		}
+
 		/*
 		 * Double buffer the status information so the hardware can
 		 * work on updating the status packet while we decifer the