[PATCH] elf: Fix crash in late dlmopen failure when auditing (bug 26076)

Florian Weimer fweimer@redhat.com
Thu Jun 4 13:20:07 GMT 2020


If _dl_map_object_deps fails, the initial module that has been
loaded by _dl_map_objects needs to be freed using _dl_close_worker.
This produces an empty namespace midway through _dl_close_worker.
The code did not expected and deferefenced a NULL pointer.

---
 elf/Makefile   | 16 +++++++++++++++-
 elf/dl-close.c |  2 +-
 2 files changed, 16 insertions(+), 2 deletions(-)

diff --git a/elf/Makefile b/elf/Makefile
index 6fe1df90bb..648d6d3d11 100644
--- a/elf/Makefile
+++ b/elf/Makefile
@@ -223,7 +223,7 @@ tests += $(tests-execstack-$(have-z-execstack))
 ifeq ($(run-built-tests),yes)
 tests-special += $(objpfx)tst-leaks1-mem.out \
 		 $(objpfx)tst-leaks1-static-mem.out $(objpfx)noload-mem.out \
-		 $(objpfx)tst-ldconfig-X.out
+		 $(objpfx)tst-ldconfig-X.out $(objpfx)tst-auditlatefail.out
 endif
 tlsmod17a-suffixes = 0 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19
 tlsmod18a-suffixes = 0 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19
@@ -1502,6 +1502,20 @@ $(objpfx)tst-auditmany.out: $(objpfx)tst-auditmanymod1.so \
 tst-auditmany-ENV = \
   LD_AUDIT=tst-auditmanymod1.so:tst-auditmanymod2.so:tst-auditmanymod3.so:tst-auditmanymod4.so:tst-auditmanymod5.so:tst-auditmanymod6.so:tst-auditmanymod7.so:tst-auditmanymod8.so:tst-auditmanymod9.so
 
+# Check that a late failure in loading an audit module does not result
+# in a segmentation fault (bug 26076).  Reuse parts of the
+# tst-auditmany test for this.  They tst-auditmany program just exits
+# with zero, after loading has failed.  Check that the expected audit
+# module load error message appears on standard error, and that output
+# from the other (successfully loaded) audit module occurred.
+$(objpfx)tst-auditlatefail.out: $(objpfx)tst-auditmanymod1.so \
+  $(objpfx)tst-dlopenfailmod1.so $(objpfx)tst-auditmany Makefile
+	$(test-wrapper) $(rtld-prefix) \
+	  --audit tst-auditmanymod1.so:tst-dlopenfailmod1.so \
+	  $(objpfx)tst-auditmany > $@ 2>&1 && \
+	grep -q "object 'tst-dlopenfailmod1.so' cannot be loaded as audit interface: cannot open shared object file; ignored." $@ && \
+	grep -q "^info: 1, la_objopen" $@; $(evaluate-test)
+
 LDFLAGS-tst-audit14 = -Wl,--audit=tst-auditlogmod-1.so
 $(objpfx)tst-auditlogmod-1.so: $(libsupport)
 $(objpfx)tst-audit14.out: $(objpfx)tst-auditlogmod-1.so
diff --git a/elf/dl-close.c b/elf/dl-close.c
index 73b2817bbf..896e59e42e 100644
--- a/elf/dl-close.c
+++ b/elf/dl-close.c
@@ -782,7 +782,7 @@ _dl_close_worker (struct link_map *map, bool force)
     {
       struct link_map *head = ns->_ns_loaded;
       /* Do not call the functions for any auditing object.  */
-      if (head->l_auditing == 0)
+      if (head != NULL && head->l_auditing == 0)
 	{
 	  struct audit_ifaces *afct = GLRO(dl_audit);
 	  for (unsigned int cnt = 0; cnt < GLRO(dl_naudit); ++cnt)



More information about the Libc-alpha mailing list