aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorMike Qiu <qiudayu@linux.vnet.ibm.com>2014-04-14 18:12:35 -0400
committerBjorn Helgaas <bhelgaas@google.com>2014-04-14 18:33:49 -0400
commit140ab6452c42174d20e2fdd27ed73b889cd86500 (patch)
tree6cc7d886506931f27419040efd98e096508fb501
parentc9eaa447e77efe77b7fa4c953bd62de8297fd6c5 (diff)
powerpc/PCI: Fix NULL dereference in sys_pciconfig_iobase() list traversal
3bc955987fb3 ("powerpc/PCI: Use list_for_each_entry() for bus traversal") caused a NULL pointer dereference because the loop body set the iterator to NULL: Unable to handle kernel paging request for data at address 0x00000000 Faulting instruction address: 0xc000000000041d78 Oops: Kernel access of bad area, sig: 11 [#1] ... NIP [c000000000041d78] .sys_pciconfig_iobase+0x68/0x1f0 LR [c000000000041e0c] .sys_pciconfig_iobase+0xfc/0x1f0 Call Trace: [c0000003b4787db0] [c000000000041e0c] .sys_pciconfig_iobase+0xfc/0x1f0 (unreliable) [c0000003b4787e30] [c000000000009ed8] syscall_exit+0x0/0x98 Fix it by using a temporary variable for the iterator. [bhelgaas: changelog, drop tmp_bus initialization] Fixes: 3bc955987fb3 powerpc/PCI: Use list_for_each_entry() for bus traversal Signed-off-by: Mike Qiu <qiudayu@linux.vnet.ibm.com> Signed-off-by: Bjorn Helgaas <bhelgaas@google.com>
-rw-r--r--arch/powerpc/kernel/pci_64.c10
1 files changed, 6 insertions, 4 deletions
diff --git a/arch/powerpc/kernel/pci_64.c b/arch/powerpc/kernel/pci_64.c
index 2a4779091a58..155013da27e0 100644
--- a/arch/powerpc/kernel/pci_64.c
+++ b/arch/powerpc/kernel/pci_64.c
@@ -208,7 +208,7 @@ long sys_pciconfig_iobase(long which, unsigned long in_bus,
208 unsigned long in_devfn) 208 unsigned long in_devfn)
209{ 209{
210 struct pci_controller* hose; 210 struct pci_controller* hose;
211 struct pci_bus *bus = NULL; 211 struct pci_bus *tmp_bus, *bus = NULL;
212 struct device_node *hose_node; 212 struct device_node *hose_node;
213 213
214 /* Argh ! Please forgive me for that hack, but that's the 214 /* Argh ! Please forgive me for that hack, but that's the
@@ -229,10 +229,12 @@ long sys_pciconfig_iobase(long which, unsigned long in_bus,
229 * used on pre-domains setup. We return the first match 229 * used on pre-domains setup. We return the first match
230 */ 230 */
231 231
232 list_for_each_entry(bus, &pci_root_buses, node) { 232 list_for_each_entry(tmp_bus, &pci_root_buses, node) {
233 if (in_bus >= bus->number && in_bus <= bus->busn_res.end) 233 if (in_bus >= tmp_bus->number &&
234 in_bus <= tmp_bus->busn_res.end) {
235 bus = tmp_bus;
234 break; 236 break;
235 bus = NULL; 237 }
236 } 238 }
237 if (bus == NULL || bus->dev.of_node == NULL) 239 if (bus == NULL || bus->dev.of_node == NULL)
238 return -ENODEV; 240 return -ENODEV;