From mboxrd@z Thu Jan 1 00:00:00 1970 Received: from eggs.gnu.org ([2001:4830:134:3::10]:43042) by lists.gnu.org with esmtp (Exim 4.71) (envelope-from ) id 1YLasG-0002wj-K1 for qemu-devel@nongnu.org; Wed, 11 Feb 2015 12:14:57 -0500 Received: from Debian-exim by eggs.gnu.org with spam-scanned (Exim 4.71) (envelope-from ) id 1YLasA-0002yb-Oe for qemu-devel@nongnu.org; Wed, 11 Feb 2015 12:14:52 -0500 Received: from mail-wi0-x229.google.com ([2a00:1450:400c:c05::229]:39789) by eggs.gnu.org with esmtp (Exim 4.71) (envelope-from ) id 1YLasA-0002yQ-IA for qemu-devel@nongnu.org; Wed, 11 Feb 2015 12:14:46 -0500 Received: by mail-wi0-f169.google.com with SMTP id em10so1919254wid.0 for ; Wed, 11 Feb 2015 09:14:46 -0800 (PST) Sender: Paolo Bonzini From: Paolo Bonzini Date: Wed, 11 Feb 2015 18:14:32 +0100 Message-Id: <1423674872-10676-4-git-send-email-pbonzini@redhat.com> In-Reply-To: <1423674872-10676-1-git-send-email-pbonzini@redhat.com> References: <1423674872-10676-1-git-send-email-pbonzini@redhat.com> Subject: [Qemu-devel] [PATCH 3/3] memory: keep the owner of the AddressSpace alive until do_address_space_destroy List-Id: List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , To: qemu-devel@nongnu.org Cc: mdroth@linux.vnet.ibm.com This fixes a use-after-free if do_address_space_destroy is executed too late. Signed-off-by: Paolo Bonzini --- memory.c | 5 +++++ 1 file changed, 5 insertions(+) diff --git a/memory.c b/memory.c index 130152c..20f6d9e 100644 --- a/memory.c +++ b/memory.c @@ -1943,6 +1943,7 @@ void memory_listener_unregister(MemoryListener *listener) void address_space_init(AddressSpace *as, MemoryRegion *root, const char *name) { + memory_region_ref(root); memory_region_transaction_begin(); as->root = root; as->current_map = g_new(FlatView, 1); @@ -1969,10 +1970,13 @@ static void do_address_space_destroy(AddressSpace *as) flatview_unref(as->current_map); g_free(as->name); g_free(as->ioeventfds); + memory_region_unref(as->root); } void address_space_destroy(AddressSpace *as) { + MemoryRegion *root = as->root; + /* Flush out anything from MemoryListeners listening in on this */ memory_region_transaction_begin(); as->root = NULL; @@ -1984,6 +1988,7 @@ void address_space_destroy(AddressSpace *as) * entries that the guest should never use. Wait for the old * values to expire before freeing the data. */ + as->root = root; call_rcu(as, do_address_space_destroy, rcu); } -- 1.8.3.1