diff --git a/reactos/ntoskrnl/mm/npool.c b/reactos/ntoskrnl/mm/npool.c index 4cff298c7fe..08629b3e0aa 100644 --- a/reactos/ntoskrnl/mm/npool.c +++ b/reactos/ntoskrnl/mm/npool.c @@ -1556,14 +1556,12 @@ VOID STDCALL ExFreeNonPagedPool (PVOID block) { 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 { - DbgPrint("ExFreePool of non-allocated address %x (magic %x)\n", - block, blk->hdr.Magic); + KeBugCheckEx(BAD_POOL_CALLER, 0x46, (ULONG_PTR)block, 0, 0); } - ASSERT(FALSE); return; } @@ -1684,6 +1682,12 @@ ExAllocateNonPagedPoolWithTag(POOL_TYPE Type, ULONG Size, ULONG Tag, PVOID Calle return(block); } +ULONG NTAPI +EiGetNonPagedPoolTag(PVOID Block) +{ + return ((HDR_USED*)((ULONG_PTR)Block - HDR_USED_SIZE))->Tag; +} + VOID INIT_FUNCTION NTAPI diff --git a/reactos/ntoskrnl/mm/pool.c b/reactos/ntoskrnl/mm/pool.c index c326a492a2a..67d617279f4 100644 --- a/reactos/ntoskrnl/mm/pool.c +++ b/reactos/ntoskrnl/mm/pool.c @@ -21,6 +21,12 @@ extern MM_STATS MmStats; /* FUNCTIONS ***************************************************************/ +ULONG NTAPI +EiGetPagedPoolTag(IN PVOID Block); + +ULONG NTAPI +EiGetNonPagedPoolTag(IN PVOID Block); + static PVOID STDCALL EiAllocatePool(POOL_TYPE PoolType, ULONG NumberOfBytes, @@ -28,22 +34,39 @@ EiAllocatePool(POOL_TYPE PoolType, PVOID Caller) { PVOID Block; + PCHAR TagChars = (PCHAR)&Tag; - /* FIXME: Handle SESSION_POOL_MASK, VERIFIER_POOL_MASK, QUOTA_POOL_MASK */ - if (PoolType & PAGED_POOL_MASK) - { - Block = ExAllocatePagedPoolWithTag(PoolType,NumberOfBytes,Tag); - } - else - { - Block = ExAllocateNonPagedPoolWithTag(PoolType,NumberOfBytes,Tag,Caller); - } + 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); - if ((PoolType & MUST_SUCCEED_POOL_MASK) && Block==NULL) - { - KeBugCheck(MUST_SUCCEED_POOL_EMPTY); - } - return(Block); +#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 */ + 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 */ #undef ExFreePool -VOID STDCALL +VOID NTAPI ExFreePool(IN PVOID Block) { - ASSERT_IRQL_LESS_OR_EQUAL(DISPATCH_LEVEL); - - if (Block >= MmPagedPoolBase && (char*)Block < ((char*)MmPagedPoolBase + MmPagedPoolSize)) - { - ExFreePagedPool(Block); - } - else - { - ExFreeNonPagedPool(Block); - } + if (Block >= MmPagedPoolBase && (char*)Block < ((char*)MmPagedPoolBase + MmPagedPoolSize)) + { + if (KeGetCurrentIrql() > APC_LEVEL) + KeBugCheckEx(BAD_POOL_CALLER, 0x09, KeGetCurrentIrql(), PagedPool, (ULONG_PTR)Block); + ExFreePagedPool(Block); + } + else + { + if (KeGetCurrentIrql() > DISPATCH_LEVEL) + KeBugCheckEx(BAD_POOL_CALLER, 0x09, KeGetCurrentIrql(), NonPagedPool, (ULONG_PTR)Block); + ExFreeNonPagedPool(Block); + } } /* * @implemented */ -VOID STDCALL +VOID NTAPI ExFreePoolWithTag(IN PVOID Block, IN ULONG Tag) { - /* FIXME: Validate the tag */ - ExFreePool(Block); + 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); } /* diff --git a/reactos/ntoskrnl/mm/ppool.c b/reactos/ntoskrnl/mm/ppool.c index fbbf20a739f..2575c8c37a3 100644 --- a/reactos/ntoskrnl/mm/ppool.c +++ b/reactos/ntoskrnl/mm/ppool.c @@ -103,6 +103,12 @@ ExFreePagedPool(IN PVOID Block) RPoolFree ( MmPagedPool, Block ); } +ULONG NTAPI +EiGetPagedPoolTag(IN PVOID Block) +{ + return RBodyToHdr(Block)->Tag; +} + #ifdef PPOOL_UMODE_TEST