From 268ef2c059058fb7cd3560f3c311c8f6359eb066 Mon Sep 17 00:00:00 2001 From: Nathaniel Filardo Date: Sat, 21 Nov 2020 03:23:05 +0000 Subject: [PATCH] SP: introduce AAL, PAL methods as per design doc These capture the primitive architectural operations we are going to use. At the moment, since all AALs and PALs are not StrictProvenance, the only implementations are stubs that just subvert the type system (but give us something to compile against, going forward). --- src/aal/aal.h | 46 ++++++++++++++++++++++++++++++++++++++++++- src/aal/aal_concept.h | 23 +++++++++++++++++++++- src/pal/pal.h | 24 ++++++++++++++++++++++ 3 files changed, 91 insertions(+), 2 deletions(-) diff --git a/src/aal/aal.h b/src/aal/aal.h index 471b460..d1a71c8 100644 --- a/src/aal/aal.h +++ b/src/aal/aal.h @@ -1,11 +1,13 @@ #pragma once #include "../ds/concept.h" #include "../ds/defines.h" +#include "../ds/ptrwrap.h" #include "aal_concept.h" #include "aal_consts.h" #include #include +#include #if defined(__i386__) || defined(_M_IX86) || defined(_X86_) || \ defined(__amd64__) || defined(__x86_64__) || defined(_M_X64) || \ @@ -113,6 +115,48 @@ namespace snmalloc } }; + template + class AAL_NoStrictProvenance : public Arch + { + static_assert( + (Arch::aal_features & StrictProvenance) == 0, + "AAL_NoStrictProvenance requires what it says on the tin"); + + public: + /** + * For architectures which do not enforce StrictProvenance, we can just + * perform an underhanded bit of type-casting. + */ + template< + typename T, + enum capptr_bounds nbounds, + enum capptr_bounds obounds, + typename U = T> + static SNMALLOC_FAST_PATH CapPtr + capptr_bound(CapPtr a, size_t size) noexcept + { + // Impose constraints on bounds annotations. + static_assert( + obounds == CBArena || obounds == CBChunkD || obounds == CBChunk || + obounds == CBChunkE); + static_assert(capptr_is_bounds_refinement()); + + UNUSED(size); + return CapPtr(a.template as_static().unsafe_capptr); + } + + /** + * For architectures which do not enforce StrictProvenance, there's nothing + * to be done, so just return the pointer unmodified with new annotation. + */ + template + static SNMALLOC_FAST_PATH CapPtr + capptr_rebound(CapPtr a, CapPtr r) noexcept + { + UNUSED(a); + return CapPtr(r.unsafe_capptr); + } + }; } // namespace snmalloc #if defined(PLATFORM_IS_X86) @@ -129,7 +173,7 @@ namespace snmalloc namespace snmalloc { - using Aal = AAL_Generic; + using Aal = AAL_Generic>; template constexpr static bool aal_supports = (AAL::aal_features & F) == F; diff --git a/src/aal/aal_concept.h b/src/aal/aal_concept.h index e199e07..6b85772 100644 --- a/src/aal/aal_concept.h +++ b/src/aal/aal_concept.h @@ -2,6 +2,7 @@ #ifdef __cpp_concepts # include "../ds/concept.h" +# include "../ds/ptrwrap.h" # include "aal_consts.h" # include @@ -38,11 +39,31 @@ namespace snmalloc { AAL::tick() } noexcept -> ConceptSame; }; + template + concept ConceptAAL_capptr_methods = + requires(CapPtr auth, CapPtr ret, size_t sz) + { + /** + * Produce a pointer with reduced authority from a more privilged pointer. + * The resulting pointer will have base at auth's address and length of + * exactly sz. auth+sz must not exceed auth's limit. + */ + { AAL::template capptr_bound(auth, sz) } noexcept + -> ConceptSame>; + + /** + * Construct a copy of auth with its target set to that of ret. + */ + { AAL::capptr_rebound(auth, ret) } noexcept + -> ConceptSame>; + }; + template concept ConceptAAL = ConceptAAL_static_members && ConceptAAL_prefetch && - ConceptAAL_tick; + ConceptAAL_tick && + ConceptAAL_capptr_methods; } // namespace snmalloc #endif diff --git a/src/pal/pal.h b/src/pal/pal.h index cceb135..03d12c6 100644 --- a/src/pal/pal.h +++ b/src/pal/pal.h @@ -69,6 +69,30 @@ namespace snmalloc // Used to keep Superslab metadata committed. static constexpr size_t OS_PAGE_SIZE = Pal::page_size; + /** + * Perform platform-specific adjustment of return pointers. + * + * This is here, rather than in every PAL proper, merely to minimize + * disruption to PALs for platforms that do not support StrictProvenance AALs. + */ + template + static SNMALLOC_FAST_PATH typename std::enable_if_t< + !aal_supports, + CapPtr()>> + capptr_export(CapPtr p) + { + return CapPtr()>(p.unsafe_capptr); + } + + template + static SNMALLOC_FAST_PATH typename std::enable_if_t< + aal_supports, + CapPtr()>> + capptr_export(CapPtr p) + { + return PAL::capptr_export(p); + } + /** * A convenience wrapper that avoids the need to litter unsafe accesses with * every call to PAL::zero.