-/* $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 $ */
/*
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;
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);
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);
}
}