Skip to contentSkip to conversation

Fix pointer dereference before call to pcie_bus_configure_settings

PATCH In review Linus Torvalds 2 participants 3 messages Sep 10, 2011 1 message not in the archive

Subsystems (3)
lore
Share & tools
lore

A message that is not in the archive (sent off-list or not yet received): [email protected]

#1 lore raw

Jon Mason,
I just noticed that you had just an "Acked-by:" on this one. It
really should be a "Signed-off-by:" since it's passing through you. Can I get that?

Also, the commit message is a bit unclear. "introduces a few issues"? Can you guys elaborate on details? Oopses? Not being able to find devices? What?

Linus

Quoted 68 lines · Jon Mason

From: Shyam Iyer <[email protected]>

Commit b03e7495a862b028294f59fc87286d6d78ee7fa1 introduces a few issues by dereferencing bus->self in the call to pcie_bus_configure_settings.

This fixes it by checking existence of bus->self before dereferencing it.

---
 arch/x86/pci/acpi.c              |    9 +++++++-- drivers/pci/hotplug/pcihp_slot.c |    4 +++- drivers/pci/probe.c              |    3 ---

 3 files changed, 10 insertions(+), 6 deletions(-)
arch/x86/pci/acpi.c +7 -2
index c953302..039d913 100644
@@ -365,8 +365,13 @@ struct pci_bus * __devinit pci_acpi_scan_root(struct acpi_pci_root *root)
         */
        if (bus) {
                struct pci_bus *child;
-               list_for_each_entry(child, &bus->children, node)
-                       pcie_bus_configure_settings(child, child->self->pcie_mpss);
+               list_for_each_entry(child, &bus->children, node) {
+                       struct pci_dev *self = child->self;
+                       if (!self)
+                               continue;
+
+                       pcie_bus_configure_settings(child, self->pcie_mpss);
+               }
        }
 
        if (!bus)
drivers/pci/hotplug/pcihp_slot.c +3 -1
index 753b21a..3ffd9c1 100644
@@ -169,7 +169,9 @@ void pci_configure_slot(struct pci_dev *dev)
                        (dev->class >> 8) == PCI_CLASS_BRIDGE_PCI)))
                return;
 
-       pcie_bus_configure_settings(dev->bus, dev->bus->self->pcie_mpss);
+       if (dev->bus && dev->bus->self)
+               pcie_bus_configure_settings(dev->bus,
+                                           dev->bus->self->pcie_mpss);
 
        memset(&hpp, 0, sizeof(hpp));
        ret = pci_get_hp_params(dev, &hpp);
drivers/pci/probe.c +0 -4
index 8473727..0820fc1 100644
@@ -1456,9 +1456,6 @@ void pcie_bus_configure_settings(struct pci_bus *bus, u8 mpss)
  {
        u8 smpss = mpss;
 
-       if (!bus->self)
-               return;
-
        if (!pci_is_pcie(bus->self))
                return;
 
--

1.7.6

#2 lore raw

PATCH 1/2 Fix pointer dereference before call to pcie_bus_configure_settings

There is a potential NULL pointer dereference in calls to pcie_bus_configure_settings due to attempts to access pci_bus self variables when the self pointer is NULL. To correct this, verify that the self pointer in pci_bus is non-NULL before dereferencing it.

arch/x86/pci/acpi.c +7 -2
index c953302..039d913 100644
@@ -365,8 +365,13 @@ struct pci_bus * __devinit pci_acpi_scan_root(struct acpi_pci_root *root)
 	 */
 	if (bus) {
 		struct pci_bus *child;
-		list_for_each_entry(child, &bus->children, node)
-			pcie_bus_configure_settings(child, child->self->pcie_mpss);
+		list_for_each_entry(child, &bus->children, node) {
+			struct pci_dev *self = child->self;
+			if (!self)
+				continue;
+
+			pcie_bus_configure_settings(child, self->pcie_mpss);
+		}
 	}
 
 	if (!bus)
drivers/pci/hotplug/pcihp_slot.c +3 -1
index 753b21a..3ffd9c1 100644
@@ -169,7 +169,9 @@ void pci_configure_slot(struct pci_dev *dev)
 			(dev->class >> 8) == PCI_CLASS_BRIDGE_PCI)))
 		return;
 
-	pcie_bus_configure_settings(dev->bus, dev->bus->self->pcie_mpss);
+	if (dev->bus && dev->bus->self)
+		pcie_bus_configure_settings(dev->bus,
+					    dev->bus->self->pcie_mpss);
 
 	memset(&hpp, 0, sizeof(hpp));
 	ret = pci_get_hp_params(dev, &hpp);
drivers/pci/probe.c +0 -3
index 8473727..0820fc1 100644
@@ -1456,9 +1456,6 @@ void pcie_bus_configure_settings(struct pci_bus *bus, u8 mpss)
 {
 	u8 smpss = mpss;
 
-	if (!bus->self)
-		return;
-
 	if (!pci_is_pcie(bus->self))
 		return;
 
#3 lore raw
Quoted 5 lines · Jon Mason

There is a potential NULL pointer dereference in calls to pcie_bus_configure_settings due to attempts to access pci_bus self variables when the self pointer is NULL.  To correct this, verify that the self pointer in pci_bus is non-NULL before dereferencing it.

Thanks,

Linus