On Mon, Aug 26, 2019 at 11:01:26AM +0100, Ricardo Mestre wrote:
> 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

Tested here, no problems with my local VMs. Confirm that the priv
process is now unveiled.

root     12241  0.0  0.0  1224  1780 ??  SU      9:11AM    0:00.01 vmd:
priv (vmd)

Just to clarify, this diff is removing chroot(2) from 3 processes:

 * priv - (cannot be pledged)
 * control - pledged "stdio,unix,sendfd,recvfd"
 * vmm - pledged "stdio,proc,sendfd,recvfd,vmm"

I think this should be OK.

-Bryan.
 
> 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