1
0
Fork 0
forked from nuttx/nuttx-update

Correct unitialization of composite USB device. A stale pointer was being reused. From David Sidrane

This commit is contained in:
Gregory Nutt 2013-11-05 09:12:08 -06:00
parent 4cb6c0ad80
commit f67ee984f3
4 changed files with 64 additions and 13 deletions

View file

@ -5966,4 +5966,8 @@
logic when buffers larger than the EP0 packet size are sent.
Also add support for decoded USB trace strings. From David
Sidrane (2013-11-5).
* drivers/usbdev/cdcacm.c, composite.c, usbmsc.c: uninitialization
logic cause re-use of a stale pointer. Changed to a two pass
uninitialization for the case of the composite driver: Memory
resources are not freed until the second uninitialization pass.
From David Sidrane (2011-1105).

View file

@ -2398,6 +2398,22 @@ void cdcacm_uninitialize(FAR void *handle)
char devname[CDCACM_DEVNAME_SIZE];
int ret;
#ifdef CONFIG_CDCACM_COMPOSITE
/* Check for pass 2 uninitialization. We did most of the work on the
* first pass uninitialization.
*/
if (priv->minor == (uint8_t)-1)
{
/* In this second and final pass, all that remains to be done is to
* free the memory resources.
*/
kfree(priv);
return;
}
#endif
/* Un-register the CDC/ACM TTY device */
sprintf(devname, CDCACM_DEVNAME_FORMAT, priv->minor);
@ -2420,9 +2436,19 @@ void cdcacm_uninitialize(FAR void *handle)
#ifndef CONFIG_CDCACM_COMPOSITE
usbdev_unregister(&drvr->drvr);
#endif
/* And free the driver structure */
kfree(priv);
#else
/* For the case of the composite driver, there is a two pass
* uninitialization sequence. We cannot yet free the driver structure.
* We will do that on the second pass. We mark the fact that we have
* already unitialized by setting the minor number to -1. If/when we
* are called again, then we will free the memory resources.
*/
priv->minor = (uint8_t)-1;
#endif
}

View file

@ -880,20 +880,12 @@ void composite_uninitialize(FAR void *handle)
DEBUGASSERT(alloc != NULL);
/* Uninitialize each of the member classes */
/* First phase uninitialization each of the member classes */
priv = &alloc->dev;
if (priv->dev1)
{
DEV1_UNINITIALIZE(priv->dev1);
priv->dev1 = NULL;
}
if (priv->dev2)
{
DEV2_UNINITIALIZE(priv->dev2);
priv->dev2 = NULL;
}
DEV1_UNINITIALIZE(priv->dev1);
DEV2_UNINITIALIZE(priv->dev2);
/* Then unregister and destroy the composite class */
@ -902,6 +894,11 @@ void composite_uninitialize(FAR void *handle)
/* Free any resources used by the composite driver */
/* None */
/* Second phase uninitialization: Clean up all memory resources */
DEV1_UNINITIALIZE(priv->dev1);
DEV2_UNINITIALIZE(priv->dev2);
/* Then free the composite driver state structure itself */
kfree(priv);

View file

@ -1739,6 +1739,22 @@ void usbmsc_uninitialize(FAR void *handle)
priv = &alloc->dev;
#ifdef CONFIG_USBMSC_COMPOSITE
/* Check for pass 2 uninitialization. We did most of the work on the
* first pass uninitialization.
*/
if (priv->thread == 0)
{
/* In this second and final pass, all that remains to be done is to
* free the memory resources.
*/
kfree(priv);
return;
}
#endif
/* If the thread hasn't already exitted, tell it to exit now */
if (priv->thstate != USBMSC_STATE_NOTSTARTED)
@ -1821,5 +1837,13 @@ void usbmsc_uninitialize(FAR void *handle)
pthread_mutex_destroy(&priv->mutex);
pthread_cond_destroy(&priv->cond);
#ifndef CONFIG_USBMSC_COMPOSITE
/* For the case of the composite driver, there is a two pass
* uninitialization sequence. We cannot yet free the driver structure.
* We will do that on the second pass (and we will know that it is the
* second pass because of priv->thread == 0)
*/
kfree(priv);
#endif
}