usbhost_hub: Prevent crash when the last hub port is used.
An off-by-one error caused invalid memory to be accessed when the last port was used. The first entry, at index 0, was never used. The USB standard uses 1-based numbering for hub ports. This number was used to index an array. This change converts the port number to a zero-based port index when the array is accessed. The zero-based value in the port field of the usbhost_hubport_s structure is also converted before printing. For testing, this bug was exposed on a 4 port hub when port 4 was used after changing USBHUB_MAX_PORTS to 4 in hub.h. The bug should also be triggered without changing hub.h if a 7 port hub is available.
This commit is contained in:
parent
694e6f550b
commit
38ba0aefca
@ -93,6 +93,14 @@
|
|||||||
|
|
||||||
#define INTIN_BUFSIZE ((USBHUB_MAX_PORTS + 8) >> 3)
|
#define INTIN_BUFSIZE ((USBHUB_MAX_PORTS + 8) >> 3)
|
||||||
|
|
||||||
|
/* Convert 0-based index to port number. */
|
||||||
|
|
||||||
|
#define PORT_NO(x) ((x) + 1)
|
||||||
|
|
||||||
|
/* Convert port number to 0-based index. */
|
||||||
|
|
||||||
|
#define PORT_INDX(x) ((x) - 1)
|
||||||
|
|
||||||
/****************************************************************************
|
/****************************************************************************
|
||||||
* Private Types
|
* Private Types
|
||||||
****************************************************************************/
|
****************************************************************************/
|
||||||
@ -223,7 +231,7 @@ static struct usbhost_registry_s g_hub =
|
|||||||
static void usbhost_hport_deactivate(FAR struct usbhost_hubport_s *hport)
|
static void usbhost_hport_deactivate(FAR struct usbhost_hubport_s *hport)
|
||||||
{
|
{
|
||||||
uinfo("Deactivating: %s port %d\n",
|
uinfo("Deactivating: %s port %d\n",
|
||||||
ROOTHUB(hport) ? "Root" : "Hub", hport->port);
|
ROOTHUB(hport) ? "Root" : "Hub", PORT_NO(hport->port));
|
||||||
|
|
||||||
/* Don't free the control pipe of root hub ports! */
|
/* Don't free the control pipe of root hub ports! */
|
||||||
|
|
||||||
@ -268,7 +276,7 @@ static int usbhost_hport_activate(FAR struct usbhost_hubport_s *hport)
|
|||||||
struct usbhost_epdesc_s epdesc;
|
struct usbhost_epdesc_s epdesc;
|
||||||
int ret;
|
int ret;
|
||||||
|
|
||||||
uinfo("Activating port %d\n", hport->port);
|
uinfo("Activating port %d\n", PORT_NO(hport->port));
|
||||||
|
|
||||||
epdesc.hport = hport;
|
epdesc.hport = hport;
|
||||||
epdesc.addr = 0;
|
epdesc.addr = 0;
|
||||||
@ -907,7 +915,7 @@ static void usbhost_hub_event(FAR void *arg)
|
|||||||
DRVR_CTRLOUT(hport->drvr, hport->ep0, ctrlreq, NULL);
|
DRVR_CTRLOUT(hport->drvr, hport->ep0, ctrlreq, NULL);
|
||||||
}
|
}
|
||||||
|
|
||||||
connport = &priv->hport[port];
|
connport = &priv->hport[PORT_INDX(port)];
|
||||||
if ((status & USBHUB_PORT_STAT_HIGH_SPEED) != 0)
|
if ((status & USBHUB_PORT_STAT_HIGH_SPEED) != 0)
|
||||||
{
|
{
|
||||||
connport->speed = USB_SPEED_HIGH;
|
connport->speed = USB_SPEED_HIGH;
|
||||||
@ -961,7 +969,7 @@ static void usbhost_hub_event(FAR void *arg)
|
|||||||
|
|
||||||
/* Free any devices classes connect on this hub port */
|
/* Free any devices classes connect on this hub port */
|
||||||
|
|
||||||
connport = &priv->hport[port];
|
connport = &priv->hport[PORT_INDX(port)];
|
||||||
if (connport->devclass != NULL)
|
if (connport->devclass != NULL)
|
||||||
{
|
{
|
||||||
CLASS_DISCONNECTED(connport->devclass);
|
CLASS_DISCONNECTED(connport->devclass);
|
||||||
@ -1071,7 +1079,7 @@ static void usbhost_disconnect_event(FAR void *arg)
|
|||||||
priv = &((FAR struct usbhost_hubclass_s *)hubclass)->hubpriv;
|
priv = &((FAR struct usbhost_hubclass_s *)hubclass)->hubpriv;
|
||||||
hport = hubclass->hport;
|
hport = hubclass->hport;
|
||||||
|
|
||||||
uinfo("Destroying hub on port %d\n", hport->port);
|
uinfo("Destroying hub on port %d\n", PORT_NO(hport->port));
|
||||||
|
|
||||||
/* Set an indication to any users of the device that the device is no
|
/* Set an indication to any users of the device that the device is no
|
||||||
* longer available.
|
* longer available.
|
||||||
|
Loading…
Reference in New Issue
Block a user