Szabolcs Nagy [Tue, 6 Sep 2022 08:08:25 +0000 (09:08 +0100)]
cheri: elf: fix SYMBOL_ADDRESS to return RX derived pointer
All symbol addresses can be derived from the RX capability of the
module (l_map_start). For RW object symbols pointer will have to
be rederived from l_rw_start.
Szabolcs Nagy [Fri, 2 Sep 2022 13:07:06 +0000 (14:07 +0100)]
cheri: elf: Use RW permissions for l_ld when needed
The dynamic section of an executable needs to be written to set the
DT_DEBUG entry for debuggers (unless the target has some other place
to store r_debug). For this reason we make l_ld writable whenever
the dynamic section is writable.
The ld.so l_ld is kept RX, since it does not have DT_DEBUG.
(Note: relocating the dynamic section is not allowed on cheri and
that's the only other reason glibc would write to it.)
This is needed now to avoid referencing abort in ld.so.
TODO: Fixing shared library profiling for capabilities requires
type fixes so capabilities are not stored into shared memory
(maybe purecap layout can match the lp64 one and then no file format
and external tooling change is required.)
TODO: Proper fix also depends on _dl_runtime_profile plt entry
TODO(pldd): cheri: elf: fix pldd to compile for purecap abi
Adjust types in the E(*) structs to support capabilities.
TODO: purecap pldd should refuse to deal with lp64 and ELF32 processes.
the code for the 32bit case should be disabled.
TODO: a correct fix requires support for all abis that can run on the
same system (purecap, lp64 and ELF32 too).
Szabolcs Nagy [Wed, 14 Sep 2022 10:25:55 +0000 (11:25 +0100)]
aarch64: morello: add dl-r_debug.h
Used internally for r_debug tests, but with the assumption that
the return value can be dereferenced, so change the prototype
and return a valid capability.
Also used in pldd, where we only support purecap abi processes.
Szabolcs Nagy [Thu, 7 Apr 2022 07:43:00 +0000 (08:43 +0100)]
cheri: elf: Setup per module RX and RW capabilities
_dl_map_segments must use capabilities, this required changes beyond
the obvious elfptr_t changes:
- Ensure map_end is derived from map_start,
- Use strict mmap bounds with MAP_FIXED: c->mapend is aligned up to
pagesize which may be out of bounds of l_map_start (covering the
load segments, but bounds are not aligned up), so use c->dataend
instead.
Propagate l_map_start and l_rw_start capabilities of ld.so and exe that
come from auxv, and ensure they are not recomputed incorrectly by ld.so.
The l_rw_range should exclude the relro region, but in libc.so and
ld.so this does not work: symbols are accessed before relro is applied
and then the permission should be writable.
Szabolcs Nagy [Thu, 20 Oct 2022 12:05:19 +0000 (13:05 +0100)]
aarch64: morello: add purecap ld.so _start code
The purecap version of aarch64 dl-start.S. Note: self relocation of
ld.so is handled by the rtld bootstrap code.
The ldso internal _dl_start still expects continuous argc, argv, envp,
auxv, so that's emulated (since the purecap ELF entry passes them in
separate registers).
Szabolcs Nagy [Fri, 15 Jul 2022 07:15:02 +0000 (08:15 +0100)]
aarch64: morello: fix ldconfig for purecap abi
Add purecap ld cache flag. Add the purecap ld.so name to known names.
Handle lib64c system library paths. And set the purecap abi flag on
cache entries.
Adjust ucontext layout for purecap ABI and add make/get/set/swapcontext
implementations accordingly.
Note: mcontext layout follows the linux sigcontext struct, in userspace
*context functions rely on the c registers stored in the extension area
and ignore the mcontext fields for x registers.
Szabolcs Nagy [Fri, 21 Oct 2022 11:35:33 +0000 (12:35 +0100)]
cheri: malloc: Ensure the mappings have RW permission
The arena allocator incrementally applies RW mprotect to a PROT_NONE
mapping. Use PROT_MAX to ensure the pointers derived from the original
mapping have RW capability permission.
Szabolcs Nagy [Mon, 28 Mar 2022 12:57:10 +0000 (13:57 +0100)]
cheri: malloc: avoid switch over uintptr_t
We should use a type that guarantees to represent all address bits.
In CHERI C this would be ptraddr_t, but we use unsigned long for now
not to cause regressions on other targets where this type is missing.
Szabolcs Nagy [Wed, 7 Jul 2021 13:21:40 +0000 (14:21 +0100)]
cheri: malloc: Disable pointer protection
Such arithmetic invalidates capabilities so this security measure does
not work for CHERI.
Note: the architecture makes it hard to corrupt pointers in malloc
metadata, but not impossible: current allocation bounds include the
metadata and capabilities are not revoked after free. These issues can
be fixed by a capability aware malloc.
Szabolcs Nagy [Fri, 18 Mar 2022 06:55:31 +0000 (06:55 +0000)]
cheri: fix invalid pointer use after realloc in localealias
This code updates pointers to a reallocated buffer to point to the new
buffer. It is not conforming (does arithmetics with freed pointers),
but it also creates invalid capabilities because the provenance is
derived from the original freed pointers instead of the new buffer.
Change the arithmetics so provenance is derived from the new buffer.
The conformance issue is not fixed.
Szabolcs Nagy [Mon, 12 Jul 2021 10:11:05 +0000 (11:11 +0100)]
cheri: fix pointer tagging in tsearch
USE_MALLOC_LOW_BIT should work for capabilities too, but we need to
ensure that pointer provenance is right: the red/black flag is
computed as uintptr_t, but with uintptr_t | uintptr_t it's not clear
which side provides the provenance.
So use unsigned int type for the flag (which is the type used in case
of !USE_MALLOC_LOW_BIT anyway), then unsigned int | uintptr_t works.
The type of RED is corrected too to match unsigned int.
Szabolcs Nagy [Tue, 1 Mar 2022 09:44:14 +0000 (09:44 +0000)]
cheri: rseq: remove const to avoid readonly permission
Using const on the definition does not work for a pure capability ABI:
the capability permissions when accessing the object will be read only.
Use a hack to hide the public declaration in the TU where the const
objects are initialized. (This should work on non-capability targets
too, but to err on the safe side only enable the hack on capability
targets.)
Szabolcs Nagy [Mon, 8 Aug 2022 08:22:44 +0000 (09:22 +0100)]
cheri: elf: add an RW capability to link_map
For each module keep an RX and an RW root capability. Use the existing
l_map_start for RX (covering all load segments) and add l_rw_start for
RW (covering all writable load segments).
For relocation processing, we also need individual RW ranges to decide
which objects need to be derived from RW and RX capabilities. In
practice most modules have exactly one RW segment and it's unlikely
that any module needs more than four distinct ranges to tightly cover
the RW mappings.
Only added on CHERI targets so always has to be used behind ifdef.
Szabolcs Nagy [Thu, 20 Oct 2022 11:18:26 +0000 (12:18 +0100)]
aarch64: morello: add purecap start code
Written in C so the self relocation code in crt1.o is easier to
maintain.
The purecap ELF entry is special: passes separate argc, argv, envp,
auxv in registers instead of on the stack.
For each module there will be separate RW and RX capabilities that
cover the writable and all load segments respectively. The relative
reloc processing code is prepared for such separate capabilities.
The static link detection (for self relocation) is not ideal, it
relies on relocations that don't work in PIC, so it is ifdefed out
for Scrt1.o. (Currently adrp of undefined weak symbol is not fixed
up by the linker to be 0 so we use movz to detect the presence of
__rela_dyn_start.)
Szabolcs Nagy [Fri, 21 Oct 2022 11:10:11 +0000 (12:10 +0100)]
aarch64: morello: define PROT_MAX
Specifies the prot flags a mapping may gain via mprotect or MAP_FIXED.
On CHERI targets this is used to get capability with more permissions
than the original mmap protection would imply.
Szabolcs Nagy [Fri, 15 Jul 2022 13:10:53 +0000 (14:10 +0100)]
aarch64: morello: fix missing variadic argument in fcntl
In fcntl va_arg is currently used even if the caller did not pass
any variadic arguments. This is undefined behaviour and does not
work with the Morello purecap ABI, so use a helper macro.
When the argument is missing, the result of the helper macro is
arbitrary as it will be ignored by the kernel, we just have to
ensure it does not cause a runtime crash.
Szabolcs Nagy [Fri, 15 Jul 2022 18:33:23 +0000 (19:33 +0100)]
TODO(gcc): cheri: work around a gcc bug in _dl_setup_stack_chk_guard
morello purecap gcc in some cases inlines 16byte memcpy as a capability
load, which is wrong if the source or dest may be unaligned.
stack guard only needs random for the address portion since only that
part is compared, so 8 byte is enough with 64 bit addresses, but the
current code is only right on little endian systems.
Szabolcs Nagy [Fri, 11 Jun 2021 11:52:26 +0000 (12:52 +0100)]
cheri: headers: Define {u}intptr_t and {u}intcap_t for CHERI
The CHERI pure capability programming model for C requires special
definition of {u}intptr_t.
Only the pure capability model is supported for hosted compilation,
but for freestanding compilation there is limited support for other
(hybrid capability) programming models too, which require new
{u}intcap_t type definitions.
Szabolcs Nagy [Tue, 26 Apr 2022 14:29:04 +0000 (15:29 +0100)]
aarch64: morello: Use separate lp64 and morello sysdep directories
Provide separate directories for lp64 and purecap abi related sysdep
functionality.
purecap may be better name than morello, but we started with morello
and that is more future compatible with alternative cheri-like
extensions on top of aarch64.
Szabolcs Nagy [Mon, 26 Jul 2021 19:31:38 +0000 (16:31 -0300)]
libio: adjust _IO_FILE / _IO_FILE_complete for 128 bit pointers
The size of the reserved space has to be adjusted because it underflows
with 16 byte pointers. With the new value there should be enough space
for 2 more pointers in the struct on CHERI targets.