mirror of
https://github.com/reactos/reactos.git
synced 2024-10-04 08:25:53 +00:00
Implemented the 'red zone check' for the non paged pool.
svn path=/trunk/; revision=20533
This commit is contained in:
parent
61b5988d34
commit
39a85a187f
|
@ -37,6 +37,15 @@
|
|||
#endif /* __GNUC__ */
|
||||
#endif
|
||||
|
||||
VOID MmPrintMemoryStatistic(VOID);
|
||||
|
||||
#define NPOOL_REDZONE_CHECK /* check the block at deallocation */
|
||||
// #define NPOOL_REDZONE_CHECK_FULL /* check all blocks at each allocation/deallocation */
|
||||
#define NPOOL_REDZONE_SIZE 8 /* number of red zone bytes */
|
||||
#define NPOOL_REDZONE_LOVALUE 0x87
|
||||
#define NPOOL_REDZONE_HIVALUE 0xA5
|
||||
|
||||
|
||||
/* avl types ****************************************************************/
|
||||
|
||||
/* FIXME:
|
||||
|
@ -73,6 +82,9 @@ typedef struct _HDR_USED
|
|||
ULONG Tag;
|
||||
PVOID Caller;
|
||||
LIST_ENTRY TagListEntry;
|
||||
#if defined(NPOOL_REDZONE_CHECK) || defined(NPOOL_REDZONE_CHECK_FULL)
|
||||
ULONG UserSize;
|
||||
#endif
|
||||
BOOLEAN Dumped;
|
||||
} HDR_USED, *PHDR_USED;
|
||||
|
||||
|
@ -83,8 +95,12 @@ typedef struct _HDR_FREE
|
|||
} HDR_FREE, *PHDR_FREE;
|
||||
|
||||
#define HDR_FREE_SIZE ROUND_UP(sizeof(HDR_FREE), MM_POOL_ALIGNMENT)
|
||||
#define HDR_USED_SIZE ROUND_UP(sizeof(HDR_USED), MM_POOL_ALIGNMENT)
|
||||
|
||||
#if defined(NPOOL_REDZONE_CHECK) || #defined(NPOOL_REDZONE_CHECK_FULL)
|
||||
#define HDR_USED_SIZE ROUND_UP(sizeof(HDR_USED) + NPOOL_REDZONE_SIZE, MM_POOL_ALIGNMENT)
|
||||
#else
|
||||
#define HDR_USED_SIZE ROUND_UP(sizeof(HDR_USED), MM_POOL_ALIGNMENT)
|
||||
#endif
|
||||
|
||||
/* GLOBALS *****************************************************************/
|
||||
|
||||
|
@ -131,15 +147,6 @@ ULONG EiUsedNonPagedPool = 0;
|
|||
/* Total quota for Non Paged Pool */
|
||||
ULONG MmTotalNonPagedPoolQuota = 0;
|
||||
|
||||
/*
|
||||
* Allocate a range of memory in the nonpaged pool
|
||||
*/
|
||||
PVOID
|
||||
MiAllocNonPagedPoolRegion(unsigned int nr_pages);
|
||||
|
||||
VOID
|
||||
MiFreeNonPagedPoolRegion(PVOID Addr, ULONG Count, BOOLEAN Free);
|
||||
|
||||
#ifdef TAG_STATISTICS_TRACKING
|
||||
#define TAG_HASH_TABLE_SIZE (1024)
|
||||
static LIST_ENTRY tag_hash_table[TAG_HASH_TABLE_SIZE];
|
||||
|
@ -772,9 +779,11 @@ MiDumpTagStats(ULONG CurrentTag, ULONG CurrentNrBlocks, ULONG CurrentSize)
|
|||
}
|
||||
else
|
||||
{
|
||||
DbgPrint("Tag %x Blocks %d Total Size %d Average Size %d\n",
|
||||
DbgPrint("Tag %x Blocks %d Total Size %d Average Size %d ",
|
||||
CurrentTag, CurrentNrBlocks, CurrentSize,
|
||||
CurrentSize / CurrentNrBlocks);
|
||||
KeRosPrintAddress((PVOID)CurrentTag);
|
||||
DbgPrint("\n");
|
||||
}
|
||||
}
|
||||
#endif /* defined(TAG_STATISTICS_TRACKING) */
|
||||
|
@ -1458,6 +1467,71 @@ ExRosQueryNonPagedPoolTag ( PVOID Addr )
|
|||
return blk->Tag;
|
||||
}
|
||||
|
||||
#if defined(NPOOL_REDZONE_CHECK) || defined(NPOOL_REDZONE_CHECK_FULL)
|
||||
void check_redzone_header(HDR_USED* hdr)
|
||||
{
|
||||
PBYTE LoZone = (PBYTE)((ULONG_PTR)hdr + HDR_USED_SIZE - NPOOL_REDZONE_SIZE);
|
||||
PBYTE HiZone = (PBYTE)((ULONG_PTR)hdr + HDR_USED_SIZE + hdr->UserSize);
|
||||
BOOL LoOK = TRUE;
|
||||
BOOL HiOK = TRUE;
|
||||
ULONG i;
|
||||
CHAR c[5];
|
||||
|
||||
for (i = 0; i < NPOOL_REDZONE_SIZE; i++)
|
||||
{
|
||||
if (LoZone[i] != NPOOL_REDZONE_LOVALUE)
|
||||
{
|
||||
LoOK = FALSE;
|
||||
}
|
||||
if (HiZone[i] != NPOOL_REDZONE_HIVALUE)
|
||||
{
|
||||
HiOK = FALSE;
|
||||
}
|
||||
}
|
||||
|
||||
if (!HiOK || !LoOK)
|
||||
{
|
||||
c[0] = (CHAR)((hdr->Tag >> 24) & 0xFF);
|
||||
c[1] = (CHAR)((hdr->Tag >> 16) & 0xFF);
|
||||
c[2] = (CHAR)((hdr->Tag >> 8) & 0xFF);
|
||||
c[3] = (CHAR)(hdr->Tag & 0xFF);
|
||||
c[4] = 0;
|
||||
|
||||
if (!isprint(c[0]) || !isprint(c[1]) || !isprint(c[2]) || !isprint(c[3]))
|
||||
{
|
||||
c[0] = 0;
|
||||
}
|
||||
|
||||
if (!LoOK)
|
||||
{
|
||||
DbgPrint("NPOOL: Low-side redzone overwritten, Block %x, Size %d, Tag %x(%s), Caller %x\n",
|
||||
(ULONG_PTR)hdr + HDR_USED_SIZE, hdr->UserSize, hdr->Tag, c, hdr->Caller);
|
||||
}
|
||||
if (!HiOK)
|
||||
{
|
||||
DbgPrint("NPPOL: High-side redzone overwritten, Block %x, Size %d, Tag %x(%s), Caller %x\n",
|
||||
(ULONG_PTR)hdr + HDR_USED_SIZE, hdr->UserSize, hdr->Tag, c, hdr->Caller);
|
||||
}
|
||||
KEBUGCHECK(0);
|
||||
}
|
||||
}
|
||||
#endif
|
||||
|
||||
#ifdef NPOOL_REDZONE_CHECK_FULL
|
||||
void check_redzone_list(void)
|
||||
{
|
||||
PLIST_ENTRY current_entry;
|
||||
|
||||
current_entry = UsedBlockListHead.Flink;
|
||||
while (current_entry != &UsedBlockListHead)
|
||||
{
|
||||
check_redzone_header(CONTAINING_RECORD(current_entry, HDR_USED, ListEntry));
|
||||
current_entry = current_entry->Flink;
|
||||
}
|
||||
}
|
||||
#endif
|
||||
|
||||
|
||||
VOID STDCALL ExFreeNonPagedPool (PVOID block)
|
||||
/*
|
||||
* FUNCTION: Releases previously allocated memory
|
||||
|
@ -1494,9 +1568,18 @@ VOID STDCALL ExFreeNonPagedPool (PVOID block)
|
|||
KEBUGCHECK(0);
|
||||
return;
|
||||
}
|
||||
memset(block, 0xcc, blk->hdr.Size - HDR_USED_SIZE);
|
||||
#ifdef TAG_STATISTICS_TRACKING
|
||||
|
||||
#if defined(NPOOL_REDZONE_CHECK) || defined(NPOOL_REDZONE_CHECK_FULL)
|
||||
check_redzone_header(blk);
|
||||
#endif
|
||||
|
||||
#ifdef NPOOL_REDZONE_CHECK_FULL
|
||||
check_redzone_list();
|
||||
#endif
|
||||
|
||||
memset(block, 0xcc, blk->hdr.Size - HDR_USED_SIZE);
|
||||
|
||||
#ifdef TAG_STATISTICS_TRACKING
|
||||
MiRemoveFromTagHashTable(blk);
|
||||
#endif
|
||||
|
||||
|
@ -1510,6 +1593,9 @@ VOID STDCALL ExFreeNonPagedPool (PVOID block)
|
|||
PVOID STDCALL
|
||||
ExAllocateNonPagedPoolWithTag(POOL_TYPE Type, ULONG Size, ULONG Tag, PVOID Caller)
|
||||
{
|
||||
#if defined(NPOOL_REDZONE_CHECK) || defined(NPOOL_REDZONE_CHECK_FULL)
|
||||
ULONG UserSize;
|
||||
#endif
|
||||
PVOID block;
|
||||
HDR_USED* best = NULL;
|
||||
KIRQL oldIrql;
|
||||
|
@ -1520,9 +1606,13 @@ ExAllocateNonPagedPoolWithTag(POOL_TYPE Type, ULONG Size, ULONG Tag, PVOID Calle
|
|||
|
||||
KeAcquireSpinLock(&MmNpoolLock, &oldIrql);
|
||||
|
||||
#ifdef NPOOL_REDZONE_CHECK_FULL
|
||||
check_redzone_list();
|
||||
#endif
|
||||
|
||||
VALIDATE_POOL;
|
||||
|
||||
#if 0
|
||||
#if 1
|
||||
/* after some allocations print the npaged pool stats */
|
||||
#ifdef TAG_STATISTICS_TRACKING
|
||||
|
||||
|
@ -1531,6 +1621,7 @@ ExAllocateNonPagedPoolWithTag(POOL_TYPE Type, ULONG Size, ULONG Tag, PVOID Calle
|
|||
if (counter++ % 100000 == 0)
|
||||
{
|
||||
MiDebugDumpNonPagedPoolStats(FALSE);
|
||||
MmPrintMemoryStatistic();
|
||||
}
|
||||
}
|
||||
#endif
|
||||
|
@ -1545,7 +1636,12 @@ ExAllocateNonPagedPoolWithTag(POOL_TYPE Type, ULONG Size, ULONG Tag, PVOID Calle
|
|||
return(NULL);
|
||||
}
|
||||
/* Make the size dword alligned, this makes the block dword alligned */
|
||||
#if defined(NPOOL_REDZONE_CHECK) || defined(NPOOL_REDZONE_CHECK_FULL)
|
||||
UserSize = Size;
|
||||
Size = ROUND_UP(Size + NPOOL_REDZONE_SIZE, MM_POOL_ALIGNMENT);
|
||||
#else
|
||||
Size = ROUND_UP(Size, MM_POOL_ALIGNMENT);
|
||||
#endif
|
||||
|
||||
if (Size >= PAGE_SIZE)
|
||||
{
|
||||
|
@ -1566,12 +1662,19 @@ ExAllocateNonPagedPoolWithTag(POOL_TYPE Type, ULONG Size, ULONG Tag, PVOID Calle
|
|||
KeReleaseSpinLock(&MmNpoolLock, oldIrql);
|
||||
DPRINT1("Trying to allocate %lu bytes from nonpaged pool - nothing suitable found, returning NULL\n",
|
||||
Size );
|
||||
KeRosDumpStackFrames(NULL, 10);
|
||||
return NULL;
|
||||
}
|
||||
best->Tag = Tag;
|
||||
best->Caller = Caller;
|
||||
best->Dumped = FALSE;
|
||||
best->TagListEntry.Flink = best->TagListEntry.Blink = NULL;
|
||||
#if defined(NPOOL_REDZONE_CHECK) || defined(NPOOL_REDZONE_CHECK_FULL)
|
||||
best->UserSize = UserSize;
|
||||
memset((PVOID)((ULONG_PTR)best + HDR_USED_SIZE - NPOOL_REDZONE_SIZE), NPOOL_REDZONE_LOVALUE, NPOOL_REDZONE_SIZE);
|
||||
memset((PVOID)((ULONG_PTR)best + HDR_USED_SIZE + UserSize), NPOOL_REDZONE_HIVALUE, NPOOL_REDZONE_SIZE);
|
||||
#endif
|
||||
|
||||
#ifdef TAG_STATISTICS_TRACKING
|
||||
|
||||
MiAddToTagHashTable(best);
|
||||
|
@ -1607,7 +1710,13 @@ MiInitializeNonPagedPool(VOID)
|
|||
FreeBlockListRoot = NULL;
|
||||
|
||||
MiNonPagedPoolAllocMap = (PVOID)((ULONG_PTR)MiNonPagedPoolStart + PAGE_SIZE);
|
||||
#if defined(NPOOL_REDZONE_CHECK) || defined(NPOOL_REDZONE_CHECK_FULL)
|
||||
MiNonPagedPoolNrOfPages = ROUND_UP(MiNonPagedPoolLength / PAGE_SIZE, 32) / 8;
|
||||
MiNonPagedPoolNrOfPages = ROUND_UP(MiNonPagedPoolNrOfPages + NPOOL_REDZONE_SIZE, MM_POOL_ALIGNMENT);
|
||||
MiNonPagedPoolNrOfPages = PAGE_ROUND_UP(MiNonPagedPoolNrOfPages + HDR_FREE_SIZE) + PAGE_SIZE;
|
||||
#else
|
||||
MiNonPagedPoolNrOfPages = PAGE_ROUND_UP(ROUND_UP(MiNonPagedPoolLength / PAGE_SIZE, 32) / 8 + HDR_FREE_SIZE) + PAGE_SIZE;
|
||||
#endif
|
||||
MiNonPagedPoolNrOfPages /= PAGE_SIZE;
|
||||
Address = MiNonPagedPoolStart;
|
||||
|
||||
|
@ -1649,10 +1758,17 @@ MiInitializeNonPagedPool(VOID)
|
|||
/* the second block contains the non paged pool bitmap */
|
||||
used = (HDR_USED*)((ULONG_PTR)free + free->hdr.Size);
|
||||
used->hdr.Magic = BLOCK_HDR_USED_MAGIC;
|
||||
#if defined(NPOOL_REDZONE_CHECK) || defined(NPOOL_REDZONE_CHECK_FULL)
|
||||
used->UserSize = ROUND_UP(MiNonPagedPoolLength / PAGE_SIZE, 32) / 8;
|
||||
used->hdr.Size = ROUND_UP(used->UserSize + NPOOL_REDZONE_SIZE, MM_POOL_ALIGNMENT) + HDR_USED_SIZE;
|
||||
memset((PVOID)((ULONG_PTR)used + HDR_USED_SIZE - NPOOL_REDZONE_SIZE), NPOOL_REDZONE_LOVALUE, NPOOL_REDZONE_SIZE);
|
||||
memset((PVOID)((ULONG_PTR)used + HDR_USED_SIZE + used->UserSize), NPOOL_REDZONE_HIVALUE, NPOOL_REDZONE_SIZE);
|
||||
#else
|
||||
used->hdr.Size = ROUND_UP(MiNonPagedPoolLength / PAGE_SIZE, 32) / 8 + HDR_USED_SIZE;
|
||||
#endif
|
||||
used->hdr.previous = &free->hdr;
|
||||
used->Tag = 0xffffffff;
|
||||
used->Caller = 0;
|
||||
used->Caller = (PVOID)MiInitializeNonPagedPool;
|
||||
used->Dumped = FALSE;
|
||||
add_to_used_list(used);
|
||||
#ifdef TAG_STATISTICS_TRACKING
|
||||
|
@ -1664,7 +1780,7 @@ MiInitializeNonPagedPool(VOID)
|
|||
free->hdr.Magic = BLOCK_HDR_FREE_MAGIC;
|
||||
free->hdr.Size = MiNonPagedPoolLength - ((ULONG_PTR)free - (ULONG_PTR)MiNonPagedPoolStart);
|
||||
free->hdr.previous = &used->hdr;
|
||||
memset((PVOID)((ULONG_PTR)free + HDR_FREE_SIZE), 0x0cc, (ULONG_PTR)Address - (ULONG_PTR)free - HDR_FREE_SIZE);
|
||||
memset((PVOID)((ULONG_PTR)free + HDR_FREE_SIZE), 0xcc, (ULONG_PTR)Address - (ULONG_PTR)free - HDR_FREE_SIZE);
|
||||
add_to_free_list(free);
|
||||
}
|
||||
|
||||
|
|
Loading…
Reference in a new issue