Enable guard pages in CHECK_CLIENT

Change the behaviour to use PROT_NONE for reservations in CHECK_CLIENT
mode.  This means that we only provide access once data is actually
being used.
This commit is contained in:
Matthew Parkinson
2021-07-16 16:35:54 +01:00
committed by Matthew Parkinson
parent 02d2ab8f7e
commit 9df0101dfd
12 changed files with 45 additions and 51 deletions

View File

@@ -113,7 +113,7 @@ namespace snmalloc
{
SNMALLOC_ASSERT(is_aligned_block<page_size>(p, size));
# ifdef USE_POSIX_COMMIT_CHECKS
# if defined(SNMALLOC_CHECK_CLIENT) && !defined(NDEBUG)
memset(p, 0x5a, size);
# endif
@@ -126,7 +126,7 @@ namespace snmalloc
while (madvise(p, size, MADV_FREE_REUSABLE) == -1 && errno == EAGAIN)
;
# ifdef USE_POSIX_COMMIT_CHECKS
# ifdef SNMALLOC_CHECK_CLIENT
// This must occur after `MADV_FREE_REUSABLE`.
//
// `mach_vm_protect` is observably slower in benchmarks.
@@ -179,7 +179,7 @@ namespace snmalloc
}
}
# ifdef USE_POSIX_COMMIT_CHECKS
# ifdef SNMALLOC_CHECK_CLIENT
// Mark pages as writable for `madvise` below.
//
// `mach_vm_protect` is observably slower in benchmarks.
@@ -218,7 +218,7 @@ namespace snmalloc
// must be initialized to 0 or addr is interepreted as a lower-bound.
mach_vm_address_t addr = 0;
# ifdef USE_POSIX_COMMIT_CHECKS
# ifdef SNMALLOC_CHECK_CLIENT
vm_prot_t prot = committed ? VM_PROT_READ | VM_PROT_WRITE : VM_PROT_NONE;
# else
vm_prot_t prot = VM_PROT_READ | VM_PROT_WRITE;

View File

@@ -35,11 +35,11 @@ namespace snmalloc
{
SNMALLOC_ASSERT(is_aligned_block<OS::page_size>(p, size));
// Call this Pal to simulate the Windows decommit in CI.
#ifdef USE_POSIX_COMMIT_CHECKS
#if defined(SNMALLOC_CHECK_CLIENT) && !defined(NDEBUG)
memset(p, 0x5a, size);
#endif
madvise(p, size, MADV_FREE);
#ifdef USE_POSIX_COMMIT_CHECKS
#ifdef SNMALLOC_CHECK_CLIENT
mprotect(p, size, PROT_NONE);
#endif
}

View File

@@ -37,10 +37,16 @@ namespace snmalloc
int log2align = static_cast<int>(bits::next_pow2_bits(size));
#ifdef SNMALLOC_CHECK_CLIENT
auto prot = committed ? PROT_READ | PROT_WRITE : PROT_NONE;
#else
auto prot = PROT_READ | PROT_WRITE;
#endif
void* p = mmap(
nullptr,
size,
PROT_READ | PROT_WRITE,
prot,
MAP_PRIVATE | MAP_ANONYMOUS | MAP_ALIGNED(log2align),
-1,
0);

View File

@@ -165,10 +165,12 @@ namespace snmalloc
static void notify_not_using(void* p, size_t size) noexcept
{
SNMALLOC_ASSERT(is_aligned_block<OS::page_size>(p, size));
#ifdef USE_POSIX_COMMIT_CHECKS
#ifdef SNMALLOC_CHECK_CLIENT
// Fill memory so that when we switch the pages back on we don't make
// assumptions on the content.
# if !defined(NDEBUG)
memset(p, 0x5a, size);
# endif
mprotect(p, size, PROT_NONE);
#else
UNUSED(p);
@@ -189,7 +191,7 @@ namespace snmalloc
SNMALLOC_ASSERT(
is_aligned_block<OS::page_size>(p, size) || (zero_mem == NoZero));
#ifdef USE_POSIX_COMMIT_CHECKS
#ifdef SNMALLOC_CHECK_CLIENT
mprotect(p, size, PROT_READ | PROT_WRITE);
#else
UNUSED(p);
@@ -260,6 +262,12 @@ namespace snmalloc
constexpr size_t min_size =
bits::is64() ? bits::one_at_bit(31) : bits::one_at_bit(27);
#ifdef SNMALLOC_CHECK_CLIENT
auto prot = PROT_NONE;
#else
auto prot = PROT_READ | PROT_WRITE;
#endif
for (size_t size_request = bits::max(size, min_size);
size_request >= size;
size_request = size_request / 2)
@@ -267,7 +275,7 @@ namespace snmalloc
void* p = mmap(
nullptr,
size_request,
PROT_READ | PROT_WRITE,
prot,
MAP_PRIVATE | MAP_ANONYMOUS | DefaultMMAPFlags<OS>::flags,
AnonFD<OS>::fd,
0);