diff --git a/etc/mtree/BSD.tests.dist b/etc/mtree/BSD.tests.dist --- a/etc/mtree/BSD.tests.dist +++ b/etc/mtree/BSD.tests.dist @@ -866,6 +866,8 @@ .. vm .. + vmm + .. .. usr.bin apply 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 @@ -80,6 +80,7 @@ struct vmmdev_softc { struct vm *vm; /* vm instance cookie */ struct cdev *cdev; + struct ucred *ucred; SLIST_ENTRY(vmmdev_softc) link; SLIST_HEAD(, devmem_softc) devmem; int flags; @@ -182,6 +183,12 @@ break; } + if (sc == NULL) + return (NULL); + + if (cr_cansee(curthread->td_ucred, sc->ucred)) + return (NULL); + return (sc); } @@ -979,6 +986,9 @@ if (sc->vm != NULL) vm_destroy(sc->vm); + if (sc->ucred != NULL) + crfree(sc->ucred); + if ((sc->flags & VSC_LINKED) != 0) { mtx_lock(&vmmdev_mtx); SLIST_REMOVE(&head, sc, vmmdev_softc, link); @@ -1096,6 +1106,7 @@ goto out; sc = malloc(sizeof(struct vmmdev_softc), M_VMMDEV, M_WAITOK | M_ZERO); + sc->ucred = crhold(curthread->td_ucred); sc->vm = vm; SLIST_INIT(&sc->devmem); @@ -1117,8 +1128,8 @@ goto out; } - error = make_dev_p(MAKEDEV_CHECKNAME, &cdev, &vmmdevsw, NULL, - UID_ROOT, GID_WHEEL, 0600, "vmm/%s", buf); + error = make_dev_p(MAKEDEV_CHECKNAME, &cdev, &vmmdevsw, sc->ucred, + UID_ROOT, GID_WHEEL, 0600, "vmm/%s", buf); if (error != 0) { vmmdev_destroy(sc); goto out; diff --git a/tests/sys/Makefile b/tests/sys/Makefile --- a/tests/sys/Makefile +++ b/tests/sys/Makefile @@ -31,6 +31,7 @@ TESTS_SUBDIRS+= sys TESTS_SUBDIRS+= vfs TESTS_SUBDIRS+= vm +TESTS_SUBDIRS+= vmm .if ${MK_AUDIT} != "no" _audit= audit diff --git a/tests/sys/vmm/Makefile b/tests/sys/vmm/Makefile new file mode 100644 --- /dev/null +++ b/tests/sys/vmm/Makefile @@ -0,0 +1,11 @@ +PACKAGE= tests + +TESTSDIR= ${TESTSBASE}/sys/vmm + +BINDIR= ${TESTSDIR} + +ATF_TESTS_SH+= vmm_cred_jail + +${PACKAGE}FILES+= utils.subr + +.include diff --git a/tests/sys/vmm/utils.subr b/tests/sys/vmm/utils.subr new file mode 100644 --- /dev/null +++ b/tests/sys/vmm/utils.subr @@ -0,0 +1,47 @@ +#- +# 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. +# + +vmm_mkjail() +{ + jailname=$1 + jail -c name=${jailname} persist allow.vmm + echo $jailname >> created_jails.lst +} +vmm_cleanup() +{ + if [ -f created_jails.lst ] + then + for jailname in `cat created_jails.lst` + do + jail -r ${jailname} + done + rm created_jails.lst + fi +} diff --git a/tests/sys/vmm/vmm_cred_jail.sh b/tests/sys/vmm/vmm_cred_jail.sh new file mode 100644 --- /dev/null +++ b/tests/sys/vmm/vmm_cred_jail.sh @@ -0,0 +1,80 @@ +#- +# 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_cred_jail_host cleanup +vmm_cred_jail_host_head() +{ + atf_set "descr" "Tests deleting the host's VM from within a jail" + atf_set "require.user" "root" +} +vmm_cred_jail_host_body() +{ + if ! kldstat -qn vmm; then + atf_skip "vmm is not loaded" + fi + bhyvectl --vm=testvm --create + vmm_mkjail myjail + atf_check -s exit:1 -e ignore jexec myjail bhyvectl --vm=testvm --destroy +} +vmm_cred_jail_host_cleanup() +{ + bhyvectl --vm=testvm --destroy + vmm_cleanup +} + +atf_test_case vmm_cred_jail_other cleanup +vmm_cred_jail_other_head() +{ + atf_set "descr" "Tests deleting a jail's VM from within another jail" + atf_set "require.user" "root" +} +vmm_cred_jail_other_body() +{ + if ! kldstat -qn vmm; then + atf_skip "vmm is not loaded" + fi + vmm_mkjail myjail1 + vmm_mkjail myjail2 + atf_check -s exit:0 jexec myjail1 bhyvectl --vm=testvm --create + atf_check -s exit:1 -e ignore jexec myjail2 bhyvectl --vm=testvm --destroy +} +vmm_cred_jail_other_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 +}