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:
committed by
Nathaniel Filardo
parent
30da31d245
commit
06873ac366
@@ -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;
|
||||
}
|
||||
|
||||
@@ -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>(
|
||||
|
||||
@@ -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;
|
||||
|
||||
@@ -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);
|
||||
}
|
||||
|
||||
|
||||
Reference in New Issue
Block a user