about summary refs log tree commit diff
path: root/elf
Commit message (Collapse)AuthorAgeFilesLines
...
* elf: Remove redundant add_to_global_resize_failure call from dl_open_argsFlorian Weimer2020-05-121-5/+0
| | | | | | | | | | The second call does not do anything because the data structures have already been resized by the call that comes before the demarcation point. Fixes commit a509eb117fac1d764b15eba64993f4bdb63d7f3c ("Avoid late dlopen failure due to scope, TLS slotinfo updates [BZ #25112]"). Reviewed-by: Carlos O'Donell <carlos@redhat.com>
* Rename __LONG_DOUBLE_USES_FLOAT128 to __LDOUBLE_REDIRECTS_TO_FLOAT128_ABIPaul E. Murphy2020-04-301-1/+1
| | | | | | | | | | | | | | | Improve the commentary to aid future developers who will stumble upon this novel, yet not always perfect, mechanism to support alternative formats for long double. Likewise, rename __LONG_DOUBLE_USES_FLOAT128 to __LDOUBLE_REDIRECTS_TO_FLOAT128_ABI now that development work has settled down. The command used was git grep -l __LONG_DOUBLE_USES_FLOAT128 ':!./ChangeLog*' | \ xargs sed -i 's/__LONG_DOUBLE_USES_FLOAT128/__LDOUBLE_REDIRECTS_TO_FLOAT128_ABI/g' Reviewed-by: Tulio Magno Quites Machado Filho <tuliom@linux.ibm.com>
* elf: Add initial flag argument to __libc_early_initFlorian Weimer2020-04-295-11/+29
| | | | | | | | | | | The rseq initialization should happen only for the libc in the base namespace (in the dynamic case) or the statically linked libc. The __libc_multiple_libcs flag does not quite cover this case at present, so this commit introduces a flag argument to __libc_early_init, indicating whether the libc being libc is the primary one (of the main program). Reviewed-by: Carlos O'Donell <carlos@redhat.com>
* elf: Implement __libc_early_initFlorian Weimer2020-04-249-2/+261
| | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | This function is defined in libc.so, and the dynamic loader calls right after relocation has been finished, before any ELF constructors or the preinit function is invoked. It is also used in the static build for initializing parts of the static libc. To locate __libc_early_init, a direct symbol lookup function is used, _dl_lookup_direct. It does not search the entire symbol scope and consults merely a single link map. This function could also be used to implement lookups in the vDSO (as an optimization). A per-namespace variable (libc_map) is added for locating libc.so, to avoid repeated traversals of the search scope. It is similar to GL(dl_initfirst). An alternative would have been to thread a context argument from _dl_open down to _dl_map_object_from_fd (where libc.so is identified). This could have avoided the global variable, but the change would be larger as a result. It would not have been possible to use this to replace GL(dl_initfirst) because that global variable is used to pass the function pointer past the stack switch from dl_main to the main program. Replacing that requires adding a new argument to _dl_init, which in turn needs changes to the architecture-specific libc.so startup code written in assembler. __libc_early_init should not be used to replace _dl_var_init (as it exists today on some architectures). Instead, _dl_lookup_direct should be used to look up a new variable symbol in libc.so, and that should then be initialized from the dynamic loader, immediately after the object has been loaded in _dl_map_object_from_fd (before relocation is run). This way, more IFUNC resolvers which depend on these variables will work. Reviewed-by: Carlos O'Donell <carlos@redhat.com>
* elf: Introduce <elf_machine_sym_no_match.h>Florian Weimer2020-04-241-8/+2
| | | | | | | | | | | MIPS needs to ignore certain existing symbols during symbol lookup. The old scheme uses the ELF_MACHINE_SYM_NO_MATCH macro, with an inline function, within its own header, with a sysdeps override for MIPS. This allows re-use of the function from another file (without having to include <dl-machine.h> or providing the default definition for ELF_MACHINE_SYM_NO_MATCH). Reviewed-by: Carlos O'Donell <carlos@redhat.com>
* elf: Support lld-style link map for librtld.mapFangrui Song2020-04-211-1/+2
| | | | | | | | | | | | | GNU ld and gold's -Map include a line like: path/to/build/libc_pic.a(check_fds.os) lld -Map does not have the archive member list, but we can still derive the members from the following output VMA LMA Size Align Out In Symbol ... 1a1c0 1a1c0 e2 16 path/to/build/libc_pic.a(check_fds.os):(.text)
* elf: Implement DT_AUDIT, DT_DEPAUDIT support [BZ #24943]Florian Weimer2020-04-038-3/+273
| | | | | | | binutils ld has supported --audit, --depaudit for a long time, only support in glibc has been missing. Reviewed-by: Carlos O'Donell <carlos@redhat.com>
* elf: Simplify handling of lists of audit stringsFlorian Weimer2020-04-031-117/+112
| | | | | | | | | | | | | | | | All list elements are colon-separated strings, and there is a hard upper limit for the number of audit modules, so it is possible to pre-allocate a fixed-size array of strings to which the LD_AUDIT environment variable and --audit arguments are added. Also eliminate the global variables for the audit list because the list is only needed briefly during startup. There is a slight behavior change: All duplicate LD_AUDIT environment variables are now processed, not just the last one as before. However, such environment vectors are invalid anyway. Reviewed-by: Carlos O'Donell <carlos@redhat.com>
* ARC: add definitions to elf/elf.hVineet Gupta2020-03-251-1/+69
| | | | Signed-off-by: Vineet Gupta <vgupta@synopsys.com>
* Fix tests which expose ldbl -> _Float128 redirectsPaul E. Murphy2020-03-251-0/+11
| | | | | | | | | | | | | | | | | | The ldbl redirects for ieee128 have some jagged edges when inspecting and manipulating symbols directly. e.g asprintf is unconditionally redirected to __asprintfieee128 thus any tests relying on GCC's redirect behavior will encounter problems if they inspect the symbol names too closely. I've mitigated tests which expose the limitations of the ldbl -> f128 redirects by giving them knowledge about the redirected symbol names. Hopefully there isn't much user code which depends on this implementation specific behavior. Reviewed-by: Tulio Magno Quites Machado Filho <tuliom@linux.ibm.com>
* parse_tunables: Fix typo in commentJonathan Wakely2020-03-131-1/+1
|
* ldconfig: trace origin paths with -vDJ Delorie2020-03-111-6/+24
| | | | | | With this patch, -v turns on a "from" trace for each directory searched, that tells you WHY that directory is being searched - is it a builtin, from the command line, or from some config file?
* elf: Fix wrong indentation from commit eb447b7b4bAdhemerval Zanella2020-03-101-5/+6
|
* elf: Add elf/check-wx-segment, a test for the presence of WX segmentsFlorian Weimer2020-03-021-0/+7
| | | | | | | Writable, executable segments defeat security hardening. The existing check for DT_TEXTREL does not catch this. hppa and SPARC currently keep the PLT in an RWX load segment.
* elf: Apply attribute_relro to pointers in elf/dl-minimal.cFlorian Weimer2020-02-261-8/+8
| | | | | | | | | | | | | The present code leaves the function pointers unprotected, but moves some of the static functions into .data.rel.ro instead. This causes the linker to produce an allocatable, executable, writable section and eventually an RWX load segment. Not only do we really do not want that, it also breaks valgrind because valgrind does not load debuginfo from the mmap interceptor if all it sees are RX and RWX mappings. Fixes commit 3a0ecccb599a6b1ad4b149dc569c0080e92d057b ("ld.so: Do not export free/calloc/malloc/realloc functions [BZ #25486]").
* csu: Use ELF constructor instead of _init in libc.soFlorian Weimer2020-02-251-1/+1
| | | | | | | | On !ELF_INITFINI architectures, _init is no longer called by the dynamic linker. We can use an ELF constructor instead because the constructor order does not matter. (The other constructors are used to set up libio vtable bypasses and do not depend on this initialization routine.)
* Introduce <elf-initfini.h> and ELF_INITFINI for all architecturesFlorian Weimer2020-02-182-8/+5
| | | | | | | | | | | | | | | | This supersedes the init_array sysdeps directory. It allows us to check for ELF_INITFINI in both C and assembler code, and skip DT_INIT and DT_FINI processing completely on newer architectures. A new header file is needed because <dl-machine.h> is incompatible with assembler code. <sysdep.h> is compatible with assembler code, but it cannot be included in all assembler files because on some architectures, it redefines register names, and some assembler files conflict with that. <elf-initfini.h> is replicated for legacy architectures which need DT_INIT/DT_FINI support. New architectures follow the generic default and disable it.
* ld.so: Do not export free/calloc/malloc/realloc functions [BZ #25486]Florian Weimer2020-02-155-19/+103
| | | | | | | | | | | | | | | | | | | Exporting functions and relying on symbol interposition from libc.so makes the choice of implementation dependent on DT_NEEDED order, which is not what some compiler drivers expect. This commit replaces one magic mechanism (symbol interposition) with another one (preprocessor-/compiler-based redirection). This makes the hand-over from the minimal malloc to the full malloc more explicit. Removing the ABI symbols is backwards-compatible because libc.so is always in scope, and the dynamic loader will find the malloc-related symbols there since commit f0b2132b35248c1f4a80f62a2c38cddcc802aa8c ("ld.so: Support moving versioned symbols between sonames [BZ #24741]"). Reviewed-by: Carlos O'Donell <carlos@redhat.com>
* elf: Extract _dl_sym_post, _dl_sym_find_caller_map from elf/dl-sym.cFlorian Weimer2020-02-152-82/+110
| | | | | | | The definitions are moved into a new file, elf/dl-sym-post.h, so that this code can be used by the dynamic loader as well. Reviewed-by: Carlos O'Donell <carlos@redhat.com>
* elf: Introduce the rtld-stubbed-symbols makefile variableFlorian Weimer2020-02-151-9/+13
| | | | | | | This generalizes a mechanism used for stack-protector support, so that it can be applied to other symbols if required. Reviewed-by: Carlos O'Donell <carlos@redhat.com>
* elf: avoid stack allocation in dl_open_workerDavid Kilroy2020-02-121-16/+12
| | | | | | | | | | | | As the sort was removed, there's no need to keep a separate map of links. Instead, when relocating objects iterate over l_initfini directly. This allows us to remove the loop copying l_initfini elements into map. We still need a loop to identify the first and last elements that need relocation. Tested by running the testsuite on x86_64.
* elf: avoid redundant sort in dlopenDavid Kilroy2020-02-121-4/+4
| | | | | | | l_initfini is already sorted by dependency in _dl_map_object_deps(), so avoid sorting again in dl_open_worker(). Tested by running the testsuite on x86_64.
* elf: Allow dlopen of filter object to work [BZ #16272]David Kilroy2020-02-1211-16/+327
| | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | There are two fixes that are needed to be able to dlopen filter objects. First _dl_map_object_deps cannot assume that map will be at the beginning of l_searchlist.r_list[], as filtees are inserted before map. Secondly dl_open_worker needs to ensure that filtees get relocated. In _dl_map_object_deps: * avoiding removing relocation dependencies of map by setting l_reserved to 0 and otherwise processing the rest of the search list. * ensure that map remains at the beginning of l_initfini - the list of things that need initialisation (and destruction). Do this by splitting the copy up. This may not be required, but matches the initialization order without dlopen. Modify dl_open_worker to relocate the objects in new->l_inifini. new->l_initfini is constructed in _dl_map_object_deps, and lists the objects that need initialization and destruction. Originally the list of objects in new->l_next are relocated. All of these objects should also be included in new->l_initfini (both lists are populated with dependencies in _dl_map_object_deps). We can't use new->l_prev to pick up filtees, as during a recursive dlopen from an interposed malloc call, l->prev can contain objects that are not ready for relocation. Add tests to verify that symbols resolve to the filtee implementation when auxiliary and filter objects are used, both as a normal link and when dlopen'd. Tested by running the testsuite on x86_64.
* elf.h: Add R_RISCV_IRELATIVEFangrui Song2020-02-121-1/+2
| | | | | | The number has been officially assigned by https://github.com/riscv/riscv-elf-psabi-doc/pull/131 https://github.com/riscv/riscv-elf-psabi-doc/commit/d21ca40a7f56812a15e97450b7bc1599c0d35b82
* Fix elf/tst-rtld-preload cross-testing.Joseph Myers2020-01-242-9/+8
| | | | | | | | | | | | | | | | | As noted in <https://sourceware.org/ml/libc-alpha/2019-06/msg00824.html>, elf/tst-rtld-preload fails when cross-testing because it attempts to run the test wrapper with itself. Unfortunately, that thread never resulted in a complete and correct patch for that test. This patch addresses the issues with that test more thoroughly. The test is changed not to use the wrapper twice, including updating the message it prints about the command it runs to be more complete and accurate after the change; the Makefile is changed not to pass the redundant '$(test-wrapper)' argument. Tested for Arm that this fixes the failure seen for that test in cross-testing.
* Fix cross-testing of tst-ifunc-fault-* tests.Joseph Myers2020-01-231-3/+4
| | | | | | | | | | The tests elf/tst-ifunc-fault-bindnow and elf/tst-ifunc-fault-lazy fail in cross-testing because they run the dynamic linker directly without using the test wrapper. This patch fixes them to use the test wrapper instead. Tested that this fixes the failure of those two tests for powerpc soft-float.
* powerpc: Move cache line size to rtld_global_roTulio Magno Quites Machado Filho2020-01-172-4/+2
| | | | | | | | | | | | | | GCC 10.0 enabled -fno-common by default and this started to point that __cache_line_size had been implemented in 2 different places: loader and libc. In order to avoid this duplication, the libc variable has been removed and the loader variable is moved to rtld_global_ro. File sysdeps/unix/sysv/linux/powerpc/dl-auxv.h has been added in order to reuse code for both static and dynamic linking scenarios. Reviewed-by: Carlos O'Donell <carlos@redhat.com>
* elf: Add elf/tst-dlopenfail-2 [BZ #25396]Florian Weimer2020-01-163-2/+83
| | | | | | | | | | | | | Without CET, a jump into a newly loaded object through an overwritten link map often does not crash, it just executes some random code. CET detects this in some cases because the function pointer does not point to the start of a function in the replacement shared object, so there is no ENDBR instruction. The new test uses a small shared object and the existing dangling link map to trigger the bug. Reviewed-by: Siddhesh Poyarekar <siddhesh@sourceware.org>
* Clear GL(dl_initfirst) when freeing its link_map memory [BZ# 25396]H.J. Lu2020-01-161-0/+4
| | | | | | | | We should clear GL(dl_initfirst) when freeing its link_map memory. Tested on Fedora 31/x86-64 with CET. Reviewed-by: Florian Weimer <fweimer@redhat.com>
* Fix "elf: Add tst-ldconfig-ld_so_conf-update test" on 32bit.Stefan Liebler2020-01-131-2/+4
| | | | | | | | | | This new test was introduced with recent commit 591236f1a33f11cc65ccf009d997071ba853e186. If run on 32bit, it fails while renaming tst-ldconfig-ld-mod.so as there is no /usr/lib64 directory. This patch is constructing the file name with help of support_libdir_prefix. Reviewed-by: Siddhesh Poyarekar <siddhesh@sourceware.org>
* elf: Add tst-ldconfig-ld_so_conf-update testAlexandra Hájková2020-01-095-3/+132
| | | | | | | | Test ldconfig after /etc/ld.so.conf update and verify a running process observes changes to /etc/ld.so.cache. The test uses the test-in-container framework. Reviewed-by: Arjun Shankar <arjun@redhat.com>
* elf: Move vDSO setup to rtld (BZ#24967)Adhemerval Zanella2020-01-032-1/+13
| | | | | | | | | | | | | | | | | | | | | | | | This patch moves the vDSO setup from libc to loader code, just after the vDSO link_map setup. For static case the initialization is moved to _dl_non_dynamic_init instead. Instead of using the mangled pointer, the vDSO data is set as attribute_relro (on _rtld_global_ro for shared or _dl_vdso_* for static). It is read-only even with partial relro. It fixes BZ#24967 now that the vDSO pointer is setup earlier than malloc interposition is called. Also, vDSO calls should not be a problem for static dlopen as indicated by BZ#20802. The vDSO pointer would be zero-initialized and the syscall will be issued instead. Checked on x86_64-linux-gnu, i686-linux-gnu, aarch64-linux-gnu, arm-linux-gnueabihf, powerpc64le-linux-gnu, powerpc64-linux-gnu, powerpc-linux-gnu, s390x-linux-gnu, sparc64-linux-gnu, and sparcv9-linux-gnu. I also run some tests on mips. Reviewed-by: Siddhesh Poyarekar <siddhesh@sourceware.org>
* elf: Enable relro for static buildAdhemerval Zanella2020-01-031-4/+14
| | | | | | | | | | | | | | | | | | | | | The code is similar to the one at elf/dl-reloc.c, where it checks for the l_relro_size from the link_map (obtained from PT_GNU_RELRO header from program headers) and calls_dl_protected_relro. For testing I will use the ones proposed by Florian's patch 'elf: Add tests for working RELRO protection' [1]. Checked on x86_64-linux-gnu, i686-linux-gnu, powerpc64le-linux-gnu, aarch64-linux-gnu, s390x-linux-gnu, and sparc64-linux-gnu. I also check with --enable-static pie on x86_64-linux-gnu, i686-linux-gnu, and aarch64-linux-gnu which seems the only architectures where static PIE is actually working (as per 9d7a3741c9e, on arm-linux-gnueabihf, powerpc64{le}-linux-gnu, and s390x-linux-gnu I am seeing runtime issues not related to my patch). [1] https://sourceware.org/ml/libc-alpha/2019-10/msg00059.html Reviewed-by: Siddhesh Poyarekar <siddhesh@sourceware.org>
* Update copyright dates not handled by scripts/update-copyrights.Joseph Myers2020-01-015-5/+5
| | | | | | | | | | | | | | | I've updated copyright dates in glibc for 2020. This is the patch for the changes not generated by scripts/update-copyrights and subsequent build / regeneration of generated files. As well as the usual annual updates, mainly dates in --version output (minus libc.texinfo which previously had to be handled manually but is now successfully updated by update-copyrights), there is a fix to sysdeps/unix/sysv/linux/powerpc/bits/termios-c_lflag.h where a typo in the copyright notice meant it failed to be updated automatically. Please remember to include 2020 in the dates for any new files added in future (which means updating any existing uncommitted patches you have that add new files to use the new copyright dates in them).
* Update copyright dates with scripts/update-copyrights.Joseph Myers2020-01-01212-212/+212
|
* Fix test isolation for elf/tst-ifunc-fault-lazy, elf/tst-ifunc-fault-bindnowFlorian Weimer2019-12-191-4/+3
| | | | | | | Previously, ld.so was invoked only with the elf subdirectory on the library search path. Since the soname link for libc.so only exists in the top-level build directory, this leaked the system libc into the test.
* tunables: report sbrk() failureDJ Delorie2019-12-161-5/+4
| | | | Reviewed-by: Carlos O'Donell <carlos@redhat.com>
* dlopen: Do not block signalsFlorian Weimer2019-12-131-26/+11
| | | | | | | | | | | | | | | | | | Blocking signals causes issues with certain anti-malware solutions which rely on an unblocked SIGSYS signal for system calls they intercept. This reverts commit a2e8aa0d9ea648068d8be52dd7b15f1b6a008e23 ("Block signals during the initial part of dlopen") and adds comments related to async signal safety to active_nodelete and its caller. Note that this does not make lazy binding async-signal-safe with regards to dlopen. It merely avoids introducing new async-signal-safety hazards as part of the NODELETE changes. Reviewed-by: Adhemerval Zanella <adhemerval.zanella@linaro.org> Reviewed-by: Carlos O'Donell <carlos@redhat.com>
* dlopen: Rework handling of pending NODELETE statusFlorian Weimer2019-12-134-38/+51
| | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | Commit a2e8aa0d9ea648068d8be52dd7b15f1b6a008e23 ("Block signals during the initial part of dlopen") was deemed necessary because of read-modify-write operations like the one in add_dependency in elf/dl-lookup.c. In the old code, we check for any kind of NODELETE status and bail out: /* Redo the NODELETE check, as when dl_load_lock wasn't held yet this could have changed. */ if (map->l_nodelete != link_map_nodelete_inactive) goto out; And then set pending status (during relocation): if (flags & DL_LOOKUP_FOR_RELOCATE) map->l_nodelete = link_map_nodelete_pending; else map->l_nodelete = link_map_nodelete_active; If a signal arrives during relocation and the signal handler, through lazy binding, adds a global scope dependency on the same map, it will set map->l_nodelete to link_map_nodelete_active. This will be overwritten with link_map_nodelete_pending by the dlopen relocation code. To avoid such problems in relation to the l_nodelete member, this commit introduces two flags for active NODELETE status (irrevocable) and pending NODELETE status (revocable until activate_nodelete is invoked). As a result, NODELETE processing in dlopen does not introduce further reasons why lazy binding from signal handlers is unsafe during dlopen, and a subsequent commit can remove signal blocking from dlopen. This does not address pre-existing issues (unrelated to the NODELETE changes) which make lazy binding in a signal handler during dlopen unsafe, such as the use of malloc in both cases. Reviewed-by: Adhemerval Zanella <adhemerval.zanella@linaro.org> Reviewed-by: Carlos O'Donell <carlos@redhat.com>
* dlopen: Fix issues related to NODELETE handling and relocationsFlorian Weimer2019-12-1323-32/+992
| | | | | | | | | | | | | | | | | | | | | | | | | The assumption behind the assert in activate_nodelete was wrong: Inconsistency detected by ld.so: dl-open.c: 459: activate_nodelete: Assertion `!imap->l_init_called || imap->l_type != lt_loaded' failed! (edit) It can happen that an already-loaded object that is in the local scope is promoted to NODELETE status, via binding to a unique symbol. Similarly, it is possible that such NODELETE promotion occurs to an already-loaded object from the global scope. This is why the loop in activate_nodelete has to cover all objects in the namespace of the new object. In do_lookup_unique, it could happen that the NODELETE status of an already-loaded object was overwritten with a pending NODELETE status. As a result, if dlopen fails, this could cause a loss of the NODELETE status of the affected object, eventually resulting in an incorrect unload. Fixes commit f63b73814f74032c0e5d0a83300e3d864ef905e5 ("Remove all loaded objects if dlopen fails, ignoring NODELETE [BZ #20839]").
* ldconfig: Do not print a warning for a missing ld.so.conf fileFlorian Weimer2019-12-111-2/+3
| | | | | | | The configuration file is not needed for working system, so printing a warning is not helpful. Reviewed-by: Carlos O'Donell <carlos@redhat.com>
* Expand $(as-needed) and $(no-as-needed) throughout the build systemFlorian Weimer2019-12-031-24/+24
| | | | | | | | | Since commit a3cc4f48e94f32c9532ee36982ac00eb1e5719b0 ("Remove --as-needed configure test."), --as-needed support is no longer optional. The macros are not much shorter and do not provide documentary value, either, so this commit removes them.
* elf: Do not run IFUNC resolvers for LD_DEBUG=unused [BZ #24214]Florian Weimer2019-12-023-0/+94
| | | | | | | | | This commit adds missing skip_ifunc checks to aarch64, arm, i386, sparc, and x86_64. A new test case ensures that IRELATIVE IFUNC resolvers do not run in various diagnostic modes of the dynamic loader. Reviewed-By: Szabolcs Nagy <szabolcs.nagy@arm.com>
* elf/tst-dlopenfail: Disable --no-as-needed for tst-dlopenfailmod1.soFlorian Weimer2019-12-021-2/+5
| | | | | Otherwise, the shared object dependency which triggers the load failure is dropped, invalidating the test.
* Move _dl_open_check to its original place in dl_open_workerFlorian Weimer2019-11-271-6/+2
| | | | | | | | | | | | This reverts the non-test change from commit d0093c5cefb7f7a4143f ("Call _dl_open_check after relocation [BZ #24259]"), given that the underlying bug has been fixed properly in commit 61b74477fa7f63 ("Remove all loaded objects if dlopen fails, ignoring NODELETE [BZ #20839]"). Tested on x86-64-linux-gnu, with and without --enable-cet. Change-Id: I995a6cfb89f25d2b0cf5e606428c2a93eb48fc33
* Block signals during the initial part of dlopenFlorian Weimer2019-11-271-2/+26
| | | | | | | | | | | Lazy binding in a signal handler that interrupts a dlopen sees intermediate dynamic linker state. This has likely been always unsafe, but with the new pending NODELETE state, this is clearly incorrect. Other threads are excluded via the loader lock, but the current thread is not. Blocking signals until right before ELF constructors run is the safe thing to do. Change-Id: Iad079080ebe7442c13313ba11dc2797953faef35
* Remove all loaded objects if dlopen fails, ignoring NODELETE [BZ #20839]Florian Weimer2019-11-279-38/+308
| | | | | | | | | | | | | This introduces a “pending NODELETE” state in the link map, which is flipped to the persistent NODELETE state late in dlopen, via activate_nodelete. During initial relocation, symbol binding records pending NODELETE state only. dlclose ignores pending NODELETE state. Taken together, this results that a partially completed dlopen is rolled back completely because new NODELETE mappings are unloaded. Tested on x86_64-linux-gnu and i386-linux-gnu. Change-Id: Ib2a3d86af6f92d75baca65431d74783ee0dbc292
* Avoid late dlopen failure due to scope, TLS slotinfo updates [BZ #25112]Florian Weimer2019-11-273-129/+249
| | | | | | | | | | | | | | | | | | | | | | | | This change splits the scope and TLS slotinfo updates in dlopen into two parts: one to resize the data structures, and one to actually apply the update. The call to add_to_global_resize in dl_open_worker is moved before the demarcation point at which no further memory allocations are allowed. _dl_add_to_slotinfo is adjusted to make the list update optional. There is some optimization possibility here because we could grow the slotinfo list of arrays in a single call, one the largest TLS modid is known. This commit does not fix the fatal meory allocation failure in _dl_update_slotinfo. Ideally, this error during dlopen should be recoverable. The update order of scopes and TLS data structures is retained, although it appears to be more correct to fully initialize TLS first, and then expose symbols in the newly loaded objects via the scope update. Tested on x86_64-linux-gnu. Change-Id: I240c58387dabda3ca1bcab48b02115175fa83d6c
* Avoid late failure in dlopen in global scope update [BZ #25112]Florian Weimer2019-11-271-48/+106
| | | | | | | | | | | | | | | | | | | | | | | | | | | The call to add_to_global in dl_open_worker happens after running ELF constructors for new objects. At this point, proper recovery from malloc failure would be quite complicated: We would have to run the ELF destructors and close all opened objects, something that we currently do not do. Instead, this change splits add_to_global into two phases, add_to_global_resize (which can raise an exception, called before ELF constructors run), and add_to_global_update (which cannot, called after ELF constructors). A complication arises due to recursive dlopen: After the inner dlopen consumes some space, the pre-allocation in the outer dlopen may no longer be sufficient. A new member in the namespace structure, _ns_global_scope_pending_adds keeps track of the maximum number of objects that need to be added to the global scope. This enables the inner add_to_global_resize call to take into account the needs of an outer dlopen. Most code in the dynamic linker assumes that the number of global scope entries fits into an unsigned int (matching the r_nlist member of struct r_scop_elem). Therefore, change the type of _ns_global_scope_alloc to unsigned int (from size_t), and add overflow checks. Change-Id: Ie08e2f318510d5a6a4bcb1c315f46791b5b77524
* Lazy binding failures during dlopen/dlclose must be fatal [BZ #24304]Florian Weimer2019-11-276-21/+210
| | | | | | | | | | | | | | | | | | | | | If a lazy binding failure happens during the execution of an ELF constructor or destructor, the dynamic loader catches the error and reports it using the dlerror mechanism. This is undesirable because there could be other constructors and destructors that need processing (which are skipped), and the process is in an inconsistent state at this point. Therefore, we have to issue a fatal dynamic loader error error and terminate the process. Note that the _dl_catch_exception in _dl_open is just an inner catch, to roll back some state locally. If called from dlopen, there is still an outer catch, which is why calling _dl_init via call_dl_init and a no-exception is required and cannot be avoiding by moving the _dl_init call directly into _dl_open. _dl_fini does not need changes because it does not install an error handler, so errors are already fatal there. Change-Id: I6b1addfe2e30f50a1781595f046f44173db9491a