Josh Boyer 700baa3
Path: news.gmane.org!not-for-mail
Josh Boyer 700baa3
From: Mika Westerberg <mika.westerberg@linux.intel.com>
Josh Boyer 700baa3
Newsgroups: gmane.linux.kernel.gpio,gmane.linux.kernel
Josh Boyer 700baa3
Subject: [PATCH] gpio / ACPI: Don't crash on NULL chip->dev
Josh Boyer 700baa3
Date: Mon, 31 Mar 2014 15:16:49 +0300
Josh Boyer 700baa3
Lines: 114
Josh Boyer 700baa3
Approved: news@gmane.org
Josh Boyer 700baa3
Message-ID: <1396268209-19108-1-git-send-email-mika.westerberg@linux.intel.com>
Josh Boyer 700baa3
NNTP-Posting-Host: plane.gmane.org
Josh Boyer 700baa3
X-Trace: ger.gmane.org 1396268225 9280 80.91.229.3 (31 Mar 2014 12:17:05 GMT)
Josh Boyer 700baa3
X-Complaints-To: usenet@ger.gmane.org
Josh Boyer 700baa3
NNTP-Posting-Date: Mon, 31 Mar 2014 12:17:05 +0000 (UTC)
Josh Boyer 700baa3
Cc: Alexandre Courbot <gnurou@gmail.com>,
Josh Boyer 700baa3
	Sabrina Dubroca <sd@queasysnail.net>,
Josh Boyer 700baa3
	linux-gpio@vger.kernel.org, linux-kernel@vger.kernel.org,
Josh Boyer 700baa3
	Mika Westerberg <mika.westerberg@linux.intel.com>
Josh Boyer 700baa3
To: Linus Walleij <linus.walleij@linaro.org>
Josh Boyer 700baa3
Original-X-From: linux-gpio-owner@vger.kernel.org Mon Mar 31 14:16:58 2014
Josh Boyer 700baa3
Return-path: <linux-gpio-owner@vger.kernel.org>
Josh Boyer 700baa3
Envelope-to: glg-linux-gpio@plane.gmane.org
Josh Boyer 700baa3
Original-Received: from vger.kernel.org ([209.132.180.67])
Josh Boyer 700baa3
	by plane.gmane.org with esmtp (Exim 4.69)
Josh Boyer 700baa3
	(envelope-from <linux-gpio-owner@vger.kernel.org>)
Josh Boyer 700baa3
	id 1WUb96-00049j-5K
Josh Boyer 700baa3
	for glg-linux-gpio@plane.gmane.org; Mon, 31 Mar 2014 14:16:56 +0200
Josh Boyer 700baa3
Original-Received: (majordomo@vger.kernel.org) by vger.kernel.org via listexpand
Josh Boyer 700baa3
	id S1752154AbaCaMQz (ORCPT <rfc822;glg-linux-gpio@m.gmane.org>);
Josh Boyer 700baa3
	Mon, 31 Mar 2014 08:16:55 -0400
Josh Boyer 700baa3
Original-Received: from mga11.intel.com ([192.55.52.93]:46420 "EHLO mga11.intel.com"
Josh Boyer 700baa3
	rhost-flags-OK-OK-OK-OK) by vger.kernel.org with ESMTP
Josh Boyer 700baa3
	id S1751749AbaCaMQy (ORCPT <rfc822;linux-gpio@vger.kernel.org>);
Josh Boyer 700baa3
	Mon, 31 Mar 2014 08:16:54 -0400
Josh Boyer 700baa3
Original-Received: from fmsmga002.fm.intel.com ([10.253.24.26])
Josh Boyer 700baa3
  by fmsmga102.fm.intel.com with ESMTP; 31 Mar 2014 05:16:54 -0700
Josh Boyer 700baa3
X-ExtLoop1: 1
Josh Boyer 700baa3
X-IronPort-AV: E=Sophos;i="4.97,764,1389772800"; 
Josh Boyer 700baa3
   d="scan'208";a="510938110"
Josh Boyer 700baa3
Original-Received: from blue.fi.intel.com ([10.237.72.156])
Josh Boyer 700baa3
  by fmsmga002.fm.intel.com with ESMTP; 31 Mar 2014 05:16:50 -0700
Josh Boyer 700baa3
Original-Received: by blue.fi.intel.com (Postfix, from userid 1004)
Josh Boyer 700baa3
	id 73976E0098; Mon, 31 Mar 2014 15:16:49 +0300 (EEST)
