https://git.reactos.org/?p=reactos.git;a=commitdiff;h=cf4138fa2433373081854b44c4bb76541d4fe0cc
commit cf4138fa2433373081854b44c4bb76541d4fe0cc Author: Thamatip Chitpong <thamatip.chitp...@reactos.org> AuthorDate: Thu Jul 25 23:09:17 2024 +0700 Commit: Thamatip Chitpong <thamatip.chitp...@reactos.org> CommitDate: Wed Jul 31 18:07:49 2024 +0700 [NTOS:CC] Protect CcFlushCache call with a mutex Fix crash when the function was called concurrently for the same file by BTRFS driver. CORE-19664 --- ntoskrnl/cc/view.c | 9 +++++++-- ntoskrnl/include/internal/cc.h | 1 + 2 files changed, 8 insertions(+), 2 deletions(-) diff --git a/ntoskrnl/cc/view.c b/ntoskrnl/cc/view.c index 90b644560e2..7c13afb3220 100644 --- a/ntoskrnl/cc/view.c +++ b/ntoskrnl/cc/view.c @@ -1142,6 +1142,8 @@ CcFlushCache ( IoStatus->Information = 0; } + KeAcquireGuardedMutex(&SharedCacheMap->FlushCacheLock); + /* * We flush the VACBs that we find here. * If there is no (dirty) VACB, it doesn't mean that there is no data to flush, so we call Mm to be sure. @@ -1161,7 +1163,7 @@ CcFlushCache ( if (!NT_SUCCESS(Status)) { CcRosReleaseVacb(SharedCacheMap, vacb, FALSE, FALSE); - goto quit; + break; } DirtyVacb = TRUE; @@ -1191,7 +1193,7 @@ CcFlushCache ( } if (!NT_SUCCESS(Status)) - goto quit; + break; if (IoStatus) IoStatus->Information += MmIosb.Information; @@ -1211,6 +1213,8 @@ CcFlushCache ( FlushStart -= FlushStart % VACB_MAPPING_GRANULARITY; } + KeReleaseGuardedMutex(&SharedCacheMap->FlushCacheLock); + quit: if (IoStatus) { @@ -1319,6 +1323,7 @@ CcRosInitializeFileCache ( KeInitializeSpinLock(&SharedCacheMap->CacheMapLock); InitializeListHead(&SharedCacheMap->CacheMapVacbListHead); InitializeListHead(&SharedCacheMap->BcbList); + KeInitializeGuardedMutex(&SharedCacheMap->FlushCacheLock); SharedCacheMap->Flags = SHARED_CACHE_MAP_IN_CREATION; diff --git a/ntoskrnl/include/internal/cc.h b/ntoskrnl/include/internal/cc.h index 90c315901d1..b37c5478f05 100644 --- a/ntoskrnl/include/internal/cc.h +++ b/ntoskrnl/include/internal/cc.h @@ -193,6 +193,7 @@ typedef struct _ROS_SHARED_CACHE_MAP LIST_ENTRY CacheMapVacbListHead; BOOLEAN PinAccess; KSPIN_LOCK CacheMapLock; + KGUARDED_MUTEX FlushCacheLock; #if DBG BOOLEAN Trace; /* enable extra trace output for this cache map and it's VACBs */ #endif