summaryrefslogtreecommitdiffstats
path: root/gpio-ACPI-Dont-crash-on-NULL-chip-dev.patch
blob: 56cd7535a22ef60ad45c4e52db0cf04bdacdf64a (plain)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
Path: news.gmane.org!not-for-mail
From: Mika Westerberg <mika.westerberg@linux.intel.com>
Newsgroups: gmane.linux.kernel.gpio,gmane.linux.kernel
Subject: [PATCH] gpio / ACPI: Don't crash on NULL chip->dev
Date: Mon, 31 Mar 2014 15:16:49 +0300
Lines: 114
Approved: news@gmane.org
Message-ID: <1396268209-19108-1-git-send-email-mika.westerberg@linux.intel.com>
NNTP-Posting-Host: plane.gmane.org
X-Trace: ger.gmane.org 1396268225 9280 80.91.229.3 (31 Mar 2014 12:17:05 GMT)
X-Complaints-To: usenet@ger.gmane.org
NNTP-Posting-Date: Mon, 31 Mar 2014 12:17:05 +0000 (UTC)
Cc: Alexandre Courbot <gnurou@gmail.com>,
	Sabrina Dubroca <sd@queasysnail.net>,
	linux-gpio@vger.kernel.org, linux-kernel@vger.kernel.org,
	Mika Westerberg <mika.westerberg@linux.intel.com>
To: Linus Walleij <linus.walleij@linaro.org>
Original-X-From: linux-gpio-owner@vger.kernel.org Mon Mar 31 14:16:58 2014
Return-path: <linux-gpio-owner@vger.kernel.org>
Envelope-to: glg-linux-gpio@plane.gmane.org
Original-Received: from vger.kernel.org ([209.132.180.67])
	by plane.gmane.org with esmtp (Exim 4.69)
	(envelope-from <linux-gpio-owner@vger.kernel.org>)
	id 1WUb96-00049j-5K
	for glg-linux-gpio@plane.gmane.org; Mon, 31 Mar 2014 14:16:56 +0200
Original-Received: (majordomo@vger.kernel.org) by vger.kernel.org via listexpand
	id S1752154AbaCaMQz (ORCPT <rfc822;glg-linux-gpio@m.gmane.org>);
	Mon, 31 Mar 2014 08:16:55 -0400
Original-Received: from mga11.intel.com ([192.55.52.93]:46420 "EHLO mga11.intel.com"
	rhost-flags-OK-OK-OK-OK) by vger.kernel.org with ESMTP
	id S1751749AbaCaMQy (ORCPT <rfc822;linux-gpio@vger.kernel.org>);
	Mon, 31 Mar 2014 08:16:54 -0400
Original-Received: from fmsmga002.fm.intel.com ([10.253.24.26])
  by fmsmga102.fm.intel.com with ESMTP; 31 Mar 2014 05:16:54 -0700
X-ExtLoop1: 1
X-IronPort-AV: E=Sophos;i="4.97,764,1389772800"; 
   d="scan'208";a="510938110"
Original-Received: from blue.fi.intel.com ([10.237.72.156])
  by fmsmga002.fm.intel.com with ESMTP; 31 Mar 2014 05:16:50 -0700
Original-Received: by blue.fi.intel.com (Postfix, from userid 1004)
	id 73976E0098; Mon, 31 Mar 2014 15:16:49 +0300 (EEST)
X-Mailer: git-send-email 1.9.1
Original-Sender: linux-gpio-owner@vger.kernel.org
Precedence: bulk
List-ID: <linux-gpio.vger.kernel.org>
X-Mailing-List: linux-gpio@vger.kernel.org
Xref: news.gmane.org gmane.linux.kernel.gpio:2461 gmane.linux.kernel:1675129
Archived-At: <http://permalink.gmane.org/gmane.linux.kernel.gpio/2461>

Commit aa92b6f689ac (gpio / ACPI: Allocate ACPI specific data directly in
acpi_gpiochip_add()) moved ACPI handle checking to acpi_gpiochip_add() but
forgot to check whether chip->dev is NULL before dereferencing it.

