DF-0075 / fix.diff
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; |