diff --git a/sys/dev/vmm/vmm_dev.c b/sys/dev/vmm/vmm_dev.c --- a/sys/dev/vmm/vmm_dev.c +++ b/sys/dev/vmm/vmm_dev.c @@ -896,6 +896,7 @@ { struct cdev *cdev; struct vmmdev_softc *sc; + int error; sx_xlock(&vmmdev_mtx); sc = vmmdev_lookup(name, cred); @@ -904,6 +905,16 @@ return (EINVAL); } + /* + * Only the creator of a VM or a privileged user can destroy it. + */ + if ((cred->cr_uid != sc->ucred->cr_uid || + cred->cr_prison != sc->ucred->cr_prison) && + (error = priv_check_cred(cred, PRIV_VMM_DESTROY)) != 0) { + sx_xunlock(&vmmdev_mtx); + return (error); + } + /* * Setting 'sc->cdev' to NULL is used to indicate that the VM * is scheduled for destruction. @@ -990,6 +1001,16 @@ return (EEXIST); } + /* + * Unprivileged users can only create VMs that will be automatically + * destroyed when the creating descriptor is closed. + */ + if ((flags & VMMCTL_CREATE_DESTROY_ON_CLOSE) == 0 && + (error = priv_check_cred(cred, PRIV_VMM_CREATE)) != 0) { + sx_xunlock(&vmmdev_mtx); + return (error); + } + error = vm_create(name, &vm); if (error != 0) { sx_xunlock(&vmmdev_mtx); diff --git a/sys/sys/priv.h b/sys/sys/priv.h --- a/sys/sys/priv.h +++ b/sys/sys/priv.h @@ -535,10 +535,16 @@ #define PRIV_VERIEXEC_NOVERIFY 701 /* Can override O_VERIFY */ #define PRIV_VERIEXEC_CONTROL 702 /* Can configure veriexec */ +/* + * vmm privileges. + */ +#define PRIV_VMM_CREATE 710 /* Can create non-temporal VMs. */ +#define PRIV_VMM_DESTROY 711 /* Can destroy other users' VMs. */ + /* * Track end of privilege list. */ -#define _PRIV_HIGHEST 703 +#define _PRIV_HIGHEST 712 /* * Validate that a named privilege is known by the privilege system. Invalid