Check if tags match in ExFreePoolWithTag

Check if provided tag is valid in ExAllocatePoolWithTag
Add lots of BugCheck(BAD_POOL_CALLER)

svn path=/trunk/; revision=35835
This commit is contained in:
Hervé Poussineau 2008-08-31 15:52:56 +00:00
parent d2ba8bac96
commit a04c3e8d7f
3 changed files with 76 additions and 32 deletions

View file

@ -1556,14 +1556,12 @@ VOID STDCALL ExFreeNonPagedPool (PVOID block)
{ {
if (blk->hdr.Magic == BLOCK_HDR_FREE_MAGIC) if (blk->hdr.Magic == BLOCK_HDR_FREE_MAGIC)
{ {
DbgPrint("ExFreePool of already freed address %x\n", block); KeBugCheckEx(BAD_POOL_CALLER, 0x07, 0, (ULONG_PTR)blk, (ULONG_PTR)block);
} }
else else
{ {
DbgPrint("ExFreePool of non-allocated address %x (magic %x)\n", KeBugCheckEx(BAD_POOL_CALLER, 0x46, (ULONG_PTR)block, 0, 0);
block, blk->hdr.Magic);
} }
ASSERT(FALSE);
return; return;
} }
@ -1684,6 +1682,12 @@ ExAllocateNonPagedPoolWithTag(POOL_TYPE Type, ULONG Size, ULONG Tag, PVOID Calle
return(block); return(block);
} }
ULONG NTAPI
EiGetNonPagedPoolTag(PVOID Block)
{
return ((HDR_USED*)((ULONG_PTR)Block - HDR_USED_SIZE))->Tag;
}
VOID VOID
INIT_FUNCTION INIT_FUNCTION
NTAPI NTAPI

View file

