Commit Graph

756 Commits

Author SHA1 Message Date
Matthew Parkinson
4b9ead8066 Fix register_clean_up being called with ScopedAllocator. (#344) 2021-07-12 19:50:36 +01:00
Matthew Parkinson
f0e2ab702a Major refactor of snmalloc (#343)
# Pagemap
 
The Pagemap now stores all the meta-data for the object allocation. The meta-data in the pagemap is effectively a triple of the sizeclass, the remote allocator, and a pointer to a 64 byte block of meta-data for this chunk of memory. By storing the pointer to a block, it allows the pagemap to handle multiple slab sizes without branching on the fast path. There is one entry in the pagemap per 16KiB of address space, but by using the same entry in the pagemap for 4 adjacent entries, then we can treat a 64KiB range can be treated as a single slab of allocations.

This change also means there is almost no capability amplification required by the implementation on CHERI for finding meta-data. The only amplification is required, when we change the way a chunk is used to a size of object allocation.


# Backend

There is a second major aspect of the refactor that there is now a narrow API that abstracts the Pagemap, PAL and address space management. This should better enable the compartmentalisation and makes it easier to produce alternative backends for various research directions. This is a template parameter that can be used to specialised by the front-end in different ways.

# Thread local state

The thread local state has been refactored into two components, one (called 'localalloc') that is stored directly in the TLS and is constant initialised, and one that is allocated in the address space (called 'coreallloc') which is lazily created and pooled.

# Difference

This removes Superslabs/Medium slabs as there meta-data is now part of the pagemap.
2021-07-12 15:53:36 +01:00
Istvan Haller
18d7cc99b6 Extended TrivialInitAtomic (#340) 2021-06-23 10:50:28 +01:00
Amari Robinson
85843e965e Rewrite Apple PAL using native APIs (#336)
This is a rewrite of the Apple PAL that implements the AlignedAllocation, Entropy, and LazyCommit features through native Apple APIs.

It adds a dependency on Security.framework via SecRandomCopyBytes. Apple actively discourages use of getentropy and the symbol is not allowed on the App Store.
2021-06-23 09:40:24 +01:00
Matthew Parkinson
0757762083 Enable overcommit for heuristic on Linux 2021-06-09 12:55:10 +01:00
David Carlier
9e88691ce6 Fix still non getentropy platform builds 2021-06-01 20:35:52 +01:00
Istvan Haller
aefd149f0a Gated the mcx16 flag to C++ compilation (#332)
* Restricted mcx16 option to C++ files as only those can include the snmalloc header
2021-05-28 17:13:49 +01:00
Theo Butler
7d346c0b2d Add init method to ABA on ARM (#331)
This method is used in the Verona SPMCQ.
2021-05-26 21:06:42 +01:00
Matthias Wahl
589ecfab02 Fix building on old libc systems without getentropy (#329)
Signed-off-by: Matthias Wahl <mwahl@wayfair.com>
2021-05-25 16:46:06 +01:00
Matthew Parkinson
e77a5d9c58 Remove cache-friendly offset. 2021-05-18 14:58:15 +01:00
Matthew Parkinson
f0ebbebf74 Refactor is_start_of_object 2021-05-18 14:58:15 +01:00
Matthew Parkinson
5198821905 CR Feedback. 2021-05-18 14:58:15 +01:00
Matthew Parkinson
208ab9a8e8 Rederive allocator id for remotes.
Storing a pointer to an allocator id in an unused object could be a
gadget for escallating priviledge of an attacker, by enabling
use-after-free to corrupt the allocator structure, and then create more
damage.

This commit adds an alternative implementation that does not cache the
allocator id.
2021-05-18 14:58:15 +01:00
Matthew Parkinson
b3796c123e Move remote cache out of alloc.h
Consolidate the remote code into a single file.
2021-05-18 14:58:15 +01:00
Matthew Parkinson
e011c297e6 Allocslab doesn't need to know impl of Remote
The Allocslab only needs to know of the RemoteAllocators existance.
2021-05-18 14:58:15 +01:00
Matthew Parkinson
118eecb2e6 Check for heap corruption
The allocator id and sizeclass are stored in deallocated objects to
provide quick lookup.  This adds checks that these are actually correct.
2021-05-18 14:58:15 +01:00
David CARLIER
c58a690b30 rust override: allows to implements alloc_zeroed as well proposal. 2021-05-06 11:55:09 +01:00
David Carlier
83e6208862 backtrace cmake vars build fix, got undetected if the system package include was already in the flags. 2021-05-06 11:54:51 +01:00
David Carlier
85db778c39 c++20 concept: enforcing type for get_entropy implementers. 2021-05-05 07:41:51 +01:00
David Carlier
15a7e159c0 consteval introduction proposal. 2021-05-04 14:43:27 +01:00
David Carlier
f3a9d3a682 c++20 (timid) introduction of constinit proposal. 2021-05-04 14:43:27 +01:00
David Carlier
e3a7eab789 unlikely annotation introduction proposal. 2021-04-30 09:49:28 +01:00
David Carlier
74077967a3 Fixing PAL haiku build similarly to NetBSD. 2021-04-30 09:49:14 +01:00
Nathaniel Filardo
017d4b1a59 Add clang-10 64-bit debug C++20 target
Just one C++20 target for the moment, to keep the CI feedback time from getting
too much larger than it already is.

clang-9 refers to C++20 as C++2a, so use clang 10.
2021-04-22 01:28:24 +01:00
Nathaniel Filardo
71db09423f CMake: add SNMALLOC_USE_CXX20 option 2021-04-22 01:28:24 +01:00
Nathaniel Filardo
80c6e95210 C++20: Add TrivialInitAtomic
C++20 does away with trivial initializers for std::atomic<T>, which means our
global pagemaps always get zeroed, sometimes after other static ctors have run
(fun fun!).  Use the new std::atomic_ref<T> when available.  Abstract all this
behind an #ifdef-ful wrapper.
2021-04-22 01:28:24 +01:00
Nathaniel Filardo
c132c86cf9 ci/README: document how to test docker images locally
While here, fix the `docker build` command: the images are named `build_${IMG}`
while the ci files are just `ci/${IMG}`, no `build_` prefix.
2021-04-21 21:49:01 +01:00
Nathaniel Filardo
7b0c38228b ci/scripts/build: allow out-of-tree builds
Specify SNMALLOC_SRC in the environment to override the default of ".." for the
source tree.
2021-04-21 21:49:01 +01:00
Nathaniel Filardo
2f3a5f7974 ci/scripts/build: Don't force C++17
Let cmake do that for us
2021-04-21 21:49:01 +01:00
Nathaniel Filardo
a949e37602 ci: move linux_x64 to Ubuntu 20.04 LTS
This brings us clang 10 and its understanding of C++20 as a standard (rather
than it being called c++2a in earlier versions).

Ubuntu folded together clang-N and clang++-N into the former, so adjust the
names of packages to be installed.
2021-04-21 21:49:01 +01:00
Nathaniel Filardo
8390a70a48 Fix static-sized alloc paths, add compilation test
The CapPtr refactoring was largely compiler guided; unfortunately, it turns out
that the static-sized alloc function is not well exercised.  As such, some type
errors and unnecessary unsafety lurked behind missing template instantiation.

Correct those and add calls to the test harness to make sure we always generate
at least one instance of each small/medium/large case.  While here, it doesn't
hurt to make sure that we call all three possible dealloc() flavors as well.
This will, if nothing else, force instantiation of the static-sized dealloc
template as well.
2021-04-20 12:17:46 +01:00
David Carlier
59d5b0b9b3 netbsd build fix.
getentropy not being guarded, providing prototype even tough we end up
 using the C++ api version.
2021-04-19 09:37:04 +01:00
Nathaniel Filardo
f037bba0a2 SP: remove pal_zero(void*, size_t)
Now that everything's over on `CapPtr`, this can go
2021-04-09 12:39:29 +01:00
Nathaniel Filardo
c673b2e0ba SP: pass CBChunk, not CBArena, down to Superslab ops 2021-04-09 12:39:29 +01:00
Nathaniel Filardo
95871ff8a1 SP: free lists and remote queues are CBAlloc
Continue tightening the screws on pointer bounds.

Notably, pointers in remote queues are bounded to the free objects.  While we
believe that something like MTE is required to make in-band metadata safe, this
is a kind of defense in depth for StrictProvenance architectures: UAF for small
and medium objects expose mostly other (free) small or medium objects and not
allocator metadata (modulo some potential aliasing when Superslabs and
Mediumslabs interconvert).  This might shift the burdon on an attacker from
simply holding a UAF pointer to having had to farm several heap pointers.

The policy of bounding remote queue pointers may make the allocator's behavior
for small objects unexpected: while initial object construction during
allocation (that is, when the free list is empty) continues to cleave out
exportable pointers from elevated pointers to internal slabs, reuse pulls from
free lists of *already-bounded* objects.  These objects are queued by the
deallocation side, of course, but these paths now include "parallel
reconstruction" of a pointer to the free object from the amplified view of the
returned pointer, rather than queueing amplified pointers and leaving
reconstruction to the allocation side.

Medium objects are possibly similarly mysterious with the added twist that
medium slabs do not store pointers but rather always cleave from their
self-reference (but their interface has always operated using pointers).
Nevertheless, pointers to medium objects end up in remote queues, so we continue
to engage in "parallel reconstruction" in the deallocation paths.
2021-04-09 12:39:29 +01:00
Nathaniel Filardo
cf50fc5e55 SP: mediumslab: reduce capptr_export calls
Mediumslabs are strung on a dllist and used to feed the allocator there.  If we
ensure that these (and the root pointer to the list itself) are already
exported, then our alloc paths can bound these to arrive at exposible pointers.

The dealloc paths, where we might want a non-exported pointer, already have one,
as they have gone through amplification to get an arena-bounded pointer.

The sole wrinkle in this plan is that we might need a pointer without platform
constraints to manipulate the memory map for page-based zeroing.  Since we have
ample room in the Mediumslab header (a few kilobytes end up being used for
padding; the curious should see b8b5f305 and 3d3b0487), just cache therein a
copy of the CBChunk-bound pointer used in Mediumslab::init() for ::alloc().
2021-04-09 12:39:29 +01:00
Nathaniel Filardo
eff76309f5 SP: bound chunks in address space 2021-04-09 12:39:29 +01:00
Nathaniel Filardo
f7821e11eb SP: LargeAlloc return CBChunk & chase consequences
Even if we opt not to bound these pointers internally (if they aren't headed out
to the user program or we later derive bounded pointers), they should still be
annotated as something other than CBArena, ensuring that we do not attempt to
use them for general amplification.
2021-04-09 12:39:29 +01:00
Nathaniel Filardo
54fec3821f SP: alloc paths: begin using CBAllocE
Begin turning the screws on bounds: pointers the allocator is about to reveal
must be annotated as CBAllocE.  Use the PAL's capptr_export and the AAL's
capptr_bound<> to get them there.
2021-04-09 12:39:29 +01:00
Nathaniel Filardo
f2f1eb33d6 SP: amplify on dealloc and query paths 2021-04-09 12:39:29 +01:00
Nathaniel Filardo
6a7e82463c SP: MemoryProviderStateMixin, AddressSpaceManager
* The AddressSpaceManager now requests address space in specified granule
  sizes and registers those allocations with an external ArenaMap.

* The DefaultArenaMap is a (somewhat erroneously named) Pagemap sparse array /
  tree for these provenance roots.  Nothing is stored on non-StrictProvenance
  architectures.

* In the Sandbox test, give an example of a different ArenaMap structure, which
  confines amplification to sandbox memory.

* Adjust some other tests to compile.
2021-04-09 12:39:29 +01:00
Nathaniel Filardo
a9722667ab SP: add ArenaMap
The ArenaMap will store our internal provenance roots.  This commit simply
introduces the data structure and does not wire it up to the rest of the tree.
2021-04-09 12:39:29 +01:00
Nathaniel Filardo
d9822036b2 SP: add bounds placeholders to message queues
Like all the annotations so far, leave these as CBArena-bounded.

However, we can start to do a little better than we were doing before: for
not-large deallocations, we know that the internal superslab pointer is
sufficiently authoritative that we can use it to get to data structures rather
than also passing an amplified pointer to the allocation in question.  This,
then, partially reverts some of the earlier changes made while plumbing
CapPtr<>s through the system.

While here, avoid quite as many void*-s in favor of Remote* or SlabNext*.
2021-04-09 12:39:29 +01:00
Nathaniel Filardo
78ab0a7937 SP: external_pointer should not leak authority
Work with high-authority pointers internally, but then copy the address onto to
the low-authority pointer originally given to us (using the same primitive as
amplification, just backwards).  This ensures that clients cannot behave
non-monotonically even if they have access to external_pointer().  That is, we
are not an amplification oracle, though we might reveal the address of an object
somewhere clients cannot otherwise access.  Notably, we might reveal if a
{Super,Medium,}Slab has changed sizeclass (or been repurposed as or from a
Largealloc), forming a covert channel for data but not capabilities.  Of course,
if the pointer provided to external_alloc() is still useful, the implied UAF in
these scenarios is still its own problem.
2021-04-09 12:39:29 +01:00
Nathaniel Filardo
268ef2c059 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).
2021-04-09 12:39:29 +01:00
Nathaniel Filardo
c5aff8ed74 SP: plumb CapPtr through cache_friendly functions
Change these functions from being void* to void* to either consuming or
producing FreeObject*-s as appropriate.
2021-04-09 12:39:29 +01:00
Nathaniel Filardo
97f508e2b3 SP: further CapPtr plumbing 2021-04-09 12:39:29 +01:00
Nathaniel Filardo
3541a0cfe1 SP: Allocator::large_alloc return CapPtr<>
Document and suppress MSVC's confusion with CapPtr<>'s constructor (the
suppression has to happen at the definition, not the use, of the constructor) in
the case of never-needs-initialization Allocator-s.
2021-04-09 12:39:29 +01:00
Nathaniel Filardo
e31751fc94 Add workaround for MSVC vs. CapPtr constructor 2021-04-09 12:39:29 +01:00
Nathaniel Filardo
d9ee19a16c SP: use CapPtr<>s in address_space, largealloc 2021-04-09 12:39:29 +01:00