DragonFlyBSD Kernel Audit
DF-2428 / fix.diff
← back to finding ↓ download raw
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);
 				}