@ -21,6 +21,12 @@ extern MM_STATS MmStats;
/* FUNCTIONS ***************************************************************/ /* FUNCTIONS ***************************************************************/
ULONG NTAPI
EiGetPagedPoolTag(IN PVOID Block);
ULONG NTAPI
EiGetNonPagedPoolTag(IN PVOID Block);
static PVOID STDCALL static PVOID STDCALL
EiAllocatePool(POOL_TYPE PoolType, EiAllocatePool(POOL_TYPE PoolType,
ULONG NumberOfBytes, ULONG NumberOfBytes,
@ -28,22 +34,39 @@ EiAllocatePool(POOL_TYPE PoolType,
PVOID Caller) PVOID Caller)
{ {
PVOID Block; PVOID Block;
PCHAR TagChars = (PCHAR)&Tag;
if (NumberOfBytes == 0)
KeBugCheckEx(BAD_POOL_CALLER, 0x00, 0, PoolType, Tag);
if (Tag == 0)
KeBugCheckEx(BAD_POOL_CALLER, 0x9b, PoolType, NumberOfBytes, (ULONG_PTR)Caller);
if (Tag == TAG('B','I','G',0))
KeBugCheckEx(BAD_POOL_CALLER, 0x9c, PoolType, NumberOfBytes, (ULONG_PTR)Caller);
#define IS_LETTER_OR_DIGIT(c) (((c) >= 'a' && (c) <= 'z') || ((c) >= 'A' && (c) <= 'Z') || ((c) >= '0' && (c) <= '9'))
if (!IS_LETTER_OR_DIGIT(TagChars[0]) &&
!IS_LETTER_OR_DIGIT(TagChars[1]) &&
!IS_LETTER_OR_DIGIT(TagChars[2]) &&
!IS_LETTER_OR_DIGIT(TagChars[3]))
KeBugCheckEx(BAD_POOL_CALLER, 0x9d, Tag, PoolType, (ULONG_PTR)Caller);
/* FIXME: Handle SESSION_POOL_MASK, VERIFIER_POOL_MASK, QUOTA_POOL_MASK */ /* FIXME: Handle SESSION_POOL_MASK, VERIFIER_POOL_MASK, QUOTA_POOL_MASK */
if (PoolType & PAGED_POOL_MASK) if (PoolType & PAGED_POOL_MASK)
{ {
Block = ExAllocatePagedPoolWithTag(PoolType,NumberOfBytes,Tag); if (KeGetCurrentIrql() > APC_LEVEL)
KeBugCheckEx(BAD_POOL_CALLER, 0x08, KeGetCurrentIrql(), PoolType, Tag);
Block = ExAllocatePagedPoolWithTag(PoolType, NumberOfBytes, Tag);
} }
else else
{ {
Block = ExAllocateNonPagedPoolWithTag(PoolType,NumberOfBytes,Tag,Caller); if (KeGetCurrentIrql() > DISPATCH_LEVEL)
KeBugCheckEx(BAD_POOL_CALLER, 0x08, KeGetCurrentIrql(), PoolType, Tag);
Block = ExAllocateNonPagedPoolWithTag(PoolType, NumberOfBytes, Tag, Caller);
} }
if ((PoolType & MUST_SUCCEED_POOL_MASK) && Block==NULL) if ((PoolType & MUST_SUCCEED_POOL_MASK) && !Block)
{ KeBugCheckEx(BAD_POOL_CALLER, 0x9a, PoolType, NumberOfBytes, Tag);
KeBugCheck(MUST_SUCCEED_POOL_EMPTY); return Block;
}
return(Block);
} }
/* /*
@ -222,17 +245,19 @@ ExAllocatePoolWithQuotaTag (IN POOL_TYPE PoolType,
* @implemented * @implemented
*/ */
#undef ExFreePool #undef ExFreePool
VOID STDCALL VOID NTAPI
ExFreePool(IN PVOID Block) ExFreePool(IN PVOID Block)
{ {
ASSERT_IRQL_LESS_OR_EQUAL(DISPATCH_LEVEL);
if (Block >= MmPagedPoolBase && (char*)Block < ((char*)MmPagedPoolBase + MmPagedPoolSize)) if (Block >= MmPagedPoolBase && (char*)Block < ((char*)MmPagedPoolBase + MmPagedPoolSize))
{ {
if (KeGetCurrentIrql() > APC_LEVEL)
KeBugCheckEx(BAD_POOL_CALLER, 0x09, KeGetCurrentIrql(), PagedPool, (ULONG_PTR)Block);
ExFreePagedPool(Block); ExFreePagedPool(Block);
} }
else else
{ {
if (KeGetCurrentIrql() > DISPATCH_LEVEL)
KeBugCheckEx(BAD_POOL_CALLER, 0x09, KeGetCurrentIrql(), NonPagedPool, (ULONG_PTR)Block);
ExFreeNonPagedPool(Block); ExFreeNonPagedPool(Block);
} }
} }
@ -240,10 +265,19 @@ ExFreePool(IN PVOID Block)
/* /*
* @implemented * @implemented
*/ */
VOID STDCALL VOID NTAPI
ExFreePoolWithTag(IN PVOID Block, IN ULONG Tag) ExFreePoolWithTag(IN PVOID Block, IN ULONG Tag)
{ {
/* FIXME: Validate the tag */ ULONG BlockTag;
if (Block >= MmPagedPoolBase && (char*)Block < ((char*)MmPagedPoolBase + MmPagedPoolSize))
BlockTag = EiGetPagedPoolTag(Block);
else
BlockTag = EiGetNonPagedPoolTag(Block);
if (BlockTag != Tag)
KeBugCheckEx(BAD_POOL_CALLER, 0x0a, (ULONG_PTR)Block, BlockTag, Tag);
ExFreePool(Block); ExFreePool(Block);
} }

View file

@ -103,6 +103,12 @@ ExFreePagedPool(IN PVOID Block)
RPoolFree ( MmPagedPool, Block ); RPoolFree ( MmPagedPool, Block );
} }
ULONG NTAPI
EiGetPagedPoolTag(IN PVOID Block)
{
return RBodyToHdr(Block)->Tag;
}
#ifdef PPOOL_UMODE_TEST #ifdef PPOOL_UMODE_TEST