Commit Graph

39265 Commits

Author SHA1 Message Date
Szabolcs Nagy
cdba5ffdae cheri: malloc: Capability narrowing using internal lookup table
Add more cap_ hooks to implement narrowing without depending on a
global capability covering the heap.  Either recording every
narrowed capability in a lookup table or recording every mapping
used for the heap are supported.  The morello implmentation uses
a lookup table for now.

The lookup table adds memory overhead, failure paths and locks.
Recording and removing entries from the lookup table must be done
carefully in realloc so on failure the old pointer is usable and
on success the old pointer is immediately reusable concurrently.
The locks require fork hooks so malloc works in multi-threaded
fork child.
2022-10-12 14:22:03 +01:00
Szabolcs Nagy
f54124b801 cheri: malloc: Initial capability narrowing support
Public interfaces return pointers with narrow bounds, this internally
requires bumping the size and alignment requirement of allocations so
the bounds are representible.

When pointers with narrow bounds need to be turned back to have wide
bounds (free, realloc), the pointer is rederived from DDC. (So this
patch relies on DDC to cover all heap memory with RW permission.)

Allocations above the mmap threshold waste memory for alignment and
realloc often falls back to the inefficient alloc, copy, free sequence
instead of mremap or other inplace solution.
2022-10-12 14:22:03 +01:00
Szabolcs Nagy
3d959e4b0e malloc: Don't use __libc_free for tcache cleanup
__libc_free must only be used for memory given out by __libc_malloc
and similar public apis, but tcache stores a cache of already freed
pointers and itself is allocated using internal malloc apis.  Strong
double free detection in __libc_free breaks tcache_thread_shutdown,
so use a cut down version of free to reset tcache entries.
2022-10-12 14:22:03 +01:00
Szabolcs Nagy
c0a839639b cheri: elf: make sure dlpi_phdr covers the load segments
In dl_iterate_phdr phdr is the only capability passed to the callback
that may be used to derive pointers of the elf module, so ensure it
has wide bounds.
2022-10-12 14:22:03 +01:00
Szabolcs Nagy
0648dbf3a0 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.
2022-10-12 14:22:03 +01:00
Szabolcs Nagy
bbfb104b50 TODO(api): cheri: fix dl_iterate_phdr dlpi_addr
The dlpi_addr field is a capability that has value l_addr, but we can
only do this for libraries (ET_DYN) where l_addr == l_map_start,
otherwise we return l_addr which is normally 0 then (ET_EXEC) so the
caller can detect and special case it.

For now l_addr != 0 and l_addr != l_map_start case is not supported.
Note: this api may be used by the unwinder to find and read .eh_frame
data.

TODO: dlpi_addr could be address only, but requires unwinder update
and agreement about the abi.
2022-10-12 14:22:03 +01:00
Szabolcs Nagy
66e78c5b74 aarch64: morello: elf: drop unused load address computation
l_addr is no longer a capability so this is not needed.
2022-10-12 14:22:03 +01:00
Szabolcs Nagy
4d7cf069ee cheri: elf: Turn l_addr back to ElfW(Addr)
Pointers are no longer derived from l_addr, but l_map_start (RX) and
l_rw_start (RW) so it does not have to be a capability.

This also allows removing hacks where l_addr was derived from DDC.
2022-10-12 14:22:03 +01:00
Szabolcs Nagy
9c11d64d6d cheri: elf: use RX, RW capabilities to derive pointers
Instead of

  map->l_addr + offset

use

  dl_rx_ptr (map, offset)
  dl_rw_ptr (map, offset)

depending on RX or RW permission requirement.
2022-10-12 14:22:03 +01:00
Szabolcs Nagy
b35504abf0 aarch64: morello: RX, RW fixes for relocation processing 2022-10-12 14:22:03 +01:00
Szabolcs Nagy
f0e8f3667c aarch64: morello: elf: Return bounded pointer in __tls_get_addr
There is no traditional TLS support in morello that would explicitly
call __tls_get_addr, but the libc uses it internally and the returned
pointer escapes to user code.  So bound the pointers according to
the tls symbol size instead of doing so in each caller.

(Affects dlsym and dynamic TLSDESC.)
2022-10-12 14:22:03 +01:00
Szabolcs Nagy
ab0bc274aa aarch64: morello: fix DL_SYMBOL_ADDRESS
It has to return a pointer that can be dereferenced, so it must be
derived correctly from RX and RW capabilities.

