[PATCH 1/1] USB: io_ti: Fix NULL dereference in chase_port()

2013-01-16 Thread Wolfgang Frisch
The tty is NULL when the port is hanging up.
chase_port() needs to check for this.

This patch is intended for stable series.
The behavior was observed and tested in Linux 3.2 and 3.7.1.

Johan Hovold submitted a more elaborate patch for the mainline kernel.


[   56.277883] usb 1-1: edge_bulk_in_callback - nonzero read bulk status 
received: -84
[   56.278811] usb 1-1: USB disconnect, device number 3
[   56.278856] usb 1-1: edge_bulk_in_callback - stopping read!
[   56.279562] BUG: unable to handle kernel NULL pointer dereference at 
01c8
[   56.280536] IP: [8144e62a] _raw_spin_lock_irqsave+0x19/0x35
[   56.281212] PGD 1dc1b067 PUD 1e0f7067 PMD 0
[   56.282085] Oops: 0002 [#1] SMP
[   56.282744] Modules linked in:
[   56.283512] CPU 1
[   56.283512] Pid: 25, comm: khubd Not tainted 3.7.1 #1 innotek GmbH 
VirtualBox/VirtualBox
[   56.283512] RIP: 0010:[8144e62a]  [8144e62a] 
_raw_spin_lock_irqsave+0x19/0x35
[   56.283512] RSP: 0018:88001fa99ab0  EFLAGS: 00010046
[   56.283512] RAX: 0046 RBX: 01c8 RCX: 00640064
[   56.283512] RDX: 0001 RSI: 88001fa99b20 RDI: 01c8
[   56.283512] RBP: 88001fa99b20 R08:  R09: 
[   56.283512] R10:  R11: 812fcb4c R12: 88001ddf53c0
[   56.283512] R13:  R14: 01c8 R15: 88001e19b9f4
[   56.283512] FS:  () GS:88001fd0() 
knlGS:
[   56.283512] CS:  0010 DS:  ES:  CR0: 8005003b
[   56.283512] CR2: 01c8 CR3: 1dc51000 CR4: 06e0
[   56.283512] DR0:  DR1:  DR2: 
[   56.283512] DR3:  DR6: 0ff0 DR7: 0400
[   56.283512] Process khubd (pid: 25, threadinfo 88001fa98000, task 
88001fa94f80)
[   56.283512] Stack:
[   56.283512]  0046 01c8 810578ec 
812fcb4c
[   56.283512]  88001e19b980 2710 812ffe81 
0001
[   56.283512]  88001fa94f80 0202 0001 
0296
[   56.283512] Call Trace:
[   56.283512]  [810578ec] ? add_wait_queue+0x12/0x3c
[   56.283512]  [812fcb4c] ? usb_serial_port_work+0x28/0x28
[   56.283512]  [812ffe81] ? chase_port+0x84/0x2d6
[   56.283512]  [81063f27] ? try_to_wake_up+0x199/0x199
[   56.283512]  [81263a5c] ? tty_ldisc_hangup+0x222/0x298
[   56.283512]  [81300171] ? edge_close+0x64/0x129
[   56.283512]  [810612f7] ? __wake_up+0x35/0x46
[   56.283512]  [8106135b] ? should_resched+0x5/0x23
[   56.283512]  [81264916] ? tty_port_shutdown+0x39/0x44
[   56.283512]  [812fcb4c] ? usb_serial_port_work+0x28/0x28
[   56.283512]  [8125d38c] ? __tty_hangup+0x307/0x351
[   56.283512]  [812e6ddc] ? usb_hcd_flush_endpoint+0xde/0xed
[   56.283512]  [8144e625] ? _raw_spin_lock_irqsave+0x14/0x35
[   56.283512]  [812fd361] ? usb_serial_disconnect+0x57/0xc2
[   56.283512]  [812ea99b] ? usb_unbind_interface+0x5c/0x131
[   56.283512]  [8128d738] ? __device_release_driver+0x7f/0xd5
[   56.283512]  [8128d9cd] ? device_release_driver+0x1a/0x25
[   56.283512]  [8128d393] ? bus_remove_device+0xd2/0xe7
[   56.283512]  [8128b7a3] ? device_del+0x119/0x167
[   56.283512]  [812e8d9d] ? usb_disable_device+0x6a/0x180
[   56.283512]  [812e2ae0] ? usb_disconnect+0x81/0xe6
[   56.283512]  [812e4435] ? hub_thread+0x577/0xe82
[   56.283512]  [8144daa7] ? __schedule+0x490/0x4be
[   56.283512]  [8105798f] ? abort_exclusive_wait+0x79/0x79
[   56.283512]  [812e3ebe] ? usb_remote_wakeup+0x2f/0x2f
[   56.283512]  [812e3ebe] ? usb_remote_wakeup+0x2f/0x2f
[   56.283512]  [810570b4] ? kthread+0x81/0x89
[   56.283512]  [81057033] ? __kthread_parkme+0x5c/0x5c
[   56.283512]  [8145387c] ? ret_from_fork+0x7c/0xb0
[   56.283512]  [81057033] ? __kthread_parkme+0x5c/0x5c
[   56.283512] Code: 8b 7c 24 08 e8 17 0b c3 ff 48 8b 04 24 48 83 c4 10 c3 53 
48 89 fb 41 50 e8 e0 0a c3 ff 48 89 04 24 e8 e7 0a c3 ff ba 00 00 01 00
f0 0f c1 13 48 8b 04 24 89 d1 c1 ea 10 66 39 d1 74 07 f3 90 66
[   56.283512] RIP  [8144e62a] _raw_spin_lock_irqsave+0x19/0x35
[   56.283512]  RSP 88001fa99ab0
[   56.283512] CR2: 01c8
[   56.283512] ---[ end trace 49714df27e1679ce ]---


Signed-off-by: Wolfgang Frisch wf...@roembden.net
---
 drivers/usb/serial/io_ti.c |3 +++
 1 file changed, 3 insertions(+)

diff --git a/drivers/usb/serial/io_ti.c b/drivers/usb/serial/io_ti.c
index 60023c2..ed83e7a 100644
--- a/drivers/usb/serial/io_ti.c
+++ b/drivers/usb/serial/io_ti.c
@@ -534,6 +534,9 @@ static void chase_port(struct edgeport_port *port, unsigned 
long timeout,
wait_queue_t wait;
unsigned long

Re: [Patch] Problem in drivers/usb/serial/io_ti - Kernel oops when disconnecting an opened device

2013-01-16 Thread Wolfgang Frisch
On 14/01/13 16:37, Johan Hovold wrote:
 I've prepared a patch series which removes the custom chase_port
 function and replaces it with the corresponding generic implementations
 instead (which does not suffer from the problem you found).

 However, I think your solution is probably the best one for the stable
 trees as it is less intrusive.

 Care to resubmit your patch with a short description and perhaps the
 stack trace from your original report? Have look at
 Documentation/SubmittingPatches for details (e.g. you need to add a
 Signed-off-by line and should configure you mail client to send the patch
 as an inline attachment). Please see my notes on the patch below as
 well.
Thanks for your clarifying and helpful comments!
I just resubmitted my patch.


 I'll respond to this mail with my series which should also fix the
 problem (and which could later be applied on top of your patch). If you
 could test it on actual hardware it would be much appreciated.
Your patches work fine on Linux 3.7.2 with a Watchport/H sensor.

Cheers,
Wolfgang


 Thanks,
 Johan



 On 03/01/13 00:44, Wolfgang Frisch wrote:
 I have a problem with my Digi Edgeport USB sensor.

 1. Environment:
 - Digi Watchport/H USB sensor (io_ti driver)
 - Linux v3.7.1 on amd64
 Tested with v3.7.1 on 2 physical machines.
 Further tests were done in a virtual machine.

 2. Observations:
 The problem was observed with Linux 3.7.1, 3.2 and 3.1.
 I'm not able to find a recent kernel without this problem.

 The sensor works until it is disconnected while its character device
 still being used. This causes a kernel Oops.

 Steps to reproduce:
 - Attach Watchport sensor
 - Connect, e.g.: minicom -D /dev/ttyUSB0
 - Detach the sensor
 - Kernel oops

 The dmesg log is attached.



 diff --git a/drivers/usb/serial/io_ti.c b/drivers/usb/serial/io_ti.c
 index 60023c2..65258c1 100644
 --- a/drivers/usb/serial/io_ti.c
 +++ b/drivers/usb/serial/io_ti.c
 @@ -534,6 +534,11 @@ static void chase_port(struct edgeport_port *port, 
 unsigned long timeout,
  wait_queue_t wait;
  unsigned long flags;

 +// FIXME: chase_port is called with tty == NULL

 You could drop this comment.

 +if (tty == NULL) {
 +return;
 +}
 +

 and this should simply be

   if (!tty)
   return;

  if (!timeout)
  timeout = (HZ * EDGE_CLOSING_WAIT)/100;


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


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