DF-1280 / fix.diff
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); |