Commit Graph

909 Commits

Author SHA1 Message Date
Konstantin Belousov
470b98e61d rtld: remove mips arch directory
Reviewed by:	imp
Sponsored by:	The FreeBSD Foundation
Differential revision:	https://reviews.freebsd.org/D33763
2022-01-06 06:00:39 +02:00
Konstantin Belousov
292cba9b49 rtld: remove mips-specific cases from generic code
Reviewed by:	imp
Sponsored by:	The FreeBSD Foundation
Differential revision:	https://reviews.freebsd.org/D33763
2022-01-06 06:00:39 +02:00
John Baldwin
8bcdb144eb TLS: Use <machine/tls.h> for libc and rtld.
- Include <machine/tls.h> in MD rtld_machdep.h headers.

- Remove local definitions of TLS_* constants from rtld_machdep.h
  headers and libc using the values from <machine/tls.h> instead.

- Use _tcb_set() instead of inlined versions in MD
  allocate_initial_tls() routines in rtld.  The one exception is amd64
  whose _tcb_set() invokes the amd64_set_fsbase ifunc.  rtld cannot
  use ifuncs, so amd64 inlines the logic to optionally write to fsbase
  directly.

- Use _tcb_set() instead of _set_tp() in libc.

- Use '&_tcb_get()->tcb_dtv' instead of _get_tp() in both rtld and libc.
  This permits removing _get_tp.c from rtld.

- Use TLS_TCB_SIZE and TLS_TCB_ALIGN with allocate_tls() in MD
  allocate_initial_tls() routines in rtld.

Reviewed by:	kib, jrtc27 (earlier version)
Differential Revision:	https://reviews.freebsd.org/D33353
2021-12-09 13:23:05 -08:00
John Baldwin
299617496c amd64: Allocate TCB with alignment of 16 rather than 8.
This matches the TLS_TCB_ALIGN definition in libc.

Reviewed by:	kib, jrtc27
Sponsored by:	The University of Cambridge, Google Inc.
Differential Revision:	https://reviews.freebsd.org/D33349
2021-12-09 13:16:45 -08:00
John Baldwin
23e0c0e9a3 mips: Add TLS_DTV_OFFSET to the result of tls_get_addr_common.
Previously TLS_DTV_OFFSET was added to the offset passed to
tls_get_addr_common; however, this approach matches powerpc and RISC-V
and better matches the intention.

Reviewed by:	kib, jrtc27
Sponsored by:	The University of Cambridge, Google Inc.
Differential Revision:	https://reviews.freebsd.org/D33347
2021-12-09 13:16:19 -08:00
John Baldwin
03f6b14106 mips: Rename TLS_DTP_OFFSET to TLS_DTV_OFFSET.
This is the more standard name for the bias of dtv pointers used on
other platforms.  This also fixes a few other places that were using
the wrong bias previously on MIPS such as dlpi_tls_data in struct
dl_phdr_info and the recently added __libc_tls_get_addr().

