aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorAmit Pundir <amit.pundir@linaro.org>2015-01-16 05:41:10 +0530
committerMoyster <oysterized@gmail.com>2018-05-16 15:12:00 +0200
commitfe12ea1c9111350b576fce11a7feed49e3ebc4e4 (patch)
treeb9f3160f5d1c303b4b6acc838f11c97d57471cee
parent0a9f997a3d3536c7750c6ec8c4023c53fda4f2fa (diff)
usb: gadget: check for accessory device before disconnecting HIDs
While disabling ConfigFS Android gadget, android_disconnect() calls kill_all_hid_devices(), if CONFIG_USB_CONFIGFS_F_ACC is enabled, to free the registered HIDs without checking whether the USB accessory device really exist or not. If USB accessory device doesn't exist then we run into following kernel panic: ----8<---- [  136.724761] Unable to handle kernel NULL pointer dereference at virtual address 00000064 [  136.724809] pgd = c0204000 [  136.731924] [00000064] *pgd=00000000 [  136.737830] Internal error: Oops: 5 [#1] SMP ARM [  136.738108] CPU: 0 PID: 0 Comm: swapper/0 Not tainted 3.18.0-rc4-00400-gf75300e-dirty #76 [  136.742788] task: c0fb19d8 ti: c0fa4000 task.ti: c0fa4000 [  136.750890] PC is at _raw_spin_lock_irqsave+0x24/0x60 [  136.756246] LR is at kill_all_hid_devices+0x24/0x114 ---->8---- This patch adds a test to check if USB Accessory device exists before freeing HIDs. Change-Id: Ie229feaf0de3f4f7a151fcaa9a994e34e15ff73b Signed-off-by: Amit Pundir <amit.pundir@linaro.org> (cherry picked from commit 32a71bce154cb89a549b9b7d28e8cf03b889d849)
-rw-r--r--drivers/usb/gadget/f_accessory.c4
1 files changed, 4 insertions, 0 deletions
diff --git a/drivers/usb/gadget/f_accessory.c b/drivers/usb/gadget/f_accessory.c
index 41c86ad64..717ef1811 100644
--- a/drivers/usb/gadget/f_accessory.c
+++ b/drivers/usb/gadget/f_accessory.c
@@ -962,6 +962,10 @@ kill_all_hid_devices(struct acc_dev *dev)
struct list_head *entry, *temp;
unsigned long flags;
+ /* do nothing if usb accessory device doesn't exist */
+ if (!dev)
+ return;
+
spin_lock_irqsave(&dev->lock, flags);
list_for_each_safe(entry, temp, &dev->hid_list) {
hid = list_entry(entry, struct acc_hid_dev, list);