Greg KH <[EMAIL PROTECTED]> writes:

> On Fri, Jan 04, 2002 at 12:38:36AM +0100, Peter Osterlund wrote:
> > 
> > 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.
> 
> First off, the usb-storage driver doesn't seem to work properly in
> 2.5.2-pre6 due to the bio and scsi changes happening.  Have you got it
> to work?

Yes, it does work with the patch I sent previously. The only problem
is that my patch will stop working again sometime in the future, when
the .address field is removed from struct scatterlist.

> > 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.
> 
> I don't see how that can happen, as this code only runs when the device
> is first plugged in (from what I can tell.)  usb_destroy_configuration()
> seems to be called much later.  Can you enable debugging in the
> usb-storage driver and see if that shows anything?

I think my device rapidly disappeared/reappeared and disappeared again
on the bus, but I don't know for sure, because I didn't have serial
console logging active at the time, and I can not repeat the problem.

Anyway, if (header->bLength < 2) is true in usb_parse_interface (line
1546), the endpoint, extra and extralen fields will never be
initialized. This will lead to either corruption or a memory leak when
usb_destroy_configuration is called. Therefore I think this patch is
correct.

--- usb.c.old   Fri Jan  4 11:56:20 2002
+++ usb.c       Fri Jan  4 14:58:18 2002
@@ -1527,6 +1527,9 @@
                }
 
                ifp = interface->altsetting + interface->num_altsetting;
+               ifp->endpoint = NULL;
+               ifp->extra = NULL;
+               ifp->extralen = 0;
                interface->num_altsetting++;
 
                memcpy(ifp, buffer, USB_DT_INTERFACE_SIZE);

Also, while analyzing this problem, I found a bug in usb-uhci.c. If
the uhci_start_usb call fails in alloc_uhci, line 3004,
uhci_pci_remove will oops, because the pci private data has not been
initialized, so uhci_t *s will be zero, and s->bus will oops. Here is
a patch to fix this bug:

--- usb-uhci.c.old      Fri Jan  4 14:06:48 2002
+++ usb-uhci.c  Fri Jan  4 14:21:01 2002
@@ -3000,13 +3000,13 @@
 
        s->irq = irq;
 
+       pci_set_drvdata(dev, s);
        if(uhci_start_usb (s) < 0) {
                uhci_pci_remove(dev);
                return -1;
        }
 
        //chain new uhci device into global list
-       pci_set_drvdata(dev, s);
        devs=s;
 
        return 0;

-- 
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