From: krw Date: Wed, 21 Jul 2021 12:22:54 +0000 (+0000) Subject: Use a dedicated struct mbr to hold the GPT protective MBR, X-Git-Url: http://artulab.com/gitweb/?a=commitdiff_plain;h=dfcac45eea04e0ae341a9133ae665c0ebff6b943;p=openbsd Use a dedicated struct mbr to hold the GPT protective MBR, either the one read from disk or the default one created when initializing GPT. Simplifies logic, eliminates MBR_init_GPT() and demotes MBR_protective_mbr() to a helper function called from GPT_read(). Nuke an unused variable in passing. No intentional functional change. --- diff --git a/sbin/fdisk/cmd.c b/sbin/fdisk/cmd.c index bea508eb0b9..ea9754ce45b 100644 --- a/sbin/fdisk/cmd.c +++ b/sbin/fdisk/cmd.c @@ -1,4 +1,4 @@ -/* $OpenBSD: cmd.c,v 1.133 2021/07/19 19:23:50 krw Exp $ */ +/* $OpenBSD: cmd.c,v 1.134 2021/07/21 12:22:54 krw Exp $ */ /* * Copyright (c) 1997 Tobias Weingartner @@ -69,7 +69,6 @@ Xreinit(char *args, struct mbr *mbr) MBR_parse(&dos_mbr, mbr->mbr_lba_self, mbr->mbr_lba_firstembr, mbr); if (dogpt) { - MBR_init_GPT(mbr); GPT_init(GHANDGP); GPT_print("s", TERSE); } else { @@ -429,10 +428,7 @@ Xselect(char *args, struct mbr *mbr) int Xprint(char *args, struct mbr *mbr) { - int efi; - - efi = MBR_protective_mbr(mbr); - if (efi != -1 && letoh64(gh.gh_sig) == GPTSIGNATURE) + if (letoh64(gh.gh_sig) == GPTSIGNATURE) GPT_print(args, VERBOSE); else MBR_print(mbr, args); @@ -443,7 +439,7 @@ Xprint(char *args, struct mbr *mbr) int Xwrite(char *args, struct mbr *mbr) { - int efi, i, n; + int i, n; for (i = 0, n = 0; i < NDOSPART; i++) if (mbr->mbr_prt[i].prt_id == 0xA6) @@ -454,20 +450,18 @@ Xwrite(char *args, struct mbr *mbr) return CMD_CONT; } - printf("Writing MBR at offset %lld.\n", (long long)mbr->mbr_lba_self); - if (MBR_write(mbr) == -1) { - warn("error writing MBR"); - return CMD_CONT; - } - if (letoh64(gh.gh_sig) == GPTSIGNATURE) { printf("Writing GPT.\n"); - efi = MBR_protective_mbr(mbr); - if (efi == -1 || GPT_write() == -1) { + if (GPT_write() == -1) { warn("error writing GPT"); return CMD_CONT; } } else { + printf("Writing MBR at offset %lld.\n", (long long)mbr->mbr_lba_self); + if (MBR_write(mbr) == -1) { + warn("error writing MBR"); + return CMD_CONT; + } GPT_zap_headers(); } diff --git a/sbin/fdisk/fdisk.c b/sbin/fdisk/fdisk.c index efd9f79e63e..6e9887f2d9a 100644 --- a/sbin/fdisk/fdisk.c +++ b/sbin/fdisk/fdisk.c @@ -1,4 +1,4 @@ -/* $OpenBSD: fdisk.c,v 1.127 2021/07/19 19:46:20 krw Exp $ */ +/* $OpenBSD: fdisk.c,v 1.128 2021/07/21 12:22:54 krw Exp $ */ /* * Copyright (c) 1997 Tobias Weingartner @@ -163,22 +163,17 @@ main(int argc, char *argv[]) err(1, "pledge"); get_default_mbr(mbrfile, &initial_mbr); - error = MBR_read(0, 0, &mbr); - if (error) - errx(1, "Can't read MBR!"); query = NULL; if (A_flag) { if (GPT_read(ANYGPT)) errx(1, "-A requires a valid GPT"); else { - initial_mbr = mbr; /* Keep current MBR. */ GPT_init(GPONLY); query = "Do you wish to write new GPT?"; } } else if (i_flag) { if (g_flag) { - MBR_init_GPT(&initial_mbr); GPT_init(GHANDGP); query = "Do you wish to write new GPT?"; } else { @@ -187,6 +182,9 @@ main(int argc, char *argv[]) "partition table?"; } } else if (u_flag) { + error = MBR_read(0, 0, &mbr); + if (error) + errx(1, "Can't read MBR!"); memcpy(initial_mbr.mbr_prt, mbr.mbr_prt, sizeof(initial_mbr.mbr_prt)); query = "Do you wish to write new MBR?"; diff --git a/sbin/fdisk/gpt.c b/sbin/fdisk/gpt.c index 0252b7f83f7..779b18f5030 100644 --- a/sbin/fdisk/gpt.c +++ b/sbin/fdisk/gpt.c @@ -1,4 +1,4 @@ -/* $OpenBSD: gpt.c,v 1.46 2021/07/18 15:28:37 krw Exp $ */ +/* $OpenBSD: gpt.c,v 1.47 2021/07/21 12:22:54 krw Exp $ */ /* * Copyright (c) 2015 Markus Muller * Copyright (c) 2015 Kenneth R Westerback @@ -23,6 +23,7 @@ #include #include +#include #include #include #include @@ -40,6 +41,7 @@ #define DPRINTF(x...) #endif +struct mbr gmbr; struct gpt_header gh; struct gpt_partition gp[NGPTPARTITIONS]; @@ -52,6 +54,61 @@ int get_partition_table(void); int init_gh(void); int init_gp(const int); uint32_t crc32(const u_char *, const uint32_t); +int protective_mbr(const struct mbr *); +int gpt_chk_mbr(struct dos_partition *, uint64_t); + +/* + * Return the index into dp[] of the EFI GPT (0xEE) partition, or -1 if no such + * partition exists. + * + * Taken from kern/subr_disk.c. + * + */ +int +gpt_chk_mbr(struct dos_partition *dp, u_int64_t dsize) +{ + struct dos_partition *dp2; + int efi, eficnt, found, i; + uint32_t psize; + + found = efi = eficnt = 0; + for (dp2 = dp, i = 0; i < NDOSPART; i++, dp2++) { + if (dp2->dp_typ == DOSPTYP_UNUSED) + continue; + found++; + if (dp2->dp_typ != DOSPTYP_EFI) + continue; + if (letoh32(dp2->dp_start) != GPTSECTOR) + continue; + psize = letoh32(dp2->dp_size); + if (psize <= (dsize - GPTSECTOR) || psize == UINT32_MAX) { + efi = i; + eficnt++; + } + } + if (found == 1 && eficnt == 1) + return efi; + + return -1; +} + +int +protective_mbr(const struct mbr *mbr) +{ + struct dos_partition dp[NDOSPART], dos_partition; + int i; + + if (mbr->mbr_lba_self != 0) + return -1; + + for (i = 0; i < NDOSPART; i++) { + PRT_make(&mbr->mbr_prt[i], mbr->mbr_lba_self, mbr->mbr_lba_firstembr, + &dos_partition); + memcpy(&dp[i], &dos_partition, sizeof(dp[i])); + } + + return gpt_chk_mbr(dp, DL_GETDSIZE(&dl)); +} int get_header(const uint64_t sector) @@ -206,12 +263,11 @@ get_partition_table(void) int GPT_read(const int which) { - struct mbr mbr; int error; - error = MBR_read(0, 0, &mbr); + error = MBR_read(0, 0, &gmbr); if (error == 0) - error = MBR_protective_mbr(&mbr); + error = protective_mbr(&gmbr); if (error) goto done; @@ -237,6 +293,7 @@ GPT_read(const int which) done: if (error != 0) { /* No valid GPT found. Zap any artifacts. */ + memset(&gmbr, 0, sizeof(gmbr)); memset(&gh, 0, sizeof(gh)); memset(&gp, 0, sizeof(gp)); } @@ -395,6 +452,15 @@ init_gh(void) memcpy(&oldgh, &gh, sizeof(oldgh)); memset(&gh, 0, sizeof(gh)); + memset(&gmbr, 0, sizeof(gmbr)); + + /* XXX Do we need the boot code? UEFI spec & Apple says no. */ + memcpy(gmbr.mbr_code, initial_mbr.mbr_code, sizeof(gmbr.mbr_code)); + gmbr.mbr_prt[0].prt_id = DOSPTYP_EFI; + gmbr.mbr_prt[0].prt_bs = 1; + gmbr.mbr_prt[0].prt_ns = UINT32_MAX; + PRT_fix_CHS(&gmbr.mbr_prt[0]); + gmbr.mbr_signature = DOSMBR_SIGNATURE; needed = sizeof(gp) / secsize + 2; @@ -508,6 +574,8 @@ GPT_write(void) const int secsize = unit_types[SECTORS].ut_conversion; uint64_t altgh, altgp, prigh, prigp, gpbytes; + MBR_write(&gmbr); + /* * XXX Assume size of gp is multiple of sector size. */ diff --git a/sbin/fdisk/gpt.h b/sbin/fdisk/gpt.h index ada2b3356f7..e9a7007ae30 100644 --- a/sbin/fdisk/gpt.h +++ b/sbin/fdisk/gpt.h @@ -1,4 +1,4 @@ -/* $OpenBSD: gpt.h,v 1.17 2021/07/18 15:28:37 krw Exp $ */ +/* $OpenBSD: gpt.h,v 1.18 2021/07/21 12:22:54 krw Exp $ */ /* * Copyright (c) 2015 Markus Muller * Copyright (c) 2015 Kenneth R Westerback @@ -27,6 +27,7 @@ void GPT_print(const char *, const int); void GPT_print_part(const int, const char *, const int); void GPT_print_parthdr(const int); +extern struct mbr gmbr; extern struct gpt_header gh; extern struct gpt_partition gp[NGPTPARTITIONS]; diff --git a/sbin/fdisk/mbr.c b/sbin/fdisk/mbr.c index 3027c752d22..4aea7b7261b 100644 --- a/sbin/fdisk/mbr.c +++ b/sbin/fdisk/mbr.c @@ -1,4 +1,4 @@ -/* $OpenBSD: mbr.c,v 1.93 2021/07/19 23:24:54 krw Exp $ */ +/* $OpenBSD: mbr.c,v 1.94 2021/07/21 12:22:54 krw Exp $ */ /* * Copyright (c) 1997 Tobias Weingartner @@ -34,52 +34,13 @@ struct mbr initial_mbr; -static int gpt_chk_mbr(struct dos_partition *, uint64_t); - -int -MBR_protective_mbr(const struct mbr *mbr) -{ - struct dos_partition dp[NDOSPART], dos_partition; - int i; - - if (mbr->mbr_lba_self != 0) - return -1; - - for (i = 0; i < NDOSPART; i++) { - PRT_make(&mbr->mbr_prt[i], mbr->mbr_lba_self, mbr->mbr_lba_firstembr, - &dos_partition); - memcpy(&dp[i], &dos_partition, sizeof(dp[i])); - } - - return gpt_chk_mbr(dp, DL_GETDSIZE(&dl)); -} - -void -MBR_init_GPT(struct mbr *mbr) -{ - memset(&mbr->mbr_prt, 0, sizeof(mbr->mbr_prt)); - - /* Use whole disk, starting after MBR. - * - * Always set the partition size to UINT32_MAX (as MS does). EFI - * firmware has been encountered that lies in unpredictable ways - * about the size of the disk, thus making it impossible to boot - * such devices. - */ - mbr->mbr_prt[0].prt_id = DOSPTYP_EFI; - mbr->mbr_prt[0].prt_bs = 1; - mbr->mbr_prt[0].prt_ns = UINT32_MAX; - - /* Fix up start/length fields. */ - PRT_fix_CHS(&mbr->mbr_prt[0]); -} - void MBR_init(struct mbr *mbr) { uint64_t adj; daddr_t daddr; + memset(&gmbr, 0, sizeof(gmbr)); memset(&gh, 0, sizeof(gh)); memset(&gp, 0, sizeof(gp)); @@ -243,38 +204,3 @@ MBR_write(const struct mbr *mbr) return 0; } - -/* - * Return the index into dp[] of the EFI GPT (0xEE) partition, or -1 if no such - * partition exists. - * - * Taken from kern/subr_disk.c. - * - */ -int -gpt_chk_mbr(struct dos_partition *dp, u_int64_t dsize) -{ - struct dos_partition *dp2; - int efi, eficnt, found, i; - uint32_t psize; - - found = efi = eficnt = 0; - for (dp2 = dp, i = 0; i < NDOSPART; i++, dp2++) { - if (dp2->dp_typ == DOSPTYP_UNUSED) - continue; - found++; - if (dp2->dp_typ != DOSPTYP_EFI) - continue; - if (letoh32(dp2->dp_start) != GPTSECTOR) - continue; - psize = letoh32(dp2->dp_size); - if (psize <= (dsize - GPTSECTOR) || psize == UINT32_MAX) { - efi = i; - eficnt++; - } - } - if (found == 1 && eficnt == 1) - return efi; - - return -1; -} diff --git a/sbin/fdisk/mbr.h b/sbin/fdisk/mbr.h index 1a143c04869..532969989aa 100644 --- a/sbin/fdisk/mbr.h +++ b/sbin/fdisk/mbr.h @@ -1,4 +1,4 @@ -/* $OpenBSD: mbr.h,v 1.39 2021/07/19 19:30:35 krw Exp $ */ +/* $OpenBSD: mbr.h,v 1.40 2021/07/21 12:22:54 krw Exp $ */ /* * Copyright (c) 1997 Tobias Weingartner @@ -34,9 +34,7 @@ void MBR_parse(const struct dos_mbr *, const uint64_t, const uint64_t, struct mbr *); void MBR_make(const struct mbr *, struct dos_mbr *); void MBR_init(struct mbr *); -void MBR_init_GPT(struct mbr *); int MBR_read(const uint64_t, const uint64_t, struct mbr *); int MBR_write(const struct mbr *); -int MBR_protective_mbr(const struct mbr *); #endif /* _MBR_H */ diff --git a/sbin/fdisk/user.c b/sbin/fdisk/user.c index ae5d1ed75d3..94924c1f516 100644 --- a/sbin/fdisk/user.c +++ b/sbin/fdisk/user.c @@ -1,4 +1,4 @@ -/* $OpenBSD: user.c,v 1.66 2021/07/19 23:24:54 krw Exp $ */ +/* $OpenBSD: user.c,v 1.67 2021/07/21 12:22:54 krw Exp $ */ /* * Copyright (c) 1997 Tobias Weingartner @@ -62,7 +62,7 @@ USER_edit(const uint64_t lba_self, const uint64_t lba_firstembr) { struct mbr mbr; char *cmd, *args; - int i, st, efi, error; + int i, st, error; static int editlevel; /* One level deeper */