From a711f2bef270fc9825cfd410525733ddd56ae720 Mon Sep 17 00:00:00 2001 From: "Alex \"Chadderz\" Chadwick" Date: Fri, 20 Apr 2018 12:23:50 +0100 Subject: [PATCH] Fix concurrency bugs in FAT_getAttr/FAT_setAttr. (#13) A relatively rare concurrency bug existed in these methods due to them not correctly holding the partition lock during calls to _FAT_directory_entryFromPath. That method can trigger reads to the partition. Due to the lock not being held, another thread could still trigger a concurrent read, potentially corrupting the cache. The fix is simply to ensure the lock is held around the calls. --- source/fatfile.c | 21 +++++++++++++-------- 1 file changed, 13 insertions(+), 8 deletions(-) diff --git a/source/fatfile.c b/source/fatfile.c index 06c2ca7..cd5ba56 100644 --- a/source/fatfile.c +++ b/source/fatfile.c @@ -46,6 +46,7 @@ #include "lock.h" bool _FAT_findEntry(const char *path, DIR_ENTRY *dirEntry) { + bool r; PARTITION *partition = _FAT_partition_getPartitionFromPath(path); // Check Partition @@ -61,8 +62,11 @@ bool _FAT_findEntry(const char *path, DIR_ENTRY *dirEntry) { } // Search for the file on the disc - return _FAT_directory_entryFromPath (partition, dirEntry, path, NULL); + _FAT_lock(&partition->lock); + r = _FAT_directory_entryFromPath (partition, dirEntry, path, NULL); + _FAT_unlock(&partition->lock); + return r; } int FAT_getAttr(const char *file) { @@ -92,16 +96,17 @@ int FAT_setAttr(const char *file, uint8_t attr) { if (strchr (file, ':') != NULL) return -1; - // Get DIR_ENTRY - if( !_FAT_directory_entryFromPath (partition, &dirEntry, file, NULL) ) - return -1; - - // Get Entry-End - entryEnd = dirEntry.dataEnd; - // Lock Partition _FAT_lock(&partition->lock); + // Get DIR_ENTRY + if( !_FAT_directory_entryFromPath (partition, &dirEntry, file, NULL) ) { + _FAT_unlock(&partition->lock); // Unlock Partition + return -1; + } + + // Get Entry-End + entryEnd = dirEntry.dataEnd; // Write Data _FAT_cache_writePartialSector (