diff --git a/sys/dev/disk/buslogic/bt.c b/sys/dev/disk/buslogic/bt.c --- a/sys/dev/disk/buslogic/bt.c +++ b/sys/dev/disk/buslogic/bt.c @@ -1052,6 +1052,18 @@ /* Just use the segments provided */ segs = (struct bus_dma_segment *) csio->data_ptr; + /* + * sglist_cnt is a user-controlled u_int16_t that + * btexecuteccb() copies verbatim into the fixed-size + * bccb->sg_list[BT_NSEG] array. Reject anything that + * would overflow the SG slot instead of copying past it. + */ + if (csio->sglist_cnt > BT_NSEG) { + btfreeccb(bt, bccb); + ccbh->status = CAM_PROVIDE_FAIL; + xpt_done(ccb); + return; + } btexecuteccb(bccb, segs, csio->sglist_cnt, 0); }