summaryrefslogtreecommitdiff
path: root/elf/dl-load.c
AgeCommit message (Collapse)Author
2018-07-16x86: Support IBT and SHSTK in Intel CET [BZ #21598]H.J. Lu
Intel Control-flow Enforcement Technology (CET) instructions: https://software.intel.com/sites/default/files/managed/4d/2a/control-flow-en forcement-technology-preview.pdf includes Indirect Branch Tracking (IBT) and Shadow Stack (SHSTK). GNU_PROPERTY_X86_FEATURE_1_IBT is added to GNU program property to indicate that all executable sections are compatible with IBT when ENDBR instruction starts each valid target where an indirect branch instruction can land. Linker sets GNU_PROPERTY_X86_FEATURE_1_IBT on output only if it is set on all relocatable inputs. On an IBT capable processor, the following steps should be taken: 1. When loading an executable without an interpreter, enable IBT and lock IBT if GNU_PROPERTY_X86_FEATURE_1_IBT is set on the executable. 2. When loading an executable with an interpreter, enable IBT if GNU_PROPERTY_X86_FEATURE_1_IBT is set on the interpreter. a. If GNU_PROPERTY_X86_FEATURE_1_IBT isn't set on the executable, disable IBT. b. Lock IBT. 3. If IBT is enabled, when loading a shared object without GNU_PROPERTY_X86_FEATURE_1_IBT: a. If legacy interwork is allowed, then mark all pages in executable PT_LOAD segments in legacy code page bitmap. Failure of legacy code page bitmap allocation causes an error. b. If legacy interwork isn't allowed, it causes an error. GNU_PROPERTY_X86_FEATURE_1_SHSTK is added to GNU program property to indicate that all executable sections are compatible with SHSTK where return address popped from shadow stack always matches return address popped from normal stack. Linker sets GNU_PROPERTY_X86_FEATURE_1_SHSTK on output only if it is set on all relocatable inputs. On a SHSTK capable processor, the following steps should be taken: 1. When loading an executable without an interpreter, enable SHSTK if GNU_PROPERTY_X86_FEATURE_1_SHSTK is set on the executable. 2. When loading an executable with an interpreter, enable SHSTK if GNU_PROPERTY_X86_FEATURE_1_SHSTK is set on interpreter. a. If GNU_PROPERTY_X86_FEATURE_1_SHSTK isn't set on the executable or any shared objects loaded via the DT_NEEDED tag, disable SHSTK. b. Otherwise lock SHSTK. 3. After SHSTK is enabled, it is an error to load a shared object without GNU_PROPERTY_X86_FEATURE_1_SHSTK. To enable CET support in glibc, --enable-cet is required to configure glibc. When CET is enabled, both compiler and assembler must support CET. Otherwise, it is a configure-time error. To support CET run-time control, 1. _dl_x86_feature_1 is added to the writable ld.so namespace to indicate if IBT or SHSTK are enabled at run-time. It should be initialized by init_cpu_features. 2. For dynamic executables: a. A l_cet field is added to struct link_map to indicate if IBT or SHSTK is enabled in an ELF module. _dl_process_pt_note or _rtld_process_pt_note is called to process PT_NOTE segment for GNU program property and set l_cet. b. _dl_open_check is added to check IBT and SHSTK compatibilty when dlopening a shared object. 3. Replace i386 _dl_runtime_resolve and _dl_runtime_profile with _dl_runtime_resolve_shstk and _dl_runtime_profile_shstk, respectively if SHSTK is enabled. CET run-time control can be changed via GLIBC_TUNABLES with $ export GLIBC_TUNABLES=glibc.tune.x86_shstk=[permissive|on|off] $ export GLIBC_TUNABLES=glibc.tune.x86_ibt=[permissive|on|off] 1. permissive: SHSTK is disabled when dlopening a legacy ELF module. 2. on: IBT or SHSTK are always enabled, regardless if there are IBT or SHSTK bits in GNU program property. 3. off: IBT or SHSTK are always disabled, regardless if there are IBT or SHSTK bits in GNU program property. <cet.h> from CET-enabled GCC is automatically included by assembly codes to add GNU_PROPERTY_X86_FEATURE_1_IBT and GNU_PROPERTY_X86_FEATURE_1_SHSTK to GNU program property. _CET_ENDBR is added at the entrance of all assembly functions whose address may be taken. _CET_NOTRACK is used to insert NOTRACK prefix with indirect jump table to support IBT. It is defined as notrack when _CET_NOTRACK is defined in <cet.h>. [BZ #21598] * configure.ac: Add --enable-cet. * configure: Regenerated. * elf/Makefille (all-built-dso): Add a comment. * elf/dl-load.c (filebuf): Moved before "dynamic-link.h". Include <dl-prop.h>. (_dl_map_object_from_fd): Call _dl_process_pt_note on PT_NOTE segment. * elf/dl-open.c: Include <dl-prop.h>. (dl_open_worker): Call _dl_open_check. * elf/rtld.c: Include <dl-prop.h>. (dl_main): Call _rtld_process_pt_note on PT_NOTE segment. Call _rtld_main_check. * sysdeps/generic/dl-prop.h: New file. * sysdeps/i386/dl-cet.c: Likewise. * sysdeps/unix/sysv/linux/x86/cpu-features.c: Likewise. * sysdeps/unix/sysv/linux/x86/dl-cet.h: Likewise. * sysdeps/x86/cet-tunables.h: Likewise. * sysdeps/x86/check-cet.awk: Likewise. * sysdeps/x86/configure: Likewise. * sysdeps/x86/configure.ac: Likewise. * sysdeps/x86/dl-cet.c: Likewise. * sysdeps/x86/dl-procruntime.c: Likewise. * sysdeps/x86/dl-prop.h: Likewise. * sysdeps/x86/libc-start.h: Likewise. * sysdeps/x86/link_map.h: Likewise. * sysdeps/i386/dl-trampoline.S (_dl_runtime_resolve): Add _CET_ENDBR. (_dl_runtime_profile): Likewise. (_dl_runtime_resolve_shstk): New. (_dl_runtime_profile_shstk): Likewise. * sysdeps/linux/x86/Makefile (sysdep-dl-routines): Add dl-cet if CET is enabled. (CFLAGS-.o): Add -fcf-protection if CET is enabled. (CFLAGS-.os): Likewise. (CFLAGS-.op): Likewise. (CFLAGS-.oS): Likewise. (asm-CPPFLAGS): Add -fcf-protection -include cet.h if CET is enabled. (tests-special): Add $(objpfx)check-cet.out. (cet-built-dso): New. (+$(cet-built-dso:=.note)): Likewise. (common-generated): Add $(cet-built-dso:$(common-objpfx)%=%.note). ($(objpfx)check-cet.out): New. (generated): Add check-cet.out. * sysdeps/x86/cpu-features.c: Include <dl-cet.h> and <cet-tunables.h>. (TUNABLE_CALLBACK (set_x86_ibt)): New prototype. (TUNABLE_CALLBACK (set_x86_shstk)): Likewise. (init_cpu_features): Call get_cet_status to check CET status and update dl_x86_feature_1 with CET status. Call TUNABLE_CALLBACK (set_x86_ibt) and TUNABLE_CALLBACK (set_x86_shstk). Disable and lock CET in libc.a. * sysdeps/x86/cpu-tunables.c: Include <cet-tunables.h>. (TUNABLE_CALLBACK (set_x86_ibt)): New function. (TUNABLE_CALLBACK (set_x86_shstk)): Likewise. * sysdeps/x86/sysdep.h (_CET_NOTRACK): New. (_CET_ENDBR): Define if not defined. (ENTRY): Add _CET_ENDBR. * sysdeps/x86/dl-tunables.list (glibc.tune): Add x86_ibt and x86_shstk. * sysdeps/x86_64/dl-trampoline.h (_dl_runtime_resolve): Add _CET_ENDBR. (_dl_runtime_profile): Likewise.
2018-06-12Fix comments in _dl_dst_count and _dl_dst_substitute.Carlos O'Donell
The comments in _dl_dst_count is adjusted to match what the code does which is count DSTs from the start of the string. With the removal of DL_DST_COUNT we no longer accept an input that starts at the first $. In _dl_dst_substitute we adjust the comment to indicate that both conditions must be true for the SUID/SGID $ORIGIN exception.
2018-06-12Improve DST handling (Bug 23102, Bug 21942, Bug 18018, Bug 23259).Carlos O'Donell
This commit improves DST handling significantly in the following ways: firstly is_dst () is overhauled to correctly process DST sequences that would be accepted given the ELF gABI. This means that we actually now accept slightly more sequences than before. Now we accept $ORIGIN$ORIGIN, but in the past we accepted only $ORIGIN\0 or $ORIGIN/..., but this kind of behaviour results in unexpected and uninterpreted DST sequences being used as literal search paths leading to security defects. Therefore the first step in correcting this defect is making is_dst () properly account for all DSTs and making the function context free in the sense that it counts DSTs without knowledge of path, or AT_SECURE. Next, _dl_dst_count () is also simplified to count all DSTs regardless of context. Then in _dl_dst_substitute () we reintroduce context-dependent processing for such things as AT_SECURE handling. At the level of _dl_dst_substitute we can have access to things like the true start of the string sequence to validate $ORIGIN-based paths rooted in trusted directories. Lastly, we tighten up the accepted sequences in AT_SECURE, and avoid leaving known unexpanded DSTs, this is noted in the NEWS entry. Verified with a sequence of 68 tests on x86_64 that cover non-AT_SECURE and AT_SECURE testing using a sysroot (requires root to run). The tests cover cases for bug 23102, bug 21942, bug 18018, and bug 23259. These tests are not yet appropriate for the glibc regression testsuite, but with the upcoming test-in-container testing framework it should be possible to include these tests upstream soon. See the mailing list for the tests: https://www.sourceware.org/ml/libc-alpha/2018-06/msg00251.html
2018-06-12Avoid cancellable I/O primitives in ld.so.Zack Weinberg
Neither the <dlfcn.h> entry points, nor lazy symbol resolution, nor initial shared library load-up, are cancellation points, so ld.so should exclusively use I/O primitives that are not cancellable. We currently achieve this by having the cancellation hooks compile as no-ops when IS_IN(rtld); this patch changes to using exclusively _nocancel primitives in the source code instead, which makes the intent clearer and significantly reduces the amount of code compiled under IS_IN(rtld) as well as IS_IN(libc) -- in particular, elf/Makefile no longer thinks we require a copy of unwind.c in rtld-libc.a. (The older mechanism is preserved as a backstop.) The bulk of the change is splitting up the files that define the _nocancel I/O functions, so they don't also define the variants that *are* cancellation points; after which, the existing logic for picking out the bits of libc that need to be recompiled as part of ld.so Just Works. I did this for all of the _nocancel functions, not just the ones used by ld.so, for consistency. fcntl was a little tricky because it's only a cancellation point for certain opcodes (F_SETLKW(64), which can block), and the existing __fcntl_nocancel wasn't applying the FCNTL_ADJUST_CMD hook, which strikes me as asking for trouble, especially as the only nontrivial definition of FCNTL_ADJUST_CMD (for powerpc64) changes F_*LK* opcodes. To fix this, fcntl_common moves to fcntl_nocancel.c along with __fcntl_nocancel, and changes its name to the extern (but hidden) symbol __fcntl_nocancel_adjusted, so that regular fcntl can continue calling it. __fcntl_nocancel now applies FCNTL_ADJUST_CMD; so that both both fcntl.c and fcntl_nocancel.c can see it, the only nontrivial definition moves from sysdeps/u/s/l/powerpc/powerpc64/fcntl.c to .../powerpc64/sysdep.h and becomes entirely a macro, instead of a macro that calls an inline function. The nptl version of libpthread also changes a little, because its "compat-routines" formerly included files that defined all the _nocancel functions it uses; instead of continuing to duplicate them, I exported the relevant ones from libc.so as GLIBC_PRIVATE. Since the Linux fcntl.c calls a function defined by fcntl_nocancel.c, it can no longer be used from libpthread.so; instead, introduce a custom forwarder, pt-fcntl.c, and export __libc_fcntl from libc.so as GLIBC_PRIVATE. The nios2-linux ABI doesn't include a copy of vfork() in libpthread, and it was handling that by manipulating libpthread-routines in .../linux/nios2/Makefile; it is cleaner to do what other such ports do, and have a pt-vfork.S that defines no symbols. Right now, it appears that Hurd does not implement _nocancel I/O, so sysdeps/generic/not-cancel.h will forward everything back to the regular functions. This changed the names of some of the functions that sysdeps/mach/hurd/dl-sysdep.c needs to interpose. * elf/dl-load.c, elf/dl-misc.c, elf/dl-profile.c, elf/rtld.c * sysdeps/unix/sysv/linux/dl-sysdep.c Include not-cancel.h. Use __close_nocancel instead of __close, __open64_nocancel instead of __open, __read_nocancel instead of __libc_read, and __write_nocancel instead of __libc_write. * csu/check_fds.c (check_one_fd) * sysdeps/posix/fdopendir.c (__fdopendir) * sysdeps/posix/opendir.c (__alloc_dir): Use __fcntl_nocancel instead of __fcntl and/or __libc_fcntl. * sysdeps/unix/sysv/linux/pthread_setname.c (pthread_setname_np) * sysdeps/unix/sysv/linux/pthread_getname.c (pthread_getname_np) * sysdeps/unix/sysv/linux/i386/smp.h (is_smp_system): Use __open64_nocancel instead of __open_nocancel. * sysdeps/unix/sysv/linux/not-cancel.h: Move all of the hidden_proto declarations to the end and issue them if either IS_IN(libc) or IS_IN(rtld). * sysdeps/unix/sysv/linux/Makefile [subdir=io] (sysdep_routines): Add close_nocancel, fcntl_nocancel, nanosleep_nocancel, open_nocancel, open64_nocancel, openat_nocancel, pause_nocancel, read_nocancel, waitpid_nocancel, write_nocancel. * io/Versions [GLIBC_PRIVATE]: Add __libc_fcntl, __fcntl_nocancel, __open64_nocancel, __write_nocancel. * posix/Versions: Add __nanosleep_nocancel, __pause_nocancel. * nptl/pt-fcntl.c: New file. * nptl/Makefile (pthread-compat-wrappers): Remove fcntl. (libpthread-routines): Add pt-fcntl. * include/fcntl.h (__fcntl_nocancel_adjusted): New function. (__libc_fcntl): Remove attribute_hidden. * sysdeps/unix/sysv/linux/fcntl.c (__libc_fcntl): Call __fcntl_nocancel_adjusted, not fcntl_common. (__fcntl_nocancel): Move to new file fcntl_nocancel.c. (fcntl_common): Rename to __fcntl_nocancel_adjusted; also move to fcntl_nocancel.c. * sysdeps/unix/sysv/linux/fcntl_nocancel.c: New file. * sysdeps/unix/sysv/linux/powerpc/powerpc64/fcntl.c: Remove file. * sysdeps/unix/sysv/linux/powerpc/powerpc64/sysdep.h: Define FCNTL_ADJUST_CMD here, as a self-contained macro. * sysdeps/unix/sysv/linux/close.c: Move __close_nocancel to... * sysdeps/unix/sysv/linux/close_nocancel.c: ...this new file. * sysdeps/unix/sysv/linux/nanosleep.c: Move __nanosleep_nocancel to... * sysdeps/unix/sysv/linux/nanosleep_nocancel.c: ...this new file. * sysdeps/unix/sysv/linux/open.c: Move __open_nocancel to... * sysdeps/unix/sysv/linux/open_nocancel.c: ...this new file. * sysdeps/unix/sysv/linux/open64.c: Move __open64_nocancel to... * sysdeps/unix/sysv/linux/open64_nocancel.c: ...this new file. * sysdeps/unix/sysv/linux/openat.c: Move __openat_nocancel to... * sysdeps/unix/sysv/linux/openat_nocancel.c: ...this new file. * sysdeps/unix/sysv/linux/openat64.c: Move __openat64_nocancel to... * sysdeps/unix/sysv/linux/openat64_nocancel.c: ...this new file. * sysdeps/unix/sysv/linux/pause.c: Move __pause_nocancel to... * sysdeps/unix/sysv/linux/pause_nocancel.c: ...this new file. * sysdeps/unix/sysv/linux/read.c: Move __read_nocancel to... * sysdeps/unix/sysv/linux/read_nocancel.c: ...this new file. * sysdeps/unix/sysv/linux/waitpid.c: Move __waitpid_nocancel to... * sysdeps/unix/sysv/linux/waitpid_nocancel.c: ...this new file. * sysdeps/unix/sysv/linux/write.c: Move __write_nocancel to... * sysdeps/unix/sysv/linux/write_nocancel.c: ...this new file. * sysdeps/unix/sysv/linux/nios2/Makefile: Don't override libpthread-routines. * sysdeps/unix/sysv/linux/nios2/pt-vfork.S: New file which defines nothing. * sysdeps/mach/hurd/dl-sysdep.c: Define __read instead of __libc_read, and __write instead of __libc_write. Define __open64 in addition to __open.
2018-05-05Fix BZ 20419. A PT_NOTE in a binary could be arbitratily large, so usingPaul Pluzhnikov
alloca for it may cause stack overflow. If the note is larger than __MAX_ALLOCA_CUTOFF, use dynamically allocated memory to read it in. 2018-05-05 Paul Pluzhnikov <ppluzhnikov@google.com> [BZ #20419] * elf/dl-load.c (open_verify): Fix stack overflow. * elf/Makefile (tst-big-note): New test. * elf/tst-big-note-lib.S: New. * elf/tst-big-note.c: New.
2018-02-21elf: Remove ad-hoc restrictions on dlopen callers [BZ #22787]Florian Weimer
This looks like a post-exploitation hardening measure: If an attacker is able to redirect execution flow, they could use that to load a DSO which contains additional code (or perhaps make the stack executable). However, the checks are not in the correct place to be effective: If they are performed before the critical operation, an attacker with sufficient control over execution flow could simply jump directly to the code which performs the operation, bypassing the check. The check would have to be executed unconditionally after the operation and terminate the process in case a caller violation was detected. Furthermore, in _dl_check_caller, there was a fallback reading global writable data (GL(dl_rtld_map).l_map_start and GL(dl_rtld_map).l_text_end), which could conceivably be targeted by an attacker to disable the check, too. Other critical functions (such as system) remain completely unprotected, so the value of these additional checks does not appear that large. Therefore this commit removes this functionality.
2018-01-01elf: check for rpath emptiness before making a copy of itDmitry V. Levin
* elf/dl-load.c (decompose_rpath): Check for rpath emptiness before making a copy of it.
2018-01-01Update copyright dates with scripts/update-copyrights.Joseph Myers
* All files with FSF copyright notices: Update copyright dates using scripts/update-copyrights. * locale/programs/charmap-kw.h: Regenerated. * locale/programs/locfile-kw.h: Likewise.
2017-12-30elf: Check for empty tokens before dynamic string token expansion [BZ #22625]Aurelien Jarno
The fillin_rpath function in elf/dl-load.c loops over each RPATH or RUNPATH tokens and interprets empty tokens as the current directory ("./"). In practice the check for empty token is done *after* the dynamic string token expansion. The expansion process can return an empty string for the $ORIGIN token if __libc_enable_secure is set or if the path of the binary can not be determined (/proc not mounted). Fix that by moving the check for empty tokens before the dynamic string token expansion. In addition, check for NULL pointer or empty strings return by expand_dynamic_string_token. The above changes highlighted a bug in decompose_rpath, an empty array is represented by the first element being NULL at the fillin_rpath level, but by using a -1 pointer in decompose_rpath and other functions. Changelog: [BZ #22625] * elf/dl-load.c (fillin_rpath): Check for empty tokens before dynamic string token expansion. Check for NULL pointer or empty string possibly returned by expand_dynamic_string_token. (decompose_rpath): Check for empty path after dynamic string token expansion.
2017-12-27elf: remove redundant is_path argumentDmitry V. Levin
is_path argument is no longer used and could be safely removed. * elf/dl-dst.h (DL_DST_COUNT): Remove is_path argument, all callers updated. * elf/dl-load.c (is_dst, _dl_dst_count, _dl_dst_substitute, expand_dynamic_string_token): Likewise. * sysdeps/generic/ldsodefs.h (_dl_dst_count, _dl_dst_substitute): Remove is_path argument.
2017-12-27elf: remove redundant code from is_dstDmitry V. Levin
is_dst is called either by _dl_dst_count or by _dl_dst_substitute. _dl_dst_count is called by DL_DST_COUNT only. DL_DST_COUNT is called either by expand_dst with is_path == 0 or by expand_dynamic_string_token. _dl_dst_substitute is called either from expand_dst with is_path == 0 or from expand_dynamic_string_token. The latter function is called either from _dl_map_object with is_path == 0 or from fillin_rpath with is_path == 1 and name containing no ':'. In any case (is_path && name[i] == ':') is always false and all code depending on it can be safely removed. * elf/dl-load.c (is_dst): Remove checks that is_path is set and name contains ':', and all code depending on these checks.
2017-12-27elf: remove redundant code from _dl_dst_substituteDmitry V. Levin
There are just two users of _dl_dst_substitute: one is expand_dst that sets is_path argument to 0, another one is expand_dynamic_string_token. The latter function also has just two users: one is _dl_map_object that sets is_path argument to 0, another one is fillin_rpath that sets is_path argument to 1 and name argument contains no ':'. In any case (is_path && name[i] == ':') is always false and all code depending on it can be safely removed. * elf/dl-load.c (_dl_dst_substitute): Remove checks that is_path is set and name contains ':', and all code depending on these checks.
2017-12-19elf: remove redundant __libc_enable_secure check from fillin_rpathDmitry V. Levin
There are just two users of fillin_rpath: one is decompose_rpath that sets check_trusted argument to 0, another one is _dl_init_paths that sets check_trusted argument to __libc_enable_secure and invokes fillin_rpath only when LD_LIBRARY_PATH is non-empty. Starting with commit glibc-2.25.90-512-gf6110a8fee2ca36f8e2d2abecf3cba9fa7b8ea7d, LD_LIBRARY_PATH is ignored for __libc_enable_secure executables, so check_trusted argument of fillin_rpath is always zero. * elf/dl-load.c (is_trusted_path): Remove. (fillin_rpath): Remove check_trusted argument and its use, all callers changed.
2017-12-18elf: do not substitute dst in $LD_LIBRARY_PATH twice [BZ #22627]Dmitry V. Levin
Starting with commit glibc-2.18.90-470-g2a939a7e6d81f109d49306bc2e10b4ac9ceed8f9 that introduced substitution of dynamic string tokens in fillin_rpath, _dl_init_paths invokes _dl_dst_substitute for $LD_LIBRARY_PATH twice: the first time it's called directly, the second time the result is passed on to fillin_rpath which calls expand_dynamic_string_token which in turn calls _dl_dst_substitute, leading to the following behaviour: $ mkdir -p /tmp/'$ORIGIN' && cd /tmp/'$ORIGIN' && echo 'int main(){}' |gcc -xc - && strace -qq -E LD_LIBRARY_PATH='$ORIGIN' -e /open ./a.out open("/tmp//tmp/$ORIGIN/tls/x86_64/libc.so.6", O_RDONLY|O_CLOEXEC) = -1 ENOENT (No such file or directory) open("/tmp//tmp/$ORIGIN/tls/libc.so.6", O_RDONLY|O_CLOEXEC) = -1 ENOENT (No such file or directory) open("/tmp//tmp/$ORIGIN/x86_64/libc.so.6", O_RDONLY|O_CLOEXEC) = -1 ENOENT (No such file or directory) open("/tmp//tmp/$ORIGIN/libc.so.6", O_RDONLY|O_CLOEXEC) = -1 ENOENT (No such file or directory) open("/etc/ld.so.cache", O_RDONLY|O_CLOEXEC) = 3 open("/lib64/libc.so.6", O_RDONLY|O_CLOEXEC) = 3 Fix this by removing the direct _dl_dst_substitute invocation. * elf/dl-load.c (_dl_init_paths): Remove _dl_dst_substitute preparatory code and invocation.
2017-12-14elf: Count components of the expanded path in _dl_init_path [BZ #22607]Florian Weimer
2017-12-14elf: Compute correct array size in _dl_init_paths [BZ #22606]Florian Weimer
2017-11-28Properly compute offsets of note descriptor and next note [BZ #22370]H.J. Lu
A note header has 3 4-bytes fields, followed by note name and note descriptor. According to gABI, in a note entry, the note name field, not note name size, is padded for the note descriptor. And the note descriptor field, not note descriptor size, is padded for the next note entry. Notes are aligned to 4 bytes in 32-bit objects and 8 bytes in 64-bit objects. For all GNU notes, the name is "GNU" which is 4 bytes. They have the same format in the first 16 bytes in both 32-bit and 64-bit objects. They differ by note descriptor size and note type. So far, .note.ABI-tag and .note.gnu.build-id notes are always aligned to 4 bytes. The exsting codes compute the note size by aligning the note name size and note descriptor size to 4 bytes. It happens to produce the same value as the actual note size by luck since the name size is 4 and offset of the note descriptor is 16. But it will produce the wrong size when note alignment is 8 bytes in 64-bit objects. This patch defines ELF_NOTE_DESC_OFFSET and ELF_NOTE_NEXT_OFFSET to properly compute offsets of note descriptor and next note. It uses alignment of PT_NOTE segment to support both 4-byte and 8-byte note alignments in 64-bit objects. To handle PT_NOTE segments with incorrect alignment, which may lead to an infinite loop, if segment alignment is less than 4, we treate alignment as 4 bytes since some note segments have 0 or 1 byte alignment. [BZ #22370] * elf/dl-hwcaps.c (ROUND): Removed. (_dl_important_hwcaps): Replace ROUND with ELF_NOTE_DESC_OFFSET and ELF_NOTE_NEXT_OFFSET. * elf/dl-load.c (ROUND): Removed. (open_verify): Replace ROUND with ELF_NOTE_NEXT_OFFSET. * elf/readelflib.c (ROUND): Removed. (process_elf_file): Replace ROUND with ELF_NOTE_NEXT_OFFSET. * include/elf.h [!_ISOMAC]: Include <libc-pointer-arith.h>. [!_ISOMAC] (ELF_NOTE_DESC_OFFSET): New. [!_ISOMAC] (ELF_NOTE_NEXT_OFFSET): Likewise.
2017-09-26Skip PT_DYNAMIC segment with p_filesz == 0 [BZ #22101]H.J. Lu
ELF objects generated with "objcopy --only-keep-debug" have Type Offset VirtAddr PhysAddr FileSiz MemSiz Flg Align DYNAMIC 0x0+e28 0x0+200e40 0x0+200e40 0x0+ 0x0+1a0 RW 0x8 with 0 file size. ld.so should skip such PT_DYNAMIC segments. Without a PT_DYNAMIC segment the loading of the shared object will fail, and therefore ldd on such objects will also fail instead of crashing. This provides better diagnostics for tooling that is attempting to inspect the invalid shared objects which may just contain debug information. [BZ #22101] * elf/Makefile (tests): Add tst-debug1. ($(objpfx)tst-debug1): New. ($(objpfx)tst-debug1.out): Likewise. ($(objpfx)tst-debug1mod1.so): Likewise. * elf/dl-load.c (_dl_map_object_from_fd): Skip PT_DYNAMIC segment with p_filesz == 0. * elf/tst-debug1.c: New file. Reviewed-by: Carlos O'Donell <carlos@redhat.com>
2017-08-31elf: Remove internal_function attributeFlorian Weimer
2017-03-01Narrowing the visibility of libc-internal.h even further.Zack Weinberg
posix/wordexp-test.c used libc-internal.h for PTR_ALIGN_DOWN; similar to what was done with libc-diag.h, I have split the definitions of cast_to_integer, ALIGN_UP, ALIGN_DOWN, PTR_ALIGN_UP, and PTR_ALIGN_DOWN to a new header, libc-pointer-arith.h. It then occurred to me that the remaining declarations in libc-internal.h are mostly to do with early initialization, and probably most of the files including it, even in the core code, don't need it anymore. Indeed, only 19 files actually need what remains of libc-internal.h. 23 others need libc-diag.h instead, and 12 need libc-pointer-arith.h instead. No file needs more than one of them, and 16 don't need any of them! So, with this patch, libc-internal.h stops including libc-diag.h as well as losing the pointer arithmetic macros, and all including files are adjusted. * include/libc-pointer-arith.h: New file. Define cast_to_integer, ALIGN_UP, ALIGN_DOWN, PTR_ALIGN_UP, and PTR_ALIGN_DOWN here. * include/libc-internal.h: Definitions of above macros moved from here. Don't include libc-diag.h anymore either. * posix/wordexp-test.c: Include stdint.h and libc-pointer-arith.h. Don't include libc-internal.h. * debug/pcprofile.c, elf/dl-tunables.c, elf/soinit.c, io/openat.c * io/openat64.c, misc/ptrace.c, nptl/pthread_clock_gettime.c * nptl/pthread_clock_settime.c, nptl/pthread_cond_common.c * string/strcoll_l.c, sysdeps/nacl/brk.c * sysdeps/unix/clock_settime.c * sysdeps/unix/sysv/linux/i386/get_clockfreq.c * sysdeps/unix/sysv/linux/ia64/get_clockfreq.c * sysdeps/unix/sysv/linux/powerpc/get_clockfreq.c * sysdeps/unix/sysv/linux/sparc/sparc64/get_clockfreq.c: Don't include libc-internal.h. * elf/get-dynamic-info.h, iconv/loop.c * iconvdata/iso-2022-cn-ext.c, locale/weight.h, locale/weightwc.h * misc/reboot.c, nis/nis_table.c, nptl_db/thread_dbP.h * nscd/connections.c, resolv/res_send.c, soft-fp/fmadf4.c * soft-fp/fmasf4.c, soft-fp/fmatf4.c, stdio-common/vfscanf.c * sysdeps/ieee754/dbl-64/e_lgamma_r.c * sysdeps/ieee754/dbl-64/k_rem_pio2.c * sysdeps/ieee754/flt-32/e_lgammaf_r.c * sysdeps/ieee754/flt-32/k_rem_pio2f.c * sysdeps/ieee754/ldbl-128/k_tanl.c * sysdeps/ieee754/ldbl-128ibm/k_tanl.c * sysdeps/ieee754/ldbl-96/e_lgammal_r.c * sysdeps/ieee754/ldbl-96/k_tanl.c, sysdeps/nptl/futex-internal.h: Include libc-diag.h instead of libc-internal.h. * elf/dl-load.c, elf/dl-reloc.c, locale/programs/locarchive.c * nptl/nptl-init.c, string/strcspn.c, string/strspn.c * malloc/malloc.c, sysdeps/i386/nptl/tls.h * sysdeps/nacl/dl-map-segments.h, sysdeps/x86_64/atomic-machine.h * sysdeps/unix/sysv/linux/spawni.c * sysdeps/x86_64/nptl/tls.h: Include libc-pointer-arith.h instead of libc-internal.h. * elf/get-dynamic-info.h, sysdeps/nacl/dl-map-segments.h * sysdeps/x86_64/atomic-machine.h: Add multiple include guard.
2017-01-01Update copyright dates with scripts/update-copyrights.Joseph Myers
2016-11-23elf: Assume TLS is initialized in _dl_map_object_from_fdFlorian Weimer
libc.so uses TLS data, so when dlopen is called later, the TLS data structures have already been initialized.
2016-01-04Update copyright dates with scripts/update-copyrights.Joseph Myers
2015-11-10NaCl: Use open_resource API for shared objectsRoland McGrath
2015-11-09ld.so: Add original DSO name if overridden by audit module [BZ #18251]Florian Weimer
* elf/dl-load.c (_dl_map_object_from_fd): Add additional parameter for original name of the DSO. Add it to the name list of the DSO if it is actually given. (_dl_map_object): Keep track of whether an audit module rewrote the file name. If yes, pass the original name to _dl_map_object_from_fd in a new parameter, otherwise NULL. When debugging is enabled, log the change of the file name. * sysdeps/mach/hur/dl-sysdep.c: Adjust commented-out call to _dl_map_object_from_fd. * elf/Makefile: Build and run tst-audit11 and tst-audit12. * elf/tst-audit11.c: New file * elf/tst-auditmod11.c: New file. * elf/tst-audit11mod1.c: New file. * elf/tst-audit11mod2.c: New file. * elf/tst-audit11mod2.map: New file. * elf/tst-audit12.c: New file * elf/tst-auditmod12.c: New file. * elf/tst-audit12mod1.c: New file. * elf/tst-audit12mod2.c: New file. * elf/tst-audit12mod2.map: New file. * elf/tst-audit12mod3.c: New file.
2015-09-18Use ALIGN_* macros in _dl_map_object_from_fd.Carlos O'Donell
Cleanup _dl_map_object_from_fd to make it clear exactly what we're doing with the mappings i.e. extending the the start of the map down to a page boundary, extending the end of the map up to a page boundary, and offset itself also to page boundary. The result is much easier to read as expected from the ALIGN_* cleanups.
2015-07-14Factor file identity rules out of generic rtld code.Roland McGrath
2015-01-25Fix segmentation fault when LD_LIBRARY_PATH contains only non-existings pathsBram
2015-01-21Fix recursive dlopen.Carlos O'Donell
The ability to recursively call dlopen is useful for malloc implementations that wish to load other dynamic modules that implement reentrant/AS-safe functions to use in their own implementation. Given that a user malloc implementation may be called by an ongoing dlopen to allocate memory the user malloc implementation interrupts dlopen and if it calls dlopen again that's a reentrant call. This patch fixes the issues with the ld.so.cache mapping and the _r_debug assertion which prevent this from working as expected. See: https://sourceware.org/ml/libc-alpha/2014-12/msg00446.html
2015-01-02Update copyright dates with scripts/update-copyrights.Joseph Myers
2014-10-31Add a hook to enable load-time inspection of program headersMatthew Fortune
This hook can be used to perform additional compatibility checks between shared libraries by inspecting custom program header information. * elf/dl-machine-reject-phdr.h: New file. * elf/dl-load.c: #include that. (open_verify): Call elf_machine_reject_phdr_p and ignore the file if that returned true.
2014-10-28elf/dl-load.c: Use __strdup.Carlos O'Donell
During a refactoring pass several repeated blocks of code in dl-load.c were turned into a call to a local function named local_strdup. There is no need for local_strdup, and the routines should instead call __strdup. This change does just that. We call the internal symbol __strdup because calling strdup is unsafe. The user might be using a standard that doesn't include strdup and may have defined this symbol in their application. During a static link we might reference the user defined symbol and crash if it doesn't implement a standards conforming strdup. The resulting code is simpler to understand, and makes it easier to debug. No regressions on x86_64. 2014-10-28 Carlos O'Donell <carlos@redhat.com> * dl-load.c (local_strdup): Remove. (expand_dynamic_string_token): Use __strdup. (decompose_rpath): Likewise. (_dl_map_object): Likewise.
2014-10-10Don't use INTVARDEF/INTUSE with __libc_enable_secure (bug 14132).Joseph Myers
Continuing the removal of the obsolete INTDEF / INTVARDEF / INTUSE mechanism, this patch replaces its use for __libc_enable_secure with the use of rtld_hidden_data_def and rtld_hidden_proto. Tested for x86_64 that installed stripped shared libraries are unchanged by the patch. [BZ #14132] * elf/dl-sysdep.c (__libc_enable_secure): Use rtld_hidden_data_def instead of INTVARDEF. (_dl_sysdep_start): Do not use INTUSE with __libc_enable_secure. * sysdeps/mach/hurd/dl-sysdep.c (__libc_enable_secure): Use rtld_hidden_data_def instead of INTVARDEF. (_dl_sysdep_start): Do not use INTUSE with __libc_enable_secure. * elf/dl-deps.c (expand_dst): Likewise. * elf/dl-load.c (_dl_dst_count): Likewise. (_dl_dst_substitute): Likewise. (decompose_rpath): Likewise. (_dl_init_paths): Likewise. (open_path): Likewise. (_dl_map_object): Likewise. * elf/rtld.c (dl_main): Likewise. (process_dl_audit): Likewise. (process_envvars): Likewise. * include/unistd.h [IS_IN_rtld] (__libc_enable_secure_internal): Remove declaration. (__libc_enable_secure): Use rtld_hidden_proto.
2014-10-09remove nested functions from elf/dl-load.cKostya Serebryany
2014-05-27Remove second argument from TLS_INIT_TP macroAndreas Schwab
2014-04-03Factor mmap/munmap of PT_LOAD segments out of _dl_map_object_from_fd et al.Roland McGrath
2014-03-272014-03-27 Paul Pluzhnikov <ppluzhnikov@google.com>Paul Pluzhnikov
* elf/dl-load.c: Finish conversion of __builtin_expect into __glibc_{un}likely.
2014-03-262014-03-26 Paul Pluzhnikov <ppluzhnikov@google.com>Paul Pluzhnikov
* elf/dl-load.c: Convert __builtin_expect into __glibc_{un}likely.
2014-03-24Fix BZ #16634.Paul Pluzhnikov
An application that erroneously tries to repeatedly dlopen("a.out", ...) may hit assertion failure: Inconsistency detected by ld.so: dl-tls.c: 474: _dl_allocate_tls_init: Assertion `listp != ((void *)0)' failed! dlopen() actually fails with "./a.out: cannot dynamically load executable", but it does so after incrementing dl_tls_max_dtv_idx. Once we run out of TLS_SLOTINFO_SURPLUS (62), we exit with above assertion failure. 2014-03-24 Paul Pluzhnikov <ppluzhnikov@google.com> [BZ #16634] * elf/dl-load.c (open_verify): Add mode parameter. Error early when ET_EXEC and mode does not have __RTLD_OPENEXEC. (open_path): Change from boolean 'secure' to complete flag 'mode' (_dl_map_object): Adjust. * elf/Makefile (tests): Add tst-dlopen-aout. * elf/tst-dlopen-aout.c: New test.
2014-03-122014-03-12 Paul Pluzhnikov <ppluzhnikov@google.com>Paul Pluzhnikov
[BZ #16381] * elf/Makefile (tests): Add tst-pie2. (tests-pie): Add tst-pie2. * elf/tst-pie2.c: New file. * elf/dl-load.c (_dl_map_object_from_fd): Assert correct l_type for ET_EXEC. * elf/rtld.c (map_doit): Load executable as lt_executable. (dl_main): Likewise.
2014-02-10Use glibc_likely instead __builtin_expect.Ondřej Bílka
2014-01-31[BZ #16046] Static dlopen correction fallout fixes.Maciej W. Rozycki
Fixes to address issues from BZ #15022 resolution, as follows: * TLS updates to csu/libc-tls.c -- we now have a proper main map, so there's no longer a need to create a separate fake one to keep TLS structures, * random updates to elf/dl-close.c -- LM_ID_BASE is now a valid name space ID for static executables as well, so assert that we don't unload the main map. Similarly dl_nns isn't supposed to be 0 for static executables anymore, * actual BZ #16046 fix to elf/dl-iteratephdr.c -- the dl_iterate_phdr special function for static executables isn't needed anymore, provided that l_phdr and l_phnum members of the main map have been properly initialized (done in _dl_non_dynamic_init in elf/dl-support.c now), * ld.so.cache loader update to elf/dl-load.c -- GL(dl_ns)[LM_ID_BASE]._ns_loaded is now always initialized in static executables so can become the fallback loader map to check for DF_1_NODEFLIB, provided that the l_flags_1 member of the main map has been properly initialized (done in elf/dl-support.c now); this also ensures previous semantics elsewhere in elf/dl-load.c, * matching updates to elf/dl-support.c -- to complement the two fixes above.
2014-01-08Obvious comment typo fix ("openened") in elf/dl-load.c.Brooks Moses
2014-01-01Update copyright notices with scripts/update-copyrightsAllan McRae
2013-12-02Return fixed version of breaking of RPATH when $ORIGIN contains colonsOndřej Bílka
2013-11-18Revert b75891075bece24be9fd85618f18af4a2daf7f1cOndřej Bílka
2013-11-18Fix breaking of RPATH when $ORIGIN contains colons. Fixes bug 10253Ondřej Bílka
We first expanded origin and then split string by colons. This misbehaves when $ORIGIN contain colon so we first split string, then expand $ORIGIN.
2013-08-21Fix typos.Ondřej Bílka
2013-06-28Test for mprotect failure in dl-load.c (bug 12492).Pierre Ynard
2013-06-28[BZ #15022] Correct global-scope dlopen issues in static executables.Maciej W. Rozycki
This change creates a link map in static executables to serve as the global search list for dlopen. It fixes a problem with the inability to access the global symbol object and a crash on an attempt to map a DSO into the global scope. Some code that has become dead after the addition of this link map is removed too and test cases are provided.