All of lore.kernel.org
 help / color / mirror / Atom feed
From: "Rafael J. Wysocki" <rjw@sisk.pl>
To: Len Brown <lenb@kernel.org>
Cc: chepioq@gmail.com, Alex Chiang <achiang@hp.com>,
	Linux PCI <linux-pci@vger.kernel.org>,
	LKML <linux-kernel@vger.kernel.org>,
	Jesse Barnes <jbarnes@virtuousgeek.org>,
	ACPI Devel Maling List <linux-acpi@vger.kernel.org>,
	Danny Feng <dfeng@redhat.com>,
	pm list <linux-pm@lists.linux-foundation.org>
Subject: [PATCH] ACPI / PCI: Fix NULL pointer dereference in acpi_get_pci_dev()
Date: Tue, 6 Oct 2009 01:30:43 +0200	[thread overview]
Message-ID: <200910060130.43246.rjw@sisk.pl> (raw)

From: Rafael J. Wysocki <rjw@sisk.pl>

acpi_get_pci_dev() assumes that every handle it finds in the ACPI CA
name space, between given device handle and the PCI root bridge
handle, corresponds to a PCI-to-PCI bridge with an existing secondary
bus.  For this reason, when it finds a struct pci_dev object
corresponding to one of them, it doesn't check if its 'subordinate'
field is a valid pointer.

However, during resume from a sleep state, as well as at startup, we
may get a dock notification, via dock_acpi_notifier registered by
dock_init(), for a docking station device that is present in the ACPI
tables, but not physically accessible at the moment.  In that
situation, the device appears to be below a PCI bridge whose
'subordinate' field is NULL.  This, in turn, causes
acpi_get_pci_dev() to trigger a NULL pointer dereference.

To fix this issue make acpi_get_pci_dev() check if pdev->subordinate
is not NULL for every device it finds in the path between the root
bridge and the device it's supposed to get to and return NULL if the
"target" device is not really accessible.

Fixes http://bugzilla.kernel.org/show_bug.cgi?id=14129, which is a
regression from 2.6.30.

Signed-off-by: Rafael J. Wysocki <rjw@sisk.pl>
Reported-by: Danny Feng <dfeng@redhat.com>
Tested-by: chepioq <chepioq@gmail.com>
---
 drivers/acpi/pci_root.c |   12 ++++++++++++
 1 file changed, 12 insertions(+)

Index: linux-2.6/drivers/acpi/pci_root.c
===================================================================
--- linux-2.6.orig/drivers/acpi/pci_root.c
+++ linux-2.6/drivers/acpi/pci_root.c
@@ -389,6 +389,18 @@ struct pci_dev *acpi_get_pci_dev(acpi_ha
 
 		pbus = pdev->subordinate;
 		pci_dev_put(pdev);
+
+		/*
+		 * During resume from a sleep state we can get a dock
+		 * notification for a device that is present in ACPI tables,
+		 * but not physically accessible at the moment, so tell the
+		 * caller it's not present in that case.
+		 */
+		if (!pbus) {
+			dev_info(&pdev->dev, "Secondary bus not present\n");
+			pdev = NULL;
+			break;
+		}
 	}
 out:
 	list_for_each_entry_safe(node, tmp, &device_list, node)

WARNING: multiple messages have this Message-ID (diff)
From: "Rafael J. Wysocki" <rjw@sisk.pl>
To: Len Brown <lenb@kernel.org>
Cc: LKML <linux-kernel@vger.kernel.org>,
	ACPI Devel Maling List <linux-acpi@vger.kernel.org>,
	pm list <linux-pm@lists.linux-foundation.org>,
	Alex Chiang <achiang@hp.com>, Danny Feng <dfeng@redhat.com>,
	Jesse Barnes <jbarnes@virtuousgeek.org>,
	Linux PCI <linux-pci@vger.kernel.org>,
	chepioq@gmail.com
Subject: [PATCH] ACPI / PCI: Fix NULL pointer dereference in acpi_get_pci_dev()
Date: Tue, 6 Oct 2009 01:30:43 +0200	[thread overview]
Message-ID: <200910060130.43246.rjw@sisk.pl> (raw)

From: Rafael J. Wysocki <rjw@sisk.pl>

acpi_get_pci_dev() assumes that every handle it finds in the ACPI CA
name space, between given device handle and the PCI root bridge
handle, corresponds to a PCI-to-PCI bridge with an existing secondary
bus.  For this reason, when it finds a struct pci_dev object
corresponding to one of them, it doesn't check if its 'subordinate'
field is a valid pointer.

