--- a/sys/kern/subr_diskslice.c +++ b/sys/kern/subr_diskslice.c @@ -553,10 +553,22 @@ } return (0); - case DIOCGSLICEINFO: - bcopy(ssp, data, (char *)&ssp->dss_slices[ssp->dss_nslices] - - (char *)ssp); + case DIOCGSLICEINFO: { + u_int n; + + /* + * The DIOCGSLICEINFO ioctl buffer is only sized for + * MAX_SLICES slice records, but GPT disks allocate + * more (up to BASE_SLICE + MAX_GPT_ENTRIES). Clamp + * the copy to the declared size of the ioctl to avoid + * overflowing the kernel ioctl buffer. + */ + n = ssp->dss_nslices; + if (n > MAX_SLICES) + n = MAX_SLICES; + bcopy(ssp, data, (char *)&ssp->dss_slices[n] - (char *)ssp); return (0); + } case DIOCSDINFO32: ops = &disklabel32_ops;