Page MenuHomeFreeBSD

D20924.id59704.diff
No OneTemporary

D20924.id59704.diff

Index: head/sys/amd64/include/vmm.h
===================================================================
--- head/sys/amd64/include/vmm.h
+++ head/sys/amd64/include/vmm.h
@@ -114,9 +114,30 @@
#define VM_INTINFO_HWEXCEPTION (3 << 8)
#define VM_INTINFO_SWINTR (4 << 8)
-#ifdef _KERNEL
+/*
+ * 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)
-#define VM_MAX_NAMELEN 32
+#ifdef _KERNEL
+CTASSERT(VM_MAX_NAMELEN >= VM_MIN_NAMELEN);
struct vm;
struct vm_exception;
Index: head/sys/amd64/include/vmm_dev.h
===================================================================
--- head/sys/amd64/include/vmm_dev.h
+++ head/sys/amd64/include/vmm_dev.h
@@ -51,7 +51,7 @@
struct vm_memseg {
int segid;
size_t len;
- char name[SPECNAMELEN + 1];
+ char name[VM_MAX_SUFFIXLEN + 1];
};
struct vm_register {
Index: head/sys/amd64/vmm/vmm_dev.c
===================================================================
--- head/sys/amd64/vmm/vmm_dev.c
+++ head/sys/amd64/vmm/vmm_dev.c
@@ -245,7 +245,7 @@
return (error);
}
-CTASSERT(sizeof(((struct vm_memseg *)0)->name) >= SPECNAMELEN + 1);
+CTASSERT(sizeof(((struct vm_memseg *)0)->name) >= VM_MAX_SUFFIXLEN + 1);
static int
get_memseg(struct vmmdev_softc *sc, struct vm_memseg *mseg)
@@ -265,7 +265,8 @@
}
KASSERT(dsc != NULL, ("%s: devmem segment %d not found",
__func__, mseg->segid));
- error = copystr(dsc->name, mseg->name, SPECNAMELEN + 1, NULL);
+ error = copystr(dsc->name, mseg->name, sizeof(mseg->name),
+ NULL);
} else {
bzero(mseg->name, sizeof(mseg->name));
}
@@ -284,10 +285,14 @@
name = NULL;
sysmem = true;
+ /*
+ * The allocation is lengthened by 1 to hold a terminating NUL. It'll
+ * by stripped off when devfs processes the full string.
+ */
if (VM_MEMSEG_NAME(mseg)) {
sysmem = false;
- name = malloc(SPECNAMELEN + 1, M_VMMDEV, M_WAITOK);
- error = copystr(mseg->name, name, SPECNAMELEN + 1, 0);
+ name = malloc(sizeof(mseg->name) M_VMMDEV, M_WAITOK);
+ error = copystr(mseg->name, name, sizeof(mseg->name), NULL);
if (error)
goto done;
}
@@ -894,26 +899,29 @@
static int
sysctl_vmm_destroy(SYSCTL_HANDLER_ARGS)
{
- int error;
- char buf[VM_MAX_NAMELEN];
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);
- strlcpy(buf, "beavis", sizeof(buf));
- error = sysctl_handle_string(oidp, buf, sizeof(buf), req);
+ 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)
- return (error);
+ goto out;
mtx_lock(&vmmdev_mtx);
sc = vmmdev_lookup(buf);
if (sc == NULL || sc->cdev == NULL) {
mtx_unlock(&vmmdev_mtx);
- return (EINVAL);
+ error = EINVAL;
+ goto out;
}
/*
@@ -943,7 +951,11 @@
destroy_dev_sched_cb(dsc->cdev, devmem_destroy, dsc);
}
destroy_dev_sched_cb(cdev, vmmdev_destroy, sc);
- return (0);
+ error = 0;
+
+out:
+ free(buf, M_VMMDEV);
+ return (error);
}
SYSCTL_PROC(_hw_vmm, OID_AUTO, destroy,
CTLTYPE_STRING | CTLFLAG_RW | CTLFLAG_PRISON,
@@ -961,30 +973,34 @@
static int
sysctl_vmm_create(SYSCTL_HANDLER_ARGS)
{
- int error;
struct vm *vm;
struct cdev *cdev;
struct vmmdev_softc *sc, *sc2;
- char buf[VM_MAX_NAMELEN];
+ char *buf;
+ int error, buflen;
error = vmm_priv_check(req->td->td_ucred);
if (error)
return (error);
- strlcpy(buf, "beavis", sizeof(buf));
- error = sysctl_handle_string(oidp, buf, sizeof(buf), req);
+ 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)
- return (error);
+ goto out;
mtx_lock(&vmmdev_mtx);
sc = vmmdev_lookup(buf);
mtx_unlock(&vmmdev_mtx);
- if (sc != NULL)
- return (EEXIST);
+ if (sc != NULL) {
+ error = EEXIST;
+ goto out;
+ }
error = vm_create(buf, &vm);
if (error != 0)
- return (error);
+ goto out;
sc = malloc(sizeof(struct vmmdev_softc), M_VMMDEV, M_WAITOK | M_ZERO);
sc->vm = vm;
@@ -1004,14 +1020,15 @@
if (sc2 != NULL) {
vmmdev_destroy(sc);
- return (EEXIST);
+ error = EEXIST;
+ goto out;
}
error = make_dev_p(MAKEDEV_CHECKNAME, &cdev, &vmmdevsw, NULL,
UID_ROOT, GID_WHEEL, 0600, "vmm/%s", buf);
if (error != 0) {
vmmdev_destroy(sc);
- return (error);
+ goto out;
}
mtx_lock(&vmmdev_mtx);
@@ -1019,7 +1036,9 @@
sc->cdev->si_drv1 = sc;
mtx_unlock(&vmmdev_mtx);
- return (0);
+out:
+ free(buf, M_VMMDEV);
+ return (error);
}
SYSCTL_PROC(_hw_vmm, OID_AUTO, create,
CTLTYPE_STRING | CTLFLAG_RW | CTLFLAG_PRISON,

File Metadata

Mime Type
text/plain
Expires
Sat, Jan 17, 2:00 AM (5 h, 9 m)
Storage Engine
blob
Storage Format
Raw Data
Storage Handle
27676946
Default Alt Text
D20924.id59704.diff (5 KB)

Event Timeline