summaryrefslogtreecommitdiff
path: root/sys/kern/subr_disk.c
diff options
context:
space:
mode:
authorKenneth R Westerback <krw@cvs.openbsd.org>2007-06-01 19:06:29 +0000
committerKenneth R Westerback <krw@cvs.openbsd.org>2007-06-01 19:06:29 +0000
commitfb46e3f564238bbc25c79e1509ce9b3484d74b33 (patch)
tree5b3399adfc0f990def4b01895bd447ecfeba06eb /sys/kern/subr_disk.c
parent6e2aa073e26eb6ab28c050459f6dedc66ca5d167 (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@
Diffstat (limited to 'sys/kern/subr_disk.c')
-rw-r--r--sys/kern/subr_disk.c43
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;
+ }
}
}