Josh Boyer 700baa3
X-Mailer: git-send-email 1.9.1
Josh Boyer 700baa3
Original-Sender: linux-gpio-owner@vger.kernel.org
Josh Boyer 700baa3
Precedence: bulk
Josh Boyer 700baa3
List-ID: <linux-gpio.vger.kernel.org>
Josh Boyer 700baa3
X-Mailing-List: linux-gpio@vger.kernel.org
Josh Boyer 700baa3
Xref: news.gmane.org gmane.linux.kernel.gpio:2461 gmane.linux.kernel:1675129
Josh Boyer 700baa3
Archived-At: <http://permalink.gmane.org/gmane.linux.kernel.gpio/2461>
Josh Boyer 700baa3
Josh Boyer 700baa3
Commit aa92b6f689ac (gpio / ACPI: Allocate ACPI specific data directly in
Josh Boyer 700baa3
acpi_gpiochip_add()) moved ACPI handle checking to acpi_gpiochip_add() but
Josh Boyer 700baa3
forgot to check whether chip->dev is NULL before dereferencing it.
Josh Boyer 700baa3
Josh Boyer 700baa3
Since chip->dev pointer is optional we can end up with crash like following:
Josh Boyer 700baa3
Josh Boyer 700baa3
 BUG: unable to handle kernel NULL pointer dereference at 00000138
Josh Boyer 700baa3
 IP: [<c126c2b3>] acpi_gpiochip_add+0x13/0x190
Josh Boyer 700baa3
 *pde = 00000000