Reviewed by:	kib, jrtc27
Sponsored by:	The University of Cambridge, Google Inc.
Differential Revision:	https://reviews.freebsd.org/D33346
2021-12-09 13:16:00 -08:00
Konstantin Belousov
c210ef1347 rtld: load preloaded vdso
Reviewed by:	emaste
Discussed with:	jrtc27
Tested by:	pho
Sponsored by:	The FreeBSD Foundation
MFC after:	1 month
Differential revision:	https://reviews.freebsd.org/D32960
2021-12-06 20:46:49 +02:00
Konstantin Belousov
63fc4e820c rtld: extract header validation into new helper check_elf_headers()
Reviewed by:	emaste
Discussed with:	jrtc27
Tested by:	pho
Sponsored by:	The FreeBSD Foundation
MFC after:	1 week
Differential revision:	https://reviews.freebsd.org/D32960
2021-12-06 20:46:49 +02:00
Konstantin Belousov
01c77a436e Pass vdso address to userspace
Reviewed by:	emaste
Discussed with:	jrtc27
Tested by:	pho
Sponsored by:	The FreeBSD Foundation
MFC after:	1 month
Differential revision:	https://reviews.freebsd.org/D32960
2021-12-06 20:46:49 +02:00
Konstantin Belousov
f340188625 rtld_paths.h: Provide _PATH_ELF32_HINTS string, unconditionally
Reviewed by:	emaste
Tested by:	jbeich
Sponsored by:	The FreeBSD Foundation
MFC after:	1 week
Differential revision:	https://reviews.freebsd.org/D33058
2021-11-25 01:55:03 +02:00
John Baldwin
b928e924f7 rtld-elf: Use _get_tp in __tls_get_addr for aarch64 and riscv64.
Reviewed by:	kib
Sponsored by:	The University of Cambridge, Google Inc.
Differential Revision:	https://reviews.freebsd.org/D33047
2021-11-17 15:50:55 -08:00
Konstantin Belousov
b61bce17f3 rtld dump_auxv: be pedantic and distiguish between auxv union members based on format
Reviewed by:	jrtc27
Sponsored by:	The FreeBSD Foundation
MFC after:	1 week
2021-11-13 22:13:10 +02:00
Konstantin Belousov
3a902ef253 rtld dump_auxv: consistently use long modifier for non-pointer auxv vals
Reviewed by:	jrtc27
Sponsored by:	The FreeBSD Foundation
MFC after:	1 week
2021-11-13 22:12:33 +02:00
Konstantin Belousov
64ba1f4cf3 rtld: Implement LD_SHOW_AUXV
It dumps auxv as seen by interpreter, right before starting any user
code.

Copied from:	glibc
Sponsored by:	The FreeBSD Foundation
MFC after:	1 week
2021-11-13 19:33:13 +02:00
Konstantin Belousov
77c088ab21 rtld: add rtld_fdprintfx()
It is same as rtld_fdprintf() without enforcement of the format string
to be a literal.

