mirror of
https://github.com/reactos/reactos.git
synced 2025-04-25 16:10:29 +00:00
- Implement a special "debug pool" allocator which catches pool overruns. It evolved from an initial patch by Art Yerkes, and is fully independent from underlying pool implementation. It supports only non-paged pool and detects only overruns now. To enable, uncomment DEBUG_NPOOL define in mm/pool.c.
svn path=/trunk/; revision=40726
This commit is contained in:
parent
d8d8b19d4a
commit
eb036429b8
4 changed files with 152 additions and 2 deletions
|
@ -558,6 +558,24 @@ VOID
|
|||
NTAPI
|
||||
ExFreePagedPool(IN PVOID Block);
|
||||
|
||||
BOOLEAN
|
||||
NTAPI
|
||||
ExpIsPoolTagDebuggable(ULONG Tag);
|
||||
|
||||
PVOID
|
||||
NTAPI
|
||||
ExpAllocateDebugPool(
|
||||
POOL_TYPE Type,
|
||||
ULONG Size,
|
||||
ULONG Tag,
|
||||
PVOID Caller,
|
||||
BOOLEAN EndOfPage
|
||||
);
|
||||
|
||||
VOID
|
||||
NTAPI
|
||||
ExpFreeDebugPool(PVOID Block);
|
||||
|
||||
VOID
|
||||
NTAPI
|
||||
MmInitializePagedPool(VOID);
|
||||
|
|
117
reactos/ntoskrnl/mm/dbgpool.c
Normal file
117
reactos/ntoskrnl/mm/dbgpool.c
Normal file
|
@ -0,0 +1,117 @@
|
|||
/*
|
||||
* PROJECT: ReactOS Kernel
|
||||
* LICENSE: GPL - See COPYING in the top level directory
|
||||
* FILE: ntoskrnl/mm/dbgpool.c
|
||||
* PURPOSE: Debug version of a pool allocator
|
||||
* PROGRAMMERS: Aleksey Bragin (aleksey@reactos.org)
|
||||
*/
|
||||
|
||||
/* INCLUDES ***************************************************************/
|
||||
|
||||
#include <ntoskrnl.h>
|
||||
#define NDEBUG
|
||||
#include <debug.h>
|
||||
|
||||
/* FUNCTIONS **************************************************************/
|
||||
|
||||
typedef struct _EI_WHOLE_PAGE_HEADER {
|
||||
PVOID ActualAddress;
|
||||
ULONG Size;
|
||||
ULONG Tag;
|
||||
} EI_WHOLE_PAGE_HEADER, *PEI_WHOLE_PAGE_HEADER;
|
||||
|
||||
BOOLEAN
|
||||
NTAPI
|
||||
ExpIsPoolTagDebuggable(ULONG Tag)
|
||||
{
|
||||
if (Tag == TAG('C', 'a', 'l', 'l')) return FALSE;
|
||||
if (Tag == TAG('D', 'r', 'i', 'v')) return FALSE;
|
||||
if (Tag == TAG('D', 'e', 'v', 'i')) return FALSE;
|
||||
if (Tag == TAG('A', 'd', 'a', 'p')) return FALSE;
|
||||
|
||||
return FALSE;//TRUE;
|
||||
}
|
||||
|
||||
|
||||
PVOID
|
||||
NTAPI
|
||||
ExpAllocateDebugPool(POOL_TYPE Type, ULONG Size, ULONG Tag, PVOID Caller, BOOLEAN EndOfPage)
|
||||
{
|
||||
ULONG UserSize = Size + sizeof(EI_WHOLE_PAGE_HEADER);
|
||||
ULONG TotalSize = UserSize + 2*PAGE_SIZE;
|
||||
ULONG_PTR UserData, GuardArea;
|
||||
PEI_WHOLE_PAGE_HEADER Header;
|
||||
ULONG_PTR Buffer;
|
||||
|
||||
/* Right now we support only end-of-page allocations */
|
||||
ASSERT(EndOfPage);
|
||||
|
||||
/* Allocate space using default routine */
|
||||
if (Type & PAGED_POOL_MASK)
|
||||
{
|
||||
Buffer = (ULONG_PTR)
|
||||
ExAllocatePagedPoolWithTag(Type, TotalSize, Tag);
|
||||
}
|
||||
else
|
||||
{
|
||||
Buffer = (ULONG_PTR)
|
||||
ExAllocateNonPagedPoolWithTag(Type, TotalSize, Tag, Caller);
|
||||
}
|
||||
|
||||
/* If allocation failed - fail too */
|
||||
if (!Buffer)
|
||||
{
|
||||
DPRINT1("A big problem! Pool allocation failed!\n");
|
||||
return NULL;
|
||||
}
|
||||
|
||||
/* Calculate guard area as placed on a page boundary
|
||||
* at the end of allocated area */
|
||||
GuardArea = PAGE_ROUND_DOWN(Buffer + TotalSize - PAGE_SIZE + 1);
|
||||
|
||||
/* Calculate user data and header pointers */
|
||||
UserData = GuardArea - Size;
|
||||
Header = (PEI_WHOLE_PAGE_HEADER)(UserData - sizeof(EI_WHOLE_PAGE_HEADER));
|
||||
|
||||
/* Fill out the header */
|
||||
Header->ActualAddress = (PVOID)Buffer;
|
||||
Header->Tag = Tag;
|
||||
Header->Size = Size;
|
||||
|
||||
/* Protect the guard page */
|
||||
MmSetPageProtect(NULL, (PVOID)GuardArea, PAGE_NOACCESS);
|
||||
|
||||
DPRINT1("Allocating whole page block Tag %c%c%c%c, Buffer %p, Header %p, UserData %p, GuardArea %p, Size %d\n",
|
||||
Tag & 0xFF, (Tag >> 8) & 0xFF,
|
||||
(Tag >> 16) & 0xFF, (Tag >> 24) & 0xFF,
|
||||
Buffer, Header, UserData, GuardArea, Size);
|
||||
|
||||
return (PVOID)UserData;
|
||||
}
|
||||
|
||||
VOID
|
||||
NTAPI
|
||||
ExpFreeDebugPool(PVOID Block)
|
||||
{
|
||||
PEI_WHOLE_PAGE_HEADER Header;
|
||||
PVOID ProtectedPage;
|
||||
|
||||
/* Get pointer to our special header */
|
||||
Header = (PEI_WHOLE_PAGE_HEADER)
|
||||
(((PCHAR)Block) - sizeof(EI_WHOLE_PAGE_HEADER));
|
||||
|
||||
DPRINT1("Freeing whole page block at %08x (Tag %c%c%c%c, %x Header %x)\n", Block,
|
||||
Header->Tag & 0xFF, (Header->Tag >> 8) & 0xFF,
|
||||
(Header->Tag >> 16) & 0xFF, (Header->Tag >> 24) & 0xFF, Header->Tag, Header);
|
||||
|
||||
/* Calculate protected page adresss */
|
||||
ProtectedPage = ((PCHAR)Block) + Header->Size;
|
||||
|
||||
/* Unprotect it */
|
||||
MmSetPageProtect(NULL, ProtectedPage, PAGE_READWRITE);
|
||||
|
||||
/* Free storage */
|
||||
ExFreeNonPagedPool(Header->ActualAddress);
|
||||
}
|
||||
|
||||
/* EOF */
|
|
@ -14,6 +14,10 @@
|
|||
#define NDEBUG
|
||||
#include <debug.h>
|
||||
|
||||
/* Uncomment to enable pool overruns debugging */
|
||||
//#define DEBUG_NPOOL
|
||||
//#define DEBUG_PPOOL
|
||||
|
||||
extern PVOID MiNonPagedPoolStart;
|
||||
extern ULONG MiNonPagedPoolLength;
|
||||
extern ULONG MmTotalPagedPoolQuota;
|
||||
|
@ -60,7 +64,12 @@ EiAllocatePool(POOL_TYPE PoolType,
|
|||
{
|
||||
if (KeGetCurrentIrql() > DISPATCH_LEVEL)
|
||||
KeBugCheckEx(BAD_POOL_CALLER, 0x08, KeGetCurrentIrql(), PoolType, Tag);
|
||||
Block = ExAllocateNonPagedPoolWithTag(PoolType, NumberOfBytes, Tag, Caller);
|
||||
#ifdef DEBUG_NPOOL
|
||||
if (ExpIsPoolTagDebuggable(Tag))
|
||||
Block = ExpAllocateDebugPool(PoolType, NumberOfBytes, Tag, Caller, TRUE);
|
||||
else
|
||||
#endif
|
||||
Block = ExAllocateNonPagedPoolWithTag(PoolType, NumberOfBytes, Tag, Caller);
|
||||
}
|
||||
|
||||
if ((PoolType & MUST_SUCCEED_POOL_MASK) && !Block)
|
||||
|
@ -292,7 +301,12 @@ ExFreePoolWithTag(
|
|||
(ULONG_PTR)Block);
|
||||
|
||||
/* Free from non-paged pool */
|
||||
ExFreeNonPagedPool(Block);
|
||||
#ifdef DEBUG_NPOOL
|
||||
if (ExpIsPoolTagDebuggable(Tag))
|
||||
ExpFreeDebugPool(Block);
|
||||
else
|
||||
#endif
|
||||
ExFreeNonPagedPool(Block);
|
||||
}
|
||||
else
|
||||
{
|
||||
|
|
|
@ -362,6 +362,7 @@
|
|||
<file>anonmem.c</file>
|
||||
<file>balance.c</file>
|
||||
<file>cont.c</file>
|
||||
<file>dbgpool.c</file>
|
||||
<file>drvlck.c</file>
|
||||
<file>freelist.c</file>
|
||||
<file>hypermap.c</file>
|
||||
|
|
Loading…
Reference in a new issue