From 2de775601c70b5ce2bdcf4b3536b6cc3ffb4b7e4 Mon Sep 17 00:00:00 2001 From: krw Date: Thu, 28 Apr 2022 13:22:19 +0000 Subject: [PATCH] Convert the internal GPT partition entries into host-endian form on input/initialization and back to little-endian when writing to disk. Easier to read the code when letoh*() and uuid_[enc|dec]_* invocations are minimized. No intentional functional change. ok jmatthew@ --- sbin/fdisk/cmd.c | 28 ++++----- sbin/fdisk/gpt.c | 151 +++++++++++++++++++++++++++------------------- sbin/fdisk/part.c | 8 +-- 3 files changed, 104 insertions(+), 83 deletions(-) diff --git a/sbin/fdisk/cmd.c b/sbin/fdisk/cmd.c index c0a820f4fa6..712e57a94c9 100644 --- a/sbin/fdisk/cmd.c +++ b/sbin/fdisk/cmd.c @@ -1,4 +1,4 @@ -/* $OpenBSD: cmd.c,v 1.158 2022/04/24 12:13:37 krw Exp $ */ +/* $OpenBSD: cmd.c,v 1.159 2022/04/28 13:22:19 krw Exp $ */ /* * Copyright (c) 1997 Tobias Weingartner @@ -253,38 +253,32 @@ Xedit(char *args, struct mbr *mbr) int gsetpid(const int pn) { - struct uuid gp_type, gp_guid; uint32_t status; GPT_print_parthdr(TERSE); GPT_print_part(pn, "s", TERSE); - uuid_dec_le(&gp[pn].gp_type, &gp_type); - if (PRT_protected_guid(&gp_type)) { + if (PRT_protected_guid(&gp[pn].gp_type)) { printf("can't edit partition type %s\n", - PRT_uuid_to_typename(&gp_type)); + PRT_uuid_to_typename(&gp[pn].gp_type)); return -1; } - gp_type = *ask_uuid(&gp_type); - if (PRT_protected_guid(&gp_type)) { + gp[pn].gp_type = *ask_uuid(&gp[pn].gp_type); + if (PRT_protected_guid(&gp[pn].gp_type)) { printf("can't change partition type to %s\n", - PRT_uuid_to_typename(&gp_type)); + PRT_uuid_to_typename(&gp[pn].gp_type)); return -1; } - uuid_dec_le(&gp[pn].gp_guid, &gp_guid); - if (uuid_is_nil(&gp_guid, NULL)) { - uuid_create(&gp_guid, &status); + if (uuid_is_nil(&gp[pn].gp_guid, NULL)) { + uuid_create(&gp[pn].gp_guid, &status); if (status != uuid_s_ok) { printf("could not create guid for partition\n"); return -1; } } - uuid_enc_le(&gp[pn].gp_type, &gp_type); - uuid_enc_le(&gp[pn].gp_guid, &gp_guid); - return 0; } @@ -469,7 +463,7 @@ Xflag(char *args, struct mbr *mbr) return CMD_CONT; } if (gh.gh_sig == GPTSIGNATURE) - gp[pn].gp_attrs = htole64(val); + gp[pn].gp_attrs = val; else mbr->mbr_prt[pn].prt_flag = val; printf("Partition %d flag value set to 0x%llx.\n", pn, val); @@ -477,9 +471,9 @@ Xflag(char *args, struct mbr *mbr) if (gh.gh_sig == GPTSIGNATURE) { for (i = 0; i < gh.gh_part_num; i++) { if (i == pn) - gp[i].gp_attrs = htole64(GPTDOSACTIVE); + gp[i].gp_attrs = GPTDOSACTIVE; else - gp[i].gp_attrs = htole64(0); + gp[i].gp_attrs = 0; } } else { for (i = 0; i < NDOSPART; i++) { diff --git a/sbin/fdisk/gpt.c b/sbin/fdisk/gpt.c index ac693bc5494..8d4837c8bca 100644 --- a/sbin/fdisk/gpt.c +++ b/sbin/fdisk/gpt.c @@ -1,4 +1,4 @@ -/* $OpenBSD: gpt.c,v 1.75 2022/04/25 17:10:09 krw Exp $ */ +/* $OpenBSD: gpt.c,v 1.76 2022/04/28 13:22:19 krw Exp $ */ /* * Copyright (c) 2015 Markus Muller * Copyright (c) 2015 Kenneth R Westerback @@ -262,29 +262,48 @@ get_header(const uint64_t sector) int get_partition_table(void) { + struct gpt_partition *legp; uint64_t gpbytes; + unsigned int pn; + int rslt = -1; uint32_t gh_part_csum; DPRINTF("gpt partition table being read from LBA %llu\n", gh.gh_part_lba); gpbytes = gh.gh_part_num * gh.gh_part_size; - memset(&gp, 0, sizeof(gp)); - if (DISK_readbytes(&gp, gh.gh_part_lba, gpbytes)) - return -1; + legp = calloc(1, gpbytes); + if (legp == NULL) + err(1, "legp"); + + if (DISK_readbytes(legp, gh.gh_part_lba, gpbytes)) + goto done; + gh_part_csum = crc32((unsigned char *)legp, gpbytes); - gh_part_csum = gh.gh_part_csum; - gh.gh_part_csum = crc32((unsigned char *)&gp, gpbytes); if (gh_part_csum != gh.gh_part_csum) { DPRINTF("gpt partition table checksum: expected 0x%x, " "got 0x%x\n", gh.gh_part_csum, gh_part_csum); /* Accept wrong-endian checksum. */ if (swap32(gh_part_csum) != gh.gh_part_csum) - return -1; + goto done; } - return 0; + memset(&gp, 0, sizeof(gp)); + for (pn = 0; pn < gh.gh_part_num; pn++) { + uuid_dec_le(&legp[pn].gp_type, &gp[pn].gp_type); + uuid_dec_le(&legp[pn].gp_guid, &gp[pn].gp_guid); + gp[pn].gp_lba_start = letoh64(legp[pn].gp_lba_start); + gp[pn].gp_lba_end = letoh64(legp[pn].gp_lba_end); + gp[pn].gp_attrs = letoh64(legp[pn].gp_attrs); + memcpy(gp[pn].gp_name, legp[pn].gp_name, + sizeof(gp[pn].gp_name)); + } + rslt = 0; + + done: + free(legp); + return rslt; } int @@ -335,7 +354,7 @@ GPT_print(const char *units, const int verbosity) const int secsize = dl.d_secsize; char *guidstr = NULL; double size; - int i; + unsigned int i, pn; uint32_t status; #ifdef DEBUG @@ -392,10 +411,10 @@ GPT_print(const char *units, const int verbosity) } GPT_print_parthdr(verbosity); - for (i = 0; i < gh.gh_part_num; i++) { - if (uuid_is_nil(&gp[i].gp_type, NULL)) + for (pn = 0; pn < gh.gh_part_num; pn++) { + if (uuid_is_nil(&gp[pn].gp_type, NULL)) continue; - GPT_print_part(i, units, verbosity); + GPT_print_part(pn, units, verbosity); } } @@ -414,23 +433,20 @@ void GPT_print_part(const unsigned int pn, const char *units, const int verbosity) { const struct unit_type *ut; - struct uuid guid; char *guidstr = NULL; double size; uint64_t sectors; uint32_t status; - uuid_dec_le(&gp[pn].gp_type, &guid); - sectors = letoh64(gp[pn].gp_lba_end) - letoh64(gp[pn].gp_lba_start) + 1; + sectors = gp[pn].gp_lba_end - gp[pn].gp_lba_start + 1; size = units_size(units, sectors, &ut); printf("%c%3u: %-36s [%12lld: %12.0f%s]\n", - (letoh64(gp[pn].gp_attrs) & GPTDOSACTIVE) ? '*' : ' ', pn, - PRT_uuid_to_typename(&guid), letoh64(gp[pn].gp_lba_start), + gp[pn].gp_attrs & GPTDOSACTIVE ? '*' : ' ', pn, + PRT_uuid_to_typename(&gp[pn].gp_type), gp[pn].gp_lba_start, size, ut->ut_abbr); if (verbosity == VERBOSE) { - uuid_dec_le(&gp[pn].gp_guid, &guid); - uuid_to_string(&guid, &guidstr, &status); + uuid_to_string(&gp[pn].gp_guid, &guidstr, &status); if (status != uuid_s_ok) printf(" "); else @@ -443,14 +459,13 @@ GPT_print_part(const unsigned int pn, const char *units, const int verbosity) int find_partition(const uint8_t *beuuid) { - struct uuid uuid, gp_type; + struct uuid uuid; unsigned int pn; uuid_dec_be(beuuid, &uuid); - uuid_enc_le(&gp_type, &uuid); for (pn = 0; pn < gh.gh_part_num; pn++) { - if (uuid_compare(&gp[pn].gp_type, &gp_type, NULL) == 0) + if (uuid_compare(&gp[pn].gp_type, &uuid, NULL) == 0) return pn; } return -1; @@ -459,13 +474,12 @@ find_partition(const uint8_t *beuuid) int add_partition(const uint8_t *beuuid, const char *name, uint64_t sectors) { - struct uuid uuid, gp_type; + struct uuid uuid; int rslt; uint64_t end, freesectors, start; uint32_t status, pn; uuid_dec_be(beuuid, &uuid); - uuid_enc_le(&gp_type, &uuid); for (pn = 0; pn < gh.gh_part_num; pn++) { if (uuid_is_nil(&gp[pn].gp_type, NULL)) @@ -493,18 +507,14 @@ add_partition(const uint8_t *beuuid, const char *name, uint64_t sectors) else if (freesectors > sectors) end = start + sectors - 1; - gp[pn].gp_type = gp_type; - gp[pn].gp_lba_start = htole64(start); - gp[pn].gp_lba_end = htole64(end); + gp[pn].gp_type = uuid; + gp[pn].gp_lba_start = start; + gp[pn].gp_lba_end = end; string_to_name(pn, name); - uuid_create(&uuid, &status); - if (status != uuid_s_ok) - goto done; - - uuid_enc_le(&gp[pn].gp_guid, &uuid); - - return 0; + uuid_create(&gp[pn].gp_guid, &status); + if (status == uuid_s_ok) + return 0; done: if (pn != gh.gh_part_num) @@ -563,7 +573,6 @@ int init_gp(const int how) { struct gpt_partition oldgp[NGPTPARTITIONS]; - struct uuid gp_type; const uint8_t gpt_uuid_efi_system[] = GPT_UUID_EFI_SYSTEM; const uint8_t gpt_uuid_openbsd[] = GPT_UUID_OPENBSD; uint64_t prt_ns; @@ -574,8 +583,7 @@ init_gp(const int how) memset(&gp, 0, sizeof(gp)); else { for (pn = 0; pn < gh.gh_part_num; pn++) { - uuid_dec_le(&gp[pn].gp_type, &gp_type); - if (PRT_protected_guid(&gp_type)) + if (PRT_protected_guid(&gp[pn].gp_type)) continue; memset(&gp[pn], 0, sizeof(gp[pn])); } @@ -648,8 +656,11 @@ int GPT_write(void) { struct gpt_header legh; + struct gpt_partition *legp; uint64_t altgh, altgp; uint64_t gpbytes, gpsectors; + unsigned int pn; + int rslt = -1; if (MBR_write(&gmbr)) return -1; @@ -663,7 +674,6 @@ GPT_write(void) legh.gh_sig = htole64(GPTSIGNATURE); legh.gh_rev = htole32(GPTREVISION); legh.gh_size = htole32(GPTMINHDRSIZE); - legh.gh_csum = 0; legh.gh_rsvd = 0; legh.gh_lba_self = htole64(GPTSECTOR); legh.gh_lba_alt = htole64(altgh); @@ -673,12 +683,27 @@ GPT_write(void) legh.gh_part_lba = htole64(GPTSECTOR + 1); legh.gh_part_num = htole32(gh.gh_part_num); legh.gh_part_size = htole32(GPTMINPARTSIZE); - legh.gh_part_csum = htole32(crc32((unsigned char *)&gp, gpbytes)); + + legp = calloc(1, gpbytes); + if (legp == NULL) + err(1, "legp"); + + for (pn = 0; pn < gh.gh_part_num; pn++) { + uuid_enc_le(&legp[pn].gp_type, &gp[pn].gp_type); + uuid_enc_le(&legp[pn].gp_guid, &gp[pn].gp_guid); + legp[pn].gp_lba_start = htole64(gp[pn].gp_lba_start); + legp[pn].gp_lba_end = htole64(gp[pn].gp_lba_end); + legp[pn].gp_attrs = htole64(gp[pn].gp_attrs); + memcpy(legp[pn].gp_name, gp[pn].gp_name, + sizeof(legp[pn].gp_name)); + } + legh.gh_part_csum = htole32(crc32((unsigned char *)legp, gpbytes)); + legh.gh_csum = 0; legh.gh_csum = htole32(crc32((unsigned char *)&legh, gh.gh_size)); if (DISK_writebytes(&legh, GPTSECTOR, gh.gh_size) || - DISK_writebytes(&gp, GPTSECTOR + 1, gpbytes)) - return -1; + DISK_writebytes(legp, GPTSECTOR + 1, gpbytes)) + goto done; legh.gh_lba_self = htole64(altgh); legh.gh_lba_alt = htole64(GPTSECTOR); @@ -688,13 +713,16 @@ GPT_write(void) if (DISK_writebytes(&legh, altgh, gh.gh_size) || DISK_writebytes(&gp, altgp, gpbytes)) - return -1; + goto done; /* Refresh in-kernel disklabel from the updated disk information. */ if (ioctl(disk.dk_fd, DIOCRLDINFO, 0) == -1) warn("DIOCRLDINFO"); + rslt = 0; - return 0; + done: + free(legp); + return rslt; } int @@ -705,8 +733,8 @@ gp_lba_start_cmp(const void *e1, const void *e2) uint64_t o1; uint64_t o2; - o1 = letoh64(p1->gp_lba_start); - o2 = letoh64(p2->gp_lba_start); + o1 = p1->gp_lba_start; + o2 = p2->gp_lba_start; if (o1 < o2) return -1; @@ -720,18 +748,18 @@ struct gpt_partition ** sort_gpt(void) { static struct gpt_partition *sgp[NGPTPARTITIONS+2]; - unsigned int i, j; + unsigned int i, pn; memset(sgp, 0, sizeof(sgp)); - j = 0; - for (i = 0; i < gh.gh_part_num; i++) { - if (letoh64(gp[i].gp_lba_start) >= gh.gh_lba_start) - sgp[j++] = &gp[i]; + i = 0; + for (pn = 0; pn < gh.gh_part_num; pn++) { + if (gp[pn].gp_lba_start >= gh.gh_lba_start) + sgp[i++] = &gp[pn]; } - if (j > 1) { - if (mergesort(sgp, j, sizeof(sgp[0]), gp_lba_start_cmp) == -1) { + if (i > 1) { + if (mergesort(sgp, i, sizeof(sgp[0]), gp_lba_start_cmp) == -1) { printf("unable to sort gpt by lba start\n"); return NULL; } @@ -758,12 +786,12 @@ lba_free(uint64_t *start, uint64_t *end) bigbs = bs; ns = 0; for (i = 0; sgp[i] != NULL; i++) { - nextbs = letoh64(sgp[i]->gp_lba_start); + nextbs = sgp[i]->gp_lba_start; if (bs < nextbs && ns < nextbs - bs) { ns = nextbs - bs; bigbs = bs; } - bs = letoh64(sgp[i]->gp_lba_end) + 1; + bs = sgp[i]->gp_lba_end + 1; } nextbs = gh.gh_lba_end + 1; if (bs < nextbs && ns < nextbs - bs) { @@ -793,8 +821,8 @@ GPT_get_lba_start(const unsigned int pn) bs = gh.gh_lba_start; - if (letoh64(gp[pn].gp_lba_start) >= bs) { - bs = letoh64(gp[pn].gp_lba_start); + if (gp[pn].gp_lba_start >= bs) { + bs = gp[pn].gp_lba_start; } else { rslt = lba_free(&bs, NULL); if (rslt == -1) { @@ -807,15 +835,14 @@ GPT_get_lba_start(const unsigned int pn) for (i = 0; i < gh.gh_part_num; i++) { if (i == pn) continue; - if (bs >= letoh64(gp[i].gp_lba_start) && - bs <= letoh64(gp[i].gp_lba_end)) { + if (bs >= gp[i].gp_lba_start && bs <= gp[i].gp_lba_end) { printf("partition %u can't start inside partition %u\n", pn, i); return -1; } } - gp[pn].gp_lba_start = htole64(bs); + gp[pn].gp_lba_start = bs; return 0; } @@ -831,10 +858,10 @@ GPT_get_lba_end(const unsigned int pn) if (sgp == NULL) return -1; - bs = letoh64(gp[pn].gp_lba_start); + bs = gp[pn].gp_lba_start; ns = gh.gh_lba_end - bs + 1; for (i = 0; sgp[i] != NULL; i++) { - nextbs = letoh64(sgp[i]->gp_lba_start); + nextbs = sgp[i]->gp_lba_start; if (nextbs > bs) { ns = nextbs - bs; break; @@ -842,7 +869,7 @@ GPT_get_lba_end(const unsigned int pn) } ns = getuint64("Partition size", ns, 1, ns); - gp[pn].gp_lba_end = htole64(bs + ns - 1); + gp[pn].gp_lba_end = bs + ns - 1; return 0; } diff --git a/sbin/fdisk/part.c b/sbin/fdisk/part.c index 50671fa30a3..ca5f00712c2 100644 --- a/sbin/fdisk/part.c +++ b/sbin/fdisk/part.c @@ -1,4 +1,4 @@ -/* $OpenBSD: part.c,v 1.123 2022/04/18 17:32:16 krw Exp $ */ +/* $OpenBSD: part.c,v 1.124 2022/04/28 13:22:19 krw Exp $ */ /* * Copyright (c) 1997 Tobias Weingartner @@ -190,7 +190,7 @@ PRT_protected_guid(const struct uuid *uuid) char *efistr = NULL, *str = NULL; const char *typename; int rslt = 0; - unsigned int i; + unsigned int i, pn; uint32_t status; uuid_dec_be(gpt_uuid_efi_system, &uuid_efi_system); @@ -208,8 +208,8 @@ PRT_protected_guid(const struct uuid *uuid) if (strncmp(str, efistr, UUID_STR_LEN) == 0) { /* Look for partitions indicating a need to preserve EFI Sys */ - for (i = 0; i < gh.gh_part_num; i++) { - typename = PRT_uuid_to_typename(&gp[i].gp_type); + for (pn = 0; pn < gh.gh_part_num; pn++) { + typename = PRT_uuid_to_typename(&gp[pn].gp_type); if (strncmp(typename, "APFS ", 5)) continue; rslt = -1; -- 2.20.1