diff --git a/src/aal/aal_cheri.h b/src/aal/aal_cheri.h index 866e0ad..1a7906e 100644 --- a/src/aal/aal_cheri.h +++ b/src/aal/aal_cheri.h @@ -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(static_cast(pb)); } diff --git a/src/pal/pal_freebsd.h b/src/pal/pal_freebsd.h index e17df29..3cd2e4f 100644 --- a/src/pal/pal_freebsd.h +++ b/src/pal/pal_freebsd.h @@ -57,6 +57,13 @@ namespace snmalloc static SNMALLOC_FAST_PATH CapPtr> capptr_to_user_address_control(CapPtr p) { + if constexpr (Aal::aal_cheri_features & Aal::AndPermsTrapsUntagged) + { + if (p == nullptr) + { + return nullptr; + } + } return CapPtr>( __builtin_cheri_perms_and( p.unsafe_ptr(),