Finish the implementation of heap_debug_malloc_with_guard_page() using mprotect
to make the guard page inaccessible. Thanks Ingo for the pointer! git-svn-id: file:///srv/svn/repos/haiku/haiku/trunk@35488 a95241bf-73f2-0310-859d-f6bbb57e9c96
This commit is contained in:
@@ -10,10 +10,14 @@
|
|||||||
*/
|
*/
|
||||||
|
|
||||||
#include <malloc.h>
|
#include <malloc.h>
|
||||||
|
#include <malloc_debug.h>
|
||||||
#include <stdio.h>
|
#include <stdio.h>
|
||||||
#include <string.h>
|
#include <string.h>
|
||||||
#include <stdlib.h>
|
#include <stdlib.h>
|
||||||
|
|
||||||
|
#include <errno.h>
|
||||||
|
#include <sys/mman.h>
|
||||||
|
|
||||||
#include <locks.h>
|
#include <locks.h>
|
||||||
#include <syscalls.h>
|
#include <syscalls.h>
|
||||||
|
|
||||||
@@ -1703,15 +1707,14 @@ heap_debug_dump_heaps(bool dumpAreas, bool dumpBins)
|
|||||||
extern "C" void *
|
extern "C" void *
|
||||||
heap_debug_malloc_with_guard_page(size_t size)
|
heap_debug_malloc_with_guard_page(size_t size)
|
||||||
{
|
{
|
||||||
size_t areaSize = ROUNDUP(size + sizeof(area_allocation_info), B_PAGE_SIZE);
|
size_t areaSize = ROUNDUP(size + sizeof(area_allocation_info) + B_PAGE_SIZE,
|
||||||
|
B_PAGE_SIZE);
|
||||||
if (areaSize < size) {
|
if (areaSize < size) {
|
||||||
// the size overflowed
|
// the size overflowed
|
||||||
return NULL;
|
return NULL;
|
||||||
}
|
}
|
||||||
|
|
||||||
void *address = NULL;
|
void *address = NULL;
|
||||||
// TODO: this needs a kernel backend (flag) to enforce adding an unmapped
|
|
||||||
// page past the required pages so it will reliably crash
|
|
||||||
area_id allocationArea = create_area("guarded area", &address,
|
area_id allocationArea = create_area("guarded area", &address,
|
||||||
B_ANY_ADDRESS, areaSize, B_NO_LOCK, B_READ_AREA | B_WRITE_AREA);
|
B_ANY_ADDRESS, areaSize, B_NO_LOCK, B_READ_AREA | B_WRITE_AREA);
|
||||||
if (allocationArea < B_OK) {
|
if (allocationArea < B_OK) {
|
||||||
@@ -1720,6 +1723,13 @@ heap_debug_malloc_with_guard_page(size_t size)
|
|||||||
return NULL;
|
return NULL;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
if (mprotect((void *)((addr_t)address + areaSize - B_PAGE_SIZE),
|
||||||
|
B_PAGE_SIZE, PROT_NONE) != 0) {
|
||||||
|
panic("heap: failed to protect guard page: %s\n", strerror(errno));
|
||||||
|
delete_area(allocationArea);
|
||||||
|
return NULL;
|
||||||
|
}
|
||||||
|
|
||||||
area_allocation_info *info = (area_allocation_info *)address;
|
area_allocation_info *info = (area_allocation_info *)address;
|
||||||
info->magic = kAreaAllocationMagic;
|
info->magic = kAreaAllocationMagic;
|
||||||
info->area = allocationArea;
|
info->area = allocationArea;
|
||||||
@@ -1731,7 +1741,7 @@ heap_debug_malloc_with_guard_page(size_t size)
|
|||||||
|
|
||||||
// the address is calculated so that the end of the allocation
|
// the address is calculated so that the end of the allocation
|
||||||
// is at the end of the usable space of the requested area
|
// is at the end of the usable space of the requested area
|
||||||
address = (void *)((addr_t)address + areaSize - size);
|
address = (void *)((addr_t)address + areaSize - B_PAGE_SIZE - size);
|
||||||
|
|
||||||
INFO(("heap: allocated area %ld for guarded allocation of %lu bytes\n",
|
INFO(("heap: allocated area %ld for guarded allocation of %lu bytes\n",
|
||||||
allocationArea, size));
|
allocationArea, size));
|
||||||
|
|||||||
Reference in New Issue
Block a user