DragonFlyBSD Kernel Audit
DF-2510 / fix.diff
← back to finding ↓ download raw
diff --git a/sys/dev/disk/nata/chipsets/ata-ahci.c b/sys/dev/disk/nata/chipsets/ata-ahci.c
--- a/sys/dev/disk/nata/chipsets/ata-ahci.c
+++ b/sys/dev/disk/nata/chipsets/ata-ahci.c
@@ -101,6 +101,13 @@
     ctlr->channels =
 	MAX(flsl(ATA_INL(ctlr->r_res2, ATA_AHCI_PI)),
 	    (ATA_INL(ctlr->r_res2, ATA_AHCI_CAP) & ATA_AHCI_NPMASK) + 1);
+    /* The legacy interrupt[] dispatch table is a fixed 8-entry array
+     * (see ata-pci.h).  AHCI can advertise up to 32 ports in CAP/PI, which
+     * would overflow interrupt[] during channel setup and cause an OOB
+     * indirect call from ata_generic_intr().  Cap to the table size.  See
+     * DF-2510. */
+    if (ctlr->channels > (int)NELEM(ctlr->interrupt))
+	ctlr->channels = (int)NELEM(ctlr->interrupt);
 
     ctlr->reset = ata_ahci_reset;
     ctlr->dmainit = ata_ahci_dmainit;