Page Menu
Home
FreeBSD
Search
Configure Global Search
Log In
Files
F165161294
D31225.id92448.diff
No One
Temporary
Actions
View File
Edit File
Delete File
View Transforms
Subscribe
Mute Notifications
Flag For Later
Award Token
Size
6 KB
Referenced Files
None
Subscribers
None
D31225.id92448.diff
View Options
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)
@@ -997,31 +1000,13 @@
}
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_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,34 @@
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, 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);
@@ -1147,12 +1157,59 @@
NULL, 0, sysctl_vmm_create, "A",
NULL);
+static void
+vmmdev_prison_cleanup(struct prison *pr)
+{
+ struct vmmdev_softc *sc;
+
+ mtx_lock(&vmmdev_mtx);
+
+ SLIST_FOREACH(sc, &head, link) {
+ 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;
+ bool vmm_disabled = false;
+
+ if (vfs_flagopt(opts, "allow.novmm", NULL, 0))
+ vmm_disabled = true;
+
+ if (vmm_disabled)
+ 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 +1217,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,8 @@
BINDIR= ${TESTSDIR}
-ATF_TESTS_SH+= vmm_cred_jail
+ATF_TESTS_SH+= vmm_cred_jail \
+ vmm_remove_jail
${PACKAGE}FILES+= utils.subr
diff --git a/tests/sys/vmm/vmm_remove_jail.sh b/tests/sys/vmm/vmm_remove_jail.sh
new file mode 100644
--- /dev/null
+++ b/tests/sys/vmm/vmm_remove_jail.sh
@@ -0,0 +1,81 @@
+#-
+# SPDX-License-Identifier: BSD-2-Clause-FreeBSD
+#
+# Copyright (c) 2021 The FreeBSD Foundation
+#
+# This software was developed by Cyril Zhang under sponsorship from
+# the FreeBSD Foundation.
+#
+# Redistribution and use in source and binary forms, with or without
+# modification, are permitted provided that the following conditions are
+# met:
+# 1. Redistributions of source code must retain the above copyright
+# notice, this list of conditions and the following disclaimer.
+# 2. Redistributions in binary form must reproduce the above copyright
+# notice, this list of conditions and the following disclaimer in
+# the documentation and/or other materials provided with the distribution.
+#
+# THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``AS IS'' AND
+# ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+# IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+# ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE
+# FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
+# DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
+# OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
+# HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
+# LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
+# OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
+# SUCH DAMAGE.
+#
+
+. $(atf_get_srcdir)/utils.subr
+
+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_remove_jail
+ atf_add_test_case vmm_unenable_jail
+}
File Metadata
Details
Attached
Mime Type
text/plain
Expires
Fri, Aug 7, 12:01 PM (9 h, 29 m)
Storage Engine
blob
Storage Format
Raw Data
Storage Handle
36170213
Default Alt Text
D31225.id92448.diff (6 KB)
Attached To
Mode
D31225: vmm: Destroy associated VM objects when a jail is destroyed
Attached
Detach File
Event Timeline
Log In to Comment