From fb46e3f564238bbc25c79e1509ce9b3484d74b33 Mon Sep 17 00:00:00 2001 From: Kenneth R Westerback Date: Fri, 1 Jun 2007 19:06:29 +0000 Subject: 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@ --- sys/kern/subr_disk.c | 43 ++++++++++++++++++++++++++++--------------- 1 file changed, 28 insertions(+), 15 deletions(-) (limited to 'sys/kern/subr_disk.c') 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; + } } } -- cgit v1.2.3