From c54d2b527d12e8bf17e3f61b908289aaa02bb9dc Mon Sep 17 00:00:00 2001 From: Nathaniel Wesley Filardo Date: Tue, 19 Oct 2021 13:33:10 +0100 Subject: [PATCH] NFC: CapPtr in external_pointer; drop capptr_rebound capptr_rebound was only ever going to be used for external_pointer, which now operates entirely using pointer_offset. So instead, just make external_pointer use capptr::AllocWild, capptr_from_client, and a new capptr_reveal_wild. --- src/aal/aal.h | 15 --------------- src/aal/aal_concept.h | 6 ------ src/ds/ptrwrap.h | 10 ++++++++++ src/mem/localalloc.h | 24 +++++++++++++----------- 4 files changed, 23 insertions(+), 32 deletions(-) diff --git a/src/aal/aal.h b/src/aal/aal.h index 821d8a3..45669e5 100644 --- a/src/aal/aal.h +++ b/src/aal/aal.h @@ -202,21 +202,6 @@ namespace snmalloc 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< - typename T, - SNMALLOC_CONCEPT(capptr::ConceptBound) BOut, - SNMALLOC_CONCEPT(capptr::ConceptBound) BIn> - static SNMALLOC_FAST_PATH CapPtr - capptr_rebound(CapPtr a, CapPtr r) noexcept - { - UNUSED(a); - return CapPtr(r.unsafe_capptr); - } }; } // namespace snmalloc diff --git a/src/aal/aal_concept.h b/src/aal/aal_concept.h index 2a14a94..15eed19 100644 --- a/src/aal/aal_concept.h +++ b/src/aal/aal_concept.h @@ -53,12 +53,6 @@ namespace snmalloc { 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 diff --git a/src/ds/ptrwrap.h b/src/ds/ptrwrap.h index 9ee2cf2..cec1874 100644 --- a/src/ds/ptrwrap.h +++ b/src/ds/ptrwrap.h @@ -371,6 +371,16 @@ namespace snmalloc return p.unsafe_capptr; } + /** + * Like capptr_reveal, but sometimes we do mean to reveal wild pointers + * (specifically in external_pointer, where we're revealing something + * architecturally derived from a user pointer). + */ + inline SNMALLOC_FAST_PATH void* capptr_reveal_wild(capptr::AllocWild p) + { + return p.unsafe_capptr; + } + /** * Given a void* from the client, it's fine to call it AllocWild. * Roughly dual to capptr_reveal(). diff --git a/src/mem/localalloc.h b/src/mem/localalloc.h index b90cca2..7c48b2a 100644 --- a/src/mem/localalloc.h +++ b/src/mem/localalloc.h @@ -628,26 +628,28 @@ namespace snmalloc // be implicit domestication through the `SharedStateHandle::Pagemap` or // we could just leave well enough alone. - // TODO bring back the CHERI bits. Wes to review if required. + capptr::AllocWild p = capptr_from_client(p_raw); + MetaEntry entry = SharedStateHandle::Pagemap::template get_metaentry( - core_alloc->backend_state_ptr(), address_cast(p_raw)); + core_alloc->backend_state_ptr(), address_cast(p)); auto sizeclass = entry.get_sizeclass(); if (likely(entry.get_remote() != SharedStateHandle::fake_large_remote)) { auto rsize = sizeclass_to_size(sizeclass); - auto offset = - address_cast(p_raw) & (sizeclass_to_slab_size(sizeclass) - 1); + auto offset = address_cast(p) & (sizeclass_to_slab_size(sizeclass) - 1); auto start_offset = round_by_sizeclass(sizeclass, offset); if constexpr (location == Start) { UNUSED(rsize); - return pointer_offset(p_raw, start_offset - offset); + return capptr_reveal_wild(pointer_offset(p, start_offset - offset)); } else if constexpr (location == End) - return pointer_offset(p_raw, rsize + start_offset - offset - 1); + return capptr_reveal_wild( + pointer_offset(p, rsize + start_offset - offset - 1)); else - return pointer_offset(p_raw, rsize + start_offset - offset); + return capptr_reveal_wild( + pointer_offset(p, rsize + start_offset - offset)); } // Sizeclass zero of a large allocation is used for not managed by us. @@ -655,13 +657,13 @@ namespace snmalloc { // This is a large allocation, find start by masking. auto rsize = bits::one_at_bit(sizeclass); - auto start = pointer_align_down(p_raw, rsize); + auto start = pointer_align_down(p, rsize); if constexpr (location == Start) - return start; + return capptr_reveal_wild(start); else if constexpr (location == End) - return pointer_offset(start, rsize - 1); + return capptr_reveal_wild(pointer_offset(start, rsize - 1)); else - return pointer_offset(start, rsize); + return capptr_reveal_wild(pointer_offset(start, rsize)); } #else UNUSED(p_raw);