pagemap: don't depend on SNMALLOC_CHECK_CLIENT

Instead, take a template parameter for the no-args init() method, so
that randomization can be disabled on StrictProvenance architectures
(CHERI), where we don't expect it to be useful, even when snmalloc is
being built to be otherwise paranoid.

Catch callsites up.
This commit is contained in:
Nathaniel Wesley Filardo
2022-12-10 07:53:15 +00:00
committed by Nathaniel Filardo
parent 30da31d245
commit 06873ac366
4 changed files with 51 additions and 28 deletions

View File

@@ -134,8 +134,16 @@ namespace snmalloc
// Initialise key for remote deallocation lists
key_global = FreeListKey(entropy.get_free_list_key());
// Need to initialise pagemap.
Pagemap::concretePagemap.init();
// Need to initialise pagemap. If SNMALLOC_CHECK_CLIENT is set and this
// isn't a StrictProvenance architecture, randomize its table's location
// within a significantly larger address space allocation.
# if defined(SNMALLOC_CHECK_CLIENT)
static constexpr bool pagemap_randomize = !aal_supports<StrictProvenance>;
# else
static constexpr bool pagemap_randomize = false;
# endif
Pagemap::concretePagemap.template init<pagemap_randomize>();
initialised = true;
}

View File

@@ -167,7 +167,7 @@ namespace snmalloc
/**
* Initialise the pagemap without bounds.
*/
template<bool has_bounds_ = has_bounds>
template<bool randomize_position, bool has_bounds_ = has_bounds>
std::enable_if_t<!has_bounds_> init()
{
SNMALLOC_ASSERT(!is_initialised());
@@ -176,14 +176,11 @@ namespace snmalloc
has_bounds_ == has_bounds, "Don't set SFINAE template parameter!");
static constexpr size_t REQUIRED_SIZE = required_size();
#ifdef SNMALLOC_CHECK_CLIENT
// Allocate a power of two extra to allow the placement of the
// pagemap be difficult to guess.
size_t additional_size = bits::next_pow2(REQUIRED_SIZE) * 4;
// pagemap be difficult to guess if randomize_position set.
size_t additional_size =
randomize_position ? bits::next_pow2(REQUIRED_SIZE) * 4 : 0;
size_t request_size = REQUIRED_SIZE + additional_size;
#else
size_t request_size = REQUIRED_SIZE;
#endif
auto new_body_untyped = PAL::reserve(request_size);
@@ -192,26 +189,32 @@ namespace snmalloc
PAL::error("Failed to initialise snmalloc.");
}
#ifdef SNMALLOC_CHECK_CLIENT
// Begin pagemap at random offset within the additionally allocated space.
static_assert(bits::is_pow2(sizeof(T)), "Next line assumes this.");
size_t offset = get_entropy64<PAL>() & (additional_size - sizeof(T));
auto new_body = pointer_offset<T>(new_body_untyped, offset);
T* new_body;
if constexpr (pal_supports<LazyCommit, PAL>)
if constexpr (randomize_position)
{
void* start_page = pointer_align_down<OS_PAGE_SIZE>(new_body);
void* end_page = pointer_align_up<OS_PAGE_SIZE>(
pointer_offset(new_body, REQUIRED_SIZE));
// Only commit readonly memory for this range, if the platform supports
// lazy commit. Otherwise, this would be a lot of memory to have
// mapped.
PAL::notify_using_readonly(
start_page, pointer_diff(start_page, end_page));
// Begin pagemap at random offset within the additionally allocated
// space.
static_assert(bits::is_pow2(sizeof(T)), "Next line assumes this.");
size_t offset = get_entropy64<PAL>() & (additional_size - sizeof(T));
new_body = pointer_offset<T>(new_body_untyped, offset);
if constexpr (pal_supports<LazyCommit, PAL>)
{
void* start_page = pointer_align_down<OS_PAGE_SIZE>(new_body);
void* end_page = pointer_align_up<OS_PAGE_SIZE>(
pointer_offset(new_body, REQUIRED_SIZE));
// Only commit readonly memory for this range, if the platform
// supports lazy commit. Otherwise, this would be a lot of memory to
// have mapped.
PAL::notify_using_readonly(
start_page, pointer_diff(start_page, end_page));
}
}
else
{
new_body = static_cast<T*>(new_body_untyped);
}
#else
auto new_body = static_cast<T*>(new_body_untyped);
#endif
// Ensure bottom page is committed
// ASSUME: new memory is zeroed.
PAL::template notify_using<NoZero>(

View File

@@ -121,7 +121,13 @@ namespace snmalloc
int main()
{
snmalloc::CustomConfig::Pagemap::concretePagemap.init(); // init pagemap
# if defined(SNMALLOC_CHECK_CLIENT)
static constexpr bool pagemap_randomize = !aal_supports<StrictProvenance>;
# else
static constexpr bool pagemap_randomize = false;
# endif
snmalloc::CustomConfig::Pagemap::concretePagemap.init<pagemap_randomize>();
snmalloc::CustomConfig::domesticate_count = 0;
LocalEntropy entropy;

View File

@@ -81,7 +81,13 @@ void test_pagemap(bool bounded)
}
else
{
pagemap_test_unbound.init();
#if defined(SNMALLOC_CHECK_CLIENT)
static constexpr bool pagemap_randomize = !aal_supports<StrictProvenance>;
#else
static constexpr bool pagemap_randomize = false;
#endif
pagemap_test_unbound.init<pagemap_randomize>();
pagemap_test_unbound.register_range(low, high - low);
}