From 1210dc491937563fd7ccbeab24f2b96912a4642e Mon Sep 17 00:00:00 2001 From: Jukka Laitinen Date: Mon, 15 Sep 2025 11:45:01 +0300 Subject: [PATCH] drivers/usbdev/cdcacm: Add a mutex around driver initialize / uninitialize This protects the driver in case multiple threads are trying to initialize or uninitialize the cdcacm concurrently. Note that this only protects the case when the private pointer is not managed outside the kernel. If someone has acquired the pointer to the driver and uses that, it also needs to manage the protection itself if needed. Signed-off-by: Jukka Laitinen --- drivers/usbdev/cdcacm.c | 24 +++++++++++++++++++++++- 1 file changed, 23 insertions(+), 1 deletion(-) diff --git a/drivers/usbdev/cdcacm.c b/drivers/usbdev/cdcacm.c index 17348460fc2..691af901b21 100644 --- a/drivers/usbdev/cdcacm.c +++ b/drivers/usbdev/cdcacm.c @@ -313,6 +313,10 @@ static const struct uart_ops_s g_uartops = cdcuart_sendbuf /* sendbuf */ }; +/* Mutex to protect device initialization / uninitialization*****************/ + +static mutex_t g_init_lock = NXMUTEX_INITIALIZER; + /**************************************************************************** * Private Functions ****************************************************************************/ @@ -3377,9 +3381,16 @@ int cdcacm_initialize(int minor, FAR void **handle) devinfo.epno[CDCACM_EP_BULKIN_IDX] = CONFIG_CDCACM_EPBULKIN; devinfo.epno[CDCACM_EP_BULKOUT_IDX] = CONFIG_CDCACM_EPBULKOUT; + ret = nxmutex_lock(&g_init_lock); + if (ret < 0) + { + return ret; + } + /* Get an instance of the serial driver class object */ ret = cdcacm_classobject(minor, &devinfo, &drvr); + if (ret == OK) { /* Register the USB serial class driver */ @@ -3392,6 +3403,8 @@ int cdcacm_initialize(int minor, FAR void **handle) } } + nxmutex_unlock(&g_init_lock); + /* Return the driver instance (if any) if the caller has requested it * by provided a pointer to the location to return it. */ @@ -3460,6 +3473,12 @@ int cdcacm_uninitialize_instance(int minor, snprintf(devname, sizeof(devname), CDCACM_DEVNAME_FORMAT, minor); + ret = nxmutex_lock(&g_init_lock); + if (ret < 0) + { + return ret; + } + /* If classdev is not provided, find it from the file system */ if (classdev == NULL) @@ -3472,7 +3491,8 @@ int cdcacm_uninitialize_instance(int minor, } else { - return -ENODEV; + ret = -ENODEV; + goto out; } } @@ -3502,6 +3522,8 @@ int cdcacm_uninitialize_instance(int minor, (uint16_t)-ret); } +out: + nxmutex_unlock(&g_init_lock); return ret; }