FAILED: patch "[PATCH] KVM: fix memory leak in kvm_io_bus_unregister_dev()" failed to apply to 4.4-stable tree
Subsystems (2)
[email protected]
maintainerThe patch below does not apply to the 4.4-stable tree.
If someone wants it applied there, or to any other stable or longterm tree, then please email the backport, including the original git commit id to <[email protected]>.
thanks,
greg k-h
------------------ original commit in Linus's tree ------------------
From f65886606c2d3b562716de030706dfe1bea4ed5e Mon Sep 17 00:00:00 2001
From: Rustam Kovhaev <[email protected]>
Date: Mon, 7 Sep 2020 11:55:35 -0700
Subject: [PATCH] KVM: fix memory leak in kvm_io_bus_unregister_dev()
when kmalloc() fails in kvm_io_bus_unregister_dev(), before removing the bus, we should iterate over all other devices linked to it and call kvm_iodevice_destructor() for them
Fixes 90db10434b16 ("KVM: kvm_io_bus_unregister_dev() should never fail")
Reported-and-tested-by [email protected]
Signed-off-by Rustam Kovhaev <[email protected]>
Reviewed-by Vitaly Kuznetsov <[email protected]>
Message-Id: <[email protected]>
Signed-off-by Paolo Bonzini <[email protected]>
virt/kvm/kvm_main.c +12 -9
@@ -4332,7 +4332,7 @@ int kvm_io_bus_register_dev(struct kvm *kvm, enum kvm_bus bus_idx, gpa_t addr,void kvm_io_bus_unregister_dev (struct kvm *kvm,enum kvm_bus bus_idx,struct kvm_io_device *dev) { -int i; +int i, j;struct kvm_io_bus *new_bus, *bus; bus =kvm_get_bus (kvm, bus_idx);
@@ -4349,17 +4349,20 @@ void kvm_io_bus_unregister_dev(struct kvm *kvm, enum kvm_bus bus_idx, new_bus =kmalloc (struct_size (bus, range, bus->dev_count -1 ),GFP_KERNEL_ACCOUNT ); -if (!new_bus) { +if (new_bus) { +memcpy (new_bus, bus,sizeof (*bus) + i *sizeof (struct kvm_io_range )); + new_bus->dev_count--; +memcpy (new_bus->range + i, bus->range + i +1 , + (new_bus->dev_count - i) *sizeof (struct kvm_io_range )); + }else {pr_err ("kvm: failed to shrink bus, removing it completely\n" ); - goto broken; +for (j =0 ; j < bus->dev_count; j++) { +if (j == i) +continue ; +kvm_iodevice_destructor (bus->range[j].dev); + } } -memcpy (new_bus, bus,sizeof (*bus) + i *sizeof (struct kvm_io_range )); - new_bus->dev_count--; -memcpy (new_bus->range + i, bus->range + i +1 , - (new_bus->dev_count - i) *sizeof (struct kvm_io_range )); - -broken:rcu_assign_pointer (kvm->buses[bus_idx], new_bus);synchronize_srcu_expedited (&kvm->srcu);kfree (bus);