From mboxrd@z Thu Jan 1 00:00:00 1970 Return-Path: Received: from rcsinet15.oracle.com ([148.87.113.117]:30770 "EHLO rcsinet15.oracle.com" rhost-flags-OK-OK-OK-OK) by vger.kernel.org with ESMTP id S1161488Ab2CSFsE (ORCPT ); Mon, 19 Mar 2012 01:48:04 -0400 From: Yinghai Lu To: Jesse Barnes , x86 Cc: Bjorn Helgaas , Andrew Morton , Linus Torvalds , Greg Kroah-Hartman , linux-pci@vger.kernel.org, linux-kernel@vger.kernel.org, Jiang Liu , Yinghai Lu Subject: [PATCH -v3 25/47] Fix an access-after-free issue in function pci_stop_and_remove_bus() Date: Sun, 18 Mar 2012 22:46:14 -0700 Message-Id: <1332135996-13860-26-git-send-email-yinghai@kernel.org> In-Reply-To: <1332135996-13860-1-git-send-email-yinghai@kernel.org> References: <1332135996-13860-1-git-send-email-yinghai@kernel.org> Sender: linux-pci-owner@vger.kernel.org List-ID: From: Jiang Liu If pci_stop_and_remove_bus() is called to remove a pci root bus, the host_bridge structure may have already been freed after returning from pci_remove_bus(). To avoid that, hold an extra reference count to the root bus before calling pci_remove_bus(), so we can safely access the pci_host_bridge structure after returning from function pci_remove_bus(). Signed-off-by: Jiang Liu Signed-off-by: Yinghai Lu --- drivers/pci/remove.c | 5 ++++- 1 files changed, 4 insertions(+), 1 deletions(-) diff --git a/drivers/pci/remove.c b/drivers/pci/remove.c index 75b0092..18efb31 100644 --- a/drivers/pci/remove.c +++ b/drivers/pci/remove.c @@ -186,6 +186,7 @@ void pci_stop_and_remove_bus(struct pci_bus *bus) if (pci_is_root_bus(bus)) { host_bridge = to_pci_host_bridge(bus->bridge); + get_device(&host_bridge->dev); pci_stop_host_bridge(host_bridge); } else pci_bridge = bus->self; @@ -194,8 +195,10 @@ void pci_stop_and_remove_bus(struct pci_bus *bus) pci_remove_bus(bus); - if (host_bridge) + if (host_bridge) { host_bridge->bus = NULL; + put_device(&host_bridge->dev); + } if (pci_bridge) pci_bridge->subordinate = NULL; -- 1.7.7