lists.openwall.net   lists  /  announce  owl-users  owl-dev  john-users  john-dev  passwdqc-users  yescrypt  popa3d-users  /  oss-security  kernel-hardening  musl  sabotage  tlsify  passwords  /  crypt-dev  xvendor  /  Bugtraq  Full-Disclosure  linux-kernel  linux-netdev  linux-ext4  linux-hardening  linux-cve-announce  PHC 
Open Source and information security mailing list archives
 
Hash Suite: Windows password security audit tool. GUI, reports in PDF.
[<prev] [next>] [<thread-prev] [thread-next>] [day] [month] [year] [list]
Message-ID: <lsq.1544392233.871357983@decadent.org.uk>
Date:   Sun, 09 Dec 2018 21:50:33 +0000
From:   Ben Hutchings <ben@...adent.org.uk>
To:     linux-kernel@...r.kernel.org, stable@...r.kernel.org
CC:     akpm@...ux-foundation.org, "Lukas Wunner" <lukas@...ner.de>,
        "Bjorn Helgaas" <bhelgaas@...gle.com>
Subject: [PATCH 3.16 052/328] PCI: pciehp: Fix unprotected list iteration
 in IRQ handler

3.16.62-rc1 review patch.  If anyone has any objections, please let me know.

------------------

From: Lukas Wunner <lukas@...ner.de>

commit 1204e35bedf4e5015cda559ed8c84789a6dae24e upstream.

Commit b440bde74f04 ("PCI: Add pci_ignore_hotplug() to ignore hotplug
events for a device") iterates over the devices on a hotplug port's
subordinate bus in pciehp's IRQ handler without acquiring pci_bus_sem.
It is thus possible for a user to cause a crash by concurrently
manipulating the device list, e.g. by disabling slot power via sysfs
on a different CPU or by initiating a remove/rescan via sysfs.

This can't be fixed by acquiring pci_bus_sem because it may sleep.
The simplest fix is to avoid the list iteration altogether and just
check the ignore_hotplug flag on the port itself.  This works because
pci_ignore_hotplug() sets the flag both on the device as well as on its
parent bridge.

We do lose the ability to print the name of the device blocking hotplug
in the debug message, but that's probably bearable.

Fixes: b440bde74f04 ("PCI: Add pci_ignore_hotplug() to ignore hotplug events for a device")
Signed-off-by: Lukas Wunner <lukas@...ner.de>
Signed-off-by: Bjorn Helgaas <bhelgaas@...gle.com>
[bwh: Backported to 3.16: s/events/intr_loc/]
Signed-off-by: Ben Hutchings <ben@...adent.org.uk>
---
 drivers/pci/hotplug/pciehp_hpc.c | 13 +++----------
 1 file changed, 3 insertions(+), 10 deletions(-)

--- a/drivers/pci/hotplug/pciehp_hpc.c
+++ b/drivers/pci/hotplug/pciehp_hpc.c
@@ -508,8 +508,6 @@ static irqreturn_t pcie_isr(int irq, voi
 {
 	struct controller *ctrl = (struct controller *)dev_id;
 	struct pci_dev *pdev = ctrl_dev(ctrl);
-	struct pci_bus *subordinate = pdev->subordinate;
-	struct pci_dev *dev;
 	struct slot *slot = ctrl->slot;
 	u16 detected, intr_loc;
 
@@ -543,14 +541,9 @@ static irqreturn_t pcie_isr(int irq, voi
 		wake_up(&ctrl->queue);
 	}
 
-	if (subordinate) {
-		list_for_each_entry(dev, &subordinate->devices, bus_list) {
-			if (dev->ignore_hotplug) {
-				ctrl_dbg(ctrl, "ignoring hotplug event %#06x (%s requested no hotplug)\n",
-					 intr_loc, pci_name(dev));
-				return IRQ_HANDLED;
-			}
-		}
+	if (pdev->ignore_hotplug) {
+		ctrl_dbg(ctrl, "ignoring hotplug event %#06x\n", intr_loc);
+		return IRQ_HANDLED;
 	}
 
 	if (!(intr_loc & ~PCI_EXP_SLTSTA_CC))

Powered by blists - more mailing lists

Powered by Openwall GNU/*/Linux Powered by OpenVZ