Josh Boyer 700baa3
 Oops: 0000 [#1] PREEMPT SMP
Josh Boyer 700baa3
 Modules linked in: ssb(+) ...
Josh Boyer 700baa3
 CPU: 0 PID: 512 Comm: modprobe Tainted: G        W     3.14.0-rc7-next-20140324-t1 #24
Josh Boyer 700baa3
 Hardware name: Dell Inc. Latitude D830                   /0UY141, BIOS A02 06/07/2007
Josh Boyer 700baa3
 task: f5799900 ti: f543e000 task.ti: f543e000
Josh Boyer 700baa3
 EIP: 0060:[<c126c2b3>] EFLAGS: 00010282 CPU: 0
Josh Boyer 700baa3
 EIP is at acpi_gpiochip_add+0x13/0x190
Josh Boyer 700baa3
 EAX: 00000000 EBX: f57824c4 ECX: 00000000 EDX: 00000000
Josh Boyer 700baa3
 ESI: f57824c4 EDI: 00000010 EBP: f543fc54 ESP: f543fc40
Josh Boyer 700baa3
  DS: 007b ES: 007b FS: 00d8 GS: 0033 SS: 0068
Josh Boyer 700baa3
 CR0: 8005003b CR2: 00000138 CR3: 355f8000 CR4: 000007d0
Josh Boyer 700baa3
 Stack:
Josh Boyer 700baa3
  f543fc5c fd1f7790 f57824c4 000000be 00000010 f543fc84 c1269f4e f543fc74
Josh Boyer 700baa3
  fd1f78bd 00008002 f57822b0 f5782090 fd1f8400 00000286 fd1f9994 00000000
Josh Boyer 700baa3
  f5782000 f543fc8c fd1f7e39 f543fcc8 fd1f0bd8 000000c0 00000000 00000000
Josh Boyer 700baa3
 Call Trace:
Josh Boyer 700baa3
  [<fd1f7790>] ? ssb_pcie_mdio_write+0xa0/0xd0 [ssb]
Josh Boyer 700baa3
  [<c1269f4e>] gpiochip_add+0xee/0x300
Josh Boyer 700baa3
  [<fd1f78bd>] ? ssb_pcicore_serdes_workaround+0xfd/0x140 [ssb]
Josh Boyer 700baa3
  [<fd1f7e39>] ssb_gpio_init+0x89/0xa0 [ssb]
Josh Boyer 700baa3
  [<fd1f0bd8>] ssb_attach_queued_buses+0xc8/0x2d0 [ssb]
Josh Boyer 700baa3
  [<fd1f0f65>] ssb_bus_register+0x185/0x1f0 [ssb]
Josh Boyer 700baa3
  [<fd1f3120>] ? ssb_pci_xtal+0x220/0x220 [ssb]
Josh Boyer 700baa3
  [<fd1f106c>] ssb_bus_pcibus_register+0x2c/0x80 [ssb]
Josh Boyer 700baa3
  [<fd1f40dc>] ssb_pcihost_probe+0x9c/0x110 [ssb]
Josh Boyer 700baa3
  [<c1276c8f>] pci_device_probe+0x6f/0xc0
Josh Boyer 700baa3
  [<c11bdb55>] ? sysfs_create_link+0x25/0x40
Josh Boyer 700baa3
  [<c131d8b9>] driver_probe_device+0x79/0x360
Josh Boyer 700baa3
  [<c1276512>] ? pci_match_device+0xb2/0xc0
Josh Boyer 700baa3
  [<c131dc51>] __driver_attach+0x71/0x80
Josh Boyer 700baa3
  [<c131dbe0>] ? __device_attach+0x40/0x40
Josh Boyer 700baa3
  [<c131bd87>] bus_for_each_dev+0x47/0x80
Josh Boyer 700baa3
  [<c131d3ae>] driver_attach+0x1e/0x20
Josh Boyer 700baa3
  [<c131dbe0>] ? __device_attach+0x40/0x40
Josh Boyer 700baa3
  [<c131d007>] bus_add_driver+0x157/0x230
Josh Boyer 700baa3
  [<c131e219>] driver_register+0x59/0xe0
Josh Boyer 700baa3
  ...
Josh Boyer 700baa3
Josh Boyer 700baa3
Fix this by checking chip->dev pointer against NULL first. Also we can now
Josh Boyer 700baa3
remove redundant check in acpi_gpiochip_request/free_interrupts().
Josh Boyer 700baa3
Josh Boyer 700baa3
Reported-by: Sabrina Dubroca <sd@queasysnail.net>
Josh Boyer 700baa3
Signed-off-by: Mika Westerberg <mika.westerberg@linux.intel.com>
Josh Boyer 700baa3
---
Josh Boyer 700baa3
Sabrina,
Josh Boyer 700baa3
Josh Boyer 700baa3
Can you please re-test this and provide your tested-by? I changed the patch
Josh Boyer 700baa3
a bit to remove redundant checks. Just to be sure that I don't accidentally
Josh Boyer 700baa3
break something.
Josh Boyer 700baa3
Josh Boyer 700baa3
Thanks.
Josh Boyer 700baa3
Josh Boyer 700baa3
 drivers/gpio/gpiolib-acpi.c | 10 ++++++++--
Josh Boyer 700baa3
 1 file changed, 8 insertions(+), 2 deletions(-)
Josh Boyer 700baa3
Josh Boyer 700baa3
diff --git a/drivers/gpio/gpiolib-acpi.c b/drivers/gpio/gpiolib-acpi.c
Josh Boyer 700baa3
index bf0f8b476696..d5be56fe689e 100644
Josh Boyer 700baa3
--- a/drivers/gpio/gpiolib-acpi.c
Josh Boyer 700baa3
+++ b/drivers/gpio/gpiolib-acpi.c
Josh Boyer 700baa3
@@ -233,7 +233,7 @@ static void acpi_gpiochip_request_interrupts(struct acpi_gpio_chip *acpi_gpio)
Josh Boyer 700baa3
 {
Josh Boyer 700baa3
 	struct gpio_chip *chip = acpi_gpio->chip;
Josh Boyer 700baa3
 
Josh Boyer 700baa3
-	if (!chip->dev || !chip->to_irq)
Josh Boyer 700baa3
+	if (!chip->to_irq)
Josh Boyer 700baa3
 		return;
Josh Boyer 700baa3
 
Josh Boyer 700baa3
 	INIT_LIST_HEAD(&acpi_gpio->events);
Josh Boyer 700baa3
@@ -253,7 +253,7 @@ static void acpi_gpiochip_free_interrupts(struct acpi_gpio_chip *acpi_gpio)
Josh Boyer 700baa3
 	struct acpi_gpio_event *event, *ep;
Josh Boyer 700baa3
 	struct gpio_chip *chip = acpi_gpio->chip;
Josh Boyer 700baa3
 
Josh Boyer 700baa3
-	if (!chip->dev || !chip->to_irq)
Josh Boyer 700baa3
+	if (!chip->to_irq)
Josh Boyer 700baa3
 		return;
Josh Boyer 700baa3
 
Josh Boyer 700baa3
 	list_for_each_entry_safe_reverse(event, ep, &acpi_gpio->events, node) {
Josh Boyer 700baa3
@@ -501,6 +501,9 @@ void acpi_gpiochip_add(struct gpio_chip *chip)
Josh Boyer 700baa3
 	acpi_handle handle;
Josh Boyer 700baa3
 	acpi_status status;
Josh Boyer 700baa3
 
Josh Boyer 700baa3
+	if (!chip || !chip->dev)
Josh Boyer 700baa3
+		return;
Josh Boyer 700baa3
+
Josh Boyer 700baa3
 	handle = ACPI_HANDLE(chip->dev);
Josh Boyer 700baa3
 	if (!handle)
Josh Boyer 700baa3
 		return;
Josh Boyer 700baa3
@@ -531,6 +534,9 @@ void acpi_gpiochip_remove(struct gpio_chip *chip)
Josh Boyer 700baa3
 	acpi_handle handle;
Josh Boyer 700baa3
 	acpi_status status;
Josh Boyer 700baa3
 
Josh Boyer 700baa3
+	if (!chip || !chip->dev)
Josh Boyer 700baa3
+		return;
Josh Boyer 700baa3
+
Josh Boyer 700baa3
 	handle = ACPI_HANDLE(chip->dev);
Josh Boyer 700baa3
 	if (!handle)
Josh Boyer 700baa3
 		return;
Josh Boyer 700baa3
-- 
Josh Boyer 700baa3
1.9.1
Josh Boyer 700baa3
Josh Boyer 700baa3
--
Josh Boyer 700baa3
To unsubscribe from this list: send the line "unsubscribe linux-gpio" in
Josh Boyer 700baa3
the body of a message to majordomo@vger.kernel.org
Josh Boyer 700baa3
More majordomo info at  http://vger.kernel.org/majordomo-info.html
Josh Boyer 700baa3