Since we can't always rely on wTotalLength to be correct, use the
variable which has been used to malloc(9) cdesc to free(9) it again,
instead of freeing wTotalLength. usbd_get_cdesc() already has the
feature built-in to return the length it has used to malloc(9) cdesc.
OK?
Index: ugen.c
===================================================================
RCS file: /cvs/src/sys/dev/usb/ugen.c,v
retrieving revision 1.106
diff -u -p -u -p -r1.106 ugen.c
--- ugen.c 13 May 2020 08:13:42 -0000 1.106
+++ ugen.c 27 Aug 2020 20:26:57 -0000
@@ -947,7 +947,7 @@ ugen_do_ioctl(struct ugen_softc *sc, int
int flag, struct proc *p)
{
struct ugen_endpoint *sce;
- int err;
+ int err, cdesc_len;
struct usbd_interface *iface;
struct usb_config_desc *cd;
usb_config_descriptor_t *cdesc;
@@ -1046,7 +1046,8 @@ ugen_do_ioctl(struct ugen_softc *sc, int
break;
case USB_GET_NO_ALT:
ai = (struct usb_alt_interface *)addr;
- cdesc = usbd_get_cdesc(sc->sc_udev, ai->uai_config_index, 0);
+ cdesc = usbd_get_cdesc(sc->sc_udev, ai->uai_config_index,
+ &cdesc_len);
if (cdesc == NULL)
return (EINVAL);
idesc = usbd_find_idesc(cdesc, ai->uai_interface_index, 0);
@@ -1056,7 +1057,7 @@ ugen_do_ioctl(struct ugen_softc *sc, int
}
ai->uai_alt_no = usbd_get_no_alts(cdesc,
idesc->bInterfaceNumber);
- free(cdesc, M_TEMP, UGETW(cdesc->wTotalLength));
+ free(cdesc, M_TEMP, cdesc_len);
break;
case USB_GET_DEVICE_DESC:
*(usb_device_descriptor_t *)addr =
@@ -1064,15 +1065,17 @@ ugen_do_ioctl(struct ugen_softc *sc, int
break;
case USB_GET_CONFIG_DESC:
cd = (struct usb_config_desc *)addr;
- cdesc = usbd_get_cdesc(sc->sc_udev, cd->ucd_config_index, 0);
+ cdesc = usbd_get_cdesc(sc->sc_udev, cd->ucd_config_index,
+ &cdesc_len);
if (cdesc == NULL)
return (EINVAL);
cd->ucd_desc = *cdesc;
- free(cdesc, M_TEMP, UGETW(cdesc->wTotalLength));
+ free(cdesc, M_TEMP, cdesc_len);
break;
case USB_GET_INTERFACE_DESC:
id = (struct usb_interface_desc *)addr;
- cdesc = usbd_get_cdesc(sc->sc_udev, id->uid_config_index, 0);
+ cdesc = usbd_get_cdesc(sc->sc_udev, id->uid_config_index,
+ &cdesc_len);
if (cdesc == NULL)
return (EINVAL);
if (id->uid_config_index == USB_CURRENT_CONFIG_INDEX &&
@@ -1086,11 +1089,12 @@ ugen_do_ioctl(struct ugen_softc *sc, int
return (EINVAL);
}
id->uid_desc = *idesc;
- free(cdesc, M_TEMP, UGETW(cdesc->wTotalLength));
+ free(cdesc, M_TEMP, cdesc_len);
break;
case USB_GET_ENDPOINT_DESC:
ed = (struct usb_endpoint_desc *)addr;
- cdesc = usbd_get_cdesc(sc->sc_udev, ed->ued_config_index, 0);
+ cdesc = usbd_get_cdesc(sc->sc_udev, ed->ued_config_index,
+ &cdesc_len);
if (cdesc == NULL)
return (EINVAL);
if (ed->ued_config_index == USB_CURRENT_CONFIG_INDEX &&
@@ -1105,7 +1109,7 @@ ugen_do_ioctl(struct ugen_softc *sc, int
return (EINVAL);
}
ed->ued_desc = *edesc;
- free(cdesc, M_TEMP, UGETW(cdesc->wTotalLength));
+ free(cdesc, M_TEMP, cdesc_len);
break;
case USB_GET_FULL_DESC:
{
@@ -1115,7 +1119,8 @@ ugen_do_ioctl(struct ugen_softc *sc, int
struct usb_full_desc *fd = (struct usb_full_desc *)addr;
int error;
- cdesc = usbd_get_cdesc(sc->sc_udev, fd->ufd_config_index, &len);
+ cdesc = usbd_get_cdesc(sc->sc_udev, fd->ufd_config_index,
+ &cdesc_len);
if (cdesc == NULL)
return (EINVAL);
if (len > fd->ufd_size)
@@ -1130,7 +1135,7 @@ ugen_do_ioctl(struct ugen_softc *sc, int
uio.uio_rw = UIO_READ;
uio.uio_procp = p;
error = uiomove((void *)cdesc, len, &uio);
- free(cdesc, M_TEMP, UGETW(cdesc->wTotalLength));
+ free(cdesc, M_TEMP, cdesc_len);
return (error);
}
case USB_DO_REQUEST:
Index: usb.c
===================================================================
RCS file: /cvs/src/sys/dev/usb/usb.c,v
retrieving revision 1.125
diff -u -p -u -p -r1.125 usb.c
--- usb.c 27 Aug 2020 19:55:00 -0000 1.125
+++ usb.c 27 Aug 2020 20:26:57 -0000
@@ -516,7 +516,7 @@ usb_fill_udc_task(void *arg)
struct usb_device_cdesc *udc = (struct usb_device_cdesc *)arg;
struct usb_softc *sc;
struct usbd_device *dev;
- int addr = udc->udc_addr;
+ int addr = udc->udc_addr, cdesc_len;
usb_config_descriptor_t *cdesc;
/* check that the bus and device are still present */
@@ -530,11 +530,11 @@ usb_fill_udc_task(void *arg)
return;
cdesc = usbd_get_cdesc(sc->sc_bus->devices[addr],
- udc->udc_config_index, 0);
+ udc->udc_config_index, &cdesc_len);
if (cdesc == NULL)
return;
udc->udc_desc = *cdesc;
- free(cdesc, M_TEMP, UGETW(cdesc->wTotalLength));
+ free(cdesc, M_TEMP, cdesc_len);
}
void