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 */
>
>