⬢ DragonFlyBSD Kernel Audit
DF-2266 / fix.diff
← back to finding ↓ download raw
--- a/sys/bus/cam/cam_periph.c	2026-10-21 08:21:37.426871402 +0000
+++ b/sys/bus/cam/cam_periph.c	2026-10-21 08:21:37.430871352 +0000
@@ -1,21 +1,5 @@
 	case CAMGETPASSTHRU:
 		ccb = cam_periph_getccb(periph, /* priority */ 1);
-		/*
-		 * DF-2266: the pooled CCB carries stale kernel pointers
-		 * (cbfcnp, path, sim_priv, timeout_ch, saved_ccb_ptr) and
-		 * old I/O bytes in the union body; the whole union is
-		 * bcopied to userspace below.  Zero it first, preserving
-		 * only path/timeout_ch which xpt_setup_ccb needs and which
-		 * must not be freed or re-inited here.
-		 */
-		{
-			struct cam_path *df_path = ccb->ccb_h.path;
-			struct callout *df_co = ccb->ccb_h.timeout_ch;
-
-			bzero(ccb, sizeof(*ccb));
-			ccb->ccb_h.path = df_path;
-			ccb->ccb_h.timeout_ch = df_co;
-		}
 		xpt_setup_ccb(&ccb->ccb_h,
 			      ccb->ccb_h.path,
 			      /*priority*/1);
\ No newline at end of file
--- a/sys/bus/cam/cam_periph.c	2026-10-21 08:21:37.430871352 +0000
+++ b/sys/bus/cam/cam_periph.c	2026-10-21 08:21:37.430871352 +0000
@@ -1,2 +1,29 @@
-		/* copy the result back out */	
-		bcopy(ccb, addr, sizeof(union ccb));
\ No newline at end of file
+		/*
+		 * DF-2266: copy the result back out through a SCRUBBED
+		 * shadow CCB: the pooled kernel CCB carries live kernel
+		 * pointers (path cam_path*, timeout_ch callout*, sim_priv
+		 * SIM softc*) and stale bytes from prior I/O in the union
+		 * body, none of which may be disclosed to userspace.  The
+		 * live CCB itself is left untouched (xpt_release_ccb still
+		 * needs its state).
+		 */
+		{
+			union ccb df_out;
+
+			bzero(&df_out, sizeof(df_out));
+			bcopy(&ccb->ccb_h, &df_out.ccb_h,
+			      sizeof(struct ccb_hdr));
+			df_out.cgdl = ccb->cgdl;
+			df_out.ccb_h.cbfcnp = NULL;
+			df_out.ccb_h.path = NULL;
+			df_out.ccb_h.timeout_ch = NULL;
+			df_out.ccb_h.sim_priv.entries[0].ptr = NULL;
+			df_out.ccb_h.sim_priv.entries[1].ptr = NULL;
+			df_out.ccb_h.xpt_links.sle.sle_next = NULL;
+			df_out.ccb_h.sim_links.sle.sle_next = NULL;
+			df_out.ccb_h.periph_links.sle.sle_next = NULL;
+			df_out.ccb_h.xpt_links.tqe.tqe_next = NULL;
+			df_out.ccb_h.sim_links.tqe.tqe_next = NULL;
+			df_out.ccb_h.periph_links.tqe.tqe_next = NULL;
+			bcopy(&df_out, addr, sizeof(union ccb));
+		}
\ No newline at end of file