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