about summary refs log tree commit diff
path: root/elf/get-dynamic-info.h
diff options
context:
space:
mode:
authorFlorian Weimer <fweimer@redhat.com>2019-11-13 15:44:56 +0100
committerFlorian Weimer <fweimer@redhat.com>2019-11-27 20:55:35 +0100
commitf63b73814f74032c0e5d0a83300e3d864ef905e5 (patch)
treedac6303d0f785a7103ede6546011bf430a42e236 /elf/get-dynamic-info.h
parenta509eb117fac1d764b15eba64993f4bdb63d7f3c (diff)
downloadglibc-f63b73814f74032c0e5d0a83300e3d864ef905e5.tar.gz
glibc-f63b73814f74032c0e5d0a83300e3d864ef905e5.tar.xz
glibc-f63b73814f74032c0e5d0a83300e3d864ef905e5.zip
Remove all loaded objects if dlopen fails, ignoring NODELETE [BZ #20839]
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
Diffstat (limited to 'elf/get-dynamic-info.h')
-rw-r--r--elf/get-dynamic-info.h2
1 files changed, 2 insertions, 0 deletions
diff --git a/elf/get-dynamic-info.h b/elf/get-dynamic-info.h
index af9dd57888..075683d729 100644
--- a/elf/get-dynamic-info.h
+++ b/elf/get-dynamic-info.h
@@ -163,6 +163,8 @@ elf_get_dynamic_info (struct link_map *l, ElfW(Dyn) *temp)
   if (info[VERSYMIDX (DT_FLAGS_1)] != NULL)
     {
       l->l_flags_1 = info[VERSYMIDX (DT_FLAGS_1)]->d_un.d_val;
+      if (l->l_flags_1 & DF_1_NODELETE)
+	l->l_nodelete = link_map_nodelete_pending;
 
       /* Only DT_1_SUPPORTED_MASK bits are supported, and we would like
 	 to assert this, but we can't. Users have been setting