On Tue, 25 Aug 2020 10:30:50 +0000
Mikolaj Kucharski <[email protected]> wrote:

> On Tue, Aug 25, 2020 at 12:24:56PM +0200, Marcus Glocker wrote:
> > On Mon, 24 Aug 2020 16:46:22 +0000
> > Mikolaj Kucharski <[email protected]> wrote:
> >   
> > > 
> > > # scanimage -L
> > > device `xerox_mfp:libusb:000:002' is a Samsung M2070 Series
> > > multi-function peripheral
> > > 
> > > I think this is part when the problem happens, from dmesg:
> > > 
> > > usbd_get_cdesc: index=0, len=32
> > > wTotalLength free = 55  
> > 
> > Ok, as expected.  We're allocating 32 bytes from somewhere, and then
> > try to free 55 bytes, which causes the panic finally.  Can you
> > please send me a full 'lsusb -v' for all the USB devices on that
> > machine?  I would like to understand whether we're mixing up
> > configuration descriptors by any chance ...
> >   
>
> # lsusb -v

Thanks.

So there is no other configuration descriptor with wTotalLength=32.
I read through the involved code path, and I couldn't find anything
obvious which could result in the wTotalLength to be changed to
another value.  Therefore the only explanation I have in mind is
that for some reason the initial control request is returning
wTotalLength=32.  You see in the former debug output that after that,
wTotalLength=55 is returned which seems to be the correct value.

To check if that really happens, can you please run this diff and send
me the output again?


Index: usb.c
===================================================================
RCS file: /cvs/src/sys/dev/usb/usb.c,v
retrieving revision 1.124
diff -u -p -u -p -r1.124 usb.c
--- usb.c       6 Oct 2019 17:11:51 -0000       1.124
+++ usb.c       26 Aug 2020 11:27:16 -0000
@@ -772,7 +772,9 @@ usbioctl(dev_t devt, u_long cmd, caddr_t
                uio.uio_rw = UIO_READ;
                uio.uio_procp = p;
                error = uiomove((void *)cdesc, len, &uio);
-               free(cdesc, M_TEMP, UGETW(cdesc->wTotalLength));
+               printf("USB_DEVICE_GET_FDESC wTotalLength free = %d\n",
+                   UGETW(cdesc->wTotalLength));
+               free(cdesc, M_TEMP, 0);
                return (error);
        }
 
Index: usb_subr.c
===================================================================
RCS file: /cvs/src/sys/dev/usb/usb_subr.c,v
retrieving revision 1.151
diff -u -p -u -p -r1.151 usb_subr.c
--- usb_subr.c  31 Jul 2020 10:49:33 -0000      1.151
+++ usb_subr.c  26 Aug 2020 11:27:16 -0000
@@ -1384,6 +1384,44 @@ usbd_get_cdesc(struct usbd_device *dev, 
                        return (0);
                len = UGETW(cdescr.wTotalLength);
                DPRINTFN(5,("%s: index=%d, len=%u\n", __func__, index, len));
+
+               if (len == 32) {
+                       printf("1:\n"
+                           "bLength=%d\nbDescriptorType=%d\nwTotalLength=%d\n"
+                           "bNumInterface=%d\nbConfigurationValue=%d\n"
+                           "iConfiguration=%d\nbmAttributes=0x%x\n"
+                           "bMaxPower=%d\n",
+                           cdescr.bLength,
+                           cdescr.bDescriptorType,
+                           UGETW(cdescr.wTotalLength),
+                           cdescr.bNumInterface,
+                           cdescr.bConfigurationValue,
+                           cdescr.iConfiguration,
+                           cdescr.bmAttributes,
+                           cdescr.bMaxPower
+                       );
+                       usbd_delay_ms(dev, 100);
+                       err = usbd_get_desc(dev, UDESC_CONFIG, index,
+                           USB_CONFIG_DESCRIPTOR_SIZE, &cdescr);
+                       if (err || cdescr.bDescriptorType != UDESC_CONFIG)
+                               return (0);
+                       len = UGETW(cdescr.wTotalLength);
+                       printf("2:\n"
+                           "bLength=%d\nbDescriptorType=%d\nwTotalLength=%d\n"
+                           "bNumInterface=%d\nbConfigurationValue=%d\n"
+                           "iConfiguration=%d\nbmAttributes=0x%x\n"
+                           "bMaxPower=%d\n",
+                           cdescr.bLength,
+                           cdescr.bDescriptorType,
+                           UGETW(cdescr.wTotalLength),
+                           cdescr.bNumInterface,
+                           cdescr.bConfigurationValue,
+                           cdescr.iConfiguration,
+                           cdescr.bmAttributes,
+                           cdescr.bMaxPower
+                       );
+               }
+                   
                if (lenp)
                        *lenp = len;
                cdesc = malloc(len, M_TEMP, M_WAITOK);

Reply via email to