summaryrefslogtreecommitdiff
path: root/usr.sbin
diff options
context:
space:
mode:
authorReyk Floeter <reyk@cvs.openbsd.org>2016-02-05 11:40:16 +0000
committerReyk Floeter <reyk@cvs.openbsd.org>2016-02-05 11:40:16 +0000
commite9772fcb0a0669a80dfbec5c5f44f41bd9b08458 (patch)
treed20969eb8f7a21fd40f5f000b2c0b4f119883aad /usr.sbin
parent2e9d74fac9361a749231e714e5b003c102dfd18d (diff)
Fix a possible use-after-free in vmd, forward the result to the
control socket before free'ing the vm. Found by and OK jsg@
Diffstat (limited to 'usr.sbin')
-rw-r--r--usr.sbin/vmd/vmd.c39
1 files changed, 23 insertions, 16 deletions
diff --git a/usr.sbin/vmd/vmd.c b/usr.sbin/vmd/vmd.c
index 3504b18d105..03ec2c1620a 100644
--- a/usr.sbin/vmd/vmd.c
+++ b/usr.sbin/vmd/vmd.c
@@ -1,4 +1,4 @@
-/* $OpenBSD: vmd.c,v 1.26 2016/02/02 17:51:11 sthen Exp $ */
+/* $OpenBSD: vmd.c,v 1.27 2016/02/05 11:40:15 reyk Exp $ */
/*
* Copyright (c) 2015 Reyk Floeter <reyk@openbsd.org>
@@ -149,29 +149,36 @@ vmd_dispatch_vmm(int fd, struct privsep_proc *p, struct imsg *imsg)
if ((vm = vm_getbyvmid(imsg->hdr.peerid)) == NULL)
fatalx("%s: invalid vm response", __func__);
vcp = &vm->vm_params;
+ vcp->vcp_id = vmr.vmr_id;
+
+ /*
+ * If the peerid is not -1, forward the response back to the
+ * the control socket. If it is -1, the request originated
+ * from the parent, not the control socket.
+ */
+ if (vm->vm_peerid != (uint32_t)-1) {
+ vmr.vmr_result = res;
+ (void)strlcpy(vmr.vmr_ttyname, vm->vm_ttyname,
+ sizeof(vmr.vmr_ttyname));
+ if (proc_compose_imsg(ps, PROC_CONTROL, -1,
+ imsg->hdr.type, vm->vm_peerid, -1,
+ &vmr, sizeof(vmr)) == -1) {
+ errno = vmr.vmr_result;
+ log_warn("%s: failed to foward vm result",
+ vcp->vcp_name);
+ vm_remove(vm);
+ return (-1);
+ }
+ }
+
if (vmr.vmr_result) {
errno = vmr.vmr_result;
log_warn("%s: failed to start vm", vcp->vcp_name);
vm_remove(vm);
} else {
- vcp->vcp_id = vmr.vmr_id;
log_info("%s: started vm %d successfully, tty %s",
vcp->vcp_name, vcp->vcp_id, vm->vm_ttyname);
}
- /*
- * If the peerid is -1, the request originated from
- * the parent, not the control socket.
- */
- if (vm->vm_peerid == (uint32_t)-1)
- break;
- vmr.vmr_result = res;
- (void)strlcpy(vmr.vmr_ttyname, vm->vm_ttyname,
- sizeof(vmr.vmr_ttyname));
- if (proc_compose_imsg(ps, PROC_CONTROL, -1, imsg->hdr.type,
- vm->vm_peerid, -1, &vmr, sizeof(vmr)) == -1) {
- vm_remove(vm);
- return (-1);
- }
break;
case IMSG_VMDOP_TERMINATE_VM_RESPONSE:
IMSG_SIZE_CHECK(imsg, &vmr);