diff --git a/sys/dev/disk/trm/trm.c b/sys/dev/disk/trm/trm.c --- a/sys/dev/disk/trm/trm.c +++ b/sys/dev/disk/trm/trm.c @@ -428,6 +428,21 @@ bus_dma_segment_t *end_seg; bus_dmasync_op_t op; + /* + * pSRBSGL is a DMA-coherent allocation of TRM_MAX_SG_LISTENTRY=32 + * entries; reject any request that would overflow it. The CAM + * scatter path passes userspace sglist_cnt verbatim. + */ + if (nseg > TRM_MAX_SG_LISTENTRY) { + ccb->ccb_h.status = CAM_REQ_TOO_BIG; + bus_dmamap_unload(pACB->buffer_dmat, pSRB->dmamap); + pSRB->pNextSRB = pACB->pFreeSRB; + pACB->pFreeSRB = pSRB; + xpt_done(ccb); + crit_exit(); + return; + } + /* Copy the segments into our SG list */ end_seg = dm_segs + nseg; psg = pSRB->pSRBSGL; @@ -3426,7 +3441,7 @@ /*lowaddr*/ BUS_SPACE_MAXADDR, /*highaddr*/ BUS_SPACE_MAXADDR, /*maxsize*/ MAXBSIZE, - /*nsegments*/ TRM_NSEG, + /*nsegments*/ TRM_MAX_SG_LISTENTRY, /*maxsegsz*/ TRM_MAXTRANSFER_SIZE, /*flags*/ BUS_DMA_ALLOCNOW, &pACB->buffer_dmat) != 0)