Skip to content

Commit 2ee3757

Browse files
sean-jcbonzini
authored andcommitted
KVM: Destroy I/O bus devices on unregister failure _after_ sync'ing SRCU
If allocating a new instance of an I/O bus fails when unregistering a device, wait to destroy the device until after all readers are guaranteed to see the new null bus. Destroying devices before the bus is nullified could lead to use-after-free since readers expect the devices on their reference of the bus to remain valid. Fixes: f658866 ("KVM: fix memory leak in kvm_io_bus_unregister_dev()") Cc: [email protected] Signed-off-by: Sean Christopherson <[email protected]> Message-Id: <[email protected]> Signed-off-by: Paolo Bonzini <[email protected]>
1 parent 24e7475 commit 2ee3757

File tree

1 file changed

+7
-3
lines changed

1 file changed

+7
-3
lines changed

virt/kvm/kvm_main.c

Lines changed: 7 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -4646,7 +4646,13 @@ void kvm_io_bus_unregister_dev(struct kvm *kvm, enum kvm_bus bus_idx,
46464646
new_bus->dev_count--;
46474647
memcpy(new_bus->range + i, bus->range + i + 1,
46484648
flex_array_size(new_bus, range, new_bus->dev_count - i));
4649-
} else {
4649+
}
4650+
4651+
rcu_assign_pointer(kvm->buses[bus_idx], new_bus);
4652+
synchronize_srcu_expedited(&kvm->srcu);
4653+
4654+
/* Destroy the old bus _after_ installing the (null) bus. */
4655+
if (!new_bus) {
46504656
pr_err("kvm: failed to shrink bus, removing it completely\n");
46514657
for (j = 0; j < bus->dev_count; j++) {
46524658
if (j == i)
@@ -4655,8 +4661,6 @@ void kvm_io_bus_unregister_dev(struct kvm *kvm, enum kvm_bus bus_idx,
46554661
}
46564662
}
46574663

4658-
rcu_assign_pointer(kvm->buses[bus_idx], new_bus);
4659-
synchronize_srcu_expedited(&kvm->srcu);
46604664
kfree(bus);
46614665
return;
46624666
}

0 commit comments

Comments
 (0)