diff options
author | bde <bde@FreeBSD.org> | 1997-09-16 10:11:49 +0000 |
---|---|---|
committer | bde <bde@FreeBSD.org> | 1997-09-16 10:11:49 +0000 |
commit | 1bd32b987b7336e1c1c99ba6a70f36b84af119ed (patch) | |
tree | d24f5e57c978dd01409c44e8d1aa86349e5e7b97 /sys/kern/subr_diskslice.c | |
parent | 35b575df346c55297cfc7dd21021aade4f39bf82 (diff) | |
download | FreeBSD-src-1bd32b987b7336e1c1c99ba6a70f36b84af119ed.zip FreeBSD-src-1bd32b987b7336e1c1c99ba6a70f36b84af119ed.tar.gz |
Reject attempts to set an in-core label which says that the "disk"
or a partition is larger than the slice.
Now `disklabel -Brw sdX auto' should fail properly on sliced disks
without partition of type 165, e.g., on zip disks with the factory
default formatting. Previously it set a bogus in-core label for
the compatibility slice and used this to corrupt the MBR (the slice
has offset 0 and size 0, but setting the label in effect corrupted
its size to nonzero).
`disklabel -Brw sdX auto' already failed properly on normally (not
dangerously dedicated) sliced disks _with_ partition of type 165,
because the compatibility slice has a nonzero offset so the MBR
remained inaccessible when the size was corrupted.
This bug only affected in-core labels. On-disk labels are checked
carefully when they read and written.
Diffstat (limited to 'sys/kern/subr_diskslice.c')
-rw-r--r-- | sys/kern/subr_diskslice.c | 14 |
1 files changed, 10 insertions, 4 deletions
diff --git a/sys/kern/subr_diskslice.c b/sys/kern/subr_diskslice.c index 28c7768..f5a8e58 100644 --- a/sys/kern/subr_diskslice.c +++ b/sys/kern/subr_diskslice.c @@ -43,7 +43,7 @@ * from: wd.c,v 1.55 1994/10/22 01:57:12 phk Exp $ * from: @(#)ufs_disksubr.c 7.16 (Berkeley) 5/4/91 * from: ufs_disksubr.c,v 1.8 1994/06/07 01:21:39 phk Exp $ - * $Id: subr_diskslice.c,v 1.36 1997/03/24 11:24:37 bde Exp $ + * $Id: subr_diskslice.c,v 1.37 1997/09/02 20:05:50 bde Exp $ */ #include <sys/param.h> @@ -304,6 +304,8 @@ dsioctl(dname, dev, cmd, data, flags, sspp, strat, setgeom) int error; struct disklabel *lp; int old_wlabel; + u_char openmask; + int part; int slice; struct diskslice *sp; struct diskslices *ssp; @@ -368,6 +370,13 @@ dsioctl(dname, dev, cmd, data, flags, sspp, strat, setgeom) /* XXX why doesn't setdisklabel() check this? */ if (error == 0 && lp->d_partitions[RAW_PART].p_offset != 0) error = EINVAL; + if (error == 0) { + if (lp->d_secperunit > sp->ds_size) + error = ENOSPC; + for (part = 0; part < lp->d_npartitions; part++) + if (lp->d_partitions[part].p_size > sp->ds_size) + error = ENOSPC; + } #if 0 /* XXX */ if (error != 0 && setgeom != NULL) error = setgeom(lp); @@ -423,9 +432,6 @@ dsioctl(dname, dev, cmd, data, flags, sspp, strat, setgeom) * if anything fails. */ for (slice = 0; slice < ssp->dss_nslices; slice++) { - u_char openmask; - int part; - for (openmask = ssp->dss_slices[slice].ds_bopenmask, part = 0; openmask; openmask >>= 1, part++) { if (!(openmask & 1)) |