> If you try to run disklabel(8) on a file that is not a device, it aborts
> aborts for want of pledge("ioctl"). This diff prints an error message
> and exits cleanly. I return exit code 1 but note that sometimes
> disklabel returns 4; the man page doesn't explain the distinction
> anywhere.
> 
>   $ disklabel /
>   Abort trap (core dumped)
>   $ obj/disklabel /
>   disklabel: / is not a device

Indeed your diff is also needed on top of mine.  Let's try this.

Index: disklabel.c
===================================================================
RCS file: /cvs/src/sbin/disklabel/disklabel.c,v
retrieving revision 1.214
diff -u -p -u -r1.214 disklabel.c
--- disklabel.c 25 Nov 2015 17:17:38 -0000      1.214
+++ disklabel.c 28 May 2016 15:30:27 -0000
@@ -119,6 +119,7 @@ main(int argc, char *argv[])
        int ch, f, error = 0;
        FILE *t;
        char *autotable = NULL;
+       struct stat st;
 
        getphysmem();
 
@@ -191,14 +192,6 @@ main(int argc, char *argv[])
        argc -= optind;
        argv += optind;
 
-       if (op == EDIT || op == EDITOR || aflag) {
-               if (pledge("stdio rpath wpath cpath disklabel proc exec", NULL) 
== -1)
-                       err(1, "pledge");
-       } else {
-               if (pledge("stdio rpath wpath disklabel", NULL) == -1)
-                       err(1, "pledge");
-       }
-
        if (op == UNSPEC)
                op = READ;
 
@@ -211,6 +204,18 @@ main(int argc, char *argv[])
            &specname);
        if (f < 0)
                err(4, "%s", specname);
+       if (fstat(f, &st) == -1)
+               errx(1, "fstat");
+       if (!S_ISBLK(st.st_mode) && !S_ISCHR(st.st_mode))
+               errx(1, "%s is not a device", dkname);
+
+       if (op == EDIT || op == EDITOR || aflag) {
+               if (pledge("stdio rpath wpath cpath disklabel proc exec", NULL) 
== -1)
+                       err(1, "pledge");
+       } else {
+               if (pledge("stdio rpath wpath disklabel", NULL) == -1)
+                       err(1, "pledge");
+       }
 
        if (autotable != NULL)
                parse_autotable(autotable);

Reply via email to