Commit Graph

158 Commits

Author SHA1 Message Date
Matthew Parkinson
72ccb23d02 Add local caching to chunk allocator 2021-10-28 14:28:36 +01:00
Matthew Parkinson
20a114cb62 Add a timer to the PAL
This adds a way to periodically pool the PAL to see if any timers have
expired.  Timers can be used to periodically provide callbacks to the
rest of snmalloc.
2021-10-28 14:28:36 +01:00
Matthew Parkinson
c1062e629e Add Madvise free to Linux layer 2021-10-28 14:28:36 +01:00
Nathaniel Wesley Filardo
342d826310 CheriBSD bugs workarounds
The correct thing to do, of course, is to fix these upstream, but that requires
understanding exactly what's wrong, and that's harder than just not tickling the
bugs.
2021-10-20 12:02:08 +01:00
Nathaniel Wesley Filardo
6ddd11faee CheriBSD/CHERI support
This adds a CHERI AAL and expands the FreeBSD PAL to cover CHERI.  It updates a
comment in ds/address.h now that there is an example architecture that
differentiates uintptr_t and address_t.
2021-10-20 12:02:08 +01:00
Nathaniel Wesley Filardo
6f79ddee31 FreeBSD RISC platforms have fewer address bits 2021-10-20 12:02:08 +01:00
Nathaniel Wesley Filardo
52a4b0c8d0 NFC: Make unsafe_capptr private, use unsafe_ptr() 2021-10-20 12:02:08 +01:00
Nathaniel Wesley Filardo
dba795ac6f NFC: move some capptr utility functions to that namespace
We'll want user_address_control_type in some particular PALs, so it can't live
in pal.h.

While here, make the spelling be capptr::is_spatial_refinement.
2021-10-20 12:02:08 +01:00
Nathaniel Wesley Filardo
9065893181 Overhaul CapPtr
* Switch to a multidimensional taxonomy.

  Rather than encoding the abstract bound states in a single enum, move to a
  more algebraic treatment.  The dimensions themselves are within the
  snmalloc::capptr_bounds namespace so that their fairly generic names do not
  conflict with consumer code.  Aliases for many points in the space are
  established outside that namespace for ease of use elsewhere.

* Introduce several new namespaces:

    * snmalloc::capptr::dimension holds each of the dimension enums

    * snmalloc::capptr holds the bound<> type itself and a ConceptBound

    * snmalloc::capptr::bounds gives convenient specializations of bound<>

    * snmalloc::capptr also has aliases for CapPtr<> itself

  All told, rather than `CapPtr<T, CBChunk>`, we now expect client code to read
  `capptr::Chunk<T>` in almost all cases (and this is just an alias for the
  appropriate `CapPtr<T, bounds<...>>` type).  When the bound<>s themselves are
  necessary, as when calling capptr_bound, we expect that they will almost
  always be pronounced using an alias (e.g., `capptr::bounds::Alloc`).

* Chase consequences.

* Prune old taxa and aliases that are no longer in use in snmalloc2.
2021-10-13 16:30:41 +01:00
Matthew Parkinson
55a7ad2d58 Introduce PalEnforceAccess
The various Pals were given different meanings in CHECK_CLIENT and
non-CHECK_CLIENT builds.  This was because it is essential
that in the CHECK_CLIENT builds access is prevented, when not requested.

This PR separates the CHECK_CLIENT concept from how the Pal should be
implemented.
2021-09-28 09:23:52 +01:00
Matthew Parkinson
b4efc40aa6 Expose notify_using_readonly
This exposes a readonly notify using, so that the underlying platform
can map the range of pages readonly into the application.  This improves
performance of external pointer on platforms that support lazy commit
of pages as it can access anything in the range.
2021-09-28 09:23:52 +01:00
Nathaniel Wesley Filardo
e212ddd0e0 Prepare for PAL address_bits 2021-09-23 15:42:53 +01:00
Nathaniel Wesley Filardo
1baf675adb PALNoAlloc should delegate more to underlying PAL 2021-09-23 15:42:53 +01:00
David Chisnall
51e75bca89 Add memcpy with bounds checks.
The memcpy implementation is not completely stupid but is almost
certainly not as good as a carefully tuned and optimised one.

Building snmalloc with FreeBSD's libc memcpy + jemalloc and with this,
each 10 times, does not show a statistically significant performance
difference at 95% confidence.  The snmalloc version has very slightly
lower median and worst-case times.  This is in no way a sensible
benchmark, but it serves as a smoke test for significant performance
regressions.

