From 86f918ee7f941c383ee32ad28dca6e48a04b6074 Mon Sep 17 00:00:00 2001 From: Johan Hovold Date: Tue, 23 Jun 2015 14:17:41 +0200 Subject: [PATCH] greybus: esx: fix null-deref on hotplug events We must be prepared to receive hotplug events as soon as we submit the SVC URB. Since commit 2eb8a6a947d7 ("core: don't set up endo until host device is initialized") this is no longer the case as the endo would not have been setup, something which may lead to a null-pointer dereference in endo_get_module_id() when the interface is created (see oops below with an added dev_dbg for hd->endo). Fix this by setting up the endo before submitting the SVC URB. [ 28.810610] gb_interface_create - hd->endo = (null) [ 28.816020] Unable to handle kernel NULL pointer dereference at virtual address 0000022b [ 28.824952] pgd = c0004000 [ 28.827880] [0000022b] *pgd=00000000 [ 28.831913] Internal error: Oops: 17 [#1] PREEMPT ARM [ 28.837183] Modules linked in: gb_es1(O+) greybus(O) netconsole [ 28.843419] CPU: 0 PID: 21 Comm: kworker/u2:1 Tainted: G O 4.1.0-rc7 #12 [ 28.851576] Hardware name: Generic AM33XX (Flattened Device Tree) [ 28.857978] Workqueue: greybus_ap ap_process_event [greybus] [ 28.863890] task: cf2961c0 ti: cf29c000 task.ti: cf29c000 [ 28.869529] PC is at endo_get_module_id+0x18/0x88 [greybus] [ 28.875355] LR is at gb_interface_add+0x88/0x204 [greybus] [ 28.881070] pc : [] lr : [] psr: 20070013 [ 28.881070] sp : cf29de08 ip : cf29de18 fp : cf29de14 [ 28.893021] r10: 00000001 r9 : 0000005a r8 : cd813ec6 [ 28.898461] r7 : 00000058 r6 : cf7fa200 r5 : 00000001 r4 : cf7fa20c [ 28.905261] r3 : 00000000 r2 : cf2961c0 r1 : 00000001 r0 : 00000000 [ 28.912067] Flags: nzCv IRQs on FIQs on Mode SVC_32 ISA ARM Segment kernel [ 28.919677] Control: 10c5387d Table: 8f508019 DAC: 00000015 [ 28.925663] Process kworker/u2:1 (pid: 21, stack limit = 0xcf29c210) [ 28.932279] Stack: (0xcf29de08 to 0xcf29e000) [ 28.936823] de00: cf29de44 cf29de18 bf005dac bf0052c8 00000058 cd813ec0 [ 28.945349] de20: cf58b60c bf00afe0 cf7fa200 cf58b600 0000005a 00000001 cf29de84 cf29de48 [ 28.953865] de40: bf004844 bf005d30 00000000 cf02d800 cf29de6c cf29de60 c00759a0 cf58b60c [ 28.962389] de60: cf2742c0 cf02d800 cf0c6000 cf29dea8 c07b745c 00000000 cf29dee4 cf29de88 [ 28.970908] de80: c005943c bf004560 00000001 00000000 c0059354 cf02d800 c0059c0c 00000001 [ 28.979426] dea0: 00000000 00000000 bf00b314 00000000 00000000 bf009144 c04e3710 cf02d800 [ 28.987945] dec0: cf2742d8 cf02d830 00000088 c0059bd0 00000000 cf2742c0 cf29df24 cf29dee8 [ 28.996464] dee0: c0059b78 c0059248 cf29c000 cf245d40 c0776890 c07b6bf3 00000000 00000000 [ 29.004983] df00: cf245d40 cf2742c0 c0059b20 00000000 00000000 00000000 cf29dfac cf29df28 [ 29.013502] df20: c005fe90 c0059b2c c07812d0 00000000 cf29df4c cf2742c0 00000000 00000001 [ 29.022025] df40: dead4ead ffffffff ffffffff c07c86b0 00000000 00000000 c05fd8e8 cf29df5c [ 29.030542] df60: cf29df5c 00000000 00000001 dead4ead ffffffff ffffffff c07c86b0 00000000 [ 29.039062] df80: 00000000 c05fd8e8 cf29df88 cf29df88 cf245d40 c005fd98 00000000 00000000 [ 29.047581] dfa0: 00000000 cf29dfb0 c00108f8 c005fda4 00000000 00000000 00000000 00000000 [ 29.056105] dfc0: 00000000 00000000 00000000 00000000 00000000 00000000 00000000 00000000 [ 29.064623] dfe0: 00000000 00000000 00000000 00000000 00000013 00000000 ffff0000 ffff0000 [ 29.073178] [] (endo_get_module_id [greybus]) from [] (gb_interface_add+0x88/0x204 [greybus]) [ 29.083887] [] (gb_interface_add [greybus]) from [] (ap_process_event+0x2f0/0x4d8 [greybus]) [ 29.094527] [] (ap_process_event [greybus]) from [] (process_one_work+0x200/0x8e4) [ 29.104228] [] (process_one_work) from [] (worker_thread+0x58/0x500) [ 29.112668] [] (worker_thread) from [] (kthread+0xf8/0x110) [ 29.120295] [] (kthread) from [] (ret_from_fork+0x14/0x3c) [ 29.127825] Code: e24cb004 e52de004 e8bd4000 e3510000 (e5d0c22b) [ 29.137481] ---[ end trace ad95c3c26bdc98ce ]--- Signed-off-by: Johan Hovold Signed-off-by: Greg Kroah-Hartman --- drivers/staging/greybus/es1.c | 19 +++++++++---------- drivers/staging/greybus/es2.c | 19 +++++++++---------- 2 files changed, 18 insertions(+), 20 deletions(-) diff --git a/drivers/staging/greybus/es1.c b/drivers/staging/greybus/es1.c index f9a6c54cca7a..067b4c13ed64 100644 --- a/drivers/staging/greybus/es1.c +++ b/drivers/staging/greybus/es1.c @@ -679,16 +679,6 @@ static int ap_probe(struct usb_interface *interface, es1->cport_out_urb_busy[i] = false; /* just to be anal */ } - /* Start up our svc urb, which allows events to start flowing */ - retval = usb_submit_urb(es1->svc_urb, GFP_KERNEL); - if (retval) - goto error; - - apb1_log_enable_dentry = debugfs_create_file("apb1_log_enable", - (S_IWUSR | S_IRUGO), - gb_debugfs_get(), es1, - &apb1_log_enable_fops); - /* * XXX Soon this will be initiated later, with a combination * XXX of a Control protocol probe operation and a @@ -700,6 +690,15 @@ static int ap_probe(struct usb_interface *interface, if (retval) goto error; + /* Start up our svc urb, which allows events to start flowing */ + retval = usb_submit_urb(es1->svc_urb, GFP_KERNEL); + if (retval) + goto error; + + apb1_log_enable_dentry = debugfs_create_file("apb1_log_enable", + (S_IWUSR | S_IRUGO), + gb_debugfs_get(), es1, + &apb1_log_enable_fops); return 0; error: ap_disconnect(interface); diff --git a/drivers/staging/greybus/es2.c b/drivers/staging/greybus/es2.c index 274d1d419320..97fa2e0c3673 100644 --- a/drivers/staging/greybus/es2.c +++ b/drivers/staging/greybus/es2.c @@ -783,16 +783,6 @@ static int ap_probe(struct usb_interface *interface, es1->cport_out_urb_busy[i] = false; /* just to be anal */ } - /* Start up our svc urb, which allows events to start flowing */ - retval = usb_submit_urb(es1->svc_urb, GFP_KERNEL); - if (retval) - goto error; - - apb1_log_enable_dentry = debugfs_create_file("apb1_log_enable", - (S_IWUSR | S_IRUGO), - gb_debugfs_get(), es1, - &apb1_log_enable_fops); - /* * XXX Soon this will be initiated later, with a combination * XXX of a Control protocol probe operation and a @@ -804,6 +794,15 @@ static int ap_probe(struct usb_interface *interface, if (retval) goto error; + /* Start up our svc urb, which allows events to start flowing */ + retval = usb_submit_urb(es1->svc_urb, GFP_KERNEL); + if (retval) + goto error; + + apb1_log_enable_dentry = debugfs_create_file("apb1_log_enable", + (S_IWUSR | S_IRUGO), + gb_debugfs_get(), es1, + &apb1_log_enable_fops); return 0; error: ap_disconnect(interface); -- 2.39.2