https://git.reactos.org/?p=reactos.git;a=commitdiff;h=42df4683d7f3b66aa49cf678002055c87e539849

commit 42df4683d7f3b66aa49cf678002055c87e539849
Author:     Pierre Schweitzer <[email protected]>
AuthorDate: Sun Apr 8 18:34:00 2018 +0200
Commit:     Pierre Schweitzer <[email protected]>
CommitDate: Sun Apr 15 22:52:53 2018 +0200

    [NTOSKRNL] Add extra sanity checks for VACB lists.
    We now always initialize list members from the VACB
    and make sure the list entry has properly been removed
    from the list before free.
    
    CORE-14349
---
 ntoskrnl/cc/fs.c   |  2 ++
 ntoskrnl/cc/view.c | 13 +++++++++++--
 2 files changed, 13 insertions(+), 2 deletions(-)

diff --git a/ntoskrnl/cc/fs.c b/ntoskrnl/cc/fs.c
index 2ab7b5f8ea..31b7ec6bac 100644
--- a/ntoskrnl/cc/fs.c
+++ b/ntoskrnl/cc/fs.c
@@ -238,6 +238,7 @@ CcPurgeCacheSection (
         /* This VACB is in range, so unlink it and mark for free */
         ASSERT(Refs == 1 || Vacb->Dirty);
         RemoveEntryList(&Vacb->VacbLruListEntry);
+        InitializeListHead(&Vacb->VacbLruListEntry);
         if (Vacb->Dirty)
         {
             CcRosUnmarkDirtyVacb(Vacb, FALSE);
@@ -253,6 +254,7 @@ CcPurgeCacheSection (
         Vacb = CONTAINING_RECORD(RemoveHeadList(&FreeList),
                                  ROS_VACB,
                                  CacheMapVacbListEntry);
+        InitializeListHead(&Vacb->CacheMapVacbListEntry);
         CcRosVacbDecRefCount(Vacb);
         CcRosInternalFreeVacb(Vacb);
     }
diff --git a/ntoskrnl/cc/view.c b/ntoskrnl/cc/view.c
index ba87c5e510..c835a03a8e 100644
--- a/ntoskrnl/cc/view.c
+++ b/ntoskrnl/cc/view.c
@@ -375,6 +375,7 @@ retry:
 
             RemoveEntryList(&current->CacheMapVacbListEntry);
             RemoveEntryList(&current->VacbLruListEntry);
+            InitializeListHead(&current->VacbLruListEntry);
             InsertHeadList(&FreeList, &current->CacheMapVacbListEntry);
 
             /* Calculate how many pages we freed for Mm */
@@ -413,6 +414,7 @@ retry:
         current = CONTAINING_RECORD(current_entry,
                                     ROS_VACB,
                                     CacheMapVacbListEntry);
+        InitializeListHead(&current->CacheMapVacbListEntry);
         CcRosVacbDecRefCount(current);
         CcRosInternalFreeVacb(current);
     }
@@ -567,6 +569,7 @@ CcRosUnmarkDirtyVacb (
     Vacb->Dirty = FALSE;
 
     RemoveEntryList(&Vacb->DirtyVacbListEntry);
+    InitializeListHead(&Vacb->DirtyVacbListEntry);
     CcTotalDirtyPages -= VACB_MAPPING_GRANULARITY / PAGE_SIZE;
     Vacb->SharedCacheMap->DirtyPages -= VACB_MAPPING_GRANULARITY / PAGE_SIZE;
     CcRosVacbDecRefCount(Vacb);
@@ -743,11 +746,12 @@ CcRosCreateVacb (
     }
 #endif
     current->MappedCount = 0;
-    current->DirtyVacbListEntry.Flink = NULL;
-    current->DirtyVacbListEntry.Blink = NULL;
     current->ReferenceCount = 0;
     current->PinCount = 0;
     KeInitializeMutex(&current->Mutex, 0);
+    InitializeListHead(&current->CacheMapVacbListEntry);
+    InitializeListHead(&current->DirtyVacbListEntry);
+    InitializeListHead(&current->VacbLruListEntry);
     CcRosAcquireVacbLock(current, NULL);
     KeAcquireGuardedMutex(&ViewLock);
 
@@ -988,6 +992,9 @@ CcRosInternalFreeVacb (
 
     ASSERT(Vacb->PinCount == 0);
     ASSERT(Vacb->ReferenceCount == 0);
+    ASSERT(IsListEmpty(&Vacb->CacheMapVacbListEntry));
+    ASSERT(IsListEmpty(&Vacb->DirtyVacbListEntry));
+    ASSERT(IsListEmpty(&Vacb->VacbLruListEntry));
     RtlFillMemory(Vacb, sizeof(Vacb), 0xfd);
     ExFreeToNPagedLookasideList(&VacbLookasideList, Vacb);
     return STATUS_SUCCESS;
@@ -1109,6 +1116,7 @@ CcRosDeleteFileCache (
             current = CONTAINING_RECORD(current_entry, ROS_VACB, 
CacheMapVacbListEntry);
             CcRosAcquireVacbLock(current, NULL);
             RemoveEntryList(&current->VacbLruListEntry);
+            InitializeListHead(&current->VacbLruListEntry);
             if (current->Dirty)
             {
                 KeAcquireSpinLock(&SharedCacheMap->CacheMapLock, &oldIrql);
@@ -1133,6 +1141,7 @@ CcRosDeleteFileCache (
         {
             current_entry = RemoveTailList(&FreeList);
             current = CONTAINING_RECORD(current_entry, ROS_VACB, 
CacheMapVacbListEntry);
+            InitializeListHead(&current->CacheMapVacbListEntry);
             CcRosVacbDecRefCount(current);
             CcRosInternalFreeVacb(current);
         }

Reply via email to