[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.

svn path=/trunk/; revision=47598
This commit is contained in:
Sir Richard 2010-06-05 18:26:15 +00:00
parent ffce25e515
commit 5d77839f4f

View file

@ -39,30 +39,33 @@ PKGUARDED_MUTEX ExpPagedPoolMutex;
* Pool list access debug macros, similar to Arthur's pfnlist.c work. * Pool list access debug macros, similar to Arthur's pfnlist.c work.
* Microsoft actually implements similar checks in the Windows Server 2003 SP1 * Microsoft actually implements similar checks in the Windows Server 2003 SP1
* pool code, but only for checked builds. * pool code, but only for checked builds.
*
* As of Vista, however, an MSDN Blog entry by a Security Team Manager indicates * 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 * 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 * number of kernel-mode attacks which depend on dangling list pointers and other
* kinds of list-based attacks. * kinds of list-based attacks.
*
* For now, I will leave these checks on all the time, but later they are likely * 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 * to be DBG-only, at least until there are enough kernel-mode security attacks
* against ReactOS to warrant the performance hit. * against ReactOS to warrant the performance hit.
* *
* For now, these are not made inline, so we can get good stack traces.
*/ */
FORCEINLINE NTAPI
PLIST_ENTRY PLIST_ENTRY
ExpDecodePoolLink(IN PLIST_ENTRY Link) ExpDecodePoolLink(IN PLIST_ENTRY Link)
{ {
return (PLIST_ENTRY)((ULONG_PTR)Link & ~1); return (PLIST_ENTRY)((ULONG_PTR)Link & ~1);
} }
FORCEINLINE NTAPI
PLIST_ENTRY PLIST_ENTRY
ExpEncodePoolLink(IN PLIST_ENTRY Link) ExpEncodePoolLink(IN PLIST_ENTRY Link)
{ {
return (PLIST_ENTRY)((ULONG_PTR)Link | 1); return (PLIST_ENTRY)((ULONG_PTR)Link | 1);
} }
FORCEINLINE NTAPI
VOID VOID
ExpCheckPoolLinks(IN PLIST_ENTRY ListHead) ExpCheckPoolLinks(IN PLIST_ENTRY ListHead)
{ {
@ -77,52 +80,56 @@ ExpCheckPoolLinks(IN PLIST_ENTRY ListHead)
} }
} }
FORCEINLINE NTAPI
VOID VOID
ExpInitializePoolListHead(IN PLIST_ENTRY ListHead) ExpInitializePoolListHead(IN PLIST_ENTRY ListHead)
{ {
ListHead->Flink = ListHead->Blink = ExpEncodePoolLink(ListHead); ListHead->Flink = ListHead->Blink = ExpEncodePoolLink(ListHead);
} }
FORCEINLINE NTAPI
BOOLEAN BOOLEAN
ExpIsPoolListEmpty(IN PLIST_ENTRY ListHead) ExpIsPoolListEmpty(IN PLIST_ENTRY ListHead)
{ {
return (ExpDecodePoolLink(ListHead->Flink) == ListHead); return (ExpDecodePoolLink(ListHead->Flink) == ListHead);
} }
FORCEINLINE NTAPI
VOID VOID
ExpRemovePoolEntryList(IN PLIST_ENTRY Entry) ExpRemovePoolEntryList(IN PLIST_ENTRY Entry)
{ {
PLIST_ENTRY Blink, Flink; PLIST_ENTRY Blink, Flink;
Flink = ExpDecodePoolLink(Entry->Flink); Flink = ExpDecodePoolLink(Entry->Flink);
Blink = ExpDecodePoolLink(Entry->Blink); Blink = ExpDecodePoolLink(Entry->Blink);
Blink->Flink = ExpEncodePoolLink(Flink);
Flink->Blink = ExpEncodePoolLink(Blink); Flink->Blink = ExpEncodePoolLink(Blink);
Blink->Flink = ExpEncodePoolLink(Flink);
} }
FORCEINLINE NTAPI
PLIST_ENTRY PLIST_ENTRY
ExpRemovePoolHeadList(IN PLIST_ENTRY ListHead) ExpRemovePoolHeadList(IN PLIST_ENTRY ListHead)
{ {
PLIST_ENTRY Head; PLIST_ENTRY Entry, Flink;
Head = ExpDecodePoolLink(ListHead->Flink); Entry = ExpDecodePoolLink(ListHead->Flink);
ExpRemovePoolEntryList(Head); Flink = ExpDecodePoolLink(Entry->Flink);
return Head; ListHead->Flink = ExpEncodePoolLink(Flink);
Flink->Blink = ExpEncodePoolLink(ListHead);
return Entry;
} }
FORCEINLINE NTAPI
PLIST_ENTRY PLIST_ENTRY
ExpRemovePoolTailList(IN PLIST_ENTRY ListHead) ExpRemovePoolTailList(IN PLIST_ENTRY ListHead)
{ {
PLIST_ENTRY Tail; PLIST_ENTRY Entry, Blink;
Tail = ExpDecodePoolLink(ListHead->Blink); Entry = ExpDecodePoolLink(ListHead->Blink);
ExpRemovePoolEntryList(Tail); Blink = ExpDecodePoolLink(Entry->Blink);
return Tail; ListHead->Blink = ExpEncodePoolLink(Blink);
Blink->Flink = ExpEncodePoolLink(ListHead);
return Entry;
} }
FORCEINLINE NTAPI
VOID VOID
ExpInsertPoolTailList(IN PLIST_ENTRY ListHead, ExpInsertPoolTailList(IN PLIST_ENTRY ListHead,
IN PLIST_ENTRY Entry) IN PLIST_ENTRY Entry)
@ -137,14 +144,14 @@ ExpInsertPoolTailList(IN PLIST_ENTRY ListHead,
ExpCheckPoolLinks(ListHead); ExpCheckPoolLinks(ListHead);
} }
FORCEINLINE NTAPI
VOID VOID
ExpInsertPoolHeadList(IN PLIST_ENTRY ListHead, ExpInsertPoolHeadList(IN PLIST_ENTRY ListHead,
IN PLIST_ENTRY Entry) IN PLIST_ENTRY Entry)
{ {
PLIST_ENTRY Flink; PLIST_ENTRY Flink;
ExpCheckPoolLinks(ListHead); ExpCheckPoolLinks(ListHead);
Flink = ExpDecodePoolLink(ListHead->Blink); Flink = ExpDecodePoolLink(ListHead->Flink);
Entry->Flink = ExpEncodePoolLink(Flink); Entry->Flink = ExpEncodePoolLink(Flink);
Entry->Blink = ExpEncodePoolLink(ListHead); Entry->Blink = ExpEncodePoolLink(ListHead);
Flink->Blink = ExpEncodePoolLink(Entry); Flink->Blink = ExpEncodePoolLink(Entry);
@ -194,7 +201,7 @@ ExInitializePoolDescriptor(IN PPOOL_DESCRIPTOR PoolDescriptor,
LastEntry = NextEntry + POOL_LISTS_PER_PAGE; LastEntry = NextEntry + POOL_LISTS_PER_PAGE;
while (NextEntry < LastEntry) while (NextEntry < LastEntry)
{ {
InitializeListHead(NextEntry); ExpInitializePoolListHead(NextEntry);
NextEntry++; NextEntry++;
} }
} }
@ -379,7 +386,7 @@ ExAllocatePoolWithTag(IN POOL_TYPE PoolType,
// //
// Are there any free entries available on this list? // Are there any free entries available on this list?
// //
if (!IsListEmpty(ListHead)) if (!ExpIsPoolListEmpty(ListHead))
{ {
// //
// Acquire the pool lock now // Acquire the pool lock now
@ -389,7 +396,7 @@ ExAllocatePoolWithTag(IN POOL_TYPE PoolType,
// //
// And make sure the list still has entries // 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 // Someone raced us (and won) before we had a chance to acquire
@ -408,7 +415,9 @@ ExAllocatePoolWithTag(IN POOL_TYPE PoolType,
// there is a guarantee that any block on this list will either be // there is a guarantee that any block on this list will either be
// of the correct size, or perhaps larger. // 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->BlockSize >= i);
ASSERT(Entry->PoolType == 0); ASSERT(Entry->PoolType == 0);
@ -508,13 +517,15 @@ ExAllocatePoolWithTag(IN POOL_TYPE PoolType,
// "full" entry, which contains enough bytes for a linked list // "full" entry, which contains enough bytes for a linked list
// and thus can be used for allocations (up to 8 bytes...) // and thus can be used for allocations (up to 8 bytes...)
// //
ExpCheckPoolLinks(&PoolDesc->ListHeads[BlockSize - 1]);
if (BlockSize != 1) if (BlockSize != 1)
{ {
// //
// Insert the free entry into the free list for this size // Insert the free entry into the free list for this size
// //
InsertTailList(&PoolDesc->ListHeads[BlockSize - 1], ExpInsertPoolTailList(&PoolDesc->ListHeads[BlockSize - 1],
POOL_FREE_BLOCK(FragmentEntry)); POOL_FREE_BLOCK(FragmentEntry));
ExpCheckPoolLinks(POOL_FREE_BLOCK(FragmentEntry));
} }
} }
@ -571,8 +582,10 @@ ExAllocatePoolWithTag(IN POOL_TYPE PoolType,
// //
// And insert the free entry into the free list for this block size // And insert the free entry into the free list for this block size
// //
InsertTailList(&PoolDesc->ListHeads[BlockSize - 1], ExpCheckPoolLinks(&PoolDesc->ListHeads[BlockSize - 1]);
POOL_FREE_BLOCK(FragmentEntry)); ExpInsertPoolTailList(&PoolDesc->ListHeads[BlockSize - 1],
POOL_FREE_BLOCK(FragmentEntry));
ExpCheckPoolLinks(POOL_FREE_BLOCK(FragmentEntry));
// //
// Release the pool lock // Release the pool lock
@ -690,7 +703,10 @@ ExFreePoolWithTag(IN PVOID P,
// The block is at least big enough to have a linked list, so go // The block is at least big enough to have a linked list, so go
// ahead and remove it // 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 @@ ExFreePoolWithTag(IN PVOID P,
// The block is at least big enough to have a linked list, so go // The block is at least big enough to have a linked list, so go
// ahead and remove it // 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 @@ ExFreePoolWithTag(IN PVOID P,
// //
// Insert this new free block, and release the pool lock // 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); ExUnlockPool(PoolDesc, OldIrql);
} }