Commit Graph

788 Commits

Author SHA1 Message Date
Istvan Haller
2ef1eea3ba Improved the ability to extend GlobalState for custom Backend implementations 2021-08-05 13:58:53 +01:00
Matthew Parkinson
81bf341732 XOR encoded next_object
This commit adds a simple XOR encoding to the next_object pointer in
FreeObjects.  This removes the trivial way of getting hold of a physical
address from the system by observing the free list pointers in
deallocated objects.
2021-07-26 15:32:32 +01:00
Matthew Parkinson
b69505fc5d Make address space manager use pagemap for next pointers (#356)
* Make address space manager use pagemap for next pointers

The address space manager uses the pagemap entry to form linked lists of
unused address space above MIN_CHUNK_SIZE.  It continues to use
references in the block below that threshold.

In the CHECK_CLIENT mode this makes it hard to corrupt the ASM as only
meta-data uses allocations below MIN_CHUNK_SIZE from the ASM. This
allocations will be protected with guard pages by the backend.

* address_space_core: use FreeChunk struct

Purely stylistic, NFCI.  This hides some somewhat gnarly reinterpret_cast-s in
favor of more, but hopefully less gnarly, casts elsewhere.

* Apply suggestions from code review

Co-authored-by: Nathaniel Wesley Filardo <nfilardo@microsoft.com>
2021-07-23 15:09:30 +01:00
Nathaniel Wesley Filardo
84a5fb9450 Correct REMOTE_MIN_ALIGN
Take the maximum of...

* CACHELINE_SIZE (for performance)

* next_pow2(NUM_SIZECLASSES + 1) so that, when the pagemap points to a Remote,
  the (small) size class stuffed in the bottom bits can be removed by alignment

* next_pow2(NUM_LARGE_CLASSES + 1) so that, when the pagemap isn't pointing to
  a Remote, when the associated chunk is (part of) a large allocation, aligning
  the Remote* results in 0.

The last of these conditions will almost never be the deciding factor, as there
are generally many more small size classes than large ones, but it shouldn't
hurt to be safe.
2021-07-23 13:51:39 +01:00
Matthew Parkinson
0cfa8f2cff Remove globalconfig.h includes. 2021-07-23 10:21:27 +01:00
Matthew Parkinson
d6bae72b20 Improve debugging for fixed_region 2021-07-23 07:23:35 +01:00
Matthew Parkinson
d965ab2645 Print stack traces for segfault
Trap the segfault signal, and call the platform error.  In most cases
for CI this will print a stack trace.
2021-07-23 07:23:35 +01:00
Matthew Parkinson
529b90b01b Default some statistics 2021-07-23 07:23:35 +01:00
Matthew Parkinson
e1ef8665a8 Add protection to meta-data
The meta-data in the CHECK_CLIENT mode is allocated from its own areas,
where most of the pages have been disabled, and the location within this
range is randomised.

This protects from trivial OOB read/write hitting the meta-data.
More complex controlled offsets are also mitigated due to the sparse
level of pages being turned on (i.e. not PROT_NONE).
2021-07-23 07:23:35 +01:00
Matthew Parkinson
6b53c29600 Fix typo. 2021-07-23 07:23:35 +01:00
Matthew Parkinson
b5e89805c8 Merge pull request #353 from mjp41/snmalloc2
Merge master into snmalloc2 branch
2021-07-21 11:14:06 +01:00
Matthew Parkinson
c1001ae7a4 Merge remote-tracking branch 'origin/master' into snmalloc2 2021-07-21 09:58:22 +01:00
Matthew Parkinson
01259b0248 Make tests single test at a time for Debug. 2021-07-21 09:36:06 +01:00
Matthew Parkinson
0b7929327a Add errors for failing to initialise the system. 2021-07-21 09:36:06 +01:00
Matthew Parkinson
8a8669f957 Add randomised start to pagemap layout
The pagemap contains a lot of important data.  This commit makes the
checked mode overallocate, and then start the pagemap at a random
offset within this range.
2021-07-21 09:36:06 +01:00
Matthew Parkinson
5d0ae71423 Remove at_least
The Pal was providing policy for overallocating a block of memory to
achieve alignment make that part of the backend.
The backend should be responsible for layout policy.
2021-07-21 09:36:06 +01:00
Matthew Parkinson
9df0101dfd Enable guard pages in CHECK_CLIENT
Change the behaviour to use PROT_NONE for reservations in CHECK_CLIENT
mode.  This means that we only provide access once data is actually
being used.
2021-07-21 09:36:06 +01:00
Matthew Parkinson
02d2ab8f7e Pagemap requires registration of used space
This PR exposes a pagemap interface to specify ranges that are being
used. The overall invariant is that any memory in the address space
manager has the pagemap committed. This means that individual operations
do not need to commit entries.

This is important for Windows that does not support lazy commit.  It is
also important if we want to PROT_NONE most of the pagemap to reduce the
risk of memory safety issues getting access to the pagemap.

There are minor changes to test to pull memory directly from the Pal.
There are also bug fixes in the pagemap tests.
2021-07-21 09:36:06 +01:00
Matthew Parkinson
da01d5b4ca Remove address space usage from Pagemap.
The pagemap allocates it self directly either from

  * the original fixed address range it is supplied, and returns the
    remaining space after the pagemap is removed; or
  * directly allocated from the PAL without using the address space
    manager.

This change in layering is required for the next commit, which imposes
the invariant that the pagemap has been committed for all spaced managed
by the address space manager.
2021-07-21 09:36:06 +01:00
Matthew Parkinson
686cb3321f Use SFINAE for varying API on pagemap 2021-07-21 09:36:06 +01:00
Matthew Parkinson
8b1ffbc166 Expose reserve_at_least in all Pals 2021-07-21 09:36:06 +01:00
Nathaniel Wesley Filardo
2ba0de76b3 mem/metaslab: use uintptr_t alignment functions
It is UB to offset from `nullptr` (except perhaps with a 0 offset).  Apparently
clang is able to use this to reason, given `void* p`, that comparing
`__builtin_align_down(p, x)` against `handle.fake_large_remote` (i.e., a `static
inline constexpr` `nullptr`) must be the same as comparing `p` itself against
`nullptr`.

In `MetaEntry`'s constructor, converting the provided `RemoteAllocator*` to
`uintptr_t` before offsetting avoids the UB.  (While here, don't use
`address_cast()`, as `address_t` will, on CHERI, be `ptraddr_t` and not
`uintptr_t`.)

Doing the alignment in `get_remote` at `uintptr_t` before casting to
`RemoteAllocator*`, rather than converting and then aligning, prevents the
reasoning above from eliminating the alignment.
2021-07-20 14:42:53 +01:00
Nathaniel Wesley Filardo
3e70963772 ds/address: add some uintptr_t manipulation functions 2021-07-20 14:42:53 +01:00
Schrodinger ZHU Yifan
704bc423cc refact(cmake): change mcx16 detection to facilitate cross compiling (#351)
* refact(cmake): change mcx16 detection to facilitate cross compiling

Signed-off-by: SchrodingerZhu <i@zhuyi.fan>
2021-07-20 08:59:44 +01:00
Matthew Parkinson
b501da69db Implements protection on remote messages queues
This extends the freelist protection to the remote message queues. They
effectively perform doubly linked list entries for the message queue
with the enqueue operation first linking in the previous pointer, and
then then atomically setting the next.  This ensures that the visible
states always satisfy the invariant that the forward and backward
pointers are correct for any visisble object.

There is a key_global that is used for all remote deallocations. The
remote cache uses the same protection to build the temporary lists
before forwarding to the next allocator.

The mpscq is integrated into the remoteallocator as it is no longer
a reusable datastructure, but a special purpose implementation.
2021-07-19 12:57:03 +01:00
Matthew Parkinson
c58b0a5f4d Removes a register copy from x86 codegen. 2021-07-19 12:57:03 +01:00
David Chisnall
e60dd3dc95 Don't depend on <entropy> if we don't need it. (#350)
Including <entropy> brings in <iostream>, which breaks the in-libc
build.
2021-07-19 11:40:27 +01:00
Matthew Parkinson
de8ef3efc7 Cleaner implementation of signed pointers. (#347)
* Cleaner implementation of signed pointers.

This encodes a back pointer in each node.  The back pointer is stored
in an encoded form so that it is hard to corrupt and trick the allocator
into following incorrect pointers.

This changes the encoding from previously being a Feistel network on
the next pointer that was using the prev as part of the key, to now
effectively using a doubly linked queue, where the back pointers are
scrambled, so it is hard to forge them.

This has the positive effects of
 - Not needing to store previous while building the list, as the append
   nows, curr and next at the point of writing into next, and does not
   need an additional previous.
 - The encoding is not affecting the actual next value, so more
   instructions can be executed in parallel by the CPU.

Future extensions, store a changing key in the FreeListBuilder so it
becomes harder to try to forge the previous token.

This approach can also be applied to the remote list, and will in a
subsequent PR.  This enables the idea to be tested.

* Remove unused header.

* Apply suggestions from code review

Co-authored-by: Nathaniel Wesley Filardo <VP331RHQ115POU58JFRLKB7OPA0L18E3@cmx.ietfng.org>

Co-authored-by: Nathaniel Wesley Filardo <VP331RHQ115POU58JFRLKB7OPA0L18E3@cmx.ietfng.org>
2021-07-15 18:31:28 +01:00
Istvan Haller
d0ecba5280 Improved OEPal integration with the new snmalloc architecture (#346)
* Improved OEPal integration with the new snmalloc architecture

* Applied PR feedback
2021-07-15 15:06:47 +01:00
Nathaniel Wesley Filardo
39c2df0b56 pagemap: don't eagerly commit on LazyCommit PALs 2021-07-13 13:50:06 +01:00
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
dcd47a0449 Allow disabling the Debug-mode check in the ABA 2021-07-06 09:45:47 +01:00
David Chisnall
b598add0d1 Fix the build with GCC and libc cleanup. (#341)
GCC is a lot more picky about extern "C" definitions in namespaces than
clang and so the `friend` declaration wasn't picked up by the version of
the function declared in the `snmalloc` namespace.  Move it out to where
GCC is happy with it.
2021-07-01 11:07:31 +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