Try to have tight object bounds and seal function symbols.
2022-10-12 14:22:03 +01:00
Szabolcs Nagy
9912e5c608 cheri: 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.
2022-10-12 14:22:03 +01:00
Szabolcs Nagy
e841326457 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.)
2022-10-12 14:22:03 +01:00
Szabolcs Nagy
a1d26f7b1d aarch64: morello: add D_PTR_RW
Writable version of D_PTR, required for updating GOT[1] and GOT[2].
2022-10-12 14:22:03 +01:00
Szabolcs Nagy
e6a2c4c4bb aarch64: morello: fix relative relocs
use the reloc processing code from cheri-rel.h which already
supports separate RX and RW capabilities per module.
2022-10-12 14:22:03 +01:00
Szabolcs Nagy
87dffcda13 cheri: Setup RX, RW capabilities for static linking
At least tls image access requires RX capability of the main link_map.
2022-10-12 14:22:03 +01:00
Szabolcs Nagy
a66d563c9e cheri: elf: Setup per module RX and RW capabilities
The l_map_start and l_rw_start of the ld.so and exe comes from the auxv
since they are normally mapped by the kernel.  Some generic code had to
be modified so l_map_start is propagated and not overwritten when it is
recomputed.

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.
2022-10-12 14:22:03 +01:00
Szabolcs Nagy
74085ebc1f aarch64: morello: Add elf_machine_rtld_base_setup
Use a new hook to do the rtld bootstrap map base address and root
capability setup on CHERI.

This will be needed to use separate per module RX and RW root caps.
2022-10-12 14:22:03 +01:00
Szabolcs Nagy
1b0716e083 elf: add dl_{rx,rw}_ptr to derive addresses within a map
To derive pointers within a module from the per module RX and RW caps.
2022-10-12 14:22:03 +01:00
Szabolcs Nagy
55ada9157d 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.
2022-10-12 14:22:03 +01:00
Szabolcs Nagy
11e0080cd5 aarch64: morello: Use purecap ELF entry ABI in _start
The purecap ELF entry is special: passes separate argc, argv, envp,
auxv in registers instead of on the stack.

The ldso internal _dl_start still expects continuous argc, argv, envp,
auxv, so that's emulated.
2022-10-12 14:22:03 +01:00
Szabolcs Nagy
bb624b6c43 aarch64: morello: use RW and RX capabilities for static start code
For each module there will be separate RW and RX capabilities that
cover the writable and all load segments respectively.

Prepare the relative reloc processing in static start code for such
separate capabilities.
2022-10-12 14:22:03 +01:00
Szabolcs Nagy
8d2bab6e17 cheri: change __libc_start_main prototype
The prototype of __libc_start_main is changed to

  void
  __libc_start_main (int main (int, char **, char **, void *),
                     int argc, char **argv, char **envp, void *auxv,
                     void rtld_fini (void), void *sp);

so envp is passed down separately and the unused init, fini args are
dropped.
2022-10-12 14:22:03 +01:00
Szabolcs Nagy
d5f9769d53 aarch64: morello: rewrite start code in C 2022-10-12 14:22:03 +01:00
Szabolcs Nagy
009e1fd306 aarch64: morello: remove ELF_MACHINE_START_ADDRESS
The start address (l_entry) is now a capability so no need to fix it.
2022-10-12 14:22:03 +01:00
Szabolcs Nagy
a3085f72f8 cheri: elf: make l_entry a capability
Previously the entry address was fixed up to be a capability before
using it so l_entry could be ElfW(Addr), but the code is simpler and
more consistent if l_entry is a capability throughout:

The AT_ENTRY auxv entry is specified to be a capability and a number
if internal l_entry usage is simpler if it is elfptr_t.
2022-10-12 14:22:03 +01:00
Szabolcs Nagy
456f4dd6e5 TODO: cheri: elf: Add new AT_* auxv types
Used for purecap ABI.

TODO: squash into
091bcf0e1c cheri: elf: Add new a_type entries
2022-10-12 14:22:03 +01:00
Szabolcs Nagy
a2d8296886 TODO: drop unused u64 reloc addr from lazy relocs
squash into
3eb1c569eb TODO(l_addr): aarch64: morello: dynamic linking support
2022-10-12 14:22:03 +01:00
Szabolcs Nagy
73f47b6560 TODO: aarch64: morello: fix abs sym reloc
TODO: squash into
3eb1c569eb TODO(l_addr): aarch64: morello: dynamic linking support
2022-10-12 14:22:03 +01:00
Szabolcs Nagy
bfc66c9896 TODO: cheri: elf: turn back to addresses: l_map_end, l_text_end, l_relro_start
TODO: squash into
51fe1e15ed TODO(incomplete): cheri: rtld: more elfptr_t in linkmap struct
2022-10-12 14:22:03 +01:00
Szabolcs Nagy
284e4f1755 aarch64: morello: update HWCAP2_MORELLO value
Unfortunately this will keep changing during the development
as upstream linux did not want to reserve a bit for morello.
2022-10-12 14:22:03 +01:00
Szabolcs Nagy
afbfdd28bd TODO(uapi): narrow capability in mmap and mremap
This is a temporary workaround.

length is rounded up to pagesize and don't use exact bound (bounds
will be larger if exact value is not representable).

TODO: kernel should do this
2022-10-12 14:22:03 +01:00
Szabolcs Nagy
c3d2d246c5 static: glibc-bug: NL_CURRENT_INDIRECT is broken so disable it
nl_langinfo_l ignores its locale argument with NL_CURRENT_INDIRECT
which is wrong when that argument does not match the current thread's
locale.

