When initialisation of one or more USB hub ports fails, we can hit a null pointer dereference when dropping the hub. Analysis shows there's a false assumption about the ports being setup, so address this. hub 2-3:1.0: USB hub found hub 2-3:1.0: 7 ports detected hub 2-3:1.0: hub_hub_status failed (err = -11) hub 2-3:1.0: config failed, can't get hub status (err -11) BUG: unable to handle kernel NULL pointer dereference at (null) IP: [<ffffffff8168ff16>] hub_quiesce+0x46/0xb0 PGD 0 Oops: 0000 [#1] SMP CPU 2 Pid: 3364, comm: khubd Not tainted 3.8.0-advanced+ #21 IBM IBM System X3755 M3 -[7164Z63]-/94Y6321 RIP: 0010:[<ffffffff8168ff16>] [<ffffffff8168ff16>] hub_quiesce+0x46/0xb0 RSP: 0018:ffff88046c535978 EFLAGS: 00010246 RAX: ffff88046c4fc100 RBX: 0000000000000000 RCX: 000000000000000b RDX: 0000000000000000 RSI: 0000000000000001 RDI: 0000000000000000 RBP: ffff88046c6b8400 R08: 0000000000000002 R09: 000000000000129b R10: 0000000000000000 R11: ffff88046c53550e R12: ffff88046c098000 R13: ffff88046c0a8430 R14: ffffffff81af72e0 R15: ffff88046c6b8400 FS: 00007fcbd36196e0(0000) GS:ffff88046fc80000(0000) knlGS:0000000000000000 CS: 0010 DS: 0000 ES: 0000 CR0: 000000008005003b CR2: 0000000000000000 CR3: 0000000001e0c000 CR4: 00000000000007e0 DR0: 0000000000000000 DR1: 0000000000000000 DR2: 0000000000000000 DR3: 0000000000000000 DR6: 00000000ffff0ff0 DR7: 0000000000000400 Process khubd (pid: 3364, threadinfo ffff88046c534000, task ffff88046c58ad00) Stack: ffff88046c0a8400 ffff88046c6b8400 ffff88046c098088 ffffffff816901a5 ffff88046c098088 ffff88046c0a8400 ffff88046c098088 ffff88046c098000 ffff88046c4fc180 ffffffff816904c1 ffffffff8169a261 ffff88046c0a8430 Call Trace: [<ffffffff816901a5>] ? hub_disconnect+0x75/0x140 [<ffffffff816904c1>] ? hub_probe+0x251/0x260 [<ffffffff8169a261>] ? usb_match_one_id+0x31/0x70 [<ffffffff8169a9a6>] ? usb_probe_interface+0x1a6/0x260 [<ffffffff815030f8>] ? driver_probe_device+0x68/0x210 [<ffffffff81503340>] ? __driver_attach+0xa0/0xa0 [<ffffffff81501a8e>] ? bus_for_each_drv+0x3e/0x80 [<ffffffff81502e18>] ? device_attach+0x98/0xb0 [<ffffffff81501ca0>] ? bus_probe_device+0x80/0xb0 [<ffffffff814fffbe>] ? device_add+0x5be/0x680 [<ffffffff8169818e>] ? usb_string+0x11e/0x1e0 [<ffffffff8169933d>] ? usb_set_configuration+0x4cd/0x7c0 [<ffffffff8116ef1d>] ? sysfs_do_create_link+0xed/0x220 [<ffffffff816a2b6f>] ? generic_probe+0x2f/0x90 [<ffffffff815030f8>] ? driver_probe_device+0x68/0x210 [<ffffffff81503340>] ? __driver_attach+0xa0/0xa0 [<ffffffff81501a8e>] ? bus_for_each_drv+0x3e/0x80 [<ffffffff81502e18>] ? device_attach+0x98/0xb0 [<ffffffff81501ca0>] ? bus_probe_device+0x80/0xb0 [<ffffffff814fffbe>] ? device_add+0x5be/0x680 [<ffffffff813956ff>] ? mix_pool_bytes.constprop.19+0x3f/0x60 [<ffffffff81690628>] ? usb_new_device+0x158/0x210 [<ffffffff816928b0>] ? hub_port_connect_change+0x570/0x9c0 [<ffffffff8169316f>] ? hub_thread+0x26f/0x7c0 [<ffffffff8108384c>] ? __wake_up_common+0x4c/0x80 [<ffffffff8107bea0>] ? abort_exclusive_wait+0xb0/0xb0 [<ffffffff81692f00>] ? usb_reset_device+0x140/0x140 [<ffffffff8107b1e3>] ? kthread+0xb3/0xc0 [<ffffffff8107b130>] ? __kthread_parkme+0x80/0x80 [<ffffffff8186332c>] ? ret_from_fork+0x7c/0xb0 [<ffffffff8107b130>] ? __kthread_parkme+0x80/0x80 Code: e4 00 00 00 02 83 fb 02 74 38 41 8b 84 24 40 04 00 00 85 c0 7e 2c 31 db 0f 1f 44 00 00 48 8b 85 f8 01 00 00 48 63 d3 48 8b 3c d0 <48> 83 3f 00 74 05 e8 9f fe ff ff ff c3 41 39 9c 24 40 04 00 00 RIP [<ffffffff8168ff16>] hub_quiesce+0x46/0xb0 RSP <ffff88046c535978> CR2: 0000000000000000 (gdb) list *(hub_quiesce+0x46) 0xffffffff81690056 is in hub_quiesce (drivers/usb/core/hub.c:1266). 1261 hub->quiescing = 1; 1262 1263 if (type != HUB_SUSPEND) { 1264 /* Disconnect all the children */ 1265 for (i = 0; i < hdev->maxchild; ++i) { 1266 if (hub->ports[i]->child) 1267 usb_disconnect(&hub->ports[i]->child); 1268 } 1269 } Signed-off-by: Daniel J Blueman <daniel@xxxxxxxxxxxxxxxxxx> --- drivers/usb/core/hub.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/drivers/usb/core/hub.c b/drivers/usb/core/hub.c index cbf7168..a7abc57 100644 --- a/drivers/usb/core/hub.c +++ b/drivers/usb/core/hub.c @@ -1263,7 +1263,7 @@ static void hub_quiesce(struct usb_hub *hub, enum hub_quiescing_type type) if (type != HUB_SUSPEND) { /* Disconnect all the children */ for (i = 0; i < hdev->maxchild; ++i) { - if (hub->ports[i]->child) + if (hub->ports[i] && hub->ports[i]->child) usb_disconnect(&hub->ports[i]->child); } } -- 1.7.10.4 -- To unsubscribe from this list: send the line "unsubscribe linux-usb" in the body of a message to majordomo@xxxxxxxxxxxxxxx More majordomo info at http://vger.kernel.org/majordomo-info.html