From cbf7d122cc50bd88cb9fd745c8341a009de0796d Mon Sep 17 00:00:00 2001 From: navin Date: Wed, 19 Sep 2012 17:04:51 +0530 Subject: staging: usbip: vhci_hcd: Fixed oops during removal of vhci_hcd In response to "usbip detach -p [port_number]" user command,vhci_shutdown_connection() gets executed which kills tcp_tx,tcp_rx kernel threads but doesn't set thread pointers to NULL. so, at the time of vhci_hcd removal vhci_shutdown_connection() again tries to kill kernel threads which are already killed. [ 312.220259] BUG: unable to handle kernel NULL pointer dereference at (null) [ 312.220313] IP: [] exit_creds+0x1f/0x70 [ 312.220349] PGD 5b7be067 PUD 5b7dc067 PMD 0 [ 312.220388] Oops: 0000 [#1] SMP [ 312.220415] Modules linked in: vhci_hcd(O-) usbip_host(O) usbip_core(O) uas usb_storage joydev parport_pc bnep rfcomm ppdev binfmt_misc snd_hda_codec_hdmi snd_hda_codec_conexant snd_hda_intel snd_hda_codec snd_hwdep snd_pcm snd_seq_midi arc4 snd_rawmidi snd_seq_midi_event snd_seq ath9k mac80211 ath9k_common ath9k_hw snd_timer snd_seq_device snd ath i915 drm_kms_helper drm psmouse cfg80211 coretemp soundcore lpc_ich i2c_algo_bit snd_page_alloc video intel_ips wmi btusb mac_hid bluetooth ideapad_laptop lp sparse_keymap serio_raw mei microcode parport r8169 [ 312.220862] CPU 0 [ 312.220882] Pid: 2095, comm: usbip_eh Tainted: G O 3.6.0-rc3+ #2 LENOVO 20042 /Base Board Product Name [ 312.220938] RIP: 0010:[] [] exit_creds+0x1f/0x70 [ 312.220979] RSP: 0018:ffff88004d6ebdb0 EFLAGS: 00010282 [ 312.221008] RAX: 0000000000000000 RBX: ffff880041c4db40 RCX: ffff88005ad52230 [ 312.221041] RDX: 0000000000000034 RSI: 0000000000000286 RDI: 0000000000000000 [ 312.221074] RBP: ffff88004d6ebdc0 R08: ffff88004d6ea000 R09: 0000000000000000 [ 312.221107] R10: 0000000000000001 R11: 0000000000000000 R12: 0000000000000000 [ 312.221144] R13: 0000000000000000 R14: ffff88005ad521d8 R15: ffff88004d6ebea0 [ 312.221177] FS: 0000000000000000(0000) GS:ffff880077400000(0000) knlGS:0000000000000000 [ 312.221214] CS: 0010 DS: 0000 ES: 0000 CR0: 000000008005003b [ 312.221241] CR2: 0000000000000000 CR3: 000000005b7b9000 CR4: 00000000000007f0 [ 312.221277] DR0: 0000000000000000 DR1: 0000000000000000 DR2: 0000000000000000 [ 312.221309] DR3: 0000000000000000 DR6: 00000000ffff0ff0 DR7: 0000000000000400 [ 312.221342] Process usbip_eh (pid: 2095, threadinfo ffff88004d6ea000, task ffff88004d44db40) [ 312.221384] Stack: [ 312.221396] ffff88004d6ebdc0 ffff880041c4db40 ffff88004d6ebde0 ffffffff81052aaa [ 312.221442] ffff880041c4db40 0000000000000000 ffff88004d6ebe10 ffffffff8107a148 [ 312.221487] ffff88005ad521f0 ffff88005ad52228 ffff88004d44db40 ffff88005ad521d8 [ 312.221536] Call Trace: [ 312.221556] [] __put_task_struct+0x4a/0x140 [ 312.221587] [] kthread_stop+0x108/0x110 [ 312.221616] [] vhci_shutdown_connection+0x49/0x2b4 [vhci_hcd] [ 312.221657] [] event_handler_loop+0x70/0x140 [usbip_core] [ 312.221692] [] ? add_wait_queue+0x60/0x60 [ 312.221721] [] ? usbip_stop_eh+0x30/0x30 [usbip_core] [ 312.221754] [] kthread+0x93/0xa0 [ 312.221784] [] kernel_thread_helper+0x4/0x10 [ 312.221814] [] ? flush_kthread_worker+0xb0/0xb0 [ 312.223589] [] ? gs_change+0x13/0x13 [ 312.225360] Code: 0b 0f 0b 66 0f 1f 84 00 00 00 00 00 55 48 89 e5 53 48 83 ec 08 66 66 66 66 90 48 8b 87 58 04 00 00 48 89 fb 48 8b bf 50 04 00 00 <8b> 00 48 c7 83 50 04 00 00 00 00 00 00 f0 ff 0f 0f 94 c0 84 c0 [ 312.229663] RIP [] exit_creds+0x1f/0x70 [ 312.231696] RSP [ 312.233648] CR2: 0000000000000000 [ 312.256464] ---[ end trace 1971ce612a167279 ]--- Signed-off-by: navin patidar Acked-by: Dan Carpenter Signed-off-by: Greg Kroah-Hartman --- drivers/staging/usbip/vhci_hcd.c | 9 ++++++--- 1 file changed, 6 insertions(+), 3 deletions(-) (limited to 'drivers/staging/usbip') diff --git a/drivers/staging/usbip/vhci_hcd.c b/drivers/staging/usbip/vhci_hcd.c index bd79d1884c4b..620d1beb4587 100644 --- a/drivers/staging/usbip/vhci_hcd.c +++ b/drivers/staging/usbip/vhci_hcd.c @@ -814,11 +814,14 @@ static void vhci_shutdown_connection(struct usbip_device *ud) } /* kill threads related to this sdev, if v.c. exists */ - if (vdev->ud.tcp_rx) + if (vdev->ud.tcp_rx) { kthread_stop_put(vdev->ud.tcp_rx); - if (vdev->ud.tcp_tx) + vdev->ud.tcp_rx = NULL; + } + if (vdev->ud.tcp_tx) { kthread_stop_put(vdev->ud.tcp_tx); - + vdev->ud.tcp_tx = NULL; + } pr_info("stop threads\n"); /* active connection is closed */ -- cgit v1.2.3