Hi,

Currently vmd(8) has 3 processes that run under chroot(2)/chdir(2), namely
control, vmm and priv. From these both control and vmm already run under
different pledge(2)s but without any filesystem access, priv in the other hand
cannot use pledge due to forbidden ioctls.

That being said the priv proc can instead just run with an unveil("/", "") to
disable fs access, and while here remove the need of chroot/chdir dance since
it's not needed any longer.

I've been running this for more than a week now without issues. Any
comments/objections? OK?

/mestre

Index: priv.c
===================================================================
RCS file: /cvs/src/usr.sbin/vmd/priv.c,v
retrieving revision 1.15
diff -u -p -u -r1.15 priv.c
--- priv.c      28 Jun 2019 13:32:51 -0000      1.15
+++ priv.c      19 Aug 2019 09:38:51 -0000
@@ -66,8 +66,14 @@ priv_run(struct privsep *ps, struct priv
 
        /*
         * no pledge(2) in the "priv" process:
-        * write ioctls are not permitted by pledge.
+        * write ioctls are not permitted by pledge, but we can restrict fs
+        * access with unveil
         */
+       /* no filesystem visibility */
+       if (unveil("/", "") == -1)
+               fatal("unveil");
+       if (unveil(NULL, NULL) == -1)
+               fatal("unveil");
 
        /* Open our own socket for generic interface ioctls */
        if ((env->vmd_fd = socket(AF_INET, SOCK_DGRAM, 0)) == -1)
Index: proc.c
===================================================================
RCS file: /cvs/src/usr.sbin/vmd/proc.c,v
retrieving revision 1.18
diff -u -p -u -r1.18 proc.c
--- proc.c      10 Sep 2018 10:36:01 -0000      1.18
+++ proc.c      19 Aug 2019 09:38:51 -0000
@@ -524,7 +524,6 @@ proc_run(struct privsep *ps, struct priv
     void (*run)(struct privsep *, struct privsep_proc *, void *), void *arg)
 {
        struct passwd           *pw;
-       const char              *root;
        struct control_sock     *rcs;
 
        log_procinit(p->p_title);
@@ -545,17 +544,6 @@ proc_run(struct privsep *ps, struct priv
                pw = p->p_pw;
        else
                pw = ps->ps_pw;
-
-       /* Change root directory */
-       if (p->p_chroot != NULL)
-               root = p->p_chroot;
-       else
-               root = pw->pw_dir;
-
-       if (chroot(root) == -1)
-               fatal("%s: chroot", __func__);
-       if (chdir("/") == -1)
-               fatal("%s: chdir(\"/\")", __func__);
 
        privsep_process = p->p_id;
 
Index: proc.h
===================================================================
RCS file: /cvs/src/usr.sbin/vmd/proc.h,v
retrieving revision 1.16
diff -u -p -u -r1.16 proc.h
--- proc.h      10 Sep 2018 10:36:01 -0000      1.16
+++ proc.h      19 Aug 2019 09:38:51 -0000
@@ -136,7 +136,6 @@ struct privsep_proc {
        void                    (*p_init)(struct privsep *,
                                    struct privsep_proc *);
        void                    (*p_shutdown)(void);
-       const char              *p_chroot;
        struct passwd           *p_pw;
        struct privsep          *p_ps;
 };
Index: vmd.c
===================================================================
RCS file: /cvs/src/usr.sbin/vmd/vmd.c,v
retrieving revision 1.115
diff -u -p -u -r1.115 vmd.c
--- vmd.c       14 Aug 2019 07:34:49 -0000      1.115
+++ vmd.c       19 Aug 2019 09:38:51 -0000
@@ -789,9 +789,8 @@ main(int argc, char **argv)
        if ((ps->ps_pw = getpwnam(VMD_USER)) == NULL)
                fatal("unknown user %s", VMD_USER);
 
-       /* First proc runs as root without pledge but in default chroot */
+       /* First proc runs as root without pledge but with unveil */
        proc_priv->p_pw = &proc_privpw; /* initialized to all 0 */
-       proc_priv->p_chroot = ps->ps_pw->pw_dir; /* from VMD_USER */
 
        /* Open /dev/vmm */
        if (env->vmd_noaction == 0) {
Index: vmm.c
===================================================================
RCS file: /cvs/src/usr.sbin/vmd/vmm.c,v
retrieving revision 1.93
diff -u -p -u -r1.93 vmm.c
--- vmm.c       28 Jun 2019 13:32:51 -0000      1.93
+++ vmm.c       19 Aug 2019 09:38:51 -0000
@@ -655,7 +655,7 @@ vmm_start_vm(struct imsg *imsg, uint32_t
        if (socketpair(AF_UNIX, SOCK_STREAM, PF_UNSPEC, fds) == -1)
                fatal("socketpair");
 
-       /* Start child vmd for this VM (fork, chroot, drop privs) */
+       /* Start child vmd for this VM (fork, drop privs) */
        ret = fork();
 
        /* Start child failed? - cleanup and leave */

Reply via email to