From 9619265f8ac53c7eff18236937a7b7673dc76cbf Mon Sep 17 00:00:00 2001 From: krw Date: Fri, 2 Sep 2022 14:18:47 +0000 Subject: [PATCH] Don't ignore an OpenBSD GPT partition just because the GPT says it extends beyond the edge of the disk the GPT currently inhabits. We only care if enough of it is addressable that a disklabel is accessible. Brings GPT handling of 'OpenBSD partitions extending too far' into line with the MBR handling of the same situation. --- sys/kern/subr_disk.c | 60 ++++++++++++++++++++++++-------------------- 1 file changed, 33 insertions(+), 27 deletions(-) diff --git a/sys/kern/subr_disk.c b/sys/kern/subr_disk.c index 5f06c010aec..483cd7cb95a 100644 --- a/sys/kern/subr_disk.c +++ b/sys/kern/subr_disk.c @@ -1,4 +1,4 @@ -/* $OpenBSD: subr_disk.c,v 1.257 2022/09/02 12:28:12 krw Exp $ */ +/* $OpenBSD: subr_disk.c,v 1.258 2022/09/02 14:18:47 krw Exp $ */ /* $NetBSD: subr_disk.c,v 1.17 1996/03/16 23:17:08 christos Exp $ */ /* @@ -590,17 +590,16 @@ int spoofgpt(struct buf *bp, void (*strat)(struct buf *), const uint8_t *dosbb, struct disklabel *lp, daddr_t *partoffp) { - static const uint8_t gpt_uuid_openbsd[] = GPT_UUID_OPENBSD; struct dos_partition dp[NDOSPART]; struct gpt_header gh; - struct uuid gptype, uuid_openbsd; + struct uuid gptype; struct gpt_partition *gp; struct partition *pp; - uint64_t lbaend, lbastart; + uint64_t lbaend, lbastart, labelsec; uint64_t gpbytes, end, start; - daddr_t labeloff, partoff; + daddr_t partoff; unsigned int i, n; - int error, obsdfound; + int error, fstype, obsdfound; uint32_t partnum; uint16_t sig; @@ -634,7 +633,6 @@ spoofgpt(struct buf *bp, void (*strat)(struct buf *), const uint8_t *dosbb, partnum = letoh32(gh.gh_part_num); n = 'i' - 'a'; /* Start spoofing at 'i', a.k.a. 8. */ - uuid_dec_be(gpt_uuid_openbsd, &uuid_openbsd); DL_SETBSTART(lp, lbastart); DL_SETBEND(lp, lbaend + 1); @@ -642,33 +640,41 @@ spoofgpt(struct buf *bp, void (*strat)(struct buf *), const uint8_t *dosbb, obsdfound = 0; for (i = 0; i < partnum; i++) { start = letoh64(gp[i].gp_lba_start); - end = letoh64(gp[i].gp_lba_end) + 1; - if (start >= end || start < lbastart || end > lbaend + 1) + if (start > lbaend || start < lbastart) + continue; + + end = letoh64(gp[i].gp_lba_end); + if (start > end) + continue; + + uuid_dec_le(&gp[i].gp_type, &gptype); + fstype = gpt_get_fstype(&gptype); + if (obsdfound && fstype == FS_BSDFFS) continue; - if (obsdfound == 0) { - labeloff = partoff + DOS_LABELSECTOR; - if (labeloff >= DL_SECTOBLK(lp, start) && - labeloff < DL_SECTOBLK(lp, end)) + + if (fstype == FS_BSDFFS) { + obsdfound = 1; + partoff = DL_SECTOBLK(lp, start); + labelsec = DL_BLKTOSEC(lp, partoff + DOS_LABELSECTOR); + if (labelsec > ((end < lbaend) ? end : lbaend)) partoff = -1; + DL_SETBSTART(lp, start); + DL_SETBEND(lp, end + 1); + continue; } - uuid_dec_le(&gp[i].gp_type, &gptype); - if (memcmp(&gptype, &uuid_openbsd, sizeof(gptype)) == 0) { - if (obsdfound == 0) { - obsdfound = 1; - partoff = DL_SECTOBLK(lp, start); - labeloff = partoff + DOS_LABELSECTOR; - if (labeloff >= DL_SECTOBLK(lp, end)) - partoff = -1; - DL_SETBSTART(lp, start); - DL_SETBEND(lp, end); - } - } else if (n < MAXPARTITIONS) { + if (partoff != -1) { + labelsec = DL_BLKTOSEC(lp, partoff + DOS_LABELSECTOR); + if (labelsec >= start && labelsec <= end) + partoff = -1; + } + + if (n < MAXPARTITIONS && end <= lbaend) { pp = &lp->d_partitions[n]; n++; - pp->p_fstype = gpt_get_fstype(&gptype); + pp->p_fstype = fstype; DL_SETPOFFSET(pp, start); - DL_SETPSIZE(pp, end - start); + DL_SETPSIZE(pp, end - start + 1); } } -- 2.20.1