Author: sir_richard
Date: Sat Jun 5 20:26:15 2010
New Revision: 47598
URL:
http://svn.reactos.org/svn/reactos?rev=47598&view=rev
Log:
[NTOS]: Fix Exp*PoolList macros. Also make then non-inlined, so we can see who called them
in a stack trace.
[NTOS]: Enable them.
This boots on my system -- if it doesn't boot on yours, someone is corrupting your
nonpaged pool. Reverting this patch is NOT the solution to your woes.
Modified:
trunk/reactos/ntoskrnl/mm/ARM3/expool.c
Modified: trunk/reactos/ntoskrnl/mm/ARM3/expool.c
URL:
http://svn.reactos.org/svn/reactos/trunk/reactos/ntoskrnl/mm/ARM3/expool.c?…
==============================================================================
--- trunk/reactos/ntoskrnl/mm/ARM3/expool.c [iso-8859-1] (original)
+++ trunk/reactos/ntoskrnl/mm/ARM3/expool.c [iso-8859-1] Sat Jun 5 20:26:15 2010
@@ -39,30 +39,33 @@
* Pool list access debug macros, similar to Arthur's pfnlist.c work.
* Microsoft actually implements similar checks in the Windows Server 2003 SP1
* pool code, but only for checked builds.
+ *
* As of Vista, however, an MSDN Blog entry by a Security Team Manager indicates
* that these checks are done even on retail builds, due to the increasing
* number of kernel-mode attacks which depend on dangling list pointers and other
* kinds of list-based attacks.
+ *
* For now, I will leave these checks on all the time, but later they are likely
* to be DBG-only, at least until there are enough kernel-mode security attacks
* against ReactOS to warrant the performance hit.
*
- */
-FORCEINLINE
+ * For now, these are not made inline, so we can get good stack traces.
+ */
+NTAPI
PLIST_ENTRY
ExpDecodePoolLink(IN PLIST_ENTRY Link)
{
return (PLIST_ENTRY)((ULONG_PTR)Link & ~1);
}
-FORCEINLINE
+NTAPI
PLIST_ENTRY
ExpEncodePoolLink(IN PLIST_ENTRY Link)
{
return (PLIST_ENTRY)((ULONG_PTR)Link | 1);
}
-FORCEINLINE
+NTAPI
VOID
ExpCheckPoolLinks(IN PLIST_ENTRY ListHead)
{
@@ -77,52 +80,56 @@
}
}
-FORCEINLINE
+NTAPI
VOID
ExpInitializePoolListHead(IN PLIST_ENTRY ListHead)
{
ListHead->Flink = ListHead->Blink = ExpEncodePoolLink(ListHead);
}
-FORCEINLINE
+NTAPI
BOOLEAN
ExpIsPoolListEmpty(IN PLIST_ENTRY ListHead)
{
return (ExpDecodePoolLink(ListHead->Flink) == ListHead);
}
-FORCEINLINE
+NTAPI
VOID
ExpRemovePoolEntryList(IN PLIST_ENTRY Entry)
{
PLIST_ENTRY Blink, Flink;
Flink = ExpDecodePoolLink(Entry->Flink);
Blink = ExpDecodePoolLink(Entry->Blink);
+ Flink->Blink = ExpEncodePoolLink(Blink);
Blink->Flink = ExpEncodePoolLink(Flink);
- Flink->Blink = ExpEncodePoolLink(Blink);
-}
-
-FORCEINLINE
+}
+
+NTAPI
PLIST_ENTRY
ExpRemovePoolHeadList(IN PLIST_ENTRY ListHead)
{
- PLIST_ENTRY Head;
- Head = ExpDecodePoolLink(ListHead->Flink);
- ExpRemovePoolEntryList(Head);
- return Head;
-}
-
-FORCEINLINE
+ PLIST_ENTRY Entry, Flink;
+ Entry = ExpDecodePoolLink(ListHead->Flink);
+ Flink = ExpDecodePoolLink(Entry->Flink);
+ ListHead->Flink = ExpEncodePoolLink(Flink);
+ Flink->Blink = ExpEncodePoolLink(ListHead);
+ return Entry;
+}
+
+NTAPI
PLIST_ENTRY
ExpRemovePoolTailList(IN PLIST_ENTRY ListHead)
{
- PLIST_ENTRY Tail;
- Tail = ExpDecodePoolLink(ListHead->Blink);
- ExpRemovePoolEntryList(Tail);
- return Tail;
-}
-
-FORCEINLINE
+ PLIST_ENTRY Entry, Blink;
+ Entry = ExpDecodePoolLink(ListHead->Blink);
+ Blink = ExpDecodePoolLink(Entry->Blink);
+ ListHead->Blink = ExpEncodePoolLink(Blink);
+ Blink->Flink = ExpEncodePoolLink(ListHead);
+ return Entry;
+}
+
+NTAPI
VOID
ExpInsertPoolTailList(IN PLIST_ENTRY ListHead,
IN PLIST_ENTRY Entry)
@@ -137,14 +144,14 @@
ExpCheckPoolLinks(ListHead);
}
-FORCEINLINE
+NTAPI
VOID
ExpInsertPoolHeadList(IN PLIST_ENTRY ListHead,
IN PLIST_ENTRY Entry)
{
PLIST_ENTRY Flink;
ExpCheckPoolLinks(ListHead);
- Flink = ExpDecodePoolLink(ListHead->Blink);
+ Flink = ExpDecodePoolLink(ListHead->Flink);
Entry->Flink = ExpEncodePoolLink(Flink);
Entry->Blink = ExpEncodePoolLink(ListHead);
Flink->Blink = ExpEncodePoolLink(Entry);
@@ -194,7 +201,7 @@
LastEntry = NextEntry + POOL_LISTS_PER_PAGE;
while (NextEntry < LastEntry)
{
- InitializeListHead(NextEntry);
+ ExpInitializePoolListHead(NextEntry);
NextEntry++;
}
}
@@ -379,7 +386,7 @@
//
// Are there any free entries available on this list?
//
- if (!IsListEmpty(ListHead))
+ if (!ExpIsPoolListEmpty(ListHead))
{
//
// Acquire the pool lock now
@@ -389,7 +396,7 @@
//
// And make sure the list still has entries
//
- if (IsListEmpty(ListHead))
+ if (ExpIsPoolListEmpty(ListHead))
{
//
// Someone raced us (and won) before we had a chance to acquire
@@ -408,7 +415,9 @@
// there is a guarantee that any block on this list will either be
// of the correct size, or perhaps larger.
//
- Entry = POOL_ENTRY(RemoveHeadList(ListHead));
+ ExpCheckPoolLinks(ListHead);
+ Entry = POOL_ENTRY(ExpRemovePoolHeadList(ListHead));
+ ExpCheckPoolLinks(ListHead);
ASSERT(Entry->BlockSize >= i);
ASSERT(Entry->PoolType == 0);
@@ -508,13 +517,15 @@
// "full" entry, which contains enough bytes for a linked list
// and thus can be used for allocations (up to 8 bytes...)
//
+ ExpCheckPoolLinks(&PoolDesc->ListHeads[BlockSize - 1]);
if (BlockSize != 1)
{
//
// Insert the free entry into the free list for this size
//
- InsertTailList(&PoolDesc->ListHeads[BlockSize - 1],
- POOL_FREE_BLOCK(FragmentEntry));
+ ExpInsertPoolTailList(&PoolDesc->ListHeads[BlockSize - 1],
+ POOL_FREE_BLOCK(FragmentEntry));
+ ExpCheckPoolLinks(POOL_FREE_BLOCK(FragmentEntry));
}
}
@@ -571,8 +582,10 @@
//
// And insert the free entry into the free list for this block size
//
- InsertTailList(&PoolDesc->ListHeads[BlockSize - 1],
- POOL_FREE_BLOCK(FragmentEntry));
+ ExpCheckPoolLinks(&PoolDesc->ListHeads[BlockSize - 1]);
+ ExpInsertPoolTailList(&PoolDesc->ListHeads[BlockSize - 1],
+ POOL_FREE_BLOCK(FragmentEntry));
+ ExpCheckPoolLinks(POOL_FREE_BLOCK(FragmentEntry));
//
// Release the pool lock
@@ -690,7 +703,10 @@
// The block is at least big enough to have a linked list, so go
// ahead and remove it
//
- RemoveEntryList(POOL_FREE_BLOCK(NextEntry));
+ ExpCheckPoolLinks(POOL_FREE_BLOCK(NextEntry));
+ ExpRemovePoolEntryList(POOL_FREE_BLOCK(NextEntry));
+
ExpCheckPoolLinks(ExpDecodePoolLink((POOL_FREE_BLOCK(NextEntry))->Flink));
+
ExpCheckPoolLinks(ExpDecodePoolLink((POOL_FREE_BLOCK(NextEntry))->Blink));
}
//
@@ -727,7 +743,10 @@
// The block is at least big enough to have a linked list, so go
// ahead and remove it
//
- RemoveEntryList(POOL_FREE_BLOCK(NextEntry));
+ ExpCheckPoolLinks(POOL_FREE_BLOCK(NextEntry));
+ ExpRemovePoolEntryList(POOL_FREE_BLOCK(NextEntry));
+
ExpCheckPoolLinks(ExpDecodePoolLink((POOL_FREE_BLOCK(NextEntry))->Flink));
+
ExpCheckPoolLinks(ExpDecodePoolLink((POOL_FREE_BLOCK(NextEntry))->Blink));
}
//
@@ -787,7 +806,8 @@
//
// Insert this new free block, and release the pool lock
//
- InsertHeadList(&PoolDesc->ListHeads[BlockSize - 1], POOL_FREE_BLOCK(Entry));
+ ExpInsertPoolHeadList(&PoolDesc->ListHeads[BlockSize - 1],
POOL_FREE_BLOCK(Entry));
+ ExpCheckPoolLinks(POOL_FREE_BLOCK(Entry));
ExUnlockPool(PoolDesc, OldIrql);
}