Since chip->dev pointer is optional we can end up with crash like following:

 BUG: unable to handle kernel NULL pointer dereference at 00000138
 IP: [<c126c2b3>] acpi_gpiochip_add+0x13/0x190
 *pde = 00000000
 Oops: 0000 [#1] PREEMPT SMP
 Modules linked in: ssb(+) ...
 CPU: 0 PID: 512 Comm: modprobe Tainted: G        W     3.14.0-rc7-next-20140324-t1 #24
 Hardware name: Dell Inc. Latitude D830                   /0UY141, BIOS A02 06/07/2007
 task: f5799900 ti: f543e000 task.ti: f543e000
 EIP: 0060:[<c126c2b3>] EFLAGS: 00010282 CPU: 0
 EIP is at acpi_gpiochip_add+0x13/0x190
 EAX: 00000000 EBX: f57824c4 ECX: 00000000 EDX: 00000000
 ESI: f57824c4 EDI: 00000010 EBP: f543fc54 ESP: f543fc40
  DS: 007b ES: 007b FS: 00d8 GS: 0033 SS: 0068
 CR0: 8005003b CR2: 00000138 CR3: 355f8000 CR4: 000007d0
 Stack:
  f543fc5c fd1f7790 f57824c4 000000be 00000010 f543fc84 c1269f4e f543fc74
  fd1f78bd 00008002 f57822b0 f5782090 fd1f8400 00000286 fd1f9994 00000000
  f5782000 f543fc8c fd1f7e39 f543fcc8 fd1f0bd8 000000c0 00000000 00000000
 Call Trace:
  [<fd1f7790>] ? ssb_pcie_mdio_write+0xa0/0xd0 [ssb]
  [<c1269f4e>] gpiochip_add+0xee/0x300
  [<fd1f78bd>] ? ssb_pcicore_serdes_workaround+0xfd/0x140 [ssb]
  [<fd1f7e39>] ssb_gpio_init+0x89/0xa0 [ssb]
  [<fd1f0bd8>] ssb_attach_queued_buses+0xc8/0x2d0 [ssb]
  [<fd1f0f65>] ssb_bus_register+0x185/0x1f0 [ssb]
  [<fd1f3120>] ? ssb_pci_xtal+0x220/0x220 [ssb]
  [<fd1f106c>] ssb_bus_pcibus_register+0x2c/0x80 [ssb]
  [<fd1f40dc>] ssb_pcihost_probe+0x9c/0x110 [ssb]
  [<c1276c8f>] pci_device_probe+0x6f/0xc0
  [<c11bdb55>] ? sysfs_create_link+0x25/0x40
  [<c131d8b9>] driver_probe_device+0x79/0x360
  [<c1276512>] ? pci_match_device+0xb2/0xc0
  [<c131dc51>] __driver_attach+0x71/0x80
  [<c131dbe0>] ? __device_attach+0x40/0x40
  [<c131bd87>] bus_for_each_dev+0x47/0x80
  [<c131d3ae>] driver_attach+0x1e/0x20
  [<c131dbe0>] ? __device_attach+0x40/0x40
  [<c131d007>] bus_add_driver+0x157/0x230
  [<c131e219>] driver_register+0x59/0xe0
  ...

Fix this by checking chip->dev pointer against NULL first. Also we can now
remove redundant check in acpi_gpiochip_request/free_interrupts().

Reported-by: Sabrina Dubroca <sd@queasysnail.net>
Signed-off-by: Mika Westerberg <mika.westerberg@linux.intel.com>
---
Sabrina,

Can you please re-test this and provide your tested-by? I changed the patch
a bit to remove redundant checks. Just to be sure that I don't accidentally
break something.

Thanks.

 drivers/gpio/gpiolib-acpi.c | 10 ++++++++--
 1 file changed, 8 insertions(+), 2 deletions(-)

diff --git a/drivers/gpio/gpiolib-acpi.c b/drivers/gpio/gpiolib-acpi.c
index bf0f8b476696..d5be56fe689e 100644
--- a/drivers/gpio/gpiolib-acpi.c
+++ b/drivers/gpio/gpiolib-acpi.c
@@ -233,7 +233,7 @@ static void acpi_gpiochip_request_interrupts(struct acpi_gpio_chip *acpi_gpio)
 {
 	struct gpio_chip *chip = acpi_gpio->chip;
 
-	if (!chip->dev || !chip->to_irq)
+	if (!chip->to_irq)
 		return;
 
 	INIT_LIST_HEAD(&acpi_gpio->events);
@@ -253,7 +253,7 @@ static void acpi_gpiochip_free_interrupts(struct acpi_gpio_chip *acpi_gpio)
 	struct acpi_gpio_event *event, *ep;
 	struct gpio_chip *chip = acpi_gpio->chip;
 
-	if (!chip->dev || !chip->to_irq)
+	if (!chip->to_irq)
 		return;
 
 	list_for_each_entry_safe_reverse(event, ep, &acpi_gpio->events, node) {
@@ -501,6 +501,9 @@ void acpi_gpiochip_add(struct gpio_chip *chip)
 	acpi_handle handle;
 	acpi_status status;
 
+	if (!chip || !chip->dev)
+		return;
+
 	handle = ACPI_HANDLE(chip->dev);
 	if (!handle)
 		return;
@@ -531,6 +534,9 @@ void acpi_gpiochip_remove(struct gpio_chip *chip)
 	acpi_handle handle;
 	acpi_status status;
 
+	if (!chip || !chip->dev)
+		return;
+
 	handle = ACPI_HANDLE(chip->dev);
 	if (!handle)
 		return;
-- 
1.9.1

--
To unsubscribe from this list: send the line "unsubscribe linux-gpio" in
the body of a message to majordomo@vger.kernel.org
More majordomo info at  http://vger.kernel.org/majordomo-info.html