Commit Graph

530 Commits

Author SHA1 Message Date
Nathaniel Filardo
a1f17e6060 Mediumslab: pre-factor init() to take explicit self 2021-04-06 16:25:57 +01:00
Nathaniel Filardo
d1b2522a10 Remove stale get_slab
Everything seems to be using the `Metaslab::get_slab` form instead
2021-04-06 16:25:57 +01:00
Nathaniel Filardo
88150b497f NFC: style-correct allocslab #include 2021-04-06 16:25:57 +01:00
Matthew Parkinson
52a1a9cce1 Changes to OE Pal. 2021-04-06 14:09:18 +01:00
Matthew Parkinson
0377fd88d4 Improve BSDs support. 2021-04-06 14:09:18 +01:00
Matthew Parkinson
5419e58633 Add random to Open Enclave Pal 2021-04-06 14:09:18 +01:00
Matthew Parkinson
cc5f1cfe9f Expose entropy on POSIX platforms
This provides a common definition for many POSIX platforms. It
can be disabled.
2021-04-06 14:09:18 +01:00
Matthew Parkinson
6daa261161 Expose Entropy on Windows 2021-04-06 14:09:18 +01:00
Matthew Parkinson
f15dc6ee2e Expose Entropy
Define various parts of random that can be used to make the layout of
memory more random.  Thread this through the allocator.

Expose the concept as part of the Pal. Subsequent commits will expose
that on different platforms.
2021-04-06 14:09:18 +01:00
Nathaniel Filardo
c5b65d07b8 FreeObject: hide harder from the compiler, tweak types
On CHERI, the compiler will always issue a warning for
`reinterpret_cast<T*>(ptraddr_t)` and similar expressions, and of course, if the
compiler can see far enough into the types, the presence of `if constexpr` will
not save us.  Therefore, lift the conditional out to two definitions of
`FreeObject::encode` using `std::enable_if_t` to gate which is used.
2021-03-26 11:43:06 +00:00
Matthew Parkinson
afc6283e01 Threshold freelist wakeup
When a slab has been fully allocated, then we no longer
check it has entries until something returns an allocation to this slab.
However, it is possible that only a single allocation is available, and
then we can end up frequently on the slow path.

This change only considers free lists that cover at least 1/8 of a slab.
This means that we will hit the slow path less frequently.  This also
means that the randomisation changes will have more entropy: with a
single element free list there is only one order.

