Commit Graph

883 Commits

Author SHA1 Message Date
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
Konstantin Belousov
99c2ce7ef1 rtld: define TLS_DTV_OFFSET on all architectures
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
34ca6025dd rtld_lock.h: Expand scope for IN_RTLD to avoid some conflicts with libc
Sponsored by:	The FreeBSD Foundation
MFC after:	1 week
Differential revision:	https://reviews.freebsd.org/D29623
2021-04-09 23:46:23 +03:00
Konstantin Belousov
f61ecf60cf rtld/x86/reloc.c: style
Sponsored by:	The FreeBSD Foundation
MFC after:	1 week
Differential revision:	https://reviews.freebsd.org/D29623
2021-04-09 23:46:23 +03:00
Konstantin Belousov
38e0610df7 rtld_lock.h: remove tautological extern's
Sponsored by:	The FreeBSD Foundation
MFC after:	1 week
Differential revision:	https://reviews.freebsd.org/D29623
2021-04-09 23:46:23 +03:00
Andrew Turner
4d9488674f Remove the last users of ARM_TP_ADDRESS
This was only needed on 32-bit arm prior to ARMv6. As we only support
ARMv6 or later remove it.

Reviewed by:	mannu
Sponsored by:	Innovate UK
Differential Revision:	https://reviews.freebsd.org/D29624
2021-04-08 07:52:54 +00:00
Konstantin Belousov
d36d681615 rtld dl_iterate_phdr(): dlpi_tls_data is wrong
dl_iterate_phdr() dlpi_tls_data should provide the TLS module segment
address, and not the TLS init segment address as it does now.

Reported by:	emacsray@gmail.com
PR:	254774
Sponsored by:	The FreeBSD Foundation
MFC after:	1 week
2021-04-06 03:23:08 +03:00
Mariusz Zaborski
e086aff91c rtld: fix the man page
In f90218886f in man page I used LD_PRELOAD_PATH_FDS instead of
LD_PRELOAD_FDS.

Reported by:	rpokala
2021-03-25 00:51:44 +01:00
Mariusz Zaborski
f90218886f rtld: introduce PRELOAD_FDS
The new PRELOAD_FDS variable accepts a list of file descriptors
that should be loaded into the process.

This may be used to optimize a loading process - in the case when
we already have a file descriptor to the library; we don't have
to look into multiple PATH to find it.

It may also be used in capability mode to load a single additional
library without the need to open a directory that contains it.

The last use of this functionality t may be a race-free method
of loading libraries.

Reviewed by:	kib, markj
Differential Revision:	https://reviews.freebsd.org/D29334
2021-03-24 23:40:48 +01:00
Mariusz Zaborski
852a88a1d9 rtld: style nits
No functional change intended.

Requested by:	kib
2021-03-24 23:40:48 +01:00
Ed Maste
7f72497ef7 libc: Use musl's optimized strchr and strchrnul
Parentheses added to HASZERO macro to avoid a GCC warning, and formatted
with clang-format as we have adopted these and don't consider them
'contrib' code.

