aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorMark Johnston <markj@FreeBSD.org>2026-02-19 14:38:29 +0000
committerMark Johnston <markj@FreeBSD.org>2026-02-19 17:16:15 +0000
commitd4c05edd410e7925875c844c0642929410f22053 (patch)
tree10cf7f1b683cc5b417d66d3c6b9e3d7199034052
parentdcbd1fccdc66ec33f0652be34a1c8bdd5293f90c (diff)
vmm: Add privilege checks to vmmctl operations
In preparation for supporting creation of VMs by unprivileged users, add some restrictions: - Disallow creation of non-transient VMs by unprivileged users. That is, if an unprivileged user creates a VM, the VM must be destroyed automatically once the last fd referencing it is gone. - Disallow destroying VMs created by a different user, unless the caller has the PRIV_VMM_DESTROY privilege. Reviewed by: bnovkov MFC after: 2 months Sponsored by: The FreeBSD Foundation Sponsored by: Klara, Inc. Differential Revision: https://reviews.freebsd.org/D54740
-rw-r--r--sys/dev/vmm/vmm_dev.c21
-rw-r--r--sys/sys/priv.h4
2 files changed, 24 insertions, 1 deletions
diff --git a/sys/dev/vmm/vmm_dev.c b/sys/dev/vmm/vmm_dev.c
index 0df21402683d..5d7802f929ae 100644
--- a/sys/dev/vmm/vmm_dev.c
+++ b/sys/dev/vmm/vmm_dev.c
@@ -898,6 +898,7 @@ vmmdev_lookup_and_destroy(const char *name, struct ucred *cred)
{
struct cdev *cdev;
struct vmmdev_softc *sc;
+ int error;
sx_xlock(&vmmdev_mtx);
sc = vmmdev_lookup(name, cred);
@@ -907,6 +908,16 @@ vmmdev_lookup_and_destroy(const char *name, struct ucred *cred)
}
/*
+ * Only the creator of a VM or a privileged user can destroy it.
+ */
+ if ((cred->cr_uid != sc->ucred->cr_uid ||
+ cred->cr_prison != sc->ucred->cr_prison) &&
+ (error = priv_check_cred(cred, PRIV_VMM_DESTROY)) != 0) {
+ sx_xunlock(&vmmdev_mtx);
+ return (error);
+ }
+
+ /*
* Setting 'sc->cdev' to NULL is used to indicate that the VM
* is scheduled for destruction.
*/
@@ -992,6 +1003,16 @@ vmmdev_create(const char *name, uint32_t flags, struct ucred *cred)
return (EEXIST);
}
+ /*
+ * Unprivileged users can only create VMs that will be automatically
+ * destroyed when the creating descriptor is closed.
+ */
+ if ((flags & VMMCTL_CREATE_DESTROY_ON_CLOSE) == 0 &&
+ (error = priv_check_cred(cred, PRIV_VMM_CREATE)) != 0) {
+ sx_xunlock(&vmmdev_mtx);
+ return (error);
+ }
+
if (!chgvmmcnt(cred->cr_ruidinfo, 1, vm_maxvmms)) {
sx_xunlock(&vmmdev_mtx);
return (ENOMEM);
diff --git a/sys/sys/priv.h b/sys/sys/priv.h
index 1ad6a4882ffc..e302d9487e64 100644
--- a/sys/sys/priv.h
+++ b/sys/sys/priv.h
@@ -539,11 +539,13 @@
* vmm privileges.
*/
#define PRIV_VMM_PPTDEV 710 /* Can manipulate ppt devices. */
+#define PRIV_VMM_CREATE 711 /* Can create non-temporal VMs. */
+#define PRIV_VMM_DESTROY 712 /* Can destroy other users' VMs. */
/*
* Track end of privilege list.
*/
-#define _PRIV_HIGHEST 711
+#define _PRIV_HIGHEST 713
/*
* Validate that a named privilege is known by the privilege system. Invalid