From 365624e2d2a342cdb693b4cc35d2312169959e28 Mon Sep 17 00:00:00 2001 From: Florian Weimer Date: Fri, 13 Dec 2019 10:18:24 +0100 Subject: dlopen: Fix issues related to NODELETE handling and relocations 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]"). --- elf/Makefile | 66 ++++++++++++++++++++++++++++++++++++++++++++++++++++++++++-- 1 file changed, 64 insertions(+), 2 deletions(-) (limited to 'elf/Makefile') diff --git a/elf/Makefile b/elf/Makefile index b2b3be203f..72a5aa88b1 100644 --- a/elf/Makefile +++ b/elf/Makefile @@ -191,7 +191,7 @@ tests += restest1 preloadtest loadfail multiload origtest resolvfail \ tst-audit1 tst-audit2 tst-audit8 tst-audit9 \ tst-addr1 tst-thrlock \ tst-unique1 tst-unique2 $(if $(CXX),tst-unique3 tst-unique4 \ - tst-nodelete) \ + tst-nodelete tst-dlopen-nodelete-reloc) \ tst-initorder tst-initorder2 tst-relsort1 tst-null-argv \ tst-tlsalign tst-tlsalign-extern tst-nodelete-opened \ tst-nodelete2 tst-audit11 tst-audit12 tst-dlsym-error tst-noload \ @@ -271,7 +271,24 @@ modules-names = testobj1 testobj2 testobj3 testobj4 testobj5 testobj6 \ tst-auditmod9a tst-auditmod9b \ $(if $(CXX),tst-unique3lib tst-unique3lib2 tst-unique4lib \ tst-nodelete-uniquemod tst-nodelete-rtldmod \ - tst-nodelete-zmod) \ + tst-nodelete-zmod \ + tst-dlopen-nodelete-reloc-mod1 \ + tst-dlopen-nodelete-reloc-mod2 \ + tst-dlopen-nodelete-reloc-mod3 \ + tst-dlopen-nodelete-reloc-mod4 \ + tst-dlopen-nodelete-reloc-mod5 \ + tst-dlopen-nodelete-reloc-mod6 \ + tst-dlopen-nodelete-reloc-mod7 \ + tst-dlopen-nodelete-reloc-mod8 \ + tst-dlopen-nodelete-reloc-mod9 \ + tst-dlopen-nodelete-reloc-mod10 \ + tst-dlopen-nodelete-reloc-mod11 \ + tst-dlopen-nodelete-reloc-mod12 \ + tst-dlopen-nodelete-reloc-mod13 \ + tst-dlopen-nodelete-reloc-mod14 \ + tst-dlopen-nodelete-reloc-mod15 \ + tst-dlopen-nodelete-reloc-mod16 \ + tst-dlopen-nodelete-reloc-mod17) \ tst-initordera1 tst-initorderb1 \ tst-initordera2 tst-initorderb2 \ tst-initordera3 tst-initordera4 \ @@ -1627,3 +1644,48 @@ $(objpfx)tst-dlopenfailmod1.so: \ $(shared-thread-library) $(objpfx)tst-dlopenfaillinkmod.so LDFLAGS-tst-dlopenfaillinkmod.so = -Wl,-soname,tst-dlopenfail-missingmod.so $(objpfx)tst-dlopenfailmod2.so: $(shared-thread-library) + +$(objpfx)tst-dlopen-nodelete-reloc: $(libdl) +$(objpfx)tst-dlopen-nodelete-reloc.out: \ + $(objpfx)tst-dlopen-nodelete-reloc-mod1.so \ + $(objpfx)tst-dlopen-nodelete-reloc-mod2.so \ + $(objpfx)tst-dlopen-nodelete-reloc-mod3.so \ + $(objpfx)tst-dlopen-nodelete-reloc-mod4.so \ + $(objpfx)tst-dlopen-nodelete-reloc-mod5.so \ + $(objpfx)tst-dlopen-nodelete-reloc-mod6.so \ + $(objpfx)tst-dlopen-nodelete-reloc-mod7.so \ + $(objpfx)tst-dlopen-nodelete-reloc-mod8.so \ + $(objpfx)tst-dlopen-nodelete-reloc-mod9.so \ + $(objpfx)tst-dlopen-nodelete-reloc-mod10.so \ + $(objpfx)tst-dlopen-nodelete-reloc-mod11.so \ + $(objpfx)tst-dlopen-nodelete-reloc-mod12.so \ + $(objpfx)tst-dlopen-nodelete-reloc-mod13.so \ + $(objpfx)tst-dlopen-nodelete-reloc-mod14.so \ + $(objpfx)tst-dlopen-nodelete-reloc-mod15.so \ + $(objpfx)tst-dlopen-nodelete-reloc-mod16.so \ + $(objpfx)tst-dlopen-nodelete-reloc-mod17.so +tst-dlopen-nodelete-reloc-mod2.so-no-z-defs = yes +LDFLAGS-tst-dlopen-nodelete-reloc-mod2.so = -Wl,-z,nodelete +$(objpfx)tst-dlopen-nodelete-reloc-mod4.so: \ + $(objpfx)tst-dlopen-nodelete-reloc-mod3.so +LDFLAGS-tst-dlopen-nodelete-reloc-mod4.so = -Wl,--no-as-needed +$(objpfx)tst-dlopen-nodelete-reloc-mod5.so: \ + $(objpfx)tst-dlopen-nodelete-reloc-mod4.so +LDFLAGS-tst-dlopen-nodelete-reloc-mod5.so = -Wl,-z,nodelete,--no-as-needed +tst-dlopen-nodelete-reloc-mod5.so-no-z-defs = yes +tst-dlopen-nodelete-reloc-mod7.so-no-z-defs = yes +$(objpfx)tst-dlopen-nodelete-reloc-mod8.so: $(libdl) +$(objpfx)tst-dlopen-nodelete-reloc-mod10.so: $(libdl) +tst-dlopen-nodelete-reloc-mod11.so-no-z-defs = yes +$(objpfx)tst-dlopen-nodelete-reloc-mod13.so: \ + $(objpfx)tst-dlopen-nodelete-reloc-mod12.so +$(objpfx)tst-dlopen-nodelete-reloc-mod15.so: \ + $(objpfx)tst-dlopen-nodelete-reloc-mod14.so +tst-dlopen-nodelete-reloc-mod16.so-no-z-defs = yes +$(objpfx)tst-dlopen-nodelete-reloc-mod16.so: \ + $(objpfx)tst-dlopen-nodelete-reloc-mod15.so +LDFLAGS-tst-dlopen-nodelete-reloc-mod16.so = -Wl,--no-as-needed +$(objpfx)tst-dlopen-nodelete-reloc-mod17.so: \ + $(objpfx)tst-dlopen-nodelete-reloc-mod15.so \ + $(objpfx)tst-dlopen-nodelete-reloc-mod16.so +LDFLAGS-tst-dlopen-nodelete-reloc-mod17.so = -Wl,--no-as-needed -- cgit 1.4.1