Page MenuHomeFreeBSD

D31225.1791852096.diff
No OneTemporary

Size
5 KB
Referenced Files
None
Subscribers
None

D31225.1791852096.diff

diff --git a/sys/amd64/vmm/vmm_dev.c b/sys/amd64/vmm/vmm_dev.c
--- a/sys/amd64/vmm/vmm_dev.c
+++ b/sys/amd64/vmm/vmm_dev.c
@@ -40,6 +40,7 @@
#include <sys/lock.h>
#include <sys/mutex.h>
#include <sys/malloc.h>
+#include <sys/mount.h>
#include <sys/conf.h>
#include <sys/sysctl.h>
#include <sys/libkern.h>
@@ -91,6 +92,7 @@
static unsigned pr_allow_flag;
static struct mtx vmmdev_mtx;
+static unsigned vmmdev_prison_slot;
static MALLOC_DEFINE(M_VMMDEV, "vmmdev", "vmmdev");
@@ -99,6 +101,7 @@
static int vmm_priv_check(struct ucred *ucred);
static int devmem_create_cdev(const char *vmname, int id, char *devmem);
static void devmem_destroy(void *arg);
+static int vmm_destroy(struct vmmdev_softc *sc);
static int
vmm_priv_check(struct ucred *ucred)
@@ -175,9 +178,7 @@
struct vmmdev_softc *sc;
struct vmmdev_softc *found = NULL;
-#ifdef notyet /* XXX kernel is not compiled with invariants */
mtx_assert(&vmmdev_mtx, MA_OWNED);
-#endif
SLIST_FOREACH(sc, &head, link) {
if (strcmp(name, vm_name(sc->vm)) == 0) {
@@ -997,31 +998,15 @@
}
static int
-sysctl_vmm_destroy(SYSCTL_HANDLER_ARGS)
+vmm_destroy(struct vmmdev_softc *sc)
{
struct devmem_softc *dsc;
- struct vmmdev_softc *sc;
struct cdev *cdev;
- char *buf;
- int error, buflen;
-
- error = vmm_priv_check(req->td->td_ucred);
- if (error)
- return (error);
- buflen = VM_MAX_NAMELEN + 1;
- buf = malloc(buflen, M_VMMDEV, M_WAITOK | M_ZERO);
- strlcpy(buf, "beavis", buflen);
- error = sysctl_handle_string(oidp, buf, buflen, req);
- if (error != 0 || req->newptr == NULL)
- goto out;
+ mtx_assert(&vmmdev_mtx, MA_OWNED);
- mtx_lock(&vmmdev_mtx);
- sc = vmmdev_lookup(buf);
if (sc == NULL || sc->cdev == NULL) {
- mtx_unlock(&vmmdev_mtx);
- error = EINVAL;
- goto out;
+ return (EINVAL);
}
/*
@@ -1033,7 +1018,6 @@
*/
cdev = sc->cdev;
sc->cdev = NULL;
- mtx_unlock(&vmmdev_mtx);
/*
* Schedule all cdevs to be destroyed:
@@ -1051,8 +1035,35 @@
destroy_dev_sched_cb(dsc->cdev, devmem_destroy, dsc);
}
destroy_dev_sched_cb(cdev, vmmdev_destroy, sc);
- error = 0;
+ return (0);
+}
+
+static int
+sysctl_vmm_destroy(SYSCTL_HANDLER_ARGS)
+{
+ struct vmmdev_softc *sc;
+ char *buf;
+ int error;
+ size_t buflen;
+
+ error = vmm_priv_check(req->td->td_ucred);
+ if (error)
+ return (error);
+
+ buflen = VM_MAX_NAMELEN + 1;
+ buf = malloc(buflen, M_VMMDEV, M_WAITOK | M_ZERO);
+ strlcpy(buf, "beavis", buflen);
+ error = sysctl_handle_string(oidp, buf, buflen, req);
+ if (error != 0 || req->newptr == NULL)
+ goto out;
+
+ mtx_lock(&vmmdev_mtx);
+
+ sc = vmmdev_lookup(buf);
+ error = vmm_destroy(sc);
+
+ mtx_unlock(&vmmdev_mtx);
out:
free(buf, M_VMMDEV);
return (error);
@@ -1078,7 +1089,8 @@
struct cdev *cdev;
struct vmmdev_softc *sc, *sc2;
char *buf;
- int error, buflen;
+ int error;
+ size_t buflen;
error = vmm_priv_check(req->td->td_ucred);
if (error)
@@ -1147,12 +1159,56 @@
NULL, 0, sysctl_vmm_create, "A",
NULL);
+static void
+vmmdev_prison_cleanup(struct prison *pr)
+{
+ struct vmmdev_softc *sc;
+ struct vmmdev_softc *tsc;
+
+ mtx_lock(&vmmdev_mtx);
+
+ SLIST_FOREACH_SAFE(sc, &head, link, tsc) {
+ if (sc->ucred->cr_prison == pr)
+ vmm_destroy(sc);
+ }
+
+ mtx_unlock(&vmmdev_mtx);
+}
+
+static int
+vmmdev_prison_remove(void *obj, void *data __unused)
+{
+ struct prison *pr = obj;
+
+ vmmdev_prison_cleanup(pr);
+ return (0);
+}
+
+static int
+vmmdev_prison_set(void *obj, void *data)
+{
+ struct prison *pr = obj;
+ struct vfsoptlist *opts = data;
+
+ if (vfs_flagopt(opts, "allow.novmm", NULL, 0))
+ vmmdev_prison_cleanup(pr);
+
+ return (0);
+}
+
void
vmmdev_init(void)
{
+ osd_method_t methods[PR_MAXMETHOD] = {
+ [PR_METHOD_SET] = vmmdev_prison_set,
+ [PR_METHOD_REMOVE] = vmmdev_prison_remove,
+ };
+
mtx_init(&vmmdev_mtx, "vmm device mutex", NULL, MTX_DEF);
pr_allow_flag = prison_add_allow(NULL, "vmm", NULL,
"Allow use of vmm in a jail.");
+
+ vmmdev_prison_slot = osd_jail_register(NULL, methods);
}
int
@@ -1160,10 +1216,12 @@
{
int error;
- if (SLIST_EMPTY(&head))
+ if (SLIST_EMPTY(&head)) {
+ osd_jail_deregister(vmmdev_prison_slot);
error = 0;
- else
+ } else {
error = EBUSY;
+ }
return (error);
}
diff --git a/tests/sys/vmm/Makefile b/tests/sys/vmm/Makefile
--- a/tests/sys/vmm/Makefile
+++ b/tests/sys/vmm/Makefile
@@ -4,7 +4,7 @@
BINDIR= ${TESTSDIR}
-ATF_TESTS_SH+= vmm_cred_jail
+ATF_TESTS_SH+= vmm_jail
${PACKAGE}FILES+= utils.subr
diff --git a/tests/sys/vmm/vmm_cred_jail.sh b/tests/sys/vmm/vmm_jail.sh
rename from tests/sys/vmm/vmm_cred_jail.sh
rename to tests/sys/vmm/vmm_jail.sh
--- a/tests/sys/vmm/vmm_cred_jail.sh
+++ b/tests/sys/vmm/vmm_jail.sh
@@ -73,8 +73,54 @@
vmm_cleanup
}
+atf_test_case vmm_remove_jail cleanup
+vmm_remove_jail_head()
+{
+ atf_set "descr" "Tests deleting a jail that has VM objects"
+ atf_set "require.user" "root"
+}
+vmm_remove_jail_body()
+{
+ if ! kldstat -qn vmm; then
+ atf_skip "vmm is not loaded"
+ fi
+ jail -c name=myjail allow.vmm persist
+ jexec myjail bhyvectl --vm=testvm --create
+ jail -r myjail
+ atf_check -s exit:1 -e ignore ls /dev/vmm
+}
+vmm_remove_jail_cleanup()
+{
+ bhyvectl --vm=testvm --destroy
+ vmm_cleanup
+}
+
+atf_test_case vmm_unenable_jail cleanup
+vmm_unenable_jail_head()
+{
+ atf_set "descr" "Tests allow.vmm=false on a jail that has VM objects"
+ atf_set "require.user" "root"
+}
+vmm_unenable_jail_body()
+{
+ if ! kldstat -qn vmm; then
+ atf_skip "vmm is not loaded"
+ fi
+ vmm_mkjail myjail
+ jexec myjail bhyvectl --vm=testvm --create
+ jail -m name=myjail allow.vmm=false
+ atf_check -s exit:1 -e ignore ls /dev/vmm
+}
+vmm_unenable_jail_cleanup()
+{
+ bhyvectl --vm=testvm --destroy
+ vmm_cleanup
+}
+
atf_init_test_cases()
{
atf_add_test_case vmm_cred_jail_host
atf_add_test_case vmm_cred_jail_other
+ atf_add_test_case vmm_remove_jail
+ atf_add_test_case vmm_unenable_jail
}

File Metadata

Mime Type
text/plain
Expires
Tue, Oct 13, 12:41 AM (2 h, 27 m)
Storage Engine
blob
Storage Format
Raw Data
Storage Handle
30353107
Default Alt Text
D31225.1791852096.diff (5 KB)

Event Timeline