[NTOSKRNL] Add extra sanity checks for VACB lists.
authorPierre Schweitzer <pierre@reactos.org>
Sun, 8 Apr 2018 16:34:00 +0000 (18:34 +0200)
committerPierre Schweitzer <pierre@reactos.org>
Sun, 15 Apr 2018 20:52:53 +0000 (22:52 +0200)
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
ntoskrnl/cc/view.c

index 2ab7b5f..31b7ec6 100644 (file)
@@ -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);
         /* 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);
         if (Vacb->Dirty)
         {
             CcRosUnmarkDirtyVacb(Vacb, FALSE);
@@ -253,6 +254,7 @@ CcPurgeCacheSection (
         Vacb = CONTAINING_RECORD(RemoveHeadList(&FreeList),
                                  ROS_VACB,
                                  CacheMapVacbListEntry);
         Vacb = CONTAINING_RECORD(RemoveHeadList(&FreeList),
                                  ROS_VACB,
                                  CacheMapVacbListEntry);
+        InitializeListHead(&Vacb->CacheMapVacbListEntry);
         CcRosVacbDecRefCount(Vacb);
         CcRosInternalFreeVacb(Vacb);
     }
         CcRosVacbDecRefCount(Vacb);
         CcRosInternalFreeVacb(Vacb);
     }
index ba87c5e..c835a03 100644 (file)
@@ -375,6 +375,7 @@ retry:
 
             RemoveEntryList(&current->CacheMapVacbListEntry);
             RemoveEntryList(&current->VacbLruListEntry);
 
             RemoveEntryList(&current->CacheMapVacbListEntry);
             RemoveEntryList(&current->VacbLruListEntry);
+            InitializeListHead(&current->VacbLruListEntry);
             InsertHeadList(&FreeList, &current->CacheMapVacbListEntry);
 
             /* Calculate how many pages we freed for Mm */
             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);
         current = CONTAINING_RECORD(current_entry,
                                     ROS_VACB,
                                     CacheMapVacbListEntry);
+        InitializeListHead(&current->CacheMapVacbListEntry);
         CcRosVacbDecRefCount(current);
         CcRosInternalFreeVacb(current);
     }
         CcRosVacbDecRefCount(current);
         CcRosInternalFreeVacb(current);
     }
@@ -567,6 +569,7 @@ CcRosUnmarkDirtyVacb (
     Vacb->Dirty = FALSE;
 
     RemoveEntryList(&Vacb->DirtyVacbListEntry);
     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);
     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;
     }
 #endif
     current->MappedCount = 0;
-    current->DirtyVacbListEntry.Flink = NULL;
-    current->DirtyVacbListEntry.Blink = NULL;
     current->ReferenceCount = 0;
     current->PinCount = 0;
     KeInitializeMutex(&current->Mutex, 0);
     current->ReferenceCount = 0;
     current->PinCount = 0;
     KeInitializeMutex(&current->Mutex, 0);
+    InitializeListHead(&current->CacheMapVacbListEntry);
+    InitializeListHead(&current->DirtyVacbListEntry);
+    InitializeListHead(&current->VacbLruListEntry);
     CcRosAcquireVacbLock(current, NULL);
     KeAcquireGuardedMutex(&ViewLock);
 
     CcRosAcquireVacbLock(current, NULL);
     KeAcquireGuardedMutex(&ViewLock);
 
@@ -988,6 +992,9 @@ CcRosInternalFreeVacb (
 
     ASSERT(Vacb->PinCount == 0);
     ASSERT(Vacb->ReferenceCount == 0);
 
     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;
     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);
             current = CONTAINING_RECORD(current_entry, ROS_VACB, CacheMapVacbListEntry);
             CcRosAcquireVacbLock(current, NULL);
             RemoveEntryList(&current->VacbLruListEntry);
+            InitializeListHead(&current->VacbLruListEntry);
             if (current->Dirty)
             {
                 KeAcquireSpinLock(&SharedCacheMap->CacheMapLock, &oldIrql);
             if (current->Dirty)
             {
                 KeAcquireSpinLock(&SharedCacheMap->CacheMapLock, &oldIrql);
@@ -1133,6 +1141,7 @@ CcRosDeleteFileCache (
         {
             current_entry = RemoveTailList(&FreeList);
             current = CONTAINING_RECORD(current_entry, ROS_VACB, CacheMapVacbListEntry);
         {
             current_entry = RemoveTailList(&FreeList);
             current = CONTAINING_RECORD(current_entry, ROS_VACB, CacheMapVacbListEntry);
+            InitializeListHead(&current->CacheMapVacbListEntry);
             CcRosVacbDecRefCount(current);
             CcRosInternalFreeVacb(current);
         }
             CcRosVacbDecRefCount(current);
             CcRosInternalFreeVacb(current);
         }