diff options
author | Kenneth R Westerback <krw@cvs.openbsd.org> | 2007-06-01 19:06:29 +0000 |
---|---|---|
committer | Kenneth R Westerback <krw@cvs.openbsd.org> | 2007-06-01 19:06:29 +0000 |
commit | fb46e3f564238bbc25c79e1509ce9b3484d74b33 (patch) | |
tree | 5b3399adfc0f990def4b01895bd447ecfeba06eb | |
parent | 6e2aa073e26eb6ab28c050459f6dedc66ca5d167 (diff) |
Add two constraints to V1 disklabels:
1) All partitions must start before the end of the disk. 2) All
partitions must end at or before the end of the disk.
Partitions not satisfying these constraints will be truncated and
marked FS_UNUSED.
ok otto@ deraadt@
-rw-r--r-- | sys/kern/subr_disk.c | 43 |
1 files changed, 28 insertions, 15 deletions
diff --git a/sys/kern/subr_disk.c b/sys/kern/subr_disk.c index 90ca865c6f8..d96842f664e 100644 --- a/sys/kern/subr_disk.c +++ b/sys/kern/subr_disk.c @@ -1,4 +1,4 @@ -/* $OpenBSD: subr_disk.c,v 1.43 2007/05/29 06:28:15 otto Exp $ */ +/* $OpenBSD: subr_disk.c,v 1.44 2007/06/01 19:06:28 krw Exp $ */ /* $NetBSD: subr_disk.c,v 1.17 1996/03/16 23:17:08 christos Exp $ */ /* @@ -187,22 +187,35 @@ dkcksum(struct disklabel *lp) void cvtdisklabelv1(struct disklabel *lp) { - int i; + struct __partitionv0 *v0pp = (struct __partitionv0 *)lp->d_partitions; + struct partition *pp = lp->d_partitions; + daddr64_t sz; + int i, oversion = lp->d_version; + + if (oversion == 0) { + lp->d_version = 1; + lp->d_secperunith = 0; + } - if (lp->d_version == 1) - return; + for (i = 0; i < MAXPARTITIONS; i++, pp++, v0pp++) { + if (oversion == 0) { + pp->p_fragblock = DISKLABELV1_FFS_FRAGBLOCK(v0pp-> + p_fsize, v0pp->p_frag); + pp->p_offseth = 0; + pp->p_sizeh = 0; + } - lp->d_version = 1; - lp->d_secperunith = 0; - for (i = 0; i < MAXPARTITIONS; i++) { - struct partition *pp = &lp->d_partitions[i]; - struct __partitionv0 *v0pp = (struct __partitionv0 *) - &lp->d_partitions[i]; - - pp->p_fragblock = DISKLABELV1_FFS_FRAGBLOCK(v0pp->p_fsize, - v0pp->p_frag); - pp->p_offseth = 0; - pp->p_sizeh = 0; + /* In a V1 label no partition extends past DL_SIZE(lp) - 1. */ + if (DL_POFFSET(pp) >= DL_DSIZE(lp)) { + pp->p_fstype = FS_UNUSED; + pp->p_offset = pp->p_offseth = 0; + pp->p_size = pp->p_sizeh = 0; + } else if ((DL_POFFSET(pp) + DL_PSIZE(pp)) > DL_DSIZE(lp)) { + pp->p_fstype = FS_UNUSED; + sz = DL_DSIZE(lp) - DL_POFFSET(pp); + pp->p_size = sz & 0xffffffff; + pp->p_sizeh = (sz >> 32) & 0xffff; + } } } |