about summary refs log tree commit diff
path: root/sysdeps
diff options
context:
space:
mode:
authorFlorian Weimer <fw@deneb.enyo.de>2019-10-28 13:15:19 +0100
committerFlorian Weimer <fw@deneb.enyo.de>2019-10-28 14:31:05 +0100
commit93e07b2f9ef6825c7165f4587d2204464c83959a (patch)
tree4425fc20f7ee96db1122d8772397240c47865dc7 /sysdeps
parentf0ead7b63b95ef1920197f50b6d4abf407f9ebe7 (diff)
downloadglibc-93e07b2f9ef6825c7165f4587d2204464c83959a.tar.gz
glibc-93e07b2f9ef6825c7165f4587d2204464c83959a.tar.xz
glibc-93e07b2f9ef6825c7165f4587d2204464c83959a.zip
Avoid late dlopen failure due to scope, TLS slotinfo updates [BZ #25112]
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_prepare 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.
Diffstat (limited to 'sysdeps')
-rw-r--r--sysdeps/generic/ldsodefs.h11
1 files changed, 9 insertions, 2 deletions
diff --git a/sysdeps/generic/ldsodefs.h b/sysdeps/generic/ldsodefs.h
index ed0aed752f..c5467575c8 100644
--- a/sysdeps/generic/ldsodefs.h
+++ b/sysdeps/generic/ldsodefs.h
@@ -1140,8 +1140,15 @@ extern void *_dl_open (const char *name, int mode, const void *caller,
    old scope, OLD can't be freed until no thread is using it.  */
 extern int _dl_scope_free (void *) attribute_hidden;
 
-/* Add module to slot information data.  */
-extern void _dl_add_to_slotinfo (struct link_map  *l) attribute_hidden;
+
+/* Add module to slot information data.  If DO_ADD is false, only the
+   required memory is allocated.  Must be called with GL
+   (dl_load_lock) acquired.  If the function has already been called
+   for the link map L with !do_add, then this function will not raise
+   an exception, otherwise it is possible that it encounters a memory
+   allocation failure.  */
+extern void _dl_add_to_slotinfo (struct link_map *l, bool do_add)
+  attribute_hidden;
 
 /* Update slot information data for at least the generation of the
    module with the given index.  */