Yesterday's code shuffling in disklabel(8) left behind a bit of a mess.

It also changed behavior of 'disklabel sd1' for non-root users
(previously you could print the disklabel without being root, now you
get EPERM).

There still is the breakage due to insufficient checks on the file
before pledging:

$ ktrace disklabel /dev/tty
Abort trap (core dumped)
$ kdump | tail
 94670 disklabel CALL  open(0x5c312b45620,0x2<O_RDWR>)
 94670 disklabel NAMI  "/dev/tty"
 94670 disklabel RET   open 3
 94670 disklabel CALL  pledge(0x5c312838423,0)
 94670 disklabel STRU  pledge promise="stdio rpath wpath disklabel"
 94670 disklabel RET   pledge 0
 94670 disklabel CALL  ioctl(3,DIOCGDINFO,0x5c312b4c180)
 94670 disklabel PLDG  ioctl, "ioctl", errno 1 Operation not permitted
 94670 disklabel PSIG  SIGABRT SIG_DFL
 94670 disklabel NAMI  "disklabel.core"

This patch reverts the change of behavior, cleans up the logic before
pledge a bit and fixes the pledge fallout. It's based on Bob's patch
that was backed out, but also covers the write flag.

Tested on amd64 with 'make release', installing the release on an usb
stick and messing about with the disklabel on that stick.

Index: disklabel.c
===================================================================
RCS file: /var/cvs/src/sbin/disklabel/disklabel.c,v
retrieving revision 1.218
diff -u -p -r1.218 disklabel.c
--- disklabel.c 28 May 2016 23:38:30 -0000      1.218
+++ disklabel.c 29 May 2016 07:28:40 -0000
@@ -174,7 +174,7 @@ main(int argc, char *argv[])
                        if (strchr("bckmgtBCKMGT", optarg[0]) == NULL ||
                            optarg[1] != '\0') {
                                fprintf(stderr, "Valid units are bckmgt\n");
-                               exit(1);
+                               return 1;
                        }
                        print_unit = tolower((unsigned char)optarg[0]);
                        break;
@@ -191,6 +191,13 @@ main(int argc, char *argv[])
        argc -= optind;
        argv += optind;
 
+       if (op == UNSPEC)
+               op = READ;
+
+       if (argc < 1 || (fstabfile && !(op == EDITOR || op == RESTORE ||
+                   aflag)))
+               usage();
+
        if (argv[0] == NULL)
                usage();
        dkname = argv[0];
@@ -199,6 +206,13 @@ main(int argc, char *argv[])
        if (f < 0)
                err(4, "%s", specname);
 
+       if (op != WRITE || aflag || dflag)
+               readlabel(f);
+       else if (argc == 2 || argc == 3)
+               makelabel(argv[1], argc == 3 ? argv[2] : NULL, &lab);
+       else
+               usage();
+
        if (op == EDIT || op == EDITOR || aflag) {
                if (pledge("stdio rpath wpath cpath disklabel proc exec", NULL) 
== -1)
                        err(1, "pledge");
@@ -207,13 +221,6 @@ main(int argc, char *argv[])
                        err(1, "pledge");
        }
 
-       if (op == UNSPEC)
-               op = READ;
-
-       if (argc < 1 || (fstabfile && !(op == EDITOR || op == RESTORE ||
-                   aflag)))
-               usage();
-
        if (autotable != NULL)
                parse_autotable(autotable);
 
@@ -221,19 +228,16 @@ main(int argc, char *argv[])
        case EDIT:
                if (argc != 1)
                        usage();
-               readlabel(f);
                error = edit(&lab, f);
                break;
        case EDITOR:
                if (argc != 1)
                        usage();
-               readlabel(f);
                error = editor(f);
                break;
        case READ:
                if (argc != 1)
                        usage();
-               readlabel(f);
 
                if (pledge("stdio", NULL) == -1)
                        err(1, "pledge");
@@ -247,7 +251,6 @@ main(int argc, char *argv[])
        case RESTORE:
                if (argc < 2 || argc > 3)
                        usage();
-               readlabel(f);
                if (!(t = fopen(argv[1], "r")))
                        err(4, "%s", argv[1]);
                error = getasciilabel(t, &lab);
@@ -263,12 +266,6 @@ main(int argc, char *argv[])
                fclose(t);
                break;
        case WRITE:
-               if (dflag || aflag) {
-                       readlabel(f);
-               } else if (argc < 2 || argc > 3)
-                       usage();
-               else
-                       makelabel(argv[1], argc == 3 ? argv[2] : NULL, &lab);
                error = checklabel(&lab);
                if (error == 0)
                        error = writelabel(f, &lab);
@@ -276,7 +273,7 @@ main(int argc, char *argv[])
        default:
                break;
        }
-       exit(error);
+       return error;
 }
 
 /*

Reply via email to