Obtained from:	musl (snapshot at commit 4d0a82170a25)
Reviewed by:	kib (libc integration), mjg (both earlier)
MFC after:	1 month
Sponsored by:	The FreeBSD Foundation
Differential Revision:	https://reviews.freebsd.org/D17630
2021-03-01 21:09:59 -05:00
David Chisnall
43d44842ae rtld: Fix null-pointer dereference
When a library is opened via fdlopen, it has a null pointer for its path
and so _rtld_bind can crash as a result of passing the null pointer to
basename() (which passes it to strrchr(), which doesn't do a null check).

PR:	253081
Submitted by:	theraven
MFC after:	1 week
Differential Revision:	https://reviews.freebsd.org/D28442
2021-02-02 16:14:16 +02:00
Ed Maste
613a08cfa2 rtld: map without PROT_EXEC for relocation
This makes text segment relocation work under W^X.

Submitted by:	Greg V <greg@unrelenting.technology> (original version)
Reviewed by:	kib
MFC after:	2 weeks
Differential Revision:	https://reviews.freebsd.org/D27953
2021-01-05 10:57:14 -05:00
Konstantin Belousov
741d78126b rtld: call close(2) after errno is saved
to prevent obliteration of error value from the original syscall.
Also improve error message for short read.

Submitted by:	Konrad Sewiłło-Jopek
MFC after:	1 week
Differential Revision:	https://reviews.freebsd.org/D27864
2021-01-02 04:43:32 +02:00
Ryan Libby
63f93c7e11 rtld-elf: link libcompiler_rt on all architectures
Statically link rtld-elf with libcompiler_rt on all architectures so
that we don't need to try to pick and choose the bits we need from it
for each architecture (we now leave that to the linker).  Compilers may
emit calls to support functions in this library, but because of the use
of the linker flag -nostdlib for rtld's special needs, the library is
not linked as normal.

Previously we had two different solutions.  On some architectures, we
were able to extract reimplementations of the necessary builtin
functions from our special build of libc.  On ARM, we just linked
libcompiler_rt.

This is motivated by the same issue as D26199 and D27665, but should be
a simpler solution that will apply to all architectures.

Reviewed by:	arichardson, kib
Sponsored by:	Dell EMC Isilon
Differential Revision:	https://reviews.freebsd.org/D27736
2020-12-28 00:44:25 -08:00
Ryan Libby
85b8932d0a Revert "rtld-elf: link udivmoddi4 from compiler_rt"
This reverts commit bce2cff0bc.

Revert D27665 in favor of a more general fix coming in D27736.
2020-12-28 00:44:25 -08:00
Marius Strobl
b58c853edf rtld-elf(1): remove obsolete pre_init() hook
It's no longer used since 600ee699ed
and r358358 respectively.
2020-12-25 19:47:46 +01:00
Ryan Libby
bce2cff0bc rtld-elf: link udivmoddi4 from compiler_rt
This fixes the gcc9 build of rtld-elf32 on amd64, which needed an
implementation of udivmoddi4.

rtld-elf uses certain functions normally found in libc, and so it
includes certain files from libc in its own build.  It has two
mechanisms to include files from libc: one that rebuilds source files in
the rtld-elf environment, and one that extracts object files from a
purpose-built no-SSP PIC archive.

In addition to libc functions, rtld-elf may need to link functions
normally found in libcompiler_rt (formerly libgcc).  Now, add an ability
to rebuild libcompiler_rt source files in the rtld-elf environment.  We
don't yet have a need for an object file extraction mechanism.

libcompiler_rt could also supply udivdi3 and umoddi3, but leave them
alone for now.

Reviewed by:	arichardson, kib
Sponsored by:	Dell EMC Isilon
Differential Revision:	https://reviews.freebsd.org/D27665
2020-12-19 08:38:31 +00:00
Ryan Libby
198a0e58ec rtld-libc: fix incremental build
ar cr is an update of an archive, not a creation of a new one.  During
incremental builds (e.g. with meta mode) the archive was not getting
cleaned, and so could retain now-deleted objects from previous builds.
Now, delete the archive before creating/updating it.

Reviewed by:	arichardson, bdrewery, kib
Sponsored by:	Dell EMC Isilon
Differential Revision:	https://reviews.freebsd.org/D27663
2020-12-19 08:38:27 +00:00
Conrad Meyer
78599c32ef Add CFI start/end proc directives to arm64, i386, and ppc
Follow-up to r353959 and r368070: do the same for other architectures.

arm32 already seems to use its own .fnstart/.fnend directives, which
appear to be ARM-specific variants of the same thing.  Likewise, MIPS
uses .frame directives.

Reviewed by:	arichardson
Differential Revision:	https://reviews.freebsd.org/D27387
2020-12-05 00:33:28 +00:00
Konstantin Belousov
71df6a153f rtld: bump r_debug.r_version to 1 from current 0.
Add r_ldbase.

Requested and reviewed by:	emaste
Sponsored by:	The FreeBSD Foundation
MFC after:	1 week
Differential revision:	https://reviews.freebsd.org/D27429
2020-12-01 22:28:01 +00:00
Gordon Bergling
812b09037d Fix a few mandoc issues
- whitespace at end of input line
- skipping paragraph macro: Pp at the end of Sh
- new sentence, new line
- consider using OS macro: Fx
- AUTHORS section without An macro
- skipping paragraph macro: Pp before Ss
2020-10-09 15:14:19 +00:00
Kyle Evans
7cc42f6d25 Do a sweep and remove most WARNS=6 settings
Repeating the default WARNS here makes it slightly more difficult to
experiment with default WARNS changes, e.g. if we did something absolutely
bananas and introduced a WARNS=7 and wanted to try lifting the default to
that.

Drop most of them; there is one in the blake2 kernel module, but I suspect
it should be dropped -- the default WARNS in the rest of the build doesn't
currently apply to kernel modules, and I haven't put too much thought into
whether it makes sense to make it so.
2020-10-01 01:10:51 +00:00
Brandon Bergren
24faccc241 [PowerPC64LE] Use a shared LIBC_ARCH for powerpc64le.
Given that we have converted to ELFv2 for BE already, endianness is the only
difference between the two ARCHs.

As such, there is no need to differentiate LIBC_ARCH between the two.

Combining them like this lets us avoid needing to have two copies of several
bits for no good reason.

Sponsored by:	Tag1 Consulting, Inc.
2020-09-23 00:21:51 +00:00
Konstantin Belousov
1db23efb83 rtld: pass argc/argv/env to dso inits.
This is consistent with how array inits are called, and also makes us
more compatible with glibc environment.

Requested by:	Alex S <iwtcex@gmail.com>
PR:	249162
Reviewed by:	dim, emaste
Sponsored by:	The FreeBSD Foundation
MFC after:	1 week
Differential revision:	https://reviews.freebsd.org/D26351
2020-09-07 21:32:27 +00:00
Konstantin Belousov
12cb97fb37 Undo 'fix off by one' part of r365360.
Noted by:	emaste
Sponsored by:	The FreeBSD Foundation
MFC after:	6 days
2020-09-05 22:48:27 +00:00
Konstantin Belousov
500433057e rtld: do not refuse to relocate objects without dynamic symtabs.
Such objects can still have valid relocations not requiring symbolic
references.

PR:	249121
Reported by:	wsh@riski.sh
Sponsored by:	The FreeBSD Foundation
MFC after:	1 week
2020-09-05 22:44:38 +00:00