vmm: Add credential to cdev object

Add a credential to the cdev object in sysctl_vmm_create(), then check
that we have the correct credentials in sysctl_vmm_destroy(). This
prevents a process in one jail from opening or destroying the /dev/vmm
file corresponding to a VM in a sibling jail.

Add regression tests.

Reviewed by:	jhb, markj
MFC after:	2 weeks
Sponsored by:	The FreeBSD Foundation
Differential Revision:	https://reviews.freebsd.org/D31156
This commit is contained in:
Cyril Zhang 2021-08-18 13:41:33 -04:00 committed by Mark Johnston
parent 0a539a0f00
commit a85404906b
6 changed files with 154 additions and 2 deletions

View File

@ -866,6 +866,8 @@
..
vm
..
vmm
..
..
usr.bin
apply

View File

@ -80,6 +80,7 @@ struct devmem_softc {
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 @@ vmmdev_lookup(const char *name)
break;
}
if (sc == NULL)
return (NULL);
if (cr_cansee(curthread->td_ucred, sc->ucred))
return (NULL);
return (sc);
}
@ -979,6 +986,9 @@ vmmdev_destroy(void *arg)
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 @@ sysctl_vmm_create(SYSCTL_HANDLER_ARGS)
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 @@ sysctl_vmm_create(SYSCTL_HANDLER_ARGS)
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;

View File

@ -31,6 +31,7 @@ TESTS_SUBDIRS+= posixshm
TESTS_SUBDIRS+= sys
TESTS_SUBDIRS+= vfs
TESTS_SUBDIRS+= vm
TESTS_SUBDIRS+= vmm
.if ${MK_AUDIT} != "no"
_audit= audit

11
tests/sys/vmm/Makefile Normal file
View File

@ -0,0 +1,11 @@
PACKAGE= tests
TESTSDIR= ${TESTSBASE}/sys/vmm
BINDIR= ${TESTSDIR}
ATF_TESTS_SH+= vmm_cred_jail
${PACKAGE}FILES+= utils.subr
.include <bsd.test.mk>

47
tests/sys/vmm/utils.subr Normal file
View File

@ -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
}

View File

@ -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
}