vmm: Restore the ability to create VMs as root in a jail
The new PRIV_VMM_CREATE and DESTROY permissions should be allowed by
jails, so need to be added to the list in prison_priv_check(). Then,
modify vmmdev_create() to verify that the jail was created with the
allow.vmm flag. This is already verified when opening /dev/vmmctl, but
checking again doesn't hurt and ensures that one can't pass the
allow.vmm policy by passing a vmmctl fd along a unix domain socket from
outside the jail.
Rename vmm_priv_check() to vmm_jail_priv_check() to make the function's
purpose more clear.
Reported by: novel
Reviewed by: bnovkov
Fixes: d4c05edd41 ("vmm: Add privilege checks to vmmctl operations")
Differential Revision: https://reviews.freebsd.org/D56119
This commit is contained in:
+11
-5
@@ -114,7 +114,7 @@ static int devmem_create_cdev(struct vmmdev_softc *sc, int id, char *devmem);
|
|||||||
static void vmmdev_destroy(struct vmmdev_softc *sc);
|
static void vmmdev_destroy(struct vmmdev_softc *sc);
|
||||||
|
|
||||||
static int
|
static int
|
||||||
vmm_priv_check(struct ucred *ucred)
|
vmm_jail_priv_check(struct ucred *ucred)
|
||||||
{
|
{
|
||||||
if (jailed(ucred) &&
|
if (jailed(ucred) &&
|
||||||
(ucred->cr_prison->pr_allow & pr_allow_vmm_flag) == 0)
|
(ucred->cr_prison->pr_allow & pr_allow_vmm_flag) == 0)
|
||||||
@@ -371,7 +371,7 @@ vmmdev_open(struct cdev *dev, int flags, int fmt, struct thread *td)
|
|||||||
* A jail without vmm access shouldn't be able to access vmm device
|
* A jail without vmm access shouldn't be able to access vmm device
|
||||||
* files at all, but check here just to be thorough.
|
* files at all, but check here just to be thorough.
|
||||||
*/
|
*/
|
||||||
error = vmm_priv_check(td->td_ucred);
|
error = vmm_jail_priv_check(td->td_ucred);
|
||||||
if (error != 0)
|
if (error != 0)
|
||||||
return (error);
|
return (error);
|
||||||
|
|
||||||
@@ -940,7 +940,7 @@ sysctl_vmm_destroy(SYSCTL_HANDLER_ARGS)
|
|||||||
char *buf;
|
char *buf;
|
||||||
int error, buflen;
|
int error, buflen;
|
||||||
|
|
||||||
error = vmm_priv_check(req->td->td_ucred);
|
error = vmm_jail_priv_check(req->td->td_ucred);
|
||||||
if (error)
|
if (error)
|
||||||
return (error);
|
return (error);
|
||||||
|
|
||||||
@@ -1016,6 +1016,12 @@ vmmdev_create(const char *name, uint32_t flags, struct ucred *cred)
|
|||||||
"An unprivileged user must run VMs in monitor mode"));
|
"An unprivileged user must run VMs in monitor mode"));
|
||||||
}
|
}
|
||||||
|
|
||||||
|
if ((error = vmm_jail_priv_check(cred)) != 0) {
|
||||||
|
sx_xunlock(&vmmdev_mtx);
|
||||||
|
return (EXTERROR(error,
|
||||||
|
"VMs cannot be created in the current jail"));
|
||||||
|
}
|
||||||
|
|
||||||
if (!chgvmmcnt(cred->cr_ruidinfo, 1, vm_maxvmms)) {
|
if (!chgvmmcnt(cred->cr_ruidinfo, 1, vm_maxvmms)) {
|
||||||
sx_xunlock(&vmmdev_mtx);
|
sx_xunlock(&vmmdev_mtx);
|
||||||
return (ENOMEM);
|
return (ENOMEM);
|
||||||
@@ -1061,7 +1067,7 @@ sysctl_vmm_create(SYSCTL_HANDLER_ARGS)
|
|||||||
if (!vmm_initialized)
|
if (!vmm_initialized)
|
||||||
return (ENXIO);
|
return (ENXIO);
|
||||||
|
|
||||||
error = vmm_priv_check(req->td->td_ucred);
|
error = vmm_jail_priv_check(req->td->td_ucred);
|
||||||
if (error != 0)
|
if (error != 0)
|
||||||
return (error);
|
return (error);
|
||||||
|
|
||||||
@@ -1126,7 +1132,7 @@ vmmctl_open(struct cdev *cdev, int flags, int fmt, struct thread *td)
|
|||||||
int error;
|
int error;
|
||||||
struct vmmctl_priv *priv;
|
struct vmmctl_priv *priv;
|
||||||
|
|
||||||
error = vmm_priv_check(td->td_ucred);
|
error = vmm_jail_priv_check(td->td_ucred);
|
||||||
if (error != 0)
|
if (error != 0)
|
||||||
return (error);
|
return (error);
|
||||||
|
|
||||||
|
|||||||
@@ -4736,6 +4736,14 @@ prison_priv_check(struct ucred *cred, int priv)
|
|||||||
else
|
else
|
||||||
return (EPERM);
|
return (EPERM);
|
||||||
|
|
||||||
|
case PRIV_VMM_CREATE:
|
||||||
|
case PRIV_VMM_DESTROY:
|
||||||
|
/*
|
||||||
|
* Jailed root can create and destroy VMs; the vmm module
|
||||||
|
* additionally checks for the allow.vmm flag.
|
||||||
|
*/
|
||||||
|
return (0);
|
||||||
|
|
||||||
case PRIV_VMM_PPTDEV:
|
case PRIV_VMM_PPTDEV:
|
||||||
/*
|
/*
|
||||||
* Allow jailed root to manage passthrough devices. vmm(4) also
|
* Allow jailed root to manage passthrough devices. vmm(4) also
|
||||||
|
|||||||
Reference in New Issue
Block a user