about summary refs log tree commit diff
path: root/src/ldso/dlerror.c
Commit message (Collapse)AuthorAgeFilesLines
* lift child restrictions after multi-threaded forkRich Felker2020-11-111-0/+2
| | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | as the outcome of Austin Group tracker issue #62, future editions of POSIX have dropped the requirement that fork be AS-safe. this allows but does not require implementations to synchronize fork with internal locks and give forked children of multithreaded parents a partly or fully unrestricted execution environment where they can continue to use the standard library (per POSIX, they can only portably use AS-safe functions). up until recently, taking this allowance did not seem desirable. however, commit 8ed2bd8bfcb4ea6448afb55a941f4b5b2b0398c0 exposed the extent to which applications and libraries are depending on the ability to use malloc and other non-AS-safe interfaces in MT-forked children, by converting latent very-low-probability catastrophic state corruption into predictable deadlock. dealing with the fallout has been a huge burden for users/distros. while it looks like most of the non-portable usage in applications could be fixed given sufficient effort, at least some of it seems to occur in language runtimes which are exposing the ability to run unrestricted code in the child as part of the contract with the programmer. any attempt at fixing such contracts is not just a technical problem but a social one, and is probably not tractable. this patch extends the fork function to take locks for all libc singletons in the parent, and release or reset those locks in the child, so that when the underlying fork operation takes place, the state protected by these locks is consistent and ready for the child to use. locking is skipped in the case where the parent is single-threaded so as not to interfere with legacy AS-safety property of fork in single-threaded programs. lock order is mostly arbitrary, but the malloc locks (including bump allocator in case it's used) must be taken after the locks on any subsystems that might use malloc, and non-AS-safe locks cannot be taken while the thread list lock is held, imposing a requirement that it be taken last.
* convert malloc use under libc-internal locks to use internal allocatorRich Felker2020-11-111-0/+5
| | | | | | | | | | | | | this change lifts undocumented restrictions on calls by replacement mallocs to libc functions that might take these locks, and sets the stage for lifting restrictions on the child execution environment after multithreaded fork. care is taken to #define macros to replace all four functions (malloc, calloc, realloc, free) even if not all of them will be used, using an undefined symbol name for the ones intended not to be used so that any inadvertent future use will be caught at compile time rather than directed to the wrong implementation.
* dlerror: don't gratuitously hold freebuf_queue lock while freeingRich Felker2020-11-111-5/+8
| | | | | | | | | | | | | | | | | | | | | | | | | thread-local buffers allocated for dlerror need to be queued for free at a later time when the owning thread exits, since malloc may be replaced by application code and the exiting context is not valid to call application code from. the code to process queue of pending frees, introduced in commit aa5a9d15e09851f7b4a1668e9dbde0f6234abada, gratuitously held the lock for the entire duration of queue processing, updating the global queue pointer after each free, despite there being no logical requirement that all frees finish before another thread can access the queue. instead, immediately claim the whole queue for freeing and release the lock, then walk the list and perform frees without the lock held. the change is unlikely to make any meaningful difference to performance, but it eliminates one point where the allocator is called under an internal lock. since the allocator may be application-provided, such calls are undesirable because they allow application code to impede forward progress of libc functions in other threads arbitrarily long, and to induce deadlock if it calls a libc function that requires the same lock. the change also eliminates a lock ordering consideration that's an impediment upcoming work with multithreaded fork.
* defer free of thread-local dlerror buffers from inconsistent contextRich Felker2019-02-151-2/+20
| | | | | | | | | | __dl_thread_cleanup is called from the context of an exiting thread that is not in a consistent state valid for calling application code. since commit c9f415d7ea2dace5bf77f6518b6afc36bb7a5732, it's possible (and supported usage) for the allocator to have been replaced by the application, so __dl_thread_cleanup can no longer call free. instead, reuse the message buffer as a linked-list pointer, and queue it to be freed the next time any dynamic linker error message is generated.
* reduce spurious inclusion of libc.hRich Felker2018-09-121-1/+0
| | | | | | | | | | | | | | | | | | | | | libc.h was intended to be a header for access to global libc state and related interfaces, but ended up included all over the place because it was the way to get the weak_alias macro. most of the inclusions removed here are places where weak_alias was needed. a few were recently introduced for hidden. some go all the way back to when libc.h defined CANCELPT_BEGIN and _END, and all (wrongly implemented) cancellation points had to include it. remaining spurious users are mostly callers of the LOCK/UNLOCK macros and files that use the LFS64 macro to define the awful *64 aliases. in a few places, new inclusion of libc.h is added because several internal headers no longer implicitly include libc.h. declarations for __lockfile and __unlockfile are moved from libc.h to stdio_impl.h so that the latter does not need libc.h. putting them in libc.h made no sense at all, since the macros in stdio_impl.h are needed to use them correctly anyway.
* move tlsdesc and internal dl function declarations to dynlink.hRich Felker2018-09-121-2/+1
|
* define and use internal macros for hidden visibility, weak refsRich Felker2018-09-051-6/+3
| | | | | | | | | this cleans up what had become widespread direct inline use of "GNU C" style attributes directly in the source, and lowers the barrier to increased use of hidden visibility, which will be useful to recovering some of the efficiency lost when the protected visibility hack was dropped in commit dc2f368e565c37728b0d620380b849c3a1ddd78f, especially on archs where the PLT ABI is costly.
* move static-linked stub invalid dso handle checking out of dynlink.cRich Felker2016-01-251-0/+12
|
* factor dlerror and error-setting code out of dynlink.cRich Felker2016-01-251-0/+52
the ultimate goal of this change is to get all code used in libc.a out of dynlink.c, so that the dynamic linker code can be moved to its own tree and object files in the src tree can all be shared between libc.a and libc.so.