DragonFlyBSD Kernel Audit
DF-1891 / 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,12 @@
     ctlr->channels =
 	MAX(flsl(ATA_INL(ctlr->r_res2, ATA_AHCI_PI)),
 	    (ATA_INL(ctlr->r_res2, ATA_AHCI_CAP) & ATA_AHCI_NPMASK) + 1);
+    /* Cap at the size of ctlr->interrupt[] (ata-pci.h "XXX SOS max ch#"
+     * = 8).  Without this cap, a malicious/glitched AHCI controller
+     * advertising CAP.NP=0x1f or PI=0xFFFFFFFF drives ata_pci_setup_intr
+     * writes off the end of interrupt[] and ata_generic_intr later calls
+     * through corrupted pointers on every IRQ. */
+    ctlr->channels = MIN(ctlr->channels, nitems(ctlr->interrupt));
 
     ctlr->reset = ata_ahci_reset;
     ctlr->dmainit = ata_ahci_dmainit;