diff options
author | Reyk Floeter <reyk@cvs.openbsd.org> | 2016-02-05 11:40:16 +0000 |
---|---|---|
committer | Reyk Floeter <reyk@cvs.openbsd.org> | 2016-02-05 11:40:16 +0000 |
commit | e9772fcb0a0669a80dfbec5c5f44f41bd9b08458 (patch) | |
tree | d20969eb8f7a21fd40f5f000b2c0b4f119883aad /usr.sbin | |
parent | 2e9d74fac9361a749231e714e5b003c102dfd18d (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.c | 39 |
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); |