git: 5635d5b61e21 - main - vmm: Fix VM_GET_CPUS compatibility
- Go to: [ bottom of page ] [ top of archives ] [ this month ]
Date: Thu, 17 Aug 2023 22:11:32 UTC
The branch main has been updated by markj: URL: https://cgit.FreeBSD.org/src/commit/?id=5635d5b61e2113b91db921267cb476b1fde93e9e commit 5635d5b61e2113b91db921267cb476b1fde93e9e Author: Mark Johnston <markj@FreeBSD.org> AuthorDate: 2023-08-17 18:49:54 +0000 Commit: Mark Johnston <markj@FreeBSD.org> CommitDate: 2023-08-17 22:10:02 +0000 vmm: Fix VM_GET_CPUS compatibility bhyve in a 13.x jail fails to boot guests with more than one vCPU because they pass too small a buffer to VM_GET_CPUS, causing the ioctl handler to return ERANGE. Handle this the same way as cpuset system calls: make sure that the result can fit in the truncated space, and relax the check on the cpuset buffer. As a side effect, fix an insufficient bounds check on "size". The signed/unsigned comparison with sizeof(cpuset_t) fails to exclude negative values, so we can end up allocating impossibly large amounts of memory. Reviewed by: jhb MFC after: 1 week Sponsored by: The FreeBSD Foundation Differential Revision: https://reviews.freebsd.org/D41496 --- sys/amd64/vmm/vmm_dev.c | 7 +++++-- 1 file changed, 5 insertions(+), 2 deletions(-) diff --git a/sys/amd64/vmm/vmm_dev.c b/sys/amd64/vmm/vmm_dev.c index c13adfd599ee..cae15d7059cb 100644 --- a/sys/amd64/vmm/vmm_dev.c +++ b/sys/amd64/vmm/vmm_dev.c @@ -989,11 +989,12 @@ vmmdev_ioctl(struct cdev *cdev, u_long cmd, caddr_t data, int fflag, error = 0; vm_cpuset = (struct vm_cpuset *)data; size = vm_cpuset->cpusetsize; - if (size < sizeof(cpuset_t) || size > CPU_MAXSIZE / NBBY) { + if (size < 1 || size > CPU_MAXSIZE / NBBY) { error = ERANGE; break; } - cpuset = malloc(size, M_TEMP, M_WAITOK | M_ZERO); + cpuset = malloc(max(size, sizeof(cpuset_t)), M_TEMP, + M_WAITOK | M_ZERO); if (vm_cpuset->which == VM_ACTIVE_CPUS) *cpuset = vm_active_cpus(sc->vm); else if (vm_cpuset->which == VM_SUSPENDED_CPUS) @@ -1002,6 +1003,8 @@ vmmdev_ioctl(struct cdev *cdev, u_long cmd, caddr_t data, int fflag, *cpuset = vm_debug_cpus(sc->vm); else error = EINVAL; + if (error == 0 && size < howmany(CPU_FLS(cpuset), NBBY)) + error = ERANGE; if (error == 0) error = copyout(cpuset, vm_cpuset->cpus, size); free(cpuset, M_TEMP);