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;
/* FIXME: Handle SESSION_POOL_MASK, VERIFIER_POOL_MASK, QUOTA_POOL_MASK */ if (NumberOfBytes == 0)
if (PoolType & PAGED_POOL_MASK) KeBugCheckEx(BAD_POOL_CALLER, 0x00, 0, PoolType, Tag);
{ if (Tag == 0)
Block = ExAllocatePagedPoolWithTag(PoolType,NumberOfBytes,Tag); KeBugCheckEx(BAD_POOL_CALLER, 0x9b, PoolType, NumberOfBytes, (ULONG_PTR)Caller);
} if (Tag == TAG('B','I','G',0))
else KeBugCheckEx(BAD_POOL_CALLER, 0x9c, PoolType, NumberOfBytes, (ULONG_PTR)Caller);
{
Block = ExAllocateNonPagedPoolWithTag(PoolType,NumberOfBytes,Tag,Caller);
}
if ((PoolType & MUST_SUCCEED_POOL_MASK) && Block==NULL) #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]) &&
KeBugCheck(MUST_SUCCEED_POOL_EMPTY); !IS_LETTER_OR_DIGIT(TagChars[1]) &&
} !IS_LETTER_OR_DIGIT(TagChars[2]) &&
return(Block); !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 */
if (PoolType & PAGED_POOL_MASK)
{
if (KeGetCurrentIrql() > APC_LEVEL)
KeBugCheckEx(BAD_POOL_CALLER, 0x08, KeGetCurrentIrql(), PoolType, Tag);
Block = ExAllocatePagedPoolWithTag(PoolType, NumberOfBytes, Tag);
}
else
{
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)
KeBugCheckEx(BAD_POOL_CALLER, 0x9a, PoolType, NumberOfBytes, Tag);
return Block;
} }
/* /*
@ -222,29 +245,40 @@ 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
{ {
ExFreeNonPagedPool(Block); if (KeGetCurrentIrql() > DISPATCH_LEVEL)
} KeBugCheckEx(BAD_POOL_CALLER, 0x09, KeGetCurrentIrql(), NonPagedPool, (ULONG_PTR)Block);
ExFreeNonPagedPool(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;
ExFreePool(Block);
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);
} }
/* /*

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