DragonFlyBSD Kernel Audit
DF-0075 / fix.diff
← back to finding ↓ download raw
diff --git a/sys/kern/subr_diskslice.c b/sys/kern/subr_diskslice.c
--- a/sys/kern/subr_diskslice.c
+++ b/sys/kern/subr_diskslice.c
@@ -554,9 +554,31 @@
 		return (0);
 
 	case DIOCGSLICEINFO:
+	{
+		struct diskslices *kssp;
+		int n, nslices;
+		/*
+		 * DF-0075: bcopy() of the raw struct exposes kernel virtual
+		 * addresses (dss_cdevsw, ds_dev, ds_label.opaque, ds_ops,
+		 * ds_devs[]) to userspace.  Copy out, then sanitize every
+		 * kernel-pointer field in the destination buffer.
+		 */
 		bcopy(ssp, data, (char *)&ssp->dss_slices[ssp->dss_nslices] -
 				 (char *)ssp);
+		kssp = (struct diskslices *)data;
+		kssp->dss_cdevsw = NULL;
+		nslices = kssp->dss_nslices;
+		if (nslices > MAX_SLICES)
+			nslices = MAX_SLICES;
+		for (n = 0; n < nslices; n++) {
+			struct diskslice *ksp = &kssp->dss_slices[n];
+			ksp->ds_dev = NULL;		/* cdev_t */
+			ksp->ds_label.opaque = NULL;	/* kmalloc'd label */
+			ksp->ds_ops = NULL;		/* static disklabel_ops* */
+			bzero(ksp->ds_devs, sizeof(ksp->ds_devs));
+		}
 		return (0);
+	}
 
 	case DIOCSDINFO32:
 		ops = &disklabel32_ops;