CheriBSD/CHERI support
This adds a CHERI AAL and expands the FreeBSD PAL to cover CHERI. It updates a comment in ds/address.h now that there is an example architecture that differentiates uintptr_t and address_t.
This commit is contained in:
committed by
Nathaniel Wesley Filardo
parent
6f79ddee31
commit
6ddd11faee
@@ -226,9 +226,17 @@ namespace snmalloc
|
||||
# include "aal_riscv.h"
|
||||
#endif
|
||||
|
||||
#if defined(__CHERI_PURE_CAPABILITY__)
|
||||
# include "aal_cheri.h"
|
||||
#endif
|
||||
|
||||
namespace snmalloc
|
||||
{
|
||||
#if defined(__CHERI_PURE_CAPABILITY__)
|
||||
using Aal = AAL_Generic<AAL_CHERI<AAL_Arch>>;
|
||||
#else
|
||||
using Aal = AAL_Generic<AAL_NoStrictProvenance<AAL_Arch>>;
|
||||
#endif
|
||||
|
||||
template<AalFeatures F, SNMALLOC_CONCEPT(ConceptAAL) AAL = Aal>
|
||||
constexpr static bool aal_supports = (AAL::aal_features & F) == F;
|
||||
|
||||
52
src/aal/aal_cheri.h
Normal file
52
src/aal/aal_cheri.h
Normal file
@@ -0,0 +1,52 @@
|
||||
#pragma once
|
||||
|
||||
#include "../ds/defines.h"
|
||||
|
||||
#include <stddef.h>
|
||||
|
||||
namespace snmalloc
|
||||
{
|
||||
/**
|
||||
* A mixin AAL that applies CHERI to a `Base` architecture. Gives
|
||||
* architectural teeth to the capptr_bound primitive.
|
||||
*/
|
||||
template<typename Base>
|
||||
class AAL_CHERI : public Base
|
||||
{
|
||||
public:
|
||||
/**
|
||||
* CHERI pointers are not integers and come with strict provenance
|
||||
* requirements.
|
||||
*/
|
||||
static constexpr uint64_t aal_features =
|
||||
(Base::aal_features & ~IntegerPointers) | StrictProvenance;
|
||||
|
||||
/**
|
||||
* On CHERI-aware compilers, ptraddr_t is an integral type that is wide
|
||||
* enough to hold any address that may be contained within a memory
|
||||
* capability. It does not carry provenance: it is not a capability, but
|
||||
* merely an address.
|
||||
*/
|
||||
typedef ptraddr_t address_t;
|
||||
|
||||
template<
|
||||
typename T,
|
||||
SNMALLOC_CONCEPT(capptr::ConceptBound) BOut,
|
||||
SNMALLOC_CONCEPT(capptr::ConceptBound) BIn,
|
||||
typename U = T>
|
||||
static SNMALLOC_FAST_PATH CapPtr<T, BOut>
|
||||
capptr_bound(CapPtr<U, BIn> a, size_t size) noexcept
|
||||
{
|
||||
static_assert(
|
||||
BIn::spatial > capptr::dimension::Spatial::Alloc,
|
||||
"Refusing to re-bound Spatial::Alloc CapPtr");
|
||||
static_assert(
|
||||
capptr::is_spatial_refinement<BIn, BOut>(),
|
||||
"capptr_bound must preserve non-spatial CapPtr dimensions");
|
||||
SNMALLOC_ASSERT(__builtin_cheri_tag_get(a.unsafe_ptr()));
|
||||
|
||||
void* pb = __builtin_cheri_bounds_set_exact(a.unsafe_ptr(), size);
|
||||
return CapPtr<T, BOut>(static_cast<T*>(pb));
|
||||
}
|
||||
};
|
||||
} // namespace snmalloc
|
||||
@@ -8,11 +8,8 @@
|
||||
namespace snmalloc
|
||||
{
|
||||
/**
|
||||
* The type used for an address. Currently, all addresses are assumed to be
|
||||
* provenance-carrying values and so it is possible to cast back from the
|
||||
* result of arithmetic on an address_t. Eventually, this will want to be
|
||||
* separated into two types, one for raw addresses and one for addresses that
|
||||
* can be cast back to pointers.
|
||||
* The type used for an address. On CHERI, this is not a provenance-carrying
|
||||
* value and so cannot be converted back to a pointer.
|
||||
*/
|
||||
using address_t = Aal::address_t;
|
||||
|
||||
|
||||
@@ -3,6 +3,13 @@
|
||||
#if defined(__FreeBSD__) && !defined(_KERNEL)
|
||||
# include "pal_bsd_aligned.h"
|
||||
|
||||
// On CHERI platforms, we need to know the value of CHERI_PERM_CHERIABI_VMMAP.
|
||||
// This pollutes the global namespace a little, sadly, but I think only with
|
||||
// symbols that begin with CHERI_, which is as close to namespaces as C offers.
|
||||
# if defined(__CHERI_PURE_CAPABILITY__)
|
||||
# include <cheri/cherireg.h>
|
||||
# endif
|
||||
|
||||
namespace snmalloc
|
||||
{
|
||||
/**
|
||||
@@ -35,6 +42,27 @@ namespace snmalloc
|
||||
Aal::address_bits :
|
||||
(Aal::aal_name == RISCV ? 38 : Aal::address_bits);
|
||||
// TODO, if we ever backport to MIPS, this should yield 39 there.
|
||||
|
||||
# if defined(__CHERI_PURE_CAPABILITY__)
|
||||
static_assert(
|
||||
aal_supports<StrictProvenance>,
|
||||
"CHERI purecap support requires StrictProvenance AAL");
|
||||
|
||||
/**
|
||||
* On CheriBSD, exporting a pointer means stripping it of the authority to
|
||||
* manage the address space it references by clearing the CHERIABI_VMMAP
|
||||
* permission bit.
|
||||
*/
|
||||
template<typename T, SNMALLOC_CONCEPT(capptr::ConceptBound) B>
|
||||
static SNMALLOC_FAST_PATH CapPtr<T, capptr::user_address_control_type<B>>
|
||||
capptr_to_user_address_control(CapPtr<T, B> p)
|
||||
{
|
||||
return CapPtr<T, capptr::user_address_control_type<B>>(
|
||||
__builtin_cheri_perms_and(
|
||||
p.unsafe_ptr(),
|
||||
~static_cast<unsigned int>(CHERI_PERM_CHERIABI_VMMAP)));
|
||||
}
|
||||
# endif
|
||||
};
|
||||
} // namespace snmalloc
|
||||
#endif
|
||||
|
||||
Reference in New Issue
Block a user