upstream glibc is not tested with static linking so this is not found.
2022-10-12 14:22:03 +01:00
Szabolcs Nagy
94f15a4231 TODO: cheri: printf: fix unused variable warning
warning happens in non-purecap build.

TODO: squash into original cheri printf change
2022-10-12 14:22:03 +01:00
Szabolcs Nagy
cb2ecefc21 cheri: use getauxptr in iconv/tst-gconv-init-failure test
On CHERI targets getauxval cannot return a valid pointer.
2022-10-12 14:22:03 +01:00
Szabolcs Nagy
85c6eba32a Fix OOB read in stdlib thousand separator handling
__correctly_grouped_prefixmb only worked with thousands_len == 1,
otherwise it read past the end of cp or thousands.

Avoid OOB access by considering thousands_len when initializing cp.

On morello with strict bounds checking this fixes

FAIL: stdlib/tst-strtod4
FAIL: stdlib/tst-strtod5i

both of which set cs_CZ.UTF-8 locale that has 3 byte thousands_len.
2022-10-12 14:22:03 +01:00
Szabolcs Nagy
059dd1983c elf: Fix _dl_debug_vdprintf stack buffer underflow
When printing numbers the alloca buffer size did not consider the
optional width parameter for padding. The width is used e.g. by
_dl_map_object_from_fd which passes '(int) sizeof (void *) * 2'
which can be larger than the buffer size on systems where
sizeof (void *) >= 2 * sizeof (unsigned long).  But even if large
width is not used currently it is better to handle it to avoid
surprises.
2022-10-12 14:22:03 +01:00
Szabolcs Nagy
ed157fcccd Fix missing NUL terminator in stdio-common/scanf13 test
sscanf is only defined on nul terminated string input, but '\0' was
missing in this test which caused _IO_str_init_static_internal to
read OOB on the stack when computing the bounds of the string.
2022-10-12 14:22:03 +01:00
Szabolcs Nagy
fbc8167346 Fix malloc/tst-scratch_buffer
The test used scratch_buffer_dupfree incorrectly:

- The passed in size must be <= buf.length.
- Must be called at most once on a buf object since it frees it.
- After it is called buf.data and buf.length must not be accessed.

All of these were violated, the test happened to work because the
buffer was on the stack, which meant the test copied out-of-bounds
bytes from the stack into a new buffer and then compared those bytes.

Run one test and avoid the issues above.
2022-10-12 12:54:07 +01:00
Szabolcs Nagy
37cfa707b0 Fix elf/tst-tls20 stack OOB access
Off-by-one error found on morello with strict stack bounds.
2022-10-12 12:54:07 +01:00
Szabolcs Nagy
00f9cd1a70 Fix off-by-one error in iconv/tst-iconv-mt
The iconv buffer sizes must not include the \0 string terminator.
(When \0 cannot be part of a valid character encoding glibc iconv
would copy it to the output as expected, but then later the explicit
output termination with *outbufpos = '\0' is out of bounds.)
2022-10-12 12:54:07 +01:00
Carlos Eduardo Seo
2f3bf4cf63 TODO(drop): aarch64: morello: CPU feature detection for Morello
Initial detection of Arm Morello architecture from the HWCAP2 bit and CPU
identification from MIDR_EL0.

TODO: not needed?
- lp64 does not have to detect
- purecap can assume morello
2022-08-05 19:45:19 +01:00
Szabolcs Nagy
ccce788403 TODO(gprof): aarch64: morello: add gprof profiling support to asm
Assembly prologue code with mcount call for gprof instrumentation.

TODO: untested, likely needs further runtime updates too.
2022-08-05 19:45:19 +01:00
Szabolcs Nagy
5ef98a9900 TODO(sprof): cheri: disable profiling shared libraries
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
2022-08-05 19:45:19 +01:00
Szabolcs Nagy
a8989aef06 TODO(audit): aarch64: morello: add _dl_runtime_profile entry
Required for LD_AUDIT PLT hooks and shared library profiling.

incomplete, untested.

TODO: needs La_aarch64* layout definition for morello
TODO: needs to save c9 for vararg abi
2022-08-05 19:45:19 +01:00
Carlos Eduardo Seo
7f9c78bc3a 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).
2022-08-05 19:45:19 +01:00
Carlos Eduardo Seo
7dac60585d cheri: Update libc.abilist for getauxptr
Updates libc.abilist files for getauxptr to version 2.37.
2022-08-05 19:45:19 +01:00
Carlos Eduardo Seo
6cca02f732 cheri: elf: Fix tst-auxv for Morello 2022-08-05 19:45:19 +01:00
Carlos Eduardo Seo
2b9e393156 TODO(api): cheri: misc: Implement new function getauxptr for CHERI capabilities
New function to return values from the auxiliary vector as
capabilities. This is the same as implemented by other C libraries.

TODO: agree about exact semantics across libcs
2022-08-05 19:45:19 +01:00