diff --git a/sys/dev/raid/hpt27xx/hpt27xx_osm_bsd.c b/sys/dev/raid/hpt27xx/hpt27xx_osm_bsd.c --- a/sys/dev/raid/hpt27xx/hpt27xx_osm_bsd.c +++ b/sys/dev/raid/hpt27xx/hpt27xx_osm_bsd.c @@ -721,6 +721,22 @@ if (ccb->ccb_h.flags & CAM_SG_LIST_PHYS) pCmd->flags.physical_sg = 1; + /* + * DF-1563: pCmd->psg aliases ext->psg which has + * exactly os_max_sg_descriptors entries. Reject + * any sglist_cnt that would overflow that fixed + * array (otherwise the loop below writes + * (sglist_cnt-N)*sizeof(SG) bytes into the adjacent + * M_DEVBUF slab). + */ + if (ccb->csio.sglist_cnt > os_max_sg_descriptors) { + cmdext_put(ext); + ldm_free_cmds(pCmd); + ccb->ccb_h.status = CAM_REQ_CMP_ERR; + xpt_done(ccb); + return; + } + for (idx = 0; idx < ccb->csio.sglist_cnt; idx++) { pCmd->psg[idx].addr.bus = sgList[idx].ds_addr; pCmd->psg[idx].size = sgList[idx].ds_len;