For large small sizes it can still be a single element, as 1/8 is of the
slab capacity is below 1. We max out the trigger at 31 elements to
reduce unneeded wasted space.
2021-03-25 12:04:36 +00:00
Matthew Parkinson
578abd8db4 Randomise slab allocation pattern (#304)
The slab allocation pattern is randomised based on the deallocation
pattern.  This achieved by using two queues to enqueue free elements
onto.  We pick "randomly", which queue to add to, and then when we take
the free_queue to use, we splice the two queues together.
2021-03-24 16:12:22 +00:00
Nathaniel Filardo
6442f4edd8 NFC: make Superslab interfaces static
As with 4f6cf8cb40, this will let us annotate
the explicit pointers
2021-03-24 11:55:05 +00:00
Nathaniel Filardo
e5a94ed902 NFC: constexpr some subexpressions in ds/bits
MSVC throws warnings for things that could be but aren't constexpr.
2021-03-24 11:55:05 +00:00
Matthew Parkinson
63f231f484 Bug fix for superslab meta-data (#302)
* Replace time measuring macro

The DO_TIME macro was used originally to get performance numbers. The
macro makes tests hard to debug. This commit replaces it with a proper
C++ class with destructor.

* Bug fix

If the superslab meta data is large, then the calculation for the
sizeclasses that could use the short slab was incorrect.  This fixes
that calculation.

Co-authored-by: Nathaniel Wesley Filardo <nfilardo@microsoft.com>
2021-03-23 12:42:11 +00:00
Matthew Parkinson
04a185e634 Remove allocated field from Metaslab
The metaslab contains a field specifying how many elements have been
allocated.  As the code has evolved this field has now always become
the maximum capacity of the slab for the sizeclass.

This commit looks up this value based on the sizeclass, and removes the
field from the slab's metadata.
2021-03-22 13:07:57 +00:00
Matthew Parkinson
d56a99a747 Remove USE_MEASURE
The initial performance monitoring for snmalloc used timing of small
operations to guide the design. This feature has not been maintained or
used for several years.

This commit removes the feature.
2021-03-21 19:00:54 +00:00
Matthew Parkinson
ca1540c0d9 Remove allow_reserve feature
This was original designed for Project Snowflake to enable a careful
interoperation between an allocator and the thread suspend behaviour in
.NET.

This feature is not being tested or used by any current project.  This
form of interop would be better served by designing a special Pal to
interop with the CLR if this is ever needed.

This commit removes the feature.
2021-03-21 19:00:54 +00:00
Matthew Parkinson
fd7b040823 Align wrapper for array. 2021-03-19 20:11:15 +00:00
Matthew Parkinson
8824622136 Better reciprocal division and modulus.
The previous reciprocal division branch on the prime that the sizeclass
was constructed from. All sizeclasses can be represented as
  2^n * {1,3,5,7}
This lead to a very small table, but some work to calculate the
appropriate shifts and multiplications to implement reciprocal division.

This commit uses a completely uniform representation for every
sizeclass using a lookup table.  Due to the precise ranges that we query
the modulus and rounding on, we can do this much more efficiently.

The func-release-rounding exhaustively tests all the queries we are
interested in.
2021-03-19 20:11:15 +00:00
Nathaniel Filardo
486ef10c21 NFC: bump pointers have just one associated Slab
Rather than ::get()-ing the `Superslab` and `Slab` for each object we just
created from the bump pointer, recognize that these objects necessarily come
from the same `Slab` (and so the same `Superslab`).  In the eventuality of
CHERI, this means we'll amplify once per bump pointer, not once per created
object.
2021-03-19 15:17:56 +00:00
Nathaniel Filardo
1549e40705 NFC: cdllist: some residual pointer wrapper violence
Missed this the last time around
2021-03-19 15:17:56 +00:00
Nathaniel Filardo
c5e08573bf NFC: prepare RemoteCache API for amplification
When post()-ing the RemoteCache to message queues, we push an entire bucket
onto a remote allocator's incoming queue (specifically, the allocator owning
the front Remote in the bucket we're moving).  In order to do that, we need to
exceed the bounds of the Remote allocation and reference its Allocslab header
(to get the ->message_queue).  On StrictProvenance architectures, this will
require that we amplify the head Remote* and then engage in some pointer math.

While Remotes contain the address of the message_queue as the allocator's
identity, this may not be a pointer, just an address, and may have undergone
obfuscation anyway.
2021-03-19 15:17:56 +00:00
Nathaniel Filardo
5938f0b5a6 NFC: add align_{down,up}<size_t>(address_t) 2021-03-19 15:17:56 +00:00
Nathaniel Filardo
ebc02a141e NFC: MPMCStack: prepare for pointer wrappers 2021-03-19 15:17:56 +00:00
Matthew Parkinson
ed615eade9 Refactor checks to improve codegen. 2021-03-19 11:28:39 +00:00
Matthew Parkinson
0983f1837b Alternate allocation pattern 2021-03-19 11:28:39 +00:00
Matthew Parkinson
50f412157f Protect free list pointers stored in object space
Free list pointers can be exploited by attackers. This commit implements
a simple encoding scheme to detect corruption of the pointers.  This can
be used to detect UAF and double free.

This does not currently address anything for Medium or Large
allocations.  It also does not address cross thread deallocations.

Co-authored-by: Nathaniel Wesley Filardo <nfilardo@microsoft.com>
2021-03-19 11:28:39 +00:00
Nathaniel Filardo
414be336f5 NFC: mpscq: prepare for pointer wrappers 2021-03-16 09:29:19 +00:00
Nathaniel Filardo
93024a2471 NFC: dllist: prepare for pointer wrapping 2021-03-16 09:29:19 +00:00
Nathaniel Filardo
1d1b013d85 NFC: cdllist: prepare for pointer wrappers 2021-03-16 09:29:19 +00:00
Nathaniel Filardo
73b86e6dff NFC: Introduce skeletal ds/ptrwrap.h
This lets us go ahead and land several preparatory commits without waiting for
the real AuthPtr<> types to show up.
2021-03-16 09:29:19 +00:00
Nathaniel Filardo
cbab7a3455 NFC: pointer_offset* functions always return void*
This requires that the caller perform the cast on the output rather than the
input, which is a little closer to the truth.  Shuffle some casts into the right
position.
2021-03-16 09:29:19 +00:00
Nathaniel Filardo
f295a3f191 alloc: de-static external_pointer
Like alloc_size, this will require amplification internally.

This patch also restores performance to the status quo ante; Clang can once
again see enough to generate the same code as it did before de-static-ing
alloc_size.
2021-03-16 09:29:19 +00:00
Nathaniel Filardo
1042fc908a alloc: de-static alloc_size
We're going to need to amplify the pointer and that's going to require access
to our AddressSpaceManager, which we only get non-statically through our
LargeAlloc.

This patch unto itself makes the world slower, perhaps because Clang can't see
the certainty of aliasing of the static and non-static paths to the same
structure.  However, when we also de-static external_pointer, that goes away and
things return to the status quo ante.
2021-03-16 09:29:19 +00:00
Nathaniel Filardo
c9588655b0 NFC: alloc_size s/size/chunkmap_slab_kind/
While here, SNMALLOC_ASSERT() that large allocs end up with sensible slab kind
values.
2021-03-16 09:29:19 +00:00
Nathaniel Filardo
08344cfa94 NFC: external_pointer s/size/chunkmap_slab_kind/
While here, SNMALLOC_ASSERT() that large allocs end up with sensible slab kind
values.
2021-03-16 09:29:19 +00:00
Nathaniel Filardo
4f6cf8cb40 NFC: make Slab, Mediumslab interfaces static
Going forward, this gives us explicit pointers with which to carry bounds
annotations.  Otherwise, assuming AuthPtr overloads operator->, a OOP-style call
like

    AuthPtr<Slab, Bounds> slab;
    slab->foo()

will create a `Slab* this` within the body of `Slab::foo`, leaving it unable to
see or propagate the Bounds annotation.  If it invokes callees that expect
`AuthPtr` arguments, it will therefore have to fabricate new `Bounds` unsafely.
2021-03-16 09:29:19 +00:00
Nathaniel Filardo
49fefc3f83 NFC: introduce SlabNext type for intra-small-slab free pointers
Mostly cosmetic, but eliminates some void*-s and makes intention clearer.
2021-03-16 09:29:19 +00:00
Nathaniel Filardo
db0ca64ff3 NFC: Add an AAL Concept, too
While here, pull out some constants to their own header.  Eventually we'll
want to match on AalFeatures in the AAL Concept.
2021-03-16 09:29:19 +00:00
Nathaniel Filardo
a6d18f842a NFC: Mark AAL methods noexcept 2021-03-16 09:29:19 +00:00
Nathaniel Filardo
263e9562c0 NFC: Feed Pagemap its primitive allocator as template arg
This will let us use Pagemaps further down the dependency stack (specifically,
we're going to want a Pagemap inside the AddressSpaceManager) by letting us
manually tie the knot rather than rely on GlobalVirtual and
default_memory_provider() being defined by the time we want a Pagemap.
2021-03-16 09:29:19 +00:00
Nathaniel Filardo
83b72722cf NFC: Split InvalidPointer out of ds/dllist.h
This lets us use Pagemaps without requiring dllists in scope
2021-03-16 09:29:19 +00:00
Nathaniel Filardo
addd98e6db NFC: Introduce Purpose parameter for PageMap wrappers
Presently, GlobalPagemap and ExternalPagemap discriminate only by type.  If it
ever happened that multiple PageMap consumers instantiated the same type using
these wrapper, they'd be conflated in the symbol table.  Therefore, add an
optional Purpose parameter that will be expanded into the symbols (but serves no
other purpose).
2021-03-16 09:29:19 +00:00
Nathaniel Filardo
6250428c3d NFC: Further disentangle chunkmap and pagemap
- Make GlobalPagemapTemplate and ExternalGlobalPagemap generic in the type of
  the pagemap they're encapsulating.

  We're going to want to use these for other kinds of pagemaps in the near
  future.

- Rename snmalloc_pagemap_global_get to snmalloc_chunkmap_global_get.

- Rename GlobalPagemap to GlobalChunkmap.
2021-03-16 09:29:19 +00:00
Nathaniel Filardo
8da12f5af8 NFC: tests: size_t and uintptr_t are not interchangable 2021-03-16 09:29:19 +00:00
Nathaniel Filardo
960733099b POSIX PAL: reset errno on failing mmap()s for zeroing
We try, if the region to be zeroed is sufficiently aligned, to use mmap to swap
out pages for zeros.
2021-03-16 09:29:19 +00:00
Matthew Parkinson
59edf294d0 Move link out of object space.
The link object was previously stored in a disused object.  This is
good for reducing meta-data, but if we want to reduce the meta-data
corruption potential, then this is not a good design choice.

This commit moves it into the Metaslab.
2021-03-15 13:28:03 +00:00
Matthew Parkinson
e7dce55f19 Move is_start_of_object into Metaslab. 2021-03-15 13:28:03 +00:00
Matthew Parkinson
1d12e34b9f Fix for Mac OS X 10.14
The dllist was able to call delete during a destructor if a template
flag was set.  This flag is never set in snmalloc, and was included
to enable reuse in another project.  This was triggering an error on
older mac builds.

This PR calls a templated function when the DLList is destructed.  Hence
other projects can specify the `delete` behaviour if required.
2021-03-09 15:07:21 +00:00