Hi!

When trying to write to a bad CDRW disk in my USB CDRW unit, I got an
oops in the usb subsystem. The oops was caused by passing junk to
kfree in usb_destroy_configuration, line 1765. The as->extra field
apparently contained junk.

I think this is caused by a race in usb_parse_interface.
interface->num_altsetting is incremented before the corresponding
altsetting[] data has been initialized. If an interrupt occurs in
between, and the interrupt causes the device to be removed, bad things
will happen.

It is quite possible that my CDRW burner somehow misbehaved on the USB
bus when I saw this problem, but a misbehaving device should not cause
a kernel panic, IMO.

Is the following patch the correct way to fix this problem? Note that
this patch will also avoid incrementing num_altsetting if an "invalid
descriptor length" (line 1546) is detected, something that could also
happen (I think) if a device is misbehaving.

--- linux-2.5-packet/drivers/usb/usb.c.old      Fri Jan  4 00:04:23 2002
+++ linux-2.5-packet/drivers/usb/usb.c  Fri Jan  4 00:17:43 2002
@@ -1527,7 +1527,6 @@
                }
 
                ifp = interface->altsetting + interface->num_altsetting;
-               interface->num_altsetting++;
 
                memcpy(ifp, buffer, USB_DT_INTERFACE_SIZE);
 
@@ -1582,6 +1581,8 @@
                        memcpy(ifp->extra, begin, len);
                        ifp->extralen = len;
                }
+
+               interface->num_altsetting++;
 
                /* Did we hit an unexpected descriptor? */
                header = (struct usb_descriptor_header *)buffer;


Here is the relevant part of the OOPS. (Hand-written, watch out for
typos.)

hub.c: hub / port 1, portstatus 103, change 1, 12 Mb/s
usb.c: USB disconnect on device 2
usb.c: kusbd: /sbin/hotplug remove 2
hub.c: port 1, portstatus 103, change 0, 12 Mb/s
usb-uhci.c: interrupt, status 2, frame# 1311
divide error: 0000
CPU:   0
EIP:   0010:[<c012ad65>]        Not tainted
EFLAGS: 00010082
eax: c39a9240   ebx: c39a9240   exc: c10e6a40   edx: 00000000
esi: c10e6a40   edi: 00000282   ebp: 00000000   esp: c3335d8c
ds: 0018   es: 0018   ss: 0018
Process uname (pid: 1292, stackpage=c3335000)
Stack: c3e8929c 00000002 c3eb6ca0 c3ae6cc0 c4817ee4 c39a9240 00000000 00000000
       00000000 c3ae6c40 00000000 00000000 c3e9a600 c3e9a600 c3eb6ca0 00000000
       c3e9a600 c48171e2 c3e9a600 c3e9a600 00000000 c48288b5 c3e9a600 00000000
Call Trace: [<c4817ee4>] [<c48171e2>] [<c48288b5>] [<c4828991>] [<c0123e54>]
   [<c0109bfa>] [<c0109d7d>] [<c012399a>] [<c0123a28>] [<c0111f3a>] [<c010cf3d>]
   [<c0111da0>] [<c0108954>]
Code: f7 76 18 89 c3 8b 41 14 89 44 99 18 89 59 14 8b 51 10 8d 42

>>EIP; c012ad65 <kfree+35/a0>   <=====
Trace; c4817ee4 <[usbcore]usb_destroy_configuration+104/210>
Trace; c48171e2 <[usbcore]usb_free_dev+22/50>
Trace; c48288b5 <[usb-uhci]process_urb+1e5/200>
Trace; c4828991 <[usb-uhci]uhci_interrupt+c1/130>
Trace; c0123e54 <__vma_link+64/c0>
Trace; c0109bfa <handle_IRQ_event+3a/70>
Trace; c0109d7d <do_IRQ+6d/b0>
Trace; c012399a <do_no_page+ea/120>
Trace; c0123a28 <handle_mm_fault+58/c0>
Trace; c0111f3a <do_page_fault+19a/4f0>
Trace; c010cf3d <old_mmap+ed/130>
Trace; c0111da0 <do_page_fault+0/4f0>
Trace; c0108954 <error_code+34/40>
Code;  c012ad65 <kfree+35/a0>
00000000 <_EIP>:
Code;  c012ad65 <kfree+35/a0>   <=====
   0:   f7 76 18                  div    0x18(%esi),%eax   <=====
Code;  c012ad68 <kfree+38/a0>
   3:   89 c3                     mov    %eax,%ebx
Code;  c012ad6a <kfree+3a/a0>
   5:   8b 41 14                  mov    0x14(%ecx),%eax
Code;  c012ad6d <kfree+3d/a0>
   8:   89 44 99 18               mov    %eax,0x18(%ecx,%ebx,4)
Code;  c012ad71 <kfree+41/a0>
   c:   89 59 14                  mov    %ebx,0x14(%ecx)
Code;  c012ad74 <kfree+44/a0>
   f:   8b 51 10                  mov    0x10(%ecx),%edx
Code;  c012ad77 <kfree+47/a0>
  12:   8d 42 00                  lea    0x0(%edx),%eax

-- 
Peter Osterlund - [EMAIL PROTECTED]
http://w1.894.telia.com/~u89404340

_______________________________________________
[EMAIL PROTECTED]
To unsubscribe, use the last form field at:
https://lists.sourceforge.net/lists/listinfo/linux-usb-devel

Reply via email to