Fix readdpmelabel() so it doesn't corrupt a disklabel about to be
authorkrw <krw@openbsd.org>
Sun, 24 Aug 2008 12:56:17 +0000 (12:56 +0000)
committerkrw <krw@openbsd.org>
Sun, 24 Aug 2008 12:56:17 +0000 (12:56 +0000)
written (i.e. partoff != NULL), and doesn't corrupt a disklabel
with more than eight (8) dpme partitions.

Problems reported by Josh Elsasser via PR#5904. Testing by Josh,
otto@, drahn@, maja@, kettenis@. Most of the diff from otto@.

ok drahn@

sys/arch/macppc/macppc/disksubr.c
sys/arch/socppc/socppc/disksubr.c

index a43f121..c0b3769 100644 (file)
@@ -1,4 +1,4 @@
-/*     $OpenBSD: disksubr.c,v 1.60 2008/06/12 06:58:36 deraadt Exp $   */
+/*     $OpenBSD: disksubr.c,v 1.61 2008/08/24 12:56:17 krw Exp $       */
 /*     $NetBSD: disksubr.c,v 1.21 1996/05/03 19:42:03 christos Exp $   */
 
 /*
@@ -108,6 +108,9 @@ readdpmelabel(struct buf *bp, void (*strat)(struct buf *),
        int i, part_cnt, n, hfspartoff = -1;
        struct part_map_entry *part;
 
+       if (partoffp)
+               *partoffp = hfspartoff;
+
        /* First check for a DPME (HFS) disklabel */
        bp->b_blkno = 1;
        bp->b_bcount = lp->d_secsize;
@@ -122,9 +125,9 @@ readdpmelabel(struct buf *bp, void (*strat)(struct buf *),
        if (part->pmSig != PART_ENTRY_MAGIC)
                return ("not a DPMI partition");
        part_cnt = part->pmMapBlkCnt;
-       n = 0;
+       n = 8;
        for (i = 0; i < part_cnt; i++) {
-               struct partition *pp = &lp->d_partitions[8+n];
+               struct partition *pp;
                char *s;
 
                bp->b_blkno = 1+i;
@@ -140,24 +143,31 @@ readdpmelabel(struct buf *bp, void (*strat)(struct buf *),
                        if ((*s >= 'a') && (*s <= 'z'))
                                *s = (*s - 'a' + 'A');
 
-               if (strcmp(part->pmPartType, PART_TYPE_OPENBSD) == 0)
+               if (strcmp(part->pmPartType, PART_TYPE_OPENBSD) == 0) {
                        hfspartoff = part->pmPyPartStart - LABELSECTOR;
+                       if (partoffp) {
+                               *partoffp = hfspartoff;
+                               return (NULL);
+                       }
+                       continue;
+               }
+
+               if (n >= MAXPARTITIONS || partoffp)
+                       continue;
 
-               /* currently we ignore all but HFS partitions */
+               /* Currently we spoof HFS partitions only. */
                if (strcmp(part->pmPartType, PART_TYPE_MAC) == 0) {
+                       pp = &lp->d_partitions[n];
                        DL_SETPOFFSET(pp, part->pmPyPartStart);
                        DL_SETPSIZE(pp, part->pmPartBlkCnt);
                        pp->p_fstype = FS_HFS;
                        n++;
                }
        }
-       lp->d_npartitions = MAXPARTITIONS;
-
        if (hfspartoff == -1)
-               return ("no OpenBSD parition inside DPME label");
+               return ("no OpenBSD partition inside DPME label");
 
-       if (partoffp)
-               *partoffp = hfspartoff;
+       lp->d_npartitions = MAXPARTITIONS;
 
        if (spoofonly)
                return (NULL);
index 3a1ee2c..7cba2a8 100644 (file)
@@ -1,4 +1,4 @@
-/*     $OpenBSD: disksubr.c,v 1.4 2008/06/12 06:58:36 deraadt Exp $    */
+/*     $OpenBSD: disksubr.c,v 1.5 2008/08/24 12:56:17 krw Exp $        */
 /*     $NetBSD: disksubr.c,v 1.21 1996/05/03 19:42:03 christos Exp $   */
 
 /*
@@ -108,6 +108,9 @@ readdpmelabel(struct buf *bp, void (*strat)(struct buf *),
        int i, part_cnt, n, hfspartoff = -1;
        struct part_map_entry *part;
 
+       if (partoffp)
+               *partoffp = hfspartoff;
+
        /* First check for a DPME (HFS) disklabel */
        bp->b_blkno = 1;
        bp->b_bcount = lp->d_secsize;
@@ -122,9 +125,9 @@ readdpmelabel(struct buf *bp, void (*strat)(struct buf *),
        if (part->pmSig != PART_ENTRY_MAGIC)
                return ("not a DPMI partition");
        part_cnt = part->pmMapBlkCnt;
-       n = 0;
+       n = 8;
        for (i = 0; i < part_cnt; i++) {
-               struct partition *pp = &lp->d_partitions[8+n];
+               struct partition *pp;
                char *s;
 
                bp->b_blkno = 1+i;
@@ -140,24 +143,31 @@ readdpmelabel(struct buf *bp, void (*strat)(struct buf *),
                        if ((*s >= 'a') && (*s <= 'z'))
                                *s = (*s - 'a' + 'A');
 
-               if (strcmp(part->pmPartType, PART_TYPE_OPENBSD) == 0)
+               if (strcmp(part->pmPartType, PART_TYPE_OPENBSD) == 0) {
                        hfspartoff = part->pmPyPartStart - LABELSECTOR;
+                       if (partoffp) {
+                               *partoffp = hfspartoff;
+                               return (NULL);
+                       }
+                       continue;
+               }
+
+               if (n >= MAXPARTITIONS || partoffp)
+                       continue;
 
-               /* currently we ignore all but HFS partitions */
+               /* Currently we spoof HFS partitions only. */
                if (strcmp(part->pmPartType, PART_TYPE_MAC) == 0) {
+                       pp = &lp->d_partitions[n];
                        DL_SETPOFFSET(pp, part->pmPyPartStart);
                        DL_SETPSIZE(pp, part->pmPartBlkCnt);
                        pp->p_fstype = FS_HFS;
                        n++;
                }
        }
-       lp->d_npartitions = MAXPARTITIONS;
-
        if (hfspartoff == -1)
-               return ("no OpenBSD parition inside DPME label");
+               return ("no OpenBSD partition inside DPME label");
 
-       if (partoffp)
-               *partoffp = hfspartoff;
+       lp->d_npartitions = MAXPARTITIONS;
 
        if (spoofonly)
                return (NULL);