CHERI: Avoid traps on nullptr
The CHERI-RISC-V `CAndPerm` and `CSetBoundsExact` instructions trap on untagged inputs, so avoid passing `nullptr` to primitives that become those instructions.
This commit is contained in:
committed by
Nathaniel Wesley Filardo
parent
13a4b0471e
commit
3a509d41f0
@@ -21,6 +21,38 @@ namespace snmalloc
|
||||
static constexpr uint64_t aal_features =
|
||||
(Base::aal_features & ~IntegerPointers) | StrictProvenance;
|
||||
|
||||
enum AalCheriFeatures : uint64_t
|
||||
{
|
||||
/**
|
||||
* This CHERI flavor traps if the capability input to a bounds-setting
|
||||
* instruction has its tag clear, rather than just leaving the output
|
||||
* untagged.
|
||||
*
|
||||
* For example, CHERI-RISC-V's CSetBoundsExact traps in contrast to
|
||||
* Morello's SCBNDSE.
|
||||
*/
|
||||
SetBoundsTrapsUntagged = (1 << 0),
|
||||
|
||||
/**
|
||||
* This CHERI flavor traps if the capability input to a
|
||||
* permissions-masking instruction has its tag clear, rather than just
|
||||
* leaving the output untagged.
|
||||
*
|
||||
* For example, CHERI-RISC-V's CAndPerms traps in contrast to Morello's
|
||||
* CLRPERM.
|
||||
*/
|
||||
AndPermsTrapsUntagged = (1 << 0),
|
||||
};
|
||||
|
||||
/**
|
||||
* Specify "features" of the particular CHERI machine we're running on.
|
||||
*/
|
||||
static constexpr uint64_t aal_cheri_features =
|
||||
/* CHERI-RISC-V prefers to trap on untagged inputs. Morello does not. */
|
||||
(Base::aal_name == RISCV ?
|
||||
SetBoundsTrapsUntagged | AndPermsTrapsUntagged :
|
||||
0);
|
||||
|
||||
/**
|
||||
* 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
|
||||
@@ -45,6 +77,14 @@ namespace snmalloc
|
||||
"capptr_bound must preserve non-spatial CapPtr dimensions");
|
||||
SNMALLOC_ASSERT(__builtin_cheri_tag_get(a.unsafe_ptr()));
|
||||
|
||||
if constexpr (aal_cheri_features & SetBoundsTrapsUntagged)
|
||||
{
|
||||
if (a == nullptr)
|
||||
{
|
||||
return nullptr;
|
||||
}
|
||||
}
|
||||
|
||||
void* pb = __builtin_cheri_bounds_set_exact(a.unsafe_ptr(), size);
|
||||
return CapPtr<T, BOut>(static_cast<T*>(pb));
|
||||
}
|
||||
|
||||
@@ -57,6 +57,13 @@ namespace snmalloc
|
||||
static SNMALLOC_FAST_PATH CapPtr<T, capptr::user_address_control_type<B>>
|
||||
capptr_to_user_address_control(CapPtr<T, B> p)
|
||||
{
|
||||
if constexpr (Aal::aal_cheri_features & Aal::AndPermsTrapsUntagged)
|
||||
{
|
||||
if (p == nullptr)
|
||||
{
|
||||
return nullptr;
|
||||
}
|
||||
}
|
||||
return CapPtr<T, capptr::user_address_control_type<B>>(
|
||||
__builtin_cheri_perms_and(
|
||||
p.unsafe_ptr(),
|
||||
|
||||
Reference in New Issue
Block a user