Hi,

chpass(1) without parameters enters in edit mode by default, in here it will
need to execute _PATH_BSHELL to spawn a new EDITOR, _PATH_SHELLS to check
(read) if we are changing from/to a non-standard shell (in case we are not
root) and read access to `tempname' to verify if the file has valid entries and
create to unlink it.

If -s is used to change a user's shell then it will need read access to
_PATH_SHELLS by the same reason already mentioned above.

Unconditionally we need to unveil _PATH_MASTERPASSWD_LOCK with write/create
permissions, _PATH_MASTERPASSWD with read and _PATH_PWD_MKDB to execute
pwd_mkdb(8).

In the -a case I'm not unveiling /etc/spwd.db since we can get it through
pledge "getpw", which can be added for completeness of all code paths.
Note also that the first pledges need "unveil" since we will call unveil(2)
afterwards.

Tested all paths successfully with a test account. Comments? OK?

Index: chpass.c
===================================================================
RCS file: /cvs/src/usr.bin/chpass/chpass.c,v
retrieving revision 1.44
diff -u -p -u -r1.44 chpass.c
--- chpass.c    8 Dec 2017 17:04:15 -0000       1.44
+++ chpass.c    7 Nov 2018 12:50:07 -0000
@@ -136,7 +136,13 @@ main(int argc, char *argv[])
                        pw_error(tempname, 1, 1);
                display(tempname, dfd, pw);
 
-               if (pledge("stdio rpath wpath cpath id proc exec",
+               if (unveil(_PATH_BSHELL, "x") == -1)
+                       err(1, "unveil");
+               if (unveil(_PATH_SHELLS, "r") == -1)
+                       err(1, "unveil");
+               if (unveil(tempname, "rc") == -1)
+                       err(1, "unveil");
+               if (pledge("stdio rpath wpath cpath id proc exec unveil",
                    NULL) == -1)
                        err(1, "pledge");
 
@@ -158,7 +164,9 @@ main(int argc, char *argv[])
        }
 
        if (op == NEWSH) {
-               if (pledge("stdio rpath wpath cpath id proc exec",
+               if (unveil(_PATH_SHELLS, "r") == -1)
+                       err(1, "unveil");
+               if (pledge("stdio rpath wpath cpath id proc exec unveil",
                    NULL) == -1)
                        err(1, "pledge");
 
@@ -175,6 +183,12 @@ main(int argc, char *argv[])
        sigdelset(&fullset, SIGINT);
        sigprocmask(SIG_BLOCK, &fullset, NULL);
 
+       if (unveil(_PATH_MASTERPASSWD_LOCK, "wc") == -1)
+               err(1, "unveil");
+       if (unveil(_PATH_MASTERPASSWD, "r") == -1)
+               err(1, "unveil");
+       if (unveil(_PATH_PWD_MKDB, "x") == -1)
+               err(1, "unveil");
        if (pledge("stdio rpath wpath cpath proc exec", NULL) == -1)
                err(1, "pledge");
 

Reply via email to