"Theo de Raadt" <[email protected]> writes:

> It might be better for vmd to open a fd to /dev/null early on,
> probably with O_CLOEXEC, and dup() it when it needs it in low-down code.

Here's an implementation.

The "vmm" process optionally opens /dev/null if we're *not* running in
"debug" mode (foreground) and opens it once early. Sets FD_CLOEXEC on
it. dup2 is done against that fd if needed like before.

Added benefit is we no longer open(2) /dev/null for every vm created.

-dv


diff refs/heads/master refs/heads/vmd-pledge
commit - f0fb81d370539aeb26fe6a527b3437ebad8ce8b4
commit + a0e53622ad39fd21b68c339a185aafaad04fe362
blob - 31120d064d64b5ca0a2b4570bc06662ad2d35b23
blob + bcac0d536ce1a8630d69dce3dcb53948dea189a4
--- usr.sbin/vmd/vmm.c
+++ usr.sbin/vmd/vmm.c
@@ -49,6 +49,7 @@ int   terminate_vm(struct vm_terminate_params *);
 int    get_info_vm(struct privsep *, struct imsg *, int);
 int    opentap(char *);

+int    dev_null = -1;
 extern struct vmd *env;

 static struct privsep_proc procs[] = {
@@ -68,6 +69,18 @@ vmm_run(struct privsep *ps, struct privsep_proc *p, vo
                fatal("failed to initialize configuration");

        /*
+        * Early-open /dev/null so we can dup2(2) std{in,out,err}
+        * after forking to create child processes.
+        */
+       if (!env->vmd_debug) {
+               dev_null = open("/dev/null", O_RDWR, 0);
+               if (dev_null == -1)
+                       fatal("/dev/null");
+               if (fcntl(dev_null, F_SETFD, FD_CLOEXEC) == -1)
+                       fatal("fcntl /dev/null");
+       }
+
+       /*
         * We aren't root, so we can't chroot(2). Use unveil(2) instead.
         */
        if (unveil(env->argv0, "x") == -1)
@@ -589,7 +602,7 @@ vmm_start_vm(struct imsg *imsg, uint32_t *id, pid_t *p
 {
        struct vmd_vm           *vm;
        char                    *nargv[10], num[32], vmm_fd[32], psp_fd[32];
-       int                      fd, ret = EINVAL;
+       int                      ret = EINVAL;
        int                      fds[2];
        pid_t                    vm_pid;
        size_t                   i, j, sz;
@@ -694,13 +707,12 @@ vmm_start_vm(struct imsg *imsg, uint32_t *id, pid_t *p
                close_fd(PROC_PARENT_SOCK_FILENO);

                /* Detach from terminal. */
-               if (!env->vmd_debug && (fd =
-                       open("/dev/null", O_RDWR, 0)) != -1) {
-                       dup2(fd, STDIN_FILENO);
-                       dup2(fd, STDOUT_FILENO);
-                       dup2(fd, STDERR_FILENO);
-                       if (fd > 2)
-                               close(fd);
+               if (!env->vmd_debug) {
+                       dup2(dev_null, STDIN_FILENO);
+                       dup2(dev_null, STDOUT_FILENO);
+                       dup2(dev_null, STDERR_FILENO);
+                       if (dev_null > 2)
+                               close(dev_null);
                }

                if (env->vmd_psp_fd > 0)

Reply via email to