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