diff options
author | anton <anton@cvs.openbsd.org> | 2019-09-11 16:55:54 +0000 |
---|---|---|
committer | anton <anton@cvs.openbsd.org> | 2019-09-11 16:55:54 +0000 |
commit | 439c1ac46ef55f839cbcf61ab7414bb2e8fb0498 (patch) | |
tree | 0ade2e4f29257b1c357c85a41fd3d44b585633de /sys/arch | |
parent | 682c42190b52237f52c1e21ccdb2e84a91de84a9 (diff) |
vm_teardown() must be serialized since it modifies the global vmm_softc
structure. Therefore grab the appropriate lock before calling the same
function. This issue has been known for a while and reported before but
lacking a way to easily reproduce it; until syzkaller came up with a
reproducer.
ok mlarkin@
Reported-by: syzbot+39ff060789d93be0084f@syzkaller.appspotmail.com
Diffstat (limited to 'sys/arch')
-rw-r--r-- | sys/arch/amd64/amd64/vmm.c | 13 |
1 files changed, 10 insertions, 3 deletions
diff --git a/sys/arch/amd64/amd64/vmm.c b/sys/arch/amd64/amd64/vmm.c index ac836690ab6..35c571e2a0b 100644 --- a/sys/arch/amd64/amd64/vmm.c +++ b/sys/arch/amd64/amd64/vmm.c @@ -1,4 +1,4 @@ -/* $OpenBSD: vmm.c,v 1.252 2019/09/10 19:36:12 anton Exp $ */ +/* $OpenBSD: vmm.c,v 1.253 2019/09/11 16:55:53 anton Exp $ */ /* * Copyright (c) 2014 Mike Larkin <mlarkin@openbsd.org> * @@ -1161,14 +1161,16 @@ vm_create(struct vm_create_params *vcp, struct proc *p) vm->vm_memory_size = memsize; strncpy(vm->vm_name, vcp->vcp_name, VMM_MAX_NAME_LEN); + rw_enter_write(&vmm_softc->vm_lock); + if (vm_impl_init(vm, p)) { printf("failed to init arch-specific features for vm 0x%p\n", vm); vm_teardown(vm); + rw_exit_write(&vmm_softc->vm_lock); return (ENOMEM); } - rw_enter_write(&vmm_softc->vm_lock); vmm_softc->vm_ct++; vmm_softc->vm_idx++; @@ -3408,6 +3410,8 @@ vm_teardown(struct vm *vm) { struct vcpu *vcpu, *tmp; + rw_assert_wrlock(&vmm_softc->vm_lock); + /* Free VCPUs */ rw_enter_write(&vm->vm_vcpu_lock); SLIST_FOREACH_SAFE(vcpu, &vm->vm_vcpu_list, vc_vcpu_link, tmp) { @@ -3910,8 +3914,11 @@ vm_run(struct vm_run_params *vrp) if (vcpu->vc_state == VCPU_STATE_REQTERM) { vrp->vrp_exit_reason = VM_EXIT_TERMINATED; vcpu->vc_state = VCPU_STATE_TERMINATED; - if (vm->vm_vcpus_running == 0) + if (vm->vm_vcpus_running == 0) { + rw_enter_write(&vmm_softc->vm_lock); vm_teardown(vm); + rw_exit_write(&vmm_softc->vm_lock); + } ret = 0; } else if (ret == EAGAIN) { /* If we are exiting, populate exit data so vmd can help. */ |