StrictProvenance architectures are likely to impose additional alignment
requirements on their pointer-sized loads and stores. On the other
hand, we must use pointer-sized loads and stores wherever possible to
ensure achieve copy. Add a StrictProvenance-aware memcpy architecture
implementation.
Thanks to Matt for suggesting the trick of avoiding even thinking about
capability operations in the too-misaligned 16-31 byte cases as well as
other helpful suggestions.
Co-authored-by: Matthew Parkinson <mattpark@microsoft.com>
Although, double frees are generally caught on large allocs. This is
done very late in the process after many operations more operations have
occurred.
This change brings that check much earlier in the process.
Make it easier to justify our avoidance of capptr_from_client and
capptr_reveal in external_pointer by performing address_cast earlier.
In particular, with this change, we can see that the pointer (and so its
authority, in CHERI) is not passed to any called function other than
address_cast and pointer_offset, and so authority is merely propagated
and neither exercised nor amplified.
Remove the long-disused capptr_reveal_wild, which was added for earlier
versions of external_pointer.
* Fix pal_linux.h for older linux systems
Where MADV_FREE is not defined - replaced with MADV_DONTNEED
Where GRND_NONBLOCK is not defined in <sys/random.h> but in <linux/random.h>
* Check for linux/random.h in CMake
as __has_include seems to not be reliable
* Use CMake module CheckIncludeFilesCXX
as C language isn't enabled by default everywhere
* Move madvise flag ifdefs into constexpr for cleaner code
These pieces of metadata (specifically, the Allocator structures) are never
deallocated at the moment, so we need not consider how we might amplify these
bounded pointers back to higher authority.
Wrap the FrontendSlabMetadata with a struct that holds the Arena-bounded
authority for Chunks that the Backend ships out to the Frontend or, for
non-StrictProvenance architecture, encapsulates the sleight of hand that turns
Chunk-bounded CapPtr-s to Arena-bounded ones.
This allows us to have a single Pipe-line of ranges where we can, nevertheless,
jump over the small buddy allocator when making large allocations. This, in
turn, will let us differentiate the types coming from the small end and the
large "tap" on this Pipe-line.
Make these generic, with the SmallBuddyRange taking its cue from the parent
Range, since we're about to change them anyway and might want to vary them again
in the future.
Expose a static CapPtr<T,B>::unsafe_from() and use that everywhere instead
(though continue to allow implicit and explicit construction of CapPtr from
nullptr).
Most ranges just deal with whatever kinds of ranges their parent deal with, but
that might be Chunk- or (soon) Arena-bounded. This commit does not yet
introduce nuance, but just sets the stage.
This way, we don't have to specify a Parent when we're just interested in
Pipe-ing things together.
We could have called these inner classes Apply and left the Pipe implementation
alone, but it's probably better to call them Type and adjust the Pipe code.
* Sanity check on parameters to large buddy.
* Check commit occurs at page granularity
* Alter PAGE_SIZE usage
Using PAGE_SIZE as the minimum size of the CHUNK means that if this is
configured to 2MiB, then there is a gap between
MAX_SMALL_SIZECLASS_SIZE, and MIN_CHUNK_SIZE, and thus
we can't represent certain sizes,
* Rename to use Config, rather than StateHandle/Globals/Backend
* Make Backend a type on Config that contains the address space management implementation
* Make Ranges part of the Backend configuration, so we can reuse code for different ways of managing memory
* Pull the common chains of range definitions into separate files for reuse.
* Move PagemapEntry to CommonConfig
* Expose Pagemap through backend, so frontend doesn't see Pagemap directly
* Remove global Pal and use DefaultPal, where one is not pass explicitly.
Co-authored-by: David Chisnall <davidchisnall@users.noreply.github.com>
Co-authored-by: Nathaniel Filardo <105816689+nwf-msr@users.noreply.github.com>
This exposes a feature on Ranges to access ranges higher up the
stack of ranges. This could be useful for applying operations in the
middle of a pipeline like
object_range.ancestor<SpecialRange>().init(...);
This allows some initialisation to be added to the middle of pipeline
without breaking the current coding pattern.
It also allows for bypassing some ranges
object_range.ancestor<LargeObjectsRange>().alloc_chunk(...);
Neither are done in this commit, but both will occur in future commits.
Co-authored-by: Nathaniel Wesley Filardo <nfilardo@microsoft.com>
This commit changes the codegen for error messages for failed memcpys.
This no longer generates a stack frame and correctly tail calls the
error messages generator.
It also turns the error messages on in Release builds. This will lead
to better adoption experience.
The ranges are naturally put together with pipes. This
commit does some template magic to make the code more
readable. There should be now functional changes with
this change.
Some secure allocators check that the C++ supplied size is correct
relative to the meta-data. This adds a check to the secure version of
snmalloc to do that.
Currently a failing debug_check_empty does not provide any information.
This change allows it to print the size of the one of the allocations
that has not been freed.
If this test fails to allocate memory, that should not cause the test to
fail. The 'abort' was added previously to confirm a infrequent failure
was caused by out-of-memory causing the test to assign to nullptr.
This was confirmed in a CI run, and now the test can be made to ignore
allocation failure.