DragonFlyBSD Kernel Audit
DF-1280 / fix.diff
← back to finding ↓ download raw
diff --git a/sys/dev/disk/mpt/mpt.c b/sys/dev/disk/mpt/mpt.c
--- a/sys/dev/disk/mpt/mpt.c
+++ b/sys/dev/disk/mpt/mpt.c
@@ -737,6 +737,25 @@
 			 */
 			reply_baddr = MPT_REPLY_BADDR(reply_desc);
 			offset = reply_baddr - (mpt->reply_phys & 0xFFFFFFFF);
+			/*
+			 * Reject out-of-range address replies.  The reply
+			 * DMA area is exactly 2 * PAGE_SIZE bytes (see
+			 * mpt_pci.c:mpt_dma_mem_alloc); a malicious or
+			 * buggy IOC that posts a reply descriptor whose
+			 * address bits point outside that window would
+			 * otherwise drive MPT_REPLY_OTOV() (and the
+			 * dmamap_sync above) into an out-of-bounds
+			 * access on mpt->reply[].
+			 */
+			if (offset > (2 * PAGE_SIZE) - MPT_REPLY_SIZE) {
+				mpt_prt(mpt, "mpt_intr: bad address reply "
+				    "0x%08x (offset %#x)\n", reply_desc, offset);
+				reply_desc = MPT_REPLY_EMPTY;
+				if (ntrips++ > 1000) {
+					break;
+				}
+				continue;
+			}
 			bus_dmamap_sync_range(mpt->reply_dmat,
 			    mpt->reply_dmap, offset, MPT_REPLY_SIZE,
 			    BUS_DMASYNC_POSTREAD);