Skip to contentSkip to conversation

Patch "KVM: kvm_io_bus_unregister_dev() should never fail" has been added to the 4.9-stable tree

PATCH [email protected] 1 participant 1 message Apr 3, 2017

Subsystems (2)
lore
Share & tools
lore

[email protected]

author maintainer Applied
#0 lore raw

This is a note to let you know that I've just added the patch titled

KVM: kvm_io_bus_unregister_dev() should never fail

to the 4.9-stable tree which can be found at:
http://www.kernel.org/git/?p=linux/kernel/git/stable/stable-queue.git;a=summary

The filename of the patch is:
kvm-kvm_io_bus_unregister_dev-should-never-fail.patch
and it can be found in the queue-4.9 subdirectory.

If you, or anyone else, feels it should not be added to the stable tree, please let <[email protected]> know about it.

Quoted 1 line

From 90db10434b163e46da413d34db8d0e77404cc645 Mon Sep 17 00:00:00 2001

From: David Hildenbrand <[email protected]>
Date: Thu, 23 Mar 2017 18:24:19 +0100
Subject: KVM: kvm_io_bus_unregister_dev() should never fail

From: David Hildenbrand <[email protected]>

commit 90db10434b163e46da413d34db8d0e77404cc645 upstream.

No caller currently checks the return value of kvm_io_bus_unregister_dev(). This is evil, as all callers silently go on freeing their device. A stale reference will remain in the io_bus, getting at least used again, when the iobus gets teared down on kvm_destroy_vm() - leading to use after free errors.

There is nothing the callers could do, except retrying over and over again.

So let's simply remove the bus altogether, print an error and make sure no one can access this broken bus again (returning -ENOMEM on any attempt to access it).

---
 include/linux/kvm_host.h |    4 ++--
 virt/kvm/eventfd.c       |    3 ++-
 virt/kvm/kvm_main.c      |   42 +++++++++++++++++++++++++-----------------
 3 files changed, 29 insertions(+), 20 deletions(-)
include/linux/kvm_host.h +2 -2
@@ -162,8 +162,8 @@ int kvm_io_bus_read(struct kvm_vcpu *vcp
 		    int len, void *val);
 int kvm_io_bus_register_dev(struct kvm *kvm, enum kvm_bus bus_idx, gpa_t addr,
 			    int len, struct kvm_io_device *dev);
-int kvm_io_bus_unregister_dev(struct kvm *kvm, enum kvm_bus bus_idx,
-			      struct kvm_io_device *dev);
+void kvm_io_bus_unregister_dev(struct kvm *kvm, enum kvm_bus bus_idx,
+			       struct kvm_io_device *dev);
 struct kvm_io_device *kvm_io_bus_get_dev(struct kvm *kvm, enum kvm_bus bus_idx,
 					 gpa_t addr);
 
virt/kvm/eventfd.c +2 -1
@@ -870,7 +870,8 @@ kvm_deassign_ioeventfd_idx(struct kvm *k
 			continue;
 
 		kvm_io_bus_unregister_dev(kvm, bus_idx, &p->dev);
-		kvm->buses[bus_idx]->ioeventfd_count--;
+		if (kvm->buses[bus_idx])
+			kvm->buses[bus_idx]->ioeventfd_count--;
 		ioeventfd_release(p);
 		ret = 0;
 		break;
virt/kvm/kvm_main.c +25 -17

107 lines not on this page · raw message

Patches currently in stable-queue which might be from [email protected] are

queue-4.9/kvm-kvm_io_bus_unregister_dev-should-never-fail.patch