Index: sys/amd64/vmm/vmm_dev.c =================================================================== --- sys/amd64/vmm/vmm_dev.c +++ sys/amd64/vmm/vmm_dev.c @@ -33,6 +33,7 @@ #include #include +#include #include #include #include @@ -43,6 +44,7 @@ #include #include #include +#include #include #include @@ -88,9 +90,24 @@ SYSCTL_DECL(_hw_vmm); +static int vmm_priv_check(struct ucred *cred); static int devmem_create_cdev(const char *vmname, int id, char *devmem); static void devmem_destroy(void *arg); +static int +vmm_priv_check(struct ucred *ucred) +{ + struct prison *prison; + + if (jailed(ucred)) { + prison = ucred->cr_prison; + if ((prison->pr_allow & PR_ALLOW_VMM) != PR_ALLOW_VMM) + return (EPERM); + } + + return (0); +} + static int vcpu_lock_one(struct vmmdev_softc *sc, int vcpu) { @@ -177,6 +194,10 @@ void *hpa, *cookie; struct vmmdev_softc *sc; + error = vmm_priv_check(curthread->td_ucred); + if (error) + return (error); + sc = vmmdev_lookup2(cdev); if (sc == NULL) return (ENXIO); @@ -351,11 +372,14 @@ uint64_t *regvals; int *regnums; + error = vmm_priv_check(curthread->td_ucred); + if (error) + return (error); + sc = vmmdev_lookup2(cdev); if (sc == NULL) return (ENXIO); - error = 0; vcpu = -1; state_changed = 0; @@ -777,6 +801,10 @@ int error, found, segid; bool sysmem; + error = vmm_priv_check(curthread->td_ucred); + if (error) + return (error); + first = *offset; last = first + mapsize; if ((nprot & PROT_EXEC) || first < 0 || first >= last) @@ -865,6 +893,10 @@ struct vmmdev_softc *sc; struct cdev *cdev; + error = vmm_priv_check(req->td->td_ucred); + if (error) + return (error); + strlcpy(buf, "beavis", sizeof(buf)); error = sysctl_handle_string(oidp, buf, sizeof(buf), req); if (error != 0 || req->newptr == NULL) @@ -906,7 +938,8 @@ destroy_dev_sched_cb(cdev, vmmdev_destroy, sc); return (0); } -SYSCTL_PROC(_hw_vmm, OID_AUTO, destroy, CTLTYPE_STRING | CTLFLAG_RW, +SYSCTL_PROC(_hw_vmm, OID_AUTO, destroy, + CTLTYPE_STRING | CTLFLAG_RW | CTLFLAG_PRISON, NULL, 0, sysctl_vmm_destroy, "A", NULL); static struct cdevsw vmmdevsw = { @@ -927,6 +960,10 @@ struct vmmdev_softc *sc, *sc2; char buf[VM_MAX_NAMELEN]; + error = vmm_priv_check(req->td->td_ucred); + if (error) + return (error); + strlcpy(buf, "beavis", sizeof(buf)); error = sysctl_handle_string(oidp, buf, sizeof(buf), req); if (error != 0 || req->newptr == NULL) @@ -977,7 +1014,8 @@ return (0); } -SYSCTL_PROC(_hw_vmm, OID_AUTO, create, CTLTYPE_STRING | CTLFLAG_RW, +SYSCTL_PROC(_hw_vmm, OID_AUTO, create, + CTLTYPE_STRING | CTLFLAG_RW | CTLFLAG_PRISON, NULL, 0, sysctl_vmm_create, "A", NULL); void Index: sys/kern/kern_jail.c =================================================================== --- sys/kern/kern_jail.c +++ sys/kern/kern_jail.c @@ -194,6 +194,7 @@ {"allow.socket_af", "allow.nosocket_af", PR_ALLOW_SOCKET_AF}, {"allow.reserved_ports", "allow.noreserved_ports", PR_ALLOW_RESERVED_PORTS}, + {"allow.vmm", "allow.novmm", PR_ALLOW_VMM}, }; const size_t pr_flag_allow_size = sizeof(pr_flag_allow); @@ -3626,6 +3627,10 @@ CTLTYPE_INT | CTLFLAG_RW | CTLFLAG_MPSAFE, NULL, PR_ALLOW_MOUNT, sysctl_jail_default_allow, "I", "Processes in jail can mount/unmount jail-friendly file systems (deprecated)"); +SYSCTL_PROC(_security_jail, OID_AUTO, vmm, + CTLTYPE_INT | CTLFLAG_RW | CTLFLAG_MPSAFE, + NULL, PR_ALLOW_VMM, sysctl_jail_default_allow, "I", + "Jail can use vmm"); static int sysctl_jail_default_level(SYSCTL_HANDLER_ARGS) @@ -3774,6 +3779,8 @@ "B", "Jail may create sockets other than just UNIX/IPv4/IPv6/route"); SYSCTL_JAIL_PARAM(_allow, reserved_ports, CTLTYPE_INT | CTLFLAG_RW, "B", "Jail may bind sockets to reserved ports"); +SYSCTL_JAIL_PARAM(_allow, vmm, CTLTYPE_INT | CTLFLAG_RW, + "B", "Jail may use vmm"); SYSCTL_JAIL_PARAM_SUBNODE(allow, mount, "Jail mount/unmount permission flags"); SYSCTL_JAIL_PARAM(_allow_mount, , CTLTYPE_INT | CTLFLAG_RW, Index: sys/sys/jail.h =================================================================== --- sys/sys/jail.h +++ sys/sys/jail.h @@ -234,7 +234,8 @@ #define PR_ALLOW_SOCKET_AF 0x00000040 #define PR_ALLOW_RESERVED_PORTS 0x00008000 #define PR_ALLOW_KMEM_ACCESS 0x00010000 /* reserved, not used yet */ -#define PR_ALLOW_ALL_STATIC 0x0001807f +#define PR_ALLOW_VMM 0x00020000 +#define PR_ALLOW_ALL_STATIC 0x0003807f /* * OSD methods