However, during resume from a sleep state, as well as at startup, we
may get a dock notification, via dock_acpi_notifier registered by
dock_init(), for a docking station device that is present in the ACPI
tables, but not physically accessible at the moment.  In that
situation, the device appears to be below a PCI bridge whose
'subordinate' field is NULL.  This, in turn, causes
acpi_get_pci_dev() to trigger a NULL pointer dereference.

To fix this issue make acpi_get_pci_dev() check if pdev->subordinate
is not NULL for every device it finds in the path between the root
bridge and the device it's supposed to get to and return NULL if the
"target" device is not really accessible.

Fixes http://bugzilla.kernel.org/show_bug.cgi?id=14129, which is a
regression from 2.6.30.

Signed-off-by: Rafael J. Wysocki <rjw@sisk.pl>
Reported-by: Danny Feng <dfeng@redhat.com>
Tested-by: chepioq <chepioq@gmail.com>
---
 drivers/acpi/pci_root.c |   12 ++++++++++++
 1 file changed, 12 insertions(+)

Index: linux-2.6/drivers/acpi/pci_root.c
===================================================================
--- linux-2.6.orig/drivers/acpi/pci_root.c
+++ linux-2.6/drivers/acpi/pci_root.c
@@ -389,6 +389,18 @@ struct pci_dev *acpi_get_pci_dev(acpi_ha
 
 		pbus = pdev->subordinate;
 		pci_dev_put(pdev);
+
+		/*
+		 * During resume from a sleep state we can get a dock
+		 * notification for a device that is present in ACPI tables,
+		 * but not physically accessible at the moment, so tell the
+		 * caller it's not present in that case.
+		 */
+		if (!pbus) {
+			dev_info(&pdev->dev, "Secondary bus not present\n");
+			pdev = NULL;
+			break;
+		}
 	}
 out:
 	list_for_each_entry_safe(node, tmp, &device_list, node)

             reply	other threads:[~2009-10-05 23:30 UTC|newest]

Thread overview: 14+ messages / expand[flat|nested]  mbox.gz  Atom feed  top
2009-10-05 23:30 Rafael J. Wysocki [this message]
2009-10-05 23:30 ` [PATCH] ACPI / PCI: Fix NULL pointer dereference in acpi_get_pci_dev() Rafael J. Wysocki
2009-10-05 23:37 ` Alex Chiang
2009-10-05 23:37 ` Alex Chiang
2009-10-06  0:01   ` Rafael J. Wysocki
2009-10-06  0:01     ` Rafael J. Wysocki
2009-10-06  2:41 ` Len Brown
2009-10-06  2:41   ` Len Brown
2009-10-12 23:01 ` [PATCH] ACPI / PCI: Fix NULL pointer dereference in acpi_get_pci_dev() (rev. 2) Rafael J. Wysocki
2009-10-12 23:01   ` Rafael J. Wysocki
2009-10-13  5:16   ` Len Brown
2009-10-13  5:16     ` Len Brown
2009-10-14 22:41   ` Alex Chiang
2009-10-14 22:41     ` Alex Chiang

Reply instructions:

You may reply publicly to this message via plain-text email
using any one of the following methods:

* Save the following mbox file, import it into your mail client,
  and reply-to-all from there: mbox

  Avoid top-posting and favor interleaved quoting:
  https://en.wikipedia.org/wiki/Posting_style#Interleaved_style

* Reply using the --to, --cc, and --in-reply-to
  switches of git-send-email(1):

  git send-email \
    --in-reply-to=200910060130.43246.rjw@sisk.pl \
    --to=rjw@sisk.pl \
    --cc=achiang@hp.com \
    --cc=chepioq@gmail.com \
    --cc=dfeng@redhat.com \
    --cc=jbarnes@virtuousgeek.org \
    --cc=lenb@kernel.org \
    --cc=linux-acpi@vger.kernel.org \
    --cc=linux-kernel@vger.kernel.org \
    --cc=linux-pci@vger.kernel.org \
    --cc=linux-pm@lists.linux-foundation.org \
    /path/to/YOUR_REPLY

  https://kernel.org/pub/software/scm/git/docs/git-send-email.html

* If your mail client supports setting the In-Reply-To header
  via mailto: links, try the mailto: link
Be sure your reply has a Subject: header at the top and a blank line before the message body.
This is an external index of several public inboxes,
see mirroring instructions on how to clone and mirror
all data and code used by this external index.