git: 7377c87e4673 - main - vmm: Consolidate VM name length checking
- Go to: [ bottom of page ] [ top of archives ] [ this month ]
Date: Tue, 04 Nov 2025 14:36:06 UTC
The branch main has been updated by markj:
URL: https://cgit.FreeBSD.org/src/commit/?id=7377c87e467343e71b3e803708b98e04ea8e84bd
commit 7377c87e467343e71b3e803708b98e04ea8e84bd
Author: Mark Johnston <markj@FreeBSD.org>
AuthorDate: 2025-11-04 13:55:07 +0000
Commit: Mark Johnston <markj@FreeBSD.org>
CommitDate: 2025-11-04 13:55:07 +0000
vmm: Consolidate VM name length checking
vm_create() is only called from one place. Rather than having similar
checks everywhere, move them to vmmdev_create().
We can safely assume that the name is nul-terminated, the vmmctl ioctl
handler and the legacy sysctl handler ensure this. So, don't bother
with strnlen().
Finally, make sure that the name buffers are the same size on all
platforms. VM_MAX_NAMELEN is supposed to be the maximum, not including
the nul terminator.
Reviewed by: corvink
MFC after: 2 weeks
Sponsored by: The FreeBSD Foundation
Sponsored by: Klara, Inc.
Differential Revision: https://reviews.freebsd.org/D53422
---
sys/amd64/include/vmm.h | 26 --------------------------
sys/amd64/include/vmm_dev.h | 2 ++
sys/amd64/vmm/vmm.c | 4 ----
sys/arm64/include/vmm.h | 21 ---------------------
sys/arm64/include/vmm_dev.h | 2 ++
sys/arm64/vmm/vmm.c | 5 +----
sys/dev/vmm/vmm_dev.c | 3 +++
sys/dev/vmm/vmm_dev.h | 3 +++
sys/dev/vmm/vmm_param.h | 33 +++++++++++++++++++++++++++++++++
sys/riscv/include/vmm.h | 3 ---
sys/riscv/include/vmm_dev.h | 2 ++
sys/riscv/vmm/vmm.c | 5 +----
12 files changed, 47 insertions(+), 62 deletions(-)
diff --git a/sys/amd64/include/vmm.h b/sys/amd64/include/vmm.h
index c7baa5e4c54a..0a2d5a80f2b0 100644
--- a/sys/amd64/include/vmm.h
+++ b/sys/amd64/include/vmm.h
@@ -122,33 +122,7 @@ enum x2apic_state {
#define VM_INTINFO_HWEXCEPTION (3 << 8)
#define VM_INTINFO_SWINTR (4 << 8)
-/*
- * The VM name has to fit into the pathname length constraints of devfs,
- * governed primarily by SPECNAMELEN. The length is the total number of
- * characters in the full path, relative to the mount point and not
- * including any leading '/' characters.
- * A prefix and a suffix are added to the name specified by the user.
- * The prefix is usually "vmm/" or "vmm.io/", but can be a few characters
- * longer for future use.
- * The suffix is a string that identifies a bootrom image or some similar
- * image that is attached to the VM. A separator character gets added to
- * the suffix automatically when generating the full path, so it must be
- * accounted for, reducing the effective length by 1.
- * The effective length of a VM name is 229 bytes for FreeBSD 13 and 37
- * bytes for FreeBSD 12. A minimum length is set for safety and supports
- * a SPECNAMELEN as small as 32 on old systems.
- */
-#define VM_MAX_PREFIXLEN 10
-#define VM_MAX_SUFFIXLEN 15
-#define VM_MIN_NAMELEN 6
-#define VM_MAX_NAMELEN \
- (SPECNAMELEN - VM_MAX_PREFIXLEN - VM_MAX_SUFFIXLEN - 1)
-
#ifdef _KERNEL
-#include <sys/kassert.h>
-
-CTASSERT(VM_MAX_NAMELEN >= VM_MIN_NAMELEN);
-
struct vm;
struct vm_exception;
struct vm_mem;
diff --git a/sys/amd64/include/vmm_dev.h b/sys/amd64/include/vmm_dev.h
index 441330fd57b8..f1c07a983a4b 100644
--- a/sys/amd64/include/vmm_dev.h
+++ b/sys/amd64/include/vmm_dev.h
@@ -34,6 +34,8 @@
#include <machine/vmm.h>
#include <machine/vmm_snapshot.h>
+#include <dev/vmm/vmm_param.h>
+
struct vm_memmap {
vm_paddr_t gpa;
int segid; /* memory segment */
diff --git a/sys/amd64/vmm/vmm.c b/sys/amd64/vmm/vmm.c
index 627a5a2c5ece..ab5e21153f8a 100644
--- a/sys/amd64/vmm/vmm.c
+++ b/sys/amd64/vmm/vmm.c
@@ -523,10 +523,6 @@ vm_create(const char *name, struct vm **retvm)
struct vm *vm;
int error;
- if (name == NULL || strnlen(name, VM_MAX_NAMELEN + 1) ==
- VM_MAX_NAMELEN + 1)
- return (EINVAL);
-
vm = malloc(sizeof(struct vm), M_VM, M_WAITOK | M_ZERO);
error = vm_mem_init(&vm->mem, 0, VM_MAXUSER_ADDRESS_LA48);
if (error != 0) {
diff --git a/sys/arm64/include/vmm.h b/sys/arm64/include/vmm.h
index 696a69669a2a..e67540eac66d 100644
--- a/sys/arm64/include/vmm.h
+++ b/sys/arm64/include/vmm.h
@@ -106,27 +106,6 @@ enum vm_reg_name {
#define VM_GUEST_BASE_IPA 0x80000000UL /* Guest kernel start ipa */
-/*
- * The VM name has to fit into the pathname length constraints of devfs,
- * governed primarily by SPECNAMELEN. The length is the total number of
- * characters in the full path, relative to the mount point and not
- * including any leading '/' characters.
- * A prefix and a suffix are added to the name specified by the user.
- * The prefix is usually "vmm/" or "vmm.io/", but can be a few characters
- * longer for future use.
- * The suffix is a string that identifies a bootrom image or some similar
- * image that is attached to the VM. A separator character gets added to
- * the suffix automatically when generating the full path, so it must be
- * accounted for, reducing the effective length by 1.
- * The effective length of a VM name is 229 bytes for FreeBSD 13 and 37
- * bytes for FreeBSD 12. A minimum length is set for safety and supports
- * a SPECNAMELEN as small as 32 on old systems.
- */
-#define VM_MAX_PREFIXLEN 10
-#define VM_MAX_SUFFIXLEN 15
-#define VM_MAX_NAMELEN \
- (SPECNAMELEN - VM_MAX_PREFIXLEN - VM_MAX_SUFFIXLEN - 1)
-
#ifdef _KERNEL
struct vm;
struct vm_exception;
diff --git a/sys/arm64/include/vmm_dev.h b/sys/arm64/include/vmm_dev.h
index 219f1116c728..289ff0fe1fc9 100644
--- a/sys/arm64/include/vmm_dev.h
+++ b/sys/arm64/include/vmm_dev.h
@@ -31,6 +31,8 @@
#include <machine/vmm.h>
+#include <dev/vmm/vmm_param.h>
+
struct vm_memmap {
vm_paddr_t gpa;
int segid; /* memory segment */
diff --git a/sys/arm64/vmm/vmm.c b/sys/arm64/vmm/vmm.c
index 58f53b34b2cb..eb5a452fddea 100644
--- a/sys/arm64/vmm/vmm.c
+++ b/sys/arm64/vmm/vmm.c
@@ -124,7 +124,7 @@ struct vm {
volatile cpuset_t suspended_cpus; /* (i) suspended vcpus */
volatile cpuset_t halted_cpus; /* (x) cpus in a hard halt */
struct vm_mem mem; /* (i) guest memory */
- char name[VM_MAX_NAMELEN]; /* (o) virtual machine name */
+ char name[VM_MAX_NAMELEN + 1]; /* (o) virtual machine name */
struct vcpu **vcpu; /* (i) guest vcpus */
struct vmm_mmio_region mmio_region[VM_MAX_MMIO_REGIONS];
/* (o) guest MMIO regions */
@@ -437,9 +437,6 @@ vm_create(const char *name, struct vm **retvm)
struct vm *vm;
int error;
- if (name == NULL || strlen(name) >= VM_MAX_NAMELEN)
- return (EINVAL);
-
vm = malloc(sizeof(struct vm), M_VMM, M_WAITOK | M_ZERO);
error = vm_mem_init(&vm->mem, 0, 1ul << 39);
if (error != 0) {
diff --git a/sys/dev/vmm/vmm_dev.c b/sys/dev/vmm/vmm_dev.c
index 08a53bb62a85..09093fe44e2b 100644
--- a/sys/dev/vmm/vmm_dev.c
+++ b/sys/dev/vmm/vmm_dev.c
@@ -984,6 +984,9 @@ vmmdev_create(const char *name, struct ucred *cred)
struct vm *vm;
int error;
+ if (name == NULL || strlen(name) > VM_MAX_NAMELEN)
+ return (EINVAL);
+
sx_xlock(&vmmdev_mtx);
sc = vmmdev_lookup(name, cred);
if (sc != NULL) {
diff --git a/sys/dev/vmm/vmm_dev.h b/sys/dev/vmm/vmm_dev.h
index c691341d4350..89fe7ec4704d 100644
--- a/sys/dev/vmm/vmm_dev.h
+++ b/sys/dev/vmm/vmm_dev.h
@@ -11,8 +11,11 @@
#include <sys/types.h>
#include <sys/ioccom.h>
+
#include <machine/vmm_dev.h>
+#include <dev/vmm/vmm_param.h>
+
#ifdef _KERNEL
struct thread;
struct vm;
diff --git a/sys/dev/vmm/vmm_param.h b/sys/dev/vmm/vmm_param.h
new file mode 100644
index 000000000000..a5040eb0f58c
--- /dev/null
+++ b/sys/dev/vmm/vmm_param.h
@@ -0,0 +1,33 @@
+/*-
+ * SPDX-License-Identifier: BSD-2-Clause
+ *
+ * Copyright (c) 2011 NetApp, Inc.
+ * All rights reserved.
+ */
+
+#ifndef _DEV_VMM_PARAM_H_
+#define _DEV_VMM_PARAM_H_
+
+/*
+ * The VM name has to fit into the pathname length constraints of devfs,
+ * governed primarily by SPECNAMELEN. The length is the total number of
+ * characters in the full path, relative to the mount point and not
+ * including any leading '/' characters.
+ * A prefix and a suffix are added to the name specified by the user.
+ * The prefix is usually "vmm/" or "vmm.io/", but can be a few characters
+ * longer for future use.
+ * The suffix is a string that identifies a bootrom image or some similar
+ * image that is attached to the VM. A separator character gets added to
+ * the suffix automatically when generating the full path, so it must be
+ * accounted for, reducing the effective length by 1.
+ * The effective length of a VM name is 229 bytes for FreeBSD 13 and 37
+ * bytes for FreeBSD 12. A minimum length is set for safety and supports
+ * a SPECNAMELEN as small as 32 on old systems.
+ */
+#define VM_MAX_PREFIXLEN 10
+#define VM_MAX_SUFFIXLEN 15
+#define VM_MIN_NAMELEN 6
+#define VM_MAX_NAMELEN \
+ (SPECNAMELEN - VM_MAX_PREFIXLEN - VM_MAX_SUFFIXLEN - 1)
+
+#endif /* !_DEV_VMM_PARAM_H_ */
diff --git a/sys/riscv/include/vmm.h b/sys/riscv/include/vmm.h
index e227dd825966..361140834805 100644
--- a/sys/riscv/include/vmm.h
+++ b/sys/riscv/include/vmm.h
@@ -103,9 +103,6 @@ enum vm_reg_name {
#define VM_INTINFO_HWEXCEPTION (3 << 8)
#define VM_INTINFO_SWINTR (4 << 8)
-#define VM_MAX_NAMELEN 32
-#define VM_MAX_SUFFIXLEN 15
-
#ifdef _KERNEL
struct vm;
diff --git a/sys/riscv/include/vmm_dev.h b/sys/riscv/include/vmm_dev.h
index 4d30d5a1c35b..a60e545b8f52 100644
--- a/sys/riscv/include/vmm_dev.h
+++ b/sys/riscv/include/vmm_dev.h
@@ -38,6 +38,8 @@
#include <machine/vmm.h>
+#include <dev/vmm/vmm_param.h>
+
struct vm_memmap {
vm_paddr_t gpa;
int segid; /* memory segment */
diff --git a/sys/riscv/vmm/vmm.c b/sys/riscv/vmm/vmm.c
index f2995b276072..e1ba0af83fae 100644
--- a/sys/riscv/vmm/vmm.c
+++ b/sys/riscv/vmm/vmm.c
@@ -120,7 +120,7 @@ struct vm {
volatile cpuset_t suspended_cpus; /* (i) suspended vcpus */
volatile cpuset_t halted_cpus; /* (x) cpus in a hard halt */
struct vm_mem mem; /* (i) [m+v] guest memory */
- char name[VM_MAX_NAMELEN]; /* (o) virtual machine name */
+ char name[VM_MAX_NAMELEN + 1]; /* (o) virtual machine name */
struct vcpu **vcpu; /* (i) guest vcpus */
struct vmm_mmio_region mmio_region[VM_MAX_MMIO_REGIONS];
/* (o) guest MMIO regions */
@@ -311,9 +311,6 @@ vm_create(const char *name, struct vm **retvm)
struct vm *vm;
int error;
- if (name == NULL || strlen(name) >= VM_MAX_NAMELEN)
- return (EINVAL);
-
vm = malloc(sizeof(struct vm), M_VMM, M_WAITOK | M_ZERO);
error = vm_mem_init(&vm->mem, 0, 1ul << 39);
if (error != 0) {