Add another epicycle to -A processing that ensures ONLY the
authorkrw <krw@openbsd.org>
Mon, 28 Jun 2021 19:50:30 +0000 (19:50 +0000)
committerkrw <krw@openbsd.org>
Mon, 28 Jun 2021 19:50:30 +0000 (19:50 +0000)
partition table is changed. Not the GPT header. Not the MBR. And
only write back as much partition table information as the header
claims to have room for.

At a minimum should make -A safer when operating on the Apple M1
GPT.

A major overhaul of this code is urgently needed before someone
sneezes too hard in its vicinity.

Feedback kettenis@ & ok deraadt@

sbin/fdisk/cmd.c
sbin/fdisk/fdisk.c
sbin/fdisk/gpt.c
sbin/fdisk/gpt.h

index 777e48b..76701b1 100644 (file)
@@ -1,4 +1,4 @@
-/*     $OpenBSD: cmd.c,v 1.117 2021/06/21 02:05:30 krw Exp $   */
+/*     $OpenBSD: cmd.c,v 1.118 2021/06/28 19:50:30 krw Exp $   */
 
 /*
  * Copyright (c) 1997 Tobias Weingartner
@@ -63,7 +63,7 @@ Xreinit(char *args, struct mbr *mbr)
 
        if (dogpt) {
                MBR_init_GPT(mbr);
-               GPT_init();
+               GPT_init(GHANDGP, 0);
                GPT_print("s", TERSE);
        } else {
                memset(&gh, 0, sizeof(gh));
index b1f3870..59a43da 100644 (file)
@@ -1,4 +1,4 @@
-/*     $OpenBSD: fdisk.c,v 1.113 2021/06/25 19:24:53 krw Exp $ */
+/*     $OpenBSD: fdisk.c,v 1.114 2021/06/28 19:50:30 krw Exp $ */
 
 /*
  * Copyright (c) 1997 Tobias Weingartner
@@ -222,14 +222,14 @@ main(int argc, char *argv[])
                if (letoh64(gh.gh_sig) != GPTSIGNATURE)
                        errx(1, "-A requires a valid GPT");
                else {
-                       MBR_init_GPT(&initial_mbr);
-                       GPT_init();
+                       initial_mbr = mbr;      /* Keep current MBR. */
+                       GPT_init(GPONLY, b_sectors);
                        query = "Do you wish to write new GPT?";
                }
        } else if (i_flag) {
                if (g_flag) {
                        MBR_init_GPT(&initial_mbr);
-                       GPT_init();
+                       GPT_init(GHANDGP, b_sectors);
                        query = "Do you wish to write new GPT?";
                } else {
                        memset(&gh, 0, sizeof(gh));
index 83e5201..df8b0f2 100644 (file)
@@ -1,4 +1,4 @@
-/*     $OpenBSD: gpt.c,v 1.33 2021/06/25 19:24:53 krw Exp $    */
+/*     $OpenBSD: gpt.c,v 1.34 2021/06/28 19:50:30 krw Exp $    */
 /*
  * Copyright (c) 2015 Markus Muller <mmu@grummel.net>
  * Copyright (c) 2015 Kenneth R Westerback <krw@openbsd.org>
@@ -49,7 +49,7 @@ int                     add_partition(const uint8_t *, const char *, uint64_t);
 int                      get_header(off_t);
 int                      get_partition_table(void);
 int                      init_gh(void);
-int                      init_gp(void);
+int                      init_gp(int, uint32_t);
 
 int
 get_header(off_t where)
@@ -413,17 +413,15 @@ init_gh(void)
 }
 
 int
-init_gp(void)
+init_gp(int how, uint32_t bootsectors)
 {
-       extern uint32_t b_sectors;
-       extern int A_flag;
        const uint8_t gpt_uuid_efi_system[] = GPT_UUID_EFI_SYSTEM;
        const uint8_t gpt_uuid_openbsd[] = GPT_UUID_OPENBSD;
        struct gpt_partition oldgp[NGPTPARTITIONS];
        int pn, rslt;
 
        memcpy(&oldgp, &gp, sizeof(oldgp));
-       if (A_flag == 0)
+       if (how == GHANDGP)
                memset(&gp, 0, sizeof(gp));
        else {
                for (pn = 0; pn < NGPTPARTITIONS; pn++) {
@@ -434,9 +432,9 @@ init_gp(void)
        }
 
        rslt = 0;
-       if (b_sectors > 0) {
+       if (bootsectors > 0) {
                rslt = add_partition(gpt_uuid_efi_system, "EFI System Area",
-                   b_sectors);
+                   bootsectors);
        }
        if (rslt == 0)
                rslt = add_partition(gpt_uuid_openbsd, "OpenBSD Area", 0);
@@ -448,13 +446,14 @@ init_gp(void)
 }
 
 int
-GPT_init(void)
+GPT_init(int how, uint32_t bootsectors)
 {
-       int rslt;
+       int rslt = 0;
 
-       rslt = init_gh();
+       if (how == GHANDGP)
+               rslt = init_gh();
        if (rslt == 0)
-               rslt = init_gp();
+               rslt = init_gp(how, bootsectors);
 
        return rslt;
 }
@@ -498,10 +497,9 @@ GPT_write(void)
        uint64_t altgh, altgp, prigh, prigp, gpbytes;
 
        /*
-        * XXX Assume we always write full-size partition table.
         * XXX Assume size of gp is multiple of sector size.
         */
-       gpbytes = sizeof(gp);
+       gpbytes = letoh64(gh.gh_part_num) * letoh64(gh.gh_part_size);
 
        prigh = GPTSECTOR;
        prigp = prigh + 1;
index f349b81..69531c0 100644 (file)
@@ -1,4 +1,4 @@
-/*     $OpenBSD: gpt.h,v 1.12 2021/06/16 15:40:47 krw Exp $    */
+/*     $OpenBSD: gpt.h,v 1.13 2021/06/28 19:50:30 krw Exp $    */
 /*
  * Copyright (c) 2015 Markus Muller <mmu@grummel.net>
  * Copyright (c) 2015 Kenneth R Westerback <krw@openbsd.org>
@@ -20,7 +20,7 @@ void          GPT_read(int);
 int            GPT_get_lba_start(unsigned int);
 int            GPT_get_lba_end(unsigned int);
 
-int            GPT_init(void);
+int            GPT_init(int, uint32_t);
 int            GPT_write(void);
 void           GPT_zap_headers(void);
 void           GPT_print(char *, int);
@@ -36,3 +36,6 @@ extern struct gpt_partition gp[NGPTPARTITIONS];
 
 #define        TERSE           0
 #define        VERBOSE         1
+
+#define        GHANDGP         0
+#define        GPONLY          1