diff --git a/sys/dev/disk/amd/amd.c b/sys/dev/disk/amd/amd.c --- a/sys/dev/disk/amd/amd.c +++ b/sys/dev/disk/amd/amd.c @@ -452,6 +452,18 @@ /* Just use the segments provided */ segs = (struct bus_dma_segment *)pcsio->data_ptr; + /* + * sglist_cnt is a user-controlled u_int16_t that + * amdexecutesrb() copies verbatim into the fixed-size + * srb->SGsegment[AMD_NSEG] array. Reject anything that + * would overflow the SRB instead of copying past its end. + */ + if (pcsio->sglist_cnt > AMD_NSEG) { + TAILQ_INSERT_HEAD(&amd->free_srbs, pSRB, links); + pccb->ccb_h.status = CAM_PROVIDE_FAIL; + xpt_done(pccb); + return; + } amdexecutesrb(pSRB, segs, pcsio->sglist_cnt, 0); } } else