The CI self-host job now uses the checked memcpy.

This also fixes an off-by-one error in the external bounds.  This is
triggered by ninja, so we will see breakage in CI if it is reintroduced.

In debug builds, we provide a verbose error containing the address of
the allocation, the base and bounds of the allocation, and a backtrace.

The backtrace was broken by the CI cleanup moving the BACKTRACE_HEADER
macro into the SNMALLOC_ namespace.  This is also fixed.

The test involves hijacking `abort`, which doesn't work everywhere.  It
also requires `backtrace` to work in configurations where stack traces
are enabled.  This is disabled in QEMU because `backtrace` appears to
crash reliably in QEMU user mode.

For now, in the -checks build configurations, we are hitting a slow path
in the pagemap on accesses so that the pages that are `PROT_NONE` don't
cause crashes.  These need to be made read-only, but this requires a PAL
change.
2021-09-16 13:53:13 +01:00
David Chisnall
c70c23ad74 CMake cleanup. (#384)
Modernise and tidy the CMake a bit:

 - Use generator expressions for a lot of conditionals so that things
   are more reliable with multi-config generators (and less verbose).
 - Remove C as a needed language.  None of the code was C but we were
   using C to test if headers worked.  This was fragile because a build
   with `CMAKE_CXX_COMPILER` set might have checked things compiled with
   the system C compiler and then failed when the specified C++ compiler
   used different headers.
 - Rename the `BACKTRACE_HEADER` macro to `SNMALLOC_BACKTRACE_HEADER`.
   This is exposed into code that consumes snmalloc and so should be
   'namespaced' (to the degree that's possible with C macros).
 - Clean up the options and use dependent options to hide options 
   that are not always relevant.
 - Use functions instead of macros for better variable scoping.
 - Factor out some duplicated bits into functions.
 - Update to the latest way of telling CMake to use C++17 or C++20.
 - Migrate everything that's setting global properties to setting only
   per-target properties.
 - Link with -nostdlib++ if it's available.  If it isn't, fall back to
   enabling the C language and linking with the C compiler.
 - Make the per-test log messages verbose outputs.  These kept scrolling
   important messages off the top of the screen for me.
 - Make building as a header-only library a public option.
 - Add install targets that install all of the headers and provide a
   config option.  This works with the header-only configuration for
   integration with things like vcpkg.
 - Fix a missing `#endif` in the `malloc_useable_size` check.  This was
   failing co compile on all platforms because of the missing `#endif`.
 - Bump the minimum version to 3.14 so that we have access to
   target_link_options.  This is necessary to use generator expressions
   for linker flags.
 - Make the linker error if the shim libraries depend on symbols that
   are not defined in the explicitly-provided libraries.
 - Make the old-Ubuntu CI jobs use C++17 explicitly (previously CMake 
   was silently ignoring the fact that the compiler didn't support C++20)
 - Fix errors found by the more aggressive linking mode.

With these changes, it's now possible to install snmalloc and then, in
another project, do something like this:

```cmake
find_package(snmalloc CONFIG REQUIRED)
target_link_libraries(t1 snmalloc::snmalloc)
target_link_libraries(t2 snmalloc::snmallocshim-static)
```

In this example, `t1` gets all of the compile flags necessary to include
snmalloc headers for its build configuration.  `t2` is additionally
linked to the snmalloc static shim library.
2021-09-03 11:31:05 +01:00
David Chisnall
cd70a7856b Fix fallout from the merge.
- CI merge issues:
   - The malloc shim libraries are renamed.
   - CMake gets very unhappy if you don't enable the C language and
     tries to link with the C compiler instead of the C++ compiler if
     you do enable it.
   - The Ubuntu packages for QEMU install a `binfmt_misc` activator for
     PowerPC64 little-endian, but set the page size to 4 KiB.  We then
     tried to run the tests (which expect 64 KiB pages) and became very
     confused when `mmap` returned 4 KiB-aligned memory.
 - Test failures:
   - Fix all of the issues UBsan found.
     - Underflow in `pointer_offset` when used to add negative offsets.
     - `CoreAlloc`'s `LocalState` accessed on a null `CoreAlloc` pointer.
     - Out of bounds access in the sizeclass list on attempts to access
       more memory than fits in the VA space.
     -
   - There was an integer overflow in `AddressSpace` that could cause it
     to try to allocate a zero-sized object, get a null pointer, and
     then try to do something with 0 - {size of the real allocation}.
   - The malloc tests weren't setting `errno` to 0 before doing
     calling `malloc`, which should set `errno` on failure, and then
     checking that `errno` was 0.
   - Don't call `PAL::error` on PAL allocation failure, return `nullptr`.
     The PALs were inconsistent about that and the new code expects to be
     able to report address-space exhaustion.
   - The malloc checks can behave differently with 0-sized allocations
     on different platforms but were very fragile about their
     expectations.
   - The malloc test didn't report failure for all of the ways that it
     could fail and so was spuriously passing on some platforms.
   - The perf test for external pointer is currently very slow on
     Windows.  The number of loops have been reduced and a timeout added
     for the Windows CI runs.
   - The logic to capture `errno` across calls was using
     `decltype(errno)`, which on some platforms where `errno` is a macro
     evaluated to `int&` and so they captured a reference rather than
     the value and failed to reset `errno`.
   - The Apple PAL can set `errno` on `notify_using` if it's called with
     memory that was not previously passed to `notify_not_using` but was
     not adequately protected against this and so would sometimes cause
     `malloc` to set `errno` to `EINVAL`.
2021-08-06 14:00:56 +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
8b1ffbc166 Expose reserve_at_least in all Pals 2021-07-21 09:36:06 +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
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
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
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
David Carlier
85db778c39 c++20 concept: enforcing type for get_entropy implementers. 2021-05-05 07:41:51 +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
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
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
005f5787ef SP: start plumbing CapPtr<>s 2021-04-09 12:39:29 +01:00
Nathaniel Filardo
cfa996692f Correct PAL Concept
The test for NoAllocation/AlignedAllocation/neither was broken and this was
undetected until the sandbox demo came into being with its NoAllocation PAL
instance.  (Sadly, this remained undetected for so long because we can't
routinely build with C++20 because std::atomic_t<>'s initialization rules
changed in ways that make us require oodles and oodles of RAM at compile time.
This patch has been validated with -j1 on a machine with lots of RAM.)

Separately, it's possible that we end up here without `using namespace std`,
which seems like overkill.  So just use `std::size_t` ourselves within the PAL
Concept definition.
2021-04-07 18:06:18 +01:00
Nathaniel Filardo
7f841ff081 NFC: Introduce and switch to pal_zero
This wrapper will allow us to pass `AuthPtr<T,B> p` to zero() without needing to
write `p.unsafe_auth_ptr` to get to a `T*` inside.  Moreover, it will give us a
convenient point to assert that `B` is such that the pointer can be used to
manipulate the memory map (i.e. is not exported).
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
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
David Carlier
35346e72c3 Making pal_noalloc self reliant and not depending on inclusion order anymore. 2021-03-03 18:07:40 +00:00
David Carlier
a1fc509a65 pal bsd aligned build fix due to the -Wconversion flag, it is expected
an integer.
2021-03-02 09:13:25 +00:00
Matthew Parkinson
8840b386bc Make LowMemoryNotification object allocated (#281)
* Make LowMemoryNotification object allocated

This makes a separate allocation for the callback object.  This makes
it easier for different callbacks to be used.

* Add reserve_with_leftover to address_space

The address_space now supports reserving for non-power of 2 allocations
and the space that is used for rounding up is retained by the
address_space.  This means that we can more tightly pack the allocators
internal objects.
2021-02-23 14:51:44 +00:00
David CARLIER
c082a331e2 POSIX_COMMIT_CHECKS adding for apple. (#284)
* POSIX_COMMIT_CHECKS adding for apple Intel
2021-02-23 14:51:02 +00:00
Matthew Parkinson
70e5f9653d Fix BSD usage of POSIX_COMMIT_CHECKS 2021-02-19 15:34:11 +00:00
David CARLIER
ee470c535e Second batch for Mac M1 (mainly) changes proposal to make the whole
work more realibly, in both mono and multi thread contexts.
2021-02-11 20:10:05 +00:00
David CARLIER
0a868484db Mac M1 fix (#278)
The actual code works fine on the usual mac Intel however, some failures
occurs with some unit tests on the ARM h/w when zero'ing page ranges.
2021-02-09 14:38:54 +00:00
Matthew Parkinson
a3660c4069 Update to use a more efficient power of 2 check. (#274) 2021-01-27 11:58:41 +00:00