diff --git a/components/fatfs/port/freertos/ffsystem.c b/components/fatfs/port/freertos/ffsystem.c index 37c31de3fe3..4a6e0140d8a 100644 --- a/components/fatfs/port/freertos/ffsystem.c +++ b/components/fatfs/port/freertos/ffsystem.c @@ -122,7 +122,7 @@ int ff_mutex_create ( /* Returns 1:Function succeeded or 0:Could not create the / semaphore of the volume created with ff_mutex_create function. */ -void ff_mutex_delete ( /* Returns 1:Function succeeded or 0:Could not delete due to an error */ +void ff_mutex_delete ( int vol /* Mutex ID: Volume mutex (0 to FF_VOLUMES - 1) or system mutex (FF_VOLUMES) */ ) { @@ -138,7 +138,10 @@ void ff_mutex_delete ( /* Returns 1:Function succeeded or 0:Could not delete due OSMutexDel(Mutex[vol], OS_DEL_ALWAYS, &err); #elif OS_TYPE == 3 /* FreeRTOS */ - vSemaphoreDelete(Mutex[vol]); + if (Mutex[vol] != NULL) { + vSemaphoreDelete(Mutex[vol]); + Mutex[vol] = NULL; /* Prevent use-after-delete in ff_mutex_take/ff_mutex_give */ + } #elif OS_TYPE == 4 /* CMSIS-RTOS */ osMutexDelete(Mutex[vol]); @@ -167,10 +170,13 @@ int ff_mutex_take ( /* Returns 1:Succeeded or 0:Timeout */ #elif OS_TYPE == 2 /* uC/OS-II */ OS_ERR err; - OSMutexPend(Mutex[vol], FF_FS_TIMEOUT, &err)); + OSMutexPend(Mutex[vol], FF_FS_TIMEOUT, &err); return (int)(err == OS_NO_ERR); #elif OS_TYPE == 3 /* FreeRTOS */ + if (vol < 0 || vol > FF_VOLUMES || Mutex[vol] == NULL) { + return 0; /* No volume mounted or mutex not created -> treat as timeout */ + } return (int)(xSemaphoreTake(Mutex[vol], FF_FS_TIMEOUT) == pdTRUE); #elif OS_TYPE == 4 /* CMSIS-RTOS */ @@ -201,7 +207,9 @@ void ff_mutex_give ( OSMutexPost(Mutex[vol]); #elif OS_TYPE == 3 /* FreeRTOS */ - xSemaphoreGive(Mutex[vol]); + if (vol >= 0 && vol <= FF_VOLUMES && Mutex[vol] != NULL) { + xSemaphoreGive(Mutex[vol]); + } #elif OS_TYPE == 4 /* CMSIS-RTOS */ osMutexRelease(Mutex[vol]); diff --git a/components/fatfs/vfs/vfs_fat_spiflash.c b/components/fatfs/vfs/vfs_fat_spiflash.c index aebc9a4923f..b1764a049ac 100644 --- a/components/fatfs/vfs/vfs_fat_spiflash.c +++ b/components/fatfs/vfs/vfs_fat_spiflash.c @@ -1,5 +1,5 @@ /* - * SPDX-FileCopyrightText: 2015-2025 Espressif Systems (Shanghai) CO LTD + * SPDX-FileCopyrightText: 2015-2026 Espressif Systems (Shanghai) CO LTD * * SPDX-License-Identifier: Apache-2.0 */ @@ -215,6 +215,11 @@ esp_err_t esp_vfs_fat_spiflash_mount_rw_wl(const char* base_path, return ESP_OK; fail: + /* Unmount FatFs volume if we had registered and attempted mount (e.g. s_f_mount_rw + * failed). Otherwise FatFs[vol] can be left set with a dangling pointer after + * esp_vfs_fat_unregister_path frees the context, and the volume mutex stays + * created; a later f_getfree then crashes in lock_volume / ff_mutex_take. */ + f_mount(0, drv, 0); esp_vfs_fat_unregister_path(base_path); ff_diskio_unregister(pdrv); free(ctx); @@ -390,6 +395,7 @@ esp_err_t esp_vfs_fat_spiflash_mount_ro(const char* base_path, return ESP_OK; fail: + f_mount(0, drv, 0); /* Unmount on failed mount so FatFs[vol] and mutex are cleaned up */ esp_vfs_fat_unregister_path(base_path); ff_diskio_unregister(pdrv); return ret;