about summary refs log tree commit diff
Commit message (Collapse)AuthorAgeFilesLines
* cheri: malloc: exact capability check in free/realloc arm/morello/mainSzabolcs Nagy2023-04-053-37/+54
| | | | | | | | | | | | Capability narrowing uses a lookup table from an address to the internally used wide capability. Keep the narrow capability in the table instead of just the address and check it. This allows free and realloc to check their input and only accept capabilities exactly matching what was returned by malloc. When a user adds restrictions on top of malloc returned capabilities (e.g. narrower bounds), realloc could bypass those restrictions when it simply looked up the internal wide capability for the address.
* TODO(vdso): aarch64: morello: disable VDSO loadingSzabolcs Nagy2023-02-211-0/+21
| | | | | | | | Once the kernel starts providing a VDSO, old binaries should continue to work (without using the new VDSO). For this we set the vdso to 0 independently of auxv, otherwise glibc attempts to load it even if the target has no vdso symbols specified and the load can crash since the setup code is not purecap compatible.
* TODO(uapi): aarch64: morello: update HWCAP2_MORELLOSzabolcs Nagy2023-02-021-1/+1
|
* cheri: malloc: Use memcpy for obstack internal copySzabolcs Nagy2023-01-061-28/+3
| | | | | | | | | Internally obstack used a backward word at a time copy. This can be an aliasing violation and likely slower than memcpy on most targets. The code is a badly written memcpy with performance issues such as the h->object_base indirection cannot be hoisted out of the loop. On CHERI architecture this is needed for copying pointers correctly.
* cheri: malloc: Fix realloc to copy all relevant bytesSzabolcs Nagy2022-12-192-2/+21
| | | | | | | | | | New code in realloc that handles when new allocation is needed for alignment reasons (for capability narrowing) used the wrong size in memcpy (size was off by SIZE_SZ unless memory tagging was enabled) and used wrongly tagged pointer for untagging the old memory. Due to this bug realloc sometimes failed to copy tail bytes of an old allocation to the new allocation when capability narrowing is enabled.
* cheri: malloc: Set fixed mmap_threshold for capability narrowingSzabolcs Nagy2022-12-092-1/+11
| | | | | | | | | | | | | Capability narrowing requires extra alignment for large allocations, this can cause significant heap fragmentation so ensure large allocations use a single mmap and unmaped on free. The fragmentation is bug 14581. This patch disables dynamic mmap threshold when cap_narrowing is enabled and uses a threshold of 256 kbytes on morello (which means at most 64 byte alignment requirement on the heap). The dynamic threshold could quickly grow very big and stay there making the fragmentation issue common.
* cheri: malloc: Set __always_fail_morecoreSzabolcs Nagy2022-12-081-0/+1
| | | | | Morello linux does not support brk syscall, so fail early in the malloc implementation instead of trying to use the syscall which always fails.
* aarch64: morello: malloc: better lookup table resize logicSzabolcs Nagy2022-12-081-1/+1
| | | | | | Capability narrowing uses a lookup table and the old logic could cause unnecessary resizes after deletes with the smallest lookup table size.
* cheri: malloc: bump OBSTACK_INTERFACE_VERSIONSzabolcs Nagy2022-12-082-0/+8
| | | | | | | | | | | | | | | | The obstack version should have been bumped after commit 2fd4de4b15a66f821057af90714145d2c034a609 [BZ #321] which changed a ptrdiff_t struct member into a union of ptrdiff_t and a pointer and thus changed the ABI on targets where ptrdiff_t and pointer have different size or alignment. This affects CHERI targets. Old versions of obstack are used in the wild and conflict with the one provided by glibc so at least on CHERI targets it has to be bumped. On other targets we don't bump the version as it changes compile time behaviour (the ABI remains backward compatible either way).
* morello: Provide documentation about the morello port.Szabolcs Nagy2022-11-221-0/+37
|
* cheri: malloc: disable capability narrowing on some testsSzabolcs Nagy2022-11-221-0/+5
| | | | | malloc/tst-malloc-backtrace tests heap corruption. malloc/tst-dynarray uses malloc_debug wrappers that access internals.
* cheri: malloc: add tunable to turn narrowing offSzabolcs Nagy2022-11-223-0/+19
|
* cheri: malloc: Capability narrowing using internal lookup tableSzabolcs Nagy2022-11-224-18/+470
| | | | | | | | | | | | | | | 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.
* cheri: malloc: Initial capability narrowing supportSzabolcs Nagy2022-11-223-8/+272
| | | | | | | | | | | | | | 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.
* malloc: Don't use __libc_free for tcache cleanupSzabolcs Nagy2022-11-221-2/+31
| | | | | | | | __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.
* cheri: use getauxptr in iconv/tst-gconv-init-failure testSzabolcs Nagy2022-11-221-3/+3
| | | | On CHERI targets getauxval cannot return a valid pointer.
* cheri: elf: Fix tst-auxv for MorelloCarlos Eduardo Seo2022-11-221-0/+8
|
* cheri: Update libc.abilist for getauxptrCarlos Eduardo Seo2022-11-2237-1/+73
| | | | Updates libc.abilist files for getauxptr to version 2.37.
* TODO(api): cheri: misc: Implement new function getauxptr for CHERI capabilitiesCarlos Eduardo Seo2022-11-224-0/+44
| | | | | | | 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
* support: Fix TEST_COMPARE for uintptr_t.Carlos Eduardo Seo2022-11-222-2/+65
| | | | TEST_COMPARE should allow comparison between two capability values.
* cheri: stdio-common: Add test for %#p printf modifierCarlos Eduardo Seo2022-11-222-0/+101
| | | | Testcase for printing capabilities.
* cheri: stdio-common: add support for printing CHERI capabilitiesCarlos Eduardo Seo2022-11-224-1/+143
| | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | This adds a new modifier %#p for printing capability information according to the CHERI C Programming guide: https://github.com/CTSRD-CHERI/cheri-c-programming/wiki/Displaying-Capabilities A %#p option in printf will display: <address> [<permissions>,<base>-<top>] (<attr>) * address: Virtual address of capability displayed as a hexadecimal value with a 0x prefix. * permissions: Zero or more of the following characters: r: LOAD permission w: STORE permission x: EXECUTE permission R: LOAD_CAP permission W: STORE_CAP permission E: EXECUTIVE permission (Morello only) * base: Lower bound of capability displayed as a hexadecimal value with a 0x prefix. * top: Upper bound of capability plus 1 displayed as a hexadecimal value with a 0x prefix. * attr: Zero or more of the following comma-separated attributes. If none of the attributes are present, this field is omitted (along with the enclosing parentheses/brackets). invalid: Capability's tag is clear. sentry: Capability is a sealed entry. sealed: Capability is sealed with a type other than the sealed entry object type. A %p option in printf will display the capability value (address) normally.
* cheri: nptl: Check user provided stack for PCS constraintsCarlos Eduardo Seo2022-11-221-1/+8
| | | | | In pthread_attr_setstack fail with EINVAL if the input stack does not meet the PCS constraints.
* cheri: Fix sigevent ABISzabolcs Nagy2022-11-221-1/+5
| | | | Adjust padding to accommodate pointer size and alignment increase.
* cheri: fix posix timersSzabolcs Nagy2022-11-221-0/+20
| | | | | | | | | | | | | We need to distinguish timerids that are small integers returned by the kernel and timerids that are pointers to struct timer. The existing pointer tagging does not work for CHERI because of the pointer shift. Simply use the top bit without shift to tag pointers. This still relies on the top byte ignore of aarch64 (the top byte does not affect the capability representation) and that pointers are not tagged for other reasons (like HWASAN). Note: this is morello specific and does not work for generic cheri.
* cheri: elf: make sure dlpi_phdr covers the load segmentsSzabolcs Nagy2022-11-221-0/+5
| | | | | | 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.
* TODO(api): cheri: fix dl_iterate_phdr dlpi_addrSzabolcs Nagy2022-11-221-0/+6
| | | | | | | | | | | | | | 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.
* TODO(api): cheri: elfptr_t in public api for unwinderSzabolcs Nagy2022-11-221-1/+1
| | | | TODO: needs agreement across cheri libcs
* TODO(uapi): cheri: start: restrict auxv capability permissionsSzabolcs Nagy2022-11-224-0/+8
| | | | TODO: not needed with full pcuabi
* cheri: Update the static tls requirement of the libcSzabolcs Nagy2022-11-221-0/+8
| | | | Larger requirement because pointers are bigger.
* aarch64: morello: fix DL_SYMBOL_ADDRESSSzabolcs Nagy2022-11-226-2/+67
| | | | | | | 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.
* aarch64: morello: add D_PTR_RWSzabolcs Nagy2022-11-222-1/+5
| | | | Writable version of D_PTR, required for updating GOT[1] and GOT[2].
* aarch64: morello: Return bounded pointer in __tls_get_addrSzabolcs Nagy2022-11-224-9/+69
| | | | | | | | | 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.)
* aarch64: morello: dynamic linking supportSzabolcs Nagy2022-11-228-2/+856
| | | | | | | | | | | | | | | | | | | | | | | | Add morello specific dl-machine.h. Add morello dynamic relocation processing support for purecap ABI. Only support R_AARCH64_NONE, R_AARCH64_ABS64 and R_AARCH64_RELATIVE dynamic relocs from the lp64 ABI. RELATIVE and IRELATIVE relocs use a helper function from cheri-rel.h to construct a capability. Also fixed the IRELATIVE handling for static linking. Use new machine routines on morello for load address computation so it is a valid capability: void *elf_machine_runtime_dynamic (void) void elf_machine_rtld_base_setup (struct link_map *map, void *args) The ld.so load address and RX, RW capabilities are derived from auxv and the RW ranges are set up based on the ld.so program headers early. __tls_get_addr should return a bounded pointer instead of fixing it in _dl_make_tlsdesc_dynamic, this is done in a separate patch.
* aarch64: morello: add lazy binding entry codeSzabolcs Nagy2022-11-221-0/+136
|
* cheri: elf: fix SYMBOL_ADDRESS to return RX derived pointerSzabolcs Nagy2022-11-221-2/+5
| | | | | | 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.
* cheri: elf: Use RW permissions for l_ld when neededSzabolcs Nagy2022-11-222-2/+6
| | | | | | | | | | | 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.)
* cheri: elf: Use elfptr_t for function symbol fixupSzabolcs Nagy2022-11-222-2/+2
| | | | Propagate capabilities during lazy binding and IFUNC fixup in dlsym.
* cheri: elf: Prepare support for dynamic relocation processingSzabolcs Nagy2022-11-222-3/+8
| | | | | | | | Type of relocation addresses must be changed from ElfW(Addr) to elfptr_t to cover both traditional and CHERI ABIs. And relative relocation processing must have access to the link_map to derive pointers from the right per module capability.
* TODO(sprof): cheri: disable profiling shared librariesSzabolcs Nagy2022-11-221-0/+4
| | | | | | | | | | 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 abiCarlos Eduardo Seo2022-11-221-15/+43
| | | | | | | | | 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).
* aarch64: morello: add dl-r_debug.hSzabolcs Nagy2022-11-221-0/+61
| | | | | | | | 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.
* aarch64: elf: avoid loading incompatible binariesSzabolcs Nagy2022-11-221-1/+2
| | | | Prevent lp64 ld.so loading purecap binaries.
* cheri: elf: use RX, RW capabilities to derive pointersSzabolcs Nagy2022-11-227-23/+24
| | | | | | | | | | | | | Instead of map->l_addr + offset use dl_rx_ptr (map, offset) dl_rw_ptr (map, offset) depending on RX or RW permission requirement.
* cheri: elf: Fix segment mapping permissionsSzabolcs Nagy2022-11-221-4/+13
| | | | | Ensure mmap returns pointers with RWX permission covering all segments. These pointers later get restricted to RX and RW permission.
* cheri: elf: Setup per module RX and RW capabilitiesSzabolcs Nagy2022-11-222-12/+111
| | | | | | | | | | | | | | | | | | | _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.
* cheri: elf: change l_entry to be elfptr_tSzabolcs Nagy2022-11-224-15/+15
| | | | | | | | | | | | It is simpler and more consistent to make l_entry a capability throughout instead of leaving it as an address and converting before use: 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. Functions returning a pointer to the user entry are also changed to use elfptr_t.
* aarch64: morello: add purecap ld.so _start codeSzabolcs Nagy2022-11-221-0/+110
| | | | | | | | | 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).
* aarch64: morello: rtld: define DL_RO_DYN_SECTIONSzabolcs Nagy2022-11-221-0/+25
| | | | The dynamic section cannot be relocated to hold pointers in place.
* aarch64: morello: fix ldconfig for purecap abiSzabolcs Nagy2022-11-225-1/+23
| | | | | | 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.