On Fri, Mar 13, 2026 at 03:50:21PM -0400, Dave Voutila wrote:
> Dave Voutila <[email protected]> writes:
>
> > "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
> >
>
> Better version with input from brynet@ on setting O_CLOEXEC at open
> time.
>

ok mlarkin

>
> diff refs/heads/master refs/heads/vmd-pledge
> commit - f0fb81d370539aeb26fe6a527b3437ebad8ce8b4
> commit + fce4c500fcfc68d1339c617f0f9380b8429a7e7f
> blob - 31120d064d64b5ca0a2b4570bc06662ad2d35b23
> blob + 4c0d2a5487ba6d9673f069c7a700a5d4c18a9227
> --- 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,16 @@ 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|O_CLOEXEC, 0);
> +             if (dev_null == -1)
> +                     fatal("/dev/null");
> +     }
> +
> +     /*
>        * We aren't root, so we can't chroot(2). Use unveil(2) instead.
>        */
>       if (unveil(env->argv0, "x") == -1)
> @@ -589,7 +600,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 +705,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