Sponsored by:	The FreeBSD Foundation
MFC after:	1 week
2021-11-13 19:33:13 +02:00
Konstantin Belousov
74aec9618f rtld: style adjustments
Consistently use `return ()'.
Fix some spacing issues with types formatting, and around binary ops.

Sponsored by:	The FreeBSD Foundation
MFC after:	1 week
2021-11-06 06:40:18 +02:00
Konstantin Belousov
c5637b8be8 rtld: ignore fstatfs(2) errors when checking MNT_NOEXEC flag
File descriptor we operate on might reference something that is not a
file, e.g. shmfd.  In this case, we cannot check MNT_NOEXEC in
principle.

If fstatfs(2) caused some failure on normal filesystem, then typical
expectation is that read or mmap of this file would also fail.  If not,
mmap(2) PROT_EXEC on MNT_NOEXEC filesystem returns EACCES.

Reported by:	obiwac@gmail.com
Sponsored by:	The FreeBSD Foundation
MFC after:	1 week
2021-11-06 06:40:17 +02:00
Konstantin Belousov
8363963a8f rtld: fix dangerous_ld_env calculation for ld_dynamic_weak
Default value for ld_dynamic_weak is true, non-default settings should
be activated for the false value.

Reported by:	obiwac@gmail.com
Sponsored by:	The FreeBSD Foundation
MFC after:	3 days
2021-11-06 06:40:17 +02:00
Konstantin Belousov
40ddde6ef9 rtld: Print currently configured search path for libraries for -v
Sponsored by:	The FreeBSD Foundation
MFC after:	1 week
2021-10-25 20:41:53 +03:00
Konstantin Belousov
33dba3bb0e rtld-elf/paths.h: Make it usable outside rtld
but still for tightly coupled things like ldd(1)

Rename paths.h to rtld_paths.h.
Add guard for rtld-specific externs declarations.
Add _COMPAT32_BASENAME_RTLD and _COMPAT32_PATH_RTLD.

Reviewed by:	arichardson, jhb
Sponsored by:	The FreeBSD Foundation
MFC after:	1 week
Differential revision:	https://reviews.freebsd.org/D32464
2021-10-21 03:08:54 +03:00
Konstantin Belousov
73dddffc31 crt_malloc: more accurate handling of mmap(2) failure
Reset both pagepool_start and pagepool_end after a mmap(2) failure,
to avoid using invalid pagepool either for allocation or munmap(2).

PR:	259076
Noted by:	Denis Koreshkov <dynamic-wind@mail.ru>
Reviewed by:	arichardson
Sponsored by:	The FreeBSD Foundation
MFC after:	1 week
Differential revision:	https://reviews.freebsd.org/D32514
2021-10-19 01:02:47 +03:00
Fangrui Song
a7d137fcbc rtld: Support DT_RELR relative relocation format
PIE and shared objects usually have many relative relocations. In
2017/2018, a compact relative relocation format RELR was proposed on
https://groups.google.com/g/generic-abi/c/bX460iggiKg/m/GxjM0L-PBAAJ
("Proposal for a new section type SHT_RELR") and is a pre-standard.
RELR usually takes 3% or smaller space than R_*_RELATIVE relocations.
The virtual memory size of a mostly statically linked PIE is typically
5~10% smaller.

ld.lld --pack-dyn-relocs=relr emits RELR relocations. DT_RELR has been
adopted by Android bionic, Linux kernel's arm64 port, Chrome OS (patched
glibc).

This patch adds DT_RELR support to FreeBSD rtld-elf.

MFC after:	1 week
Differential Revision:	https://reviews.freebsd.org/D32524
2021-10-17 02:37:13 +03:00
Emmanuel Vadot
d0f0e0bd74 rtld: Do not install libmap.conf when installing the COMPAT32 version
This has the effect of installing the same file twice at the same location
and confuse pkgbase as we add this file twice in the package config part.

MFC after:  1 week
Sponsored by: Beckhoff Automation GmbH & Co. KG
2021-10-13 14:42:08 +02:00
Konstantin Belousov
ba7f9c1b61 rtld direct exec: add -d option
to ignore lack of execute permission on the binary.  The check is a
bad security theatre anyway.

Reviewed by:	arichardson, imp
Sponsored by:	The FreeBSD Foundation
MFC after:	1 week
Differential revision:	https://reviews.freebsd.org/D32464
2021-10-13 03:41:48 +03:00
Konstantin Belousov
19e008e7f7 crt_malloc: Be more persistent when handling mmap() failure
In the situation with limited address space, together with
fragmentation, it is possible for mmap() request in morecore() to fail
when asking for required size + NPOOLPAGES, but succeed without the
addend.  Retry allocation there.

PR:	259076
Reported by:	Denis Koreshkov <dynamic-wind@mail.ru>
Reviewed by:	arichardson
Sponsored by:	The FreeBSD Foundation
MFC after:	1 week
Differential revision:	https://reviews.freebsd.org/D32474
2021-10-13 02:37:09 +03:00
Konstantin Belousov
0b72d2965d crt_malloc: use uintptr_t instead of long for arithmetic on addresses
and avoid unneeded casts

Reviewed by:	arichardson (previous version)
Sponsored by:	The FreeBSD Foundation
MFC after:	1 week
Differential revision:	https://reviews.freebsd.org/D32474
2021-10-13 02:37:09 +03:00
Konstantin Belousov
aa68b3bb2e rtld: constify most variables holding references to the environment values
Reviewed by:	markj
Sponsored by:	The FreeBSD Foundation
MFC after:	1 week
Differential revision:	https://reviews.freebsd.org/D31545
2021-08-17 15:06:08 +03:00
Konstantin Belousov
b4b2748891 rtld: provide private getenv(3)
Reviewed by:	arichardson, markj
Sponsored by:	The FreeBSD Foundation
MFC after:	1 week
Differential revision:	https://reviews.freebsd.org/D31545
2021-08-17 15:05:47 +03:00
Konstantin Belousov
bfd4c875a1 rtld: avoid use of of getenv(3) for evaluating rtld env vars (LD_XXX)
Scan through the set of environment variables during initialization and
store values in the corresponding ld_env_var_desc structure, in the
single pass at init time. This does not eliminate use of getenv(3) and
unsetenv(3) completely, but provides a foundation to do that as the next
step.

Also organize the scan in a way that makes it easier to support aliases
like LD_DEBUG vs. LD_64_DEBUG.

Suggested by:	arichardson
Reviewed by:	arichardson, markj
Sponsored by:	The FreeBSD Foundation
MFC after:	1 week
Differential revision:	https://reviews.freebsd.org/D31545
2021-08-17 15:05:47 +03:00
Konstantin Belousov
451dc2b7cc rtld: rework how environment variables are named
Instead of specifying the main name part of the environment variable as the
string literal, create array of the var names and access them by symbolic
index.  Convert main name parts into complete names by prefixing with
ABI-specific ld_env_vars.

This way the name is not repeated, and also it can carry additional
proporties explicitly.  For instance, cleanup of the environment for
the setuid image does not require retyping all names.

Reviewed by:	arichardson, markj
MFC after:	1 week
Sponsored by:	The FreeBSD Foundation
Differential revision:	https://reviews.freebsd.org/D31545
2021-08-17 15:05:46 +03:00
Fangrui Song
7da378f9de rtld: Switch to the standard symbol lookup behavior if LD_DYNAMIC_WEAK is set
The current lookup prefers a strong definition to a STB_WEAK definition
(similar to glibc pre-2.2 behavior) which does not conform to the ELF
specification.

The non-compliant behavior provoked https://reviews.llvm.org/D4418
which was intended to fix -shared-libasan but introduced
new problems (and caused some sanitizer tests (e.g.
test/asan/TestCases/interception_failure_test.cpp) to fail): sanitizer
interceptors are STB_GLOBAL instead of STB_WEAK, so defining a second
STB_GLOBAL interceptor can lead to a multiple definition linker error.
For example, in a -fsanitize={address,memory,...} build, libc functions
like malloc/free/strtol/... cannot be provided by user object files.

See
https://docs.freebsd.org/cgi/getmsg.cgi?fetch=16483939+0+archive/2014/freebsd-current/20140716.freebsd-current
for discussions.

This patch implements the ELF-compliant behavior when LD_DYNAMIC_WEAK is
set. STB_WEAK wrestling in symbol lookups in `Search the dynamic linker
itself` are untouched.

Reviewed by:	kib
MFC after:	1 week
Differential revision:	https://reviews.freebsd.org/D26352
2021-08-16 13:55:35 +03:00
Fangrui Song
8f63fa78e8 rtld: Remove calculate_tls_end
Variant I architectures use off and Variant II ones use size + off.
Define TLS_VARIANT_I/TLS_VARIANT_II symbols similarly to how libc
handles it.

Reviewed by:	kib
MFC after:	1 week
Differential revision:	https://reviews.freebsd.org/D31539
Differential revision:	https://reviews.freebsd.org/D31541
2021-08-16 13:55:35 +03:00
Fangrui Song
e6c7696203 rtld: Fix i386/amd64 TP offset when p_vaddr % p_align != 0
For a Variant II architecture, the TP offset of a TLS symbol is st_value -
tlsoffset + r_addend. tlsoffset is computed by either calculate_tls_offset
or calculate_first_tls_offset.

The return value of calculate_first_tls_offset is the smallest integer
satisfying res >= size and (-res) % p_align = p_vaddr % p_align
(= p_offset % p_align).  (The formula is a bit contrived. The basic idea
is to subtract the minimum integer from size + align - 1 so that the result
ihas the expected remainder.)

Reviewed by:	kib
MFC after:	1 week
Differential revision:	https://reviews.freebsd.org/D31538
Differential revision:	https://reviews.freebsd.org/D31541
2021-08-16 13:55:34 +03:00
Konstantin Belousov
c9f833abf1 rtld: Round down relro_size
lld rounds up p_memsz(PT_GNU_RELRO) to satisfy common-page-size. If the
page size is smaller than common-page-size, rounding up relro_size may
incorrectly make some RW pages read-only.

GNU ld, gold, and ld.lld ensures p_vaddr+p_memsz is a multiple of
common-page-size. While max-page-size >= system the page size,
common-page-size can be smaller than the system page size.

Submitted by:	MaskRay
MFC after:	1 week
Differential revision:	https://reviews.freebsd.org/D31498
2021-08-13 12:58:53 +03:00
Alex Richardson
7bc797e3f3 Add build system support for ASAN+UBSAN instrumentation
This adds two new options WITH_ASAN/WITH_UBSAN that can be set to
enable instrumentation of all binaries with AddressSanitizer and/or
UndefinedBehaviourSanitizer. This current patch is almost sufficient
to get a complete buildworld with sanitizer instrumentation but in
order to actually build and boot a system it depends on a few more
follow-up commits.

Reviewed By:	brooks, kib, markj
Differential Revision: https://reviews.freebsd.org/D31043
2021-08-02 14:33:24 +01:00
Mark Johnston
f238ebd142 rtld/arm64: Remove checks for undefined symbols when processing TPREL64
lld emits several GOT relocations referencing the null sumbol in libc.so
when compiled with -ftls-model=initial-exec.  This symbol is specified
to be undefined.

We generally do not handle dynamic TLS relocations against weak,
undefined symbols, so avoid printing a warning here.  This makes it
possible to compile libc.so using the initial-exec TLS model on arm64.

Reviewed by:	jrtc27, kib
MFC after:	2 weeks
Sponsored by:	The FreeBSD Foundation
Differential Revision:	https://reviews.freebsd.org/D31069
2021-07-15 22:41:10 -04:00
Alex Richardson
e34c713b0e rtld/tests: Avoid function name conflict with libc opendir()
This prevents these tests from being compiled with ASAN since the asan
interceptors also define opendir() but matching the libc function.

Reviewed By:	oshogbo, kib, markj
Differential Revision: https://reviews.freebsd.org/D31038
2021-07-06 10:51:57 +01:00
Alex Richardson
e3be51b2bc rtld-elf: Check the return value of obj_enforce_relro()
The mprotect() call was failing on CheriBSD when changing rtld's relro
page permissions due to missing CHERI capability permissions on the
mprotect() argument but did not report an error since the return value
was being ignored. It should never fail on any supported FreeBSD
architecture, but checking the return value seems like a good
sanity check to me.

Reviewed By:	kib, imp
MFC after:	1 week
Differential Revision: https://reviews.freebsd.org/D30820
2021-06-22 09:10:48 +01:00
Konstantin Belousov
e3149e0a02 rtld: Rename -t option to -u (ignore LD_ vars)
Requested by:	arichardson
Sponsored by:	The FreeBSD Foundation
MFC after:	3 days
2021-06-03 01:55:08 +03:00
Konstantin Belousov
d81f999ac2 rtld direct exec: add option to ignore LD_ variables
Sponsored by:	The FreeBSD Foundation
MFC after:	1 week
2021-05-29 17:59:09 +03:00
Konstantin Belousov
529ab5a759 rtld: initialize default dlerror_seen_val as true
There should be no error after startup.

PR:	255698
Reported by:	Eugene M. Kim <astralblue@gmail.com>
Sponsored by:	The FreeBSD Foundation
MFC after:	1 week
2021-05-13 02:31:29 +03:00
Konstantin Belousov
630caa95d4 rtld: preserve the 'seen' state of the dlerror message in errmsg_save()
rtld preserves its current error message around calls to user init/fini
lists, to not override original error with potential secondary errors
caused by user code recursing into rtld.  After 4d9128da54,
the preservation of the string itself is not enough, the 'seen'
indicator must be preserved as well.  Otherwise, since new code does not
clear string (it cannot), call to _rtld_error() from errmsg_restore()
revived whatever message was consumed last.

Change errmsg_save() to return structure recording both 'seen' indicator
and the message, if any.

PR:	255698
Reported by:	Eugene M. Kim <astralblue@gmail.com>
Sponsored by:	The FreeBSD Foundation
MFC after:	3 days
2021-05-11 02:47:00 +03:00
Konstantin Belousov
9b33518ada rtld_lock.h: add some comments about versioning of struct RtldLockInfo
Sponsored by:	The FreeBSD Foundation
MFC after:	6 days
2021-04-11 11:16:13 +03:00
Konstantin Belousov
4d9128da54 rtld: make dlerror() thread-local
PR:	95339
Discussed with:	arichardson
Sponsored by:	The FreeBSD Foundation
MFC after:	1 week
Differential revision:	https://reviews.freebsd.org/D29633
2021-04-10 17:33:34 +03:00
Konstantin Belousov
08bfbd4359 rtld: workaround for broken ABI
Right now, libthr does not initialize RtldLockInfo.rtli_version when calling
_rtld_thread_init(), which makes versioning the interface troublesome.

Add a workaround: if the calling object of _rtld_thread_init() exports
the "_pli_rtli_version" symbol, then consider rtli_version initialized.
Otherwise, forcibly set it to RTLI_VERSION_ONE, currently defined as
RTLI_VERSION.

Export "_pli_rtli_version" from libthr and properly initialize rtli_version.

Sponsored by:	The FreeBSD Foundation
MFC after:	1 week
Differential revision:	https://reviews.freebsd.org/D29633
2021-04-10 17:33:33 +03:00
Konstantin Belousov
4d7f08c84b rtld: unstaticise lockinfo and obj_from_addr()
Sponsored by:	The FreeBSD Foundation
MFC after:	1 week
Differential revision:	https://reviews.freebsd.org/D29633
2021-04-10 17:33:33 +03:00
Konstantin Belousov
e8b9c508b7 rtld: use _get_tp() in __tls_get_addr()
This eliminates some non-trivial amount of code duplication, where done.
Only x86 and mips are handled right now.

Tested by:      bdragon (powerpc), mhorne (riscv)
Sponsored by:	The FreeBSD Foundation
MFC after:	1 week
Differential revision:	https://reviews.freebsd.org/D29623
2021-04-09 23:46:24 +03:00
Konstantin Belousov
7cb32a0d03 rtld: avoid recursing on rtld_bind_lock for write
This fixes a regression in d36d681615, where the call to
__tls_get_address() was performed under rtld_bind_lock write-locked.
Instead use tls_get_addr_slow() directly, with locked = true.

Reported by:	jkim, many others
Tested by:	jkim, bdragon (powerpc), mhorne (riscv)
Sponsored by:	The FreeBSD Foundation
MFC after:	1 week
Differential revision:	https://reviews.freebsd.org/D29623
2021-04-09 23:46:24 +03:00
Konstantin Belousov
8950804842 rtld: allow to use tls_get_addr_slow() from context where rtld_bind_lock is locked
Explicit locked parameter is added

Sponsored by:	The FreeBSD Foundation
MFC after:	1 week
Differential revision:	https://reviews.freebsd.org/D29623
2021-04-09 23:46:24 +03:00
Konstantin Belousov
85d846b369 rtld: style tls_get_addr_slow
Sponsored by:	The FreeBSD Foundation
MFC after:	1 week
Differential revision:	https://reviews.freebsd.org/D29623
2021-04-09 23:46:24 +03:00