]> git.ipfire.org Git - thirdparty/glibc.git/commitdiff
ld.so: Add original DSO name if overridden by audit module [BZ #18251]
authorFlorian Weimer <fweimer@redhat.com>
Mon, 9 Nov 2015 15:52:31 +0000 (16:52 +0100)
committerFlorian Weimer <fweimer@redhat.com>
Mon, 9 Nov 2015 16:01:46 +0000 (17:01 +0100)
* elf/dl-load.c (_dl_map_object_from_fd): Add additional parameter
for original name of the DSO.  Add it to the name list of the DSO
if it is actually given.
(_dl_map_object): Keep track of whether an audit module rewrote
the file name.  If yes, pass the original name to
_dl_map_object_from_fd in a new parameter, otherwise NULL.  When
debugging is enabled, log the change of the file name.
* sysdeps/mach/hur/dl-sysdep.c: Adjust commented-out call to
_dl_map_object_from_fd.
* elf/Makefile: Build and run tst-audit11 and tst-audit12.
* elf/tst-audit11.c: New file
* elf/tst-auditmod11.c: New file.
* elf/tst-audit11mod1.c: New file.
* elf/tst-audit11mod2.c: New file.
* elf/tst-audit11mod2.map: New file.
* elf/tst-audit12.c: New file
* elf/tst-auditmod12.c: New file.
* elf/tst-audit12mod1.c: New file.
* elf/tst-audit12mod2.c: New file.
* elf/tst-audit12mod2.map: New file.
* elf/tst-audit12mod3.c: New file.

15 files changed:
ChangeLog
elf/Makefile
elf/dl-load.c
elf/tst-audit11.c [new file with mode: 0644]
elf/tst-audit11mod1.c [new file with mode: 0644]
elf/tst-audit11mod2.c [new file with mode: 0644]
elf/tst-audit11mod2.map [new file with mode: 0644]
elf/tst-audit12.c [new file with mode: 0644]
elf/tst-audit12mod1.c [new file with mode: 0644]
elf/tst-audit12mod2.c [new file with mode: 0644]
elf/tst-audit12mod2.map [new file with mode: 0644]
elf/tst-audit12mod3.c [new file with mode: 0644]
elf/tst-auditmod11.c [new file with mode: 0644]
elf/tst-auditmod12.c [new file with mode: 0644]
sysdeps/mach/hurd/dl-sysdep.c

index 2918a23a4c496a5e83ac32fe07e2a4a1ea120884..d534b69088becfb83cdb3823ecb740debe23dc49 100644 (file)
--- a/ChangeLog
+++ b/ChangeLog
@@ -1,3 +1,27 @@
+2015-11-09  Ulrich Drepper  <drepper@gmail.com>
+
+       * elf/dl-load.c (_dl_map_object_from_fd): Add additional parameter
+       for original name of the DSO.  Add it to the name list of the DSO
+       if it is actually given.
+       (_dl_map_object): Keep track of whether an audit module rewrote
+       the file name.  If yes, pass the original name to
+       _dl_map_object_from_fd in a new parameter, otherwise NULL.  When
+       debugging is enabled, log the change of the file name.
+       * sysdeps/mach/hur/dl-sysdep.c: Adjust commented-out call to
+       _dl_map_object_from_fd.
+       * elf/Makefile: Build and run tst-audit11 and tst-audit12.
+       * elf/tst-audit11.c: New file
+       * elf/tst-auditmod11.c: New file.
+       * elf/tst-audit11mod1.c: New file.
+       * elf/tst-audit11mod2.c: New file.
+       * elf/tst-audit11mod2.map: New file.
+       * elf/tst-audit12.c: New file
+       * elf/tst-auditmod12.c: New file.
+       * elf/tst-audit12mod1.c: New file.
+       * elf/tst-audit12mod2.c: New file.
+       * elf/tst-audit12mod2.map: New file.
+       * elf/tst-audit12mod3.c: New file.
+
 2015-11-09  Stefan Liebler  <stli@linux.vnet.ibm.com>
 
        * sysdeps/s390/longjmp.c (longjmp, _longjmp, siglongjmp):
index 546c8eb376bb61d29459a0268c9644d969632941..76985ccd16042c26e9d0e74813d89d979605b024 100644 (file)
@@ -149,7 +149,7 @@ tests += loadtest restest1 preloadtest loadfail multiload origtest resolvfail \
         tst-nodelete) \
         tst-initorder tst-initorder2 tst-relsort1 tst-null-argv \
         tst-ptrguard1 tst-tlsalign tst-tlsalign-extern tst-nodelete-opened \
-        tst-nodelete2
+        tst-nodelete2 tst-audit11 tst-audit12
 #       reldep9
 ifeq ($(build-hardcoded-path-in-tests),yes)
 tests += tst-dlopen-aout
@@ -219,7 +219,9 @@ modules-names = testobj1 testobj2 testobj3 testobj4 testobj5 testobj6 \
                tst-initorder2d \
                tst-relsort1mod1 tst-relsort1mod2 tst-array2dep \
                tst-array5dep tst-null-argv-lib \
-               tst-tlsalign-lib tst-nodelete-opened-lib tst-nodelete2mod
+               tst-tlsalign-lib tst-nodelete-opened-lib tst-nodelete2mod \
+               tst-audit11mod1 tst-audit11mod2 tst-auditmod11 \
+               tst-audit12mod1 tst-audit12mod2 tst-audit12mod3 tst-auditmod12
 ifeq (yes,$(have-protected-data))
 modules-names += tst-protected1moda tst-protected1modb
 tests += tst-protected1a tst-protected1b
@@ -1220,3 +1222,15 @@ $(objpfx)tst-unused-dep.out: $(objpfx)testobj1.so
 $(objpfx)tst-unused-dep-cmp.out: $(objpfx)tst-unused-dep.out
        cmp $< /dev/null > $@; \
        $(evaluate-test)
+
+$(objpfx)tst-audit11.out: $(objpfx)tst-auditmod11.so $(objpfx)tst-audit11mod1.so
+$(objpfx)tst-audit11: $(libdl)
+tst-audit11-ENV = LD_AUDIT=$(objpfx)tst-auditmod11.so
+$(objpfx)tst-audit11mod1.so: $(objpfx)tst-audit11mod2.so
+LDFLAGS-tst-audit11mod2.so = -Wl,--version-script=tst-audit11mod2.map,-soname,tst-audit11mod2.so
+
+$(objpfx)tst-audit12.out: $(objpfx)tst-auditmod12.so $(objpfx)tst-audit12mod1.so $(objpfx)tst-audit12mod3.so
+$(objpfx)tst-audit12: $(libdl)
+tst-audit12-ENV = LD_AUDIT=$(objpfx)tst-auditmod12.so
+$(objpfx)tst-audit12mod1.so: $(objpfx)tst-audit12mod2.so
+LDFLAGS-tst-audit12mod2.so = -Wl,--version-script=tst-audit12mod2.map
index 993a419bddb2acd37256c1cbdecba81734c0f6b9..c5e948e7e03467155e440d27e7c593815e49b041 100644 (file)
@@ -863,9 +863,10 @@ lose (int code, int fd, const char *name, char *realname, struct link_map *l,
 static
 #endif
 struct link_map *
-_dl_map_object_from_fd (const char *name, int fd, struct filebuf *fbp,
-                       char *realname, struct link_map *loader, int l_type,
-                       int mode, void **stack_endp, Lmid_t nsid)
+_dl_map_object_from_fd (const char *name, const char *origname, int fd,
+                       struct filebuf *fbp, char *realname,
+                       struct link_map *loader, int l_type, int mode,
+                       void **stack_endp, Lmid_t nsid)
 {
   struct link_map *l = NULL;
   const ElfW(Ehdr) *header;
@@ -1391,6 +1392,17 @@ cannot enable executable stack as shared object requires");
   /* Finally the file information.  */
   l->l_file_id = id;
 
+#ifdef SHARED
+  /* When auditing is used the recorded names might not include the
+     name by which the DSO is actually known.  Add that as well.  */
+  if (__glibc_unlikely (origname != NULL))
+    add_name_to_object (l, origname);
+#else
+  /* Audit modules only exist when linking is dynamic so ORIGNAME
+     cannot be non-NULL.  */
+  assert (origname == NULL);
+#endif
+
   /* When we profile the SONAME might be needed for something else but
      loading.  Add it right away.  */
   if (__glibc_unlikely (GLRO(dl_profile) != NULL)
@@ -1904,6 +1916,7 @@ _dl_map_object (struct link_map *loader, const char *name,
                int type, int trace_mode, int mode, Lmid_t nsid)
 {
   int fd;
+  const char *origname = NULL;
   char *realname;
   char *name_copy;
   struct link_map *l;
@@ -1961,6 +1974,7 @@ _dl_map_object (struct link_map *loader, const char *name,
        {
          if (afct->objsearch != NULL)
            {
+             const char *before = name;
              name = afct->objsearch (name, &loader->l_audit[cnt].cookie,
                                      LA_SER_ORIG);
              if (name == NULL)
@@ -1969,6 +1983,15 @@ _dl_map_object (struct link_map *loader, const char *name,
                  fd = -1;
                  goto no_file;
                }
+             if (before != name && strcmp (before, name) != 0)
+               {
+                 if (__glibc_unlikely (GLRO(dl_debug_mask) & DL_DEBUG_FILES))
+                   _dl_debug_printf ("audit changed filename %s -> %s\n",
+                                     before, name);
+
+                 if (origname == NULL)
+                   origname = before;
+               }
            }
 
          afct = afct->next;
@@ -2183,8 +2206,8 @@ _dl_map_object (struct link_map *loader, const char *name,
     }
 
   void *stack_end = __libc_stack_end;
-  return _dl_map_object_from_fd (name, fd, &fb, realname, loader, type, mode,
-                                &stack_end, nsid);
+  return _dl_map_object_from_fd (name, origname, fd, &fb, realname, loader,
+                                type, mode, &stack_end, nsid);
 }
 
 struct add_path_state
diff --git a/elf/tst-audit11.c b/elf/tst-audit11.c
new file mode 100644 (file)
index 0000000..15a44f9
--- /dev/null
@@ -0,0 +1,36 @@
+/* Test version symbol binding can find a DSO replaced by la_objsearch.
+   Copyright (C) 2015 Free Software Foundation, Inc.
+   This file is part of the GNU C Library.
+
+   The GNU C Library is free software; you can redistribute it and/or
+   modify it under the terms of the GNU Lesser General Public
+   License as published by the Free Software Foundation; either
+   version 2.1 of the License, or (at your option) any later version.
+
+   The GNU C Library is distributed in the hope that it will be useful,
+   but WITHOUT ANY WARRANTY; without even the implied warranty of
+   MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
+   Lesser General Public License for more details.
+
+   You should have received a copy of the GNU Lesser General Public
+   License along with the GNU C Library; if not, see
+   <http://www.gnu.org/licenses/>.  */
+
+#include <dlfcn.h>
+#include <stdio.h>
+
+int
+do_test (void)
+{
+  puts ("Start");
+  if (dlopen ("$ORIGIN/tst-audit11mod1.so", RTLD_LAZY) == NULL)
+    {
+      printf ("module not loaded: %s\n", dlerror ());
+      return 1;
+    }
+  puts ("OK");
+  return 0;
+}
+
+#define TEST_FUNCTION do_test ()
+#include "../test-skeleton.c"
diff --git a/elf/tst-audit11mod1.c b/elf/tst-audit11mod1.c
new file mode 100644 (file)
index 0000000..32df01f
--- /dev/null
@@ -0,0 +1,24 @@
+/* DSO directly opened by tst-audit11.
+   Copyright (C) 2015 Free Software Foundation, Inc.
+   This file is part of the GNU C Library.
+
+   The GNU C Library is free software; you can redistribute it and/or
+   modify it under the terms of the GNU Lesser General Public
+   License as published by the Free Software Foundation; either
+   version 2.1 of the License, or (at your option) any later version.
+
+   The GNU C Library is distributed in the hope that it will be useful,
+   but WITHOUT ANY WARRANTY; without even the implied warranty of
+   MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
+   Lesser General Public License for more details.
+
+   You should have received a copy of the GNU Lesser General Public
+   License along with the GNU C Library; if not, see
+   <http://www.gnu.org/licenses/>.  */
+
+extern int f2 (void);
+int
+f1 (void)
+{
+  return f2 ();
+}
diff --git a/elf/tst-audit11mod2.c b/elf/tst-audit11mod2.c
new file mode 100644 (file)
index 0000000..211456f
--- /dev/null
@@ -0,0 +1,23 @@
+/* DSO indirectly opened by tst-audit11, with symbol versioning.
+   Copyright (C) 2015 Free Software Foundation, Inc.
+   This file is part of the GNU C Library.
+
+   The GNU C Library is free software; you can redistribute it and/or
+   modify it under the terms of the GNU Lesser General Public
+   License as published by the Free Software Foundation; either
+   version 2.1 of the License, or (at your option) any later version.
+
+   The GNU C Library is distributed in the hope that it will be useful,
+   but WITHOUT ANY WARRANTY; without even the implied warranty of
+   MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
+   Lesser General Public License for more details.
+
+   You should have received a copy of the GNU Lesser General Public
+   License along with the GNU C Library; if not, see
+   <http://www.gnu.org/licenses/>.  */
+
+int
+f2 (void)
+{
+  return 42;
+}
diff --git a/elf/tst-audit11mod2.map b/elf/tst-audit11mod2.map
new file mode 100644 (file)
index 0000000..76d4d5b
--- /dev/null
@@ -0,0 +1,22 @@
+/* Symbol versioning for the DSO indirectly opened by tst-audit11.
+   Copyright (C) 2015 Free Software Foundation, Inc.
+   This file is part of the GNU C Library.
+
+   The GNU C Library is free software; you can redistribute it and/or
+   modify it under the terms of the GNU Lesser General Public
+   License as published by the Free Software Foundation; either
+   version 2.1 of the License, or (at your option) any later version.
+
+   The GNU C Library is distributed in the hope that it will be useful,
+   but WITHOUT ANY WARRANTY; without even the implied warranty of
+   MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
+   Lesser General Public License for more details.
+
+   You should have received a copy of the GNU Lesser General Public
+   License along with the GNU C Library; if not, see
+   <http://www.gnu.org/licenses/>.  */
+
+V1 {
+  global: f2;
+  local: *;
+};
diff --git a/elf/tst-audit12.c b/elf/tst-audit12.c
new file mode 100644 (file)
index 0000000..cd026bd
--- /dev/null
@@ -0,0 +1,49 @@
+/* Test that symbol is bound to a DSO replaced by la_objsearch.
+   Copyright (C) 2015 Free Software Foundation, Inc.
+   This file is part of the GNU C Library.
+
+   The GNU C Library is free software; you can redistribute it and/or
+   modify it under the terms of the GNU Lesser General Public
+   License as published by the Free Software Foundation; either
+   version 2.1 of the License, or (at your option) any later version.
+
+   The GNU C Library is distributed in the hope that it will be useful,
+   but WITHOUT ANY WARRANTY; without even the implied warranty of
+   MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
+   Lesser General Public License for more details.
+
+   You should have received a copy of the GNU Lesser General Public
+   License along with the GNU C Library; if not, see
+   <http://www.gnu.org/licenses/>.  */
+
+#include <dlfcn.h>
+#include <stdio.h>
+
+int
+do_test (void)
+{
+  puts ("Start");
+  void *h = dlopen ("$ORIGIN/tst-audit12mod1.so", RTLD_LAZY);
+  if (h == NULL)
+    {
+      printf ("module not loaded: %s\n", dlerror ());
+      return 1;
+    }
+  int (*fp) (void) = (int (*) (void)) dlsym (h, "f1");
+  if (fp == NULL)
+    {
+      printf ("function f1 not found: %s\n", dlerror ());
+      return 1;
+    }
+  int res = fp ();
+  if (res != 43)
+    {
+      puts ("incorrect function f2 called");
+      return 1;
+    }
+  printf ("%d is OK\n", res);
+  return 0;
+}
+
+#define TEST_FUNCTION do_test ()
+#include "../test-skeleton.c"
diff --git a/elf/tst-audit12mod1.c b/elf/tst-audit12mod1.c
new file mode 100644 (file)
index 0000000..9ad73b6
--- /dev/null
@@ -0,0 +1,24 @@
+/* DSO directly opened by tst-audit12.
+   Copyright (C) 2015 Free Software Foundation, Inc.
+   This file is part of the GNU C Library.
+
+   The GNU C Library is free software; you can redistribute it and/or
+   modify it under the terms of the GNU Lesser General Public
+   License as published by the Free Software Foundation; either
+   version 2.1 of the License, or (at your option) any later version.
+
+   The GNU C Library is distributed in the hope that it will be useful,
+   but WITHOUT ANY WARRANTY; without even the implied warranty of
+   MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
+   Lesser General Public License for more details.
+
+   You should have received a copy of the GNU Lesser General Public
+   License along with the GNU C Library; if not, see
+   <http://www.gnu.org/licenses/>.  */
+
+extern int f2 (void);
+int
+f1 (void)
+{
+  return f2 ();
+}
diff --git a/elf/tst-audit12mod2.c b/elf/tst-audit12mod2.c
new file mode 100644 (file)
index 0000000..de48b6a
--- /dev/null
@@ -0,0 +1,23 @@
+/* Replaced DSO referenced by tst-audit12mod1.so, for tst-audit12.
+   Copyright (C) 2015 Free Software Foundation, Inc.
+   This file is part of the GNU C Library.
+
+   The GNU C Library is free software; you can redistribute it and/or
+   modify it under the terms of the GNU Lesser General Public
+   License as published by the Free Software Foundation; either
+   version 2.1 of the License, or (at your option) any later version.
+
+   The GNU C Library is distributed in the hope that it will be useful,
+   but WITHOUT ANY WARRANTY; without even the implied warranty of
+   MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
+   Lesser General Public License for more details.
+
+   You should have received a copy of the GNU Lesser General Public
+   License along with the GNU C Library; if not, see
+   <http://www.gnu.org/licenses/>.  */
+
+int
+f2 (void)
+{
+  return 42;
+}
diff --git a/elf/tst-audit12mod2.map b/elf/tst-audit12mod2.map
new file mode 100644 (file)
index 0000000..1030ac6
--- /dev/null
@@ -0,0 +1,22 @@
+/* Symbol versioning for tst-audit12mod2.so used by tst-audit12.
+   Copyright (C) 2015 Free Software Foundation, Inc.
+   This file is part of the GNU C Library.
+
+   The GNU C Library is free software; you can redistribute it and/or
+   modify it under the terms of the GNU Lesser General Public
+   License as published by the Free Software Foundation; either
+   version 2.1 of the License, or (at your option) any later version.
+
+   The GNU C Library is distributed in the hope that it will be useful,
+   but WITHOUT ANY WARRANTY; without even the implied warranty of
+   MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
+   Lesser General Public License for more details.
+
+   You should have received a copy of the GNU Lesser General Public
+   License along with the GNU C Library; if not, see
+   <http://www.gnu.org/licenses/>.  */
+
+V1 {
+  global: f2;
+  local: *;
+};
diff --git a/elf/tst-audit12mod3.c b/elf/tst-audit12mod3.c
new file mode 100644 (file)
index 0000000..e4e9d4b
--- /dev/null
@@ -0,0 +1,23 @@
+/* Replacement DSO loaded by the audit module, for tst-audit12.
+   Copyright (C) 2015 Free Software Foundation, Inc.
+   This file is part of the GNU C Library.
+
+   The GNU C Library is free software; you can redistribute it and/or
+   modify it under the terms of the GNU Lesser General Public
+   License as published by the Free Software Foundation; either
+   version 2.1 of the License, or (at your option) any later version.
+
+   The GNU C Library is distributed in the hope that it will be useful,
+   but WITHOUT ANY WARRANTY; without even the implied warranty of
+   MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
+   Lesser General Public License for more details.
+
+   You should have received a copy of the GNU Lesser General Public
+   License along with the GNU C Library; if not, see
+   <http://www.gnu.org/licenses/>.  */
+
+int
+f2 (void)
+{
+  return 43;
+}
diff --git a/elf/tst-auditmod11.c b/elf/tst-auditmod11.c
new file mode 100644 (file)
index 0000000..cfcb34f
--- /dev/null
@@ -0,0 +1,39 @@
+/* Audit module for tst-audit11.
+   Copyright (C) 2015 Free Software Foundation, Inc.
+   This file is part of the GNU C Library.
+
+   The GNU C Library is free software; you can redistribute it and/or
+   modify it under the terms of the GNU Lesser General Public
+   License as published by the Free Software Foundation; either
+   version 2.1 of the License, or (at your option) any later version.
+
+   The GNU C Library is distributed in the hope that it will be useful,
+   but WITHOUT ANY WARRANTY; without even the implied warranty of
+   MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
+   Lesser General Public License for more details.
+
+   You should have received a copy of the GNU Lesser General Public
+   License along with the GNU C Library; if not, see
+   <http://www.gnu.org/licenses/>.  */
+
+#include <link.h>
+#include <stdio.h>
+#include <stdlib.h>
+#include <string.h>
+#include <unistd.h>
+
+unsigned int
+la_version (unsigned int version)
+{
+  return version;
+}
+
+char *
+la_objsearch (const char *name, uintptr_t *cookie, unsigned int flag)
+{
+  if (strcmp (name, "tst-audit11mod2.so") == 0)
+    {
+      return (char *) "$ORIGIN/tst-audit11mod2.so";
+    }
+  return (char *) name;
+}
diff --git a/elf/tst-auditmod12.c b/elf/tst-auditmod12.c
new file mode 100644 (file)
index 0000000..0c532bd
--- /dev/null
@@ -0,0 +1,43 @@
+/* Audit module for tst-audit12.
+   Copyright (C) 2015 Free Software Foundation, Inc.
+   This file is part of the GNU C Library.
+
+   The GNU C Library is free software; you can redistribute it and/or
+   modify it under the terms of the GNU Lesser General Public
+   License as published by the Free Software Foundation; either
+   version 2.1 of the License, or (at your option) any later version.
+
+   The GNU C Library is distributed in the hope that it will be useful,
+   but WITHOUT ANY WARRANTY; without even the implied warranty of
+   MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
+   Lesser General Public License for more details.
+
+   You should have received a copy of the GNU Lesser General Public
+   License along with the GNU C Library; if not, see
+   <http://www.gnu.org/licenses/>.  */
+
+#include <link.h>
+#include <stdio.h>
+#include <stdlib.h>
+#include <string.h>
+#include <unistd.h>
+
+unsigned int
+la_version (unsigned int version)
+{
+  return version;
+}
+
+char *
+la_objsearch (const char *name, uintptr_t *cookie, unsigned int flag)
+{
+  const char target[] = "tst-audit12mod2.so";
+
+  size_t namelen = strlen (name);
+  if (namelen >= sizeof (target) - 1
+      && strcmp (name + namelen - (sizeof (target) - 1), target) == 0)
+    {
+      return (char *) "$ORIGIN/tst-audit12mod3.so";
+    }
+  return (char *) name;
+}
index 317605b42579cb4a9c4e1b6323c12ab0d2f5900c..e446f157e2ef285f99f2d5f5dd78baf6f41f2317 100644 (file)
@@ -186,7 +186,7 @@ unfmh();                    /* XXX */
            assert_perror (err);
 
            lastslash = strrchr (p, '/');
-           l = _dl_map_object_from_fd (lastslash ? lastslash + 1 : p,
+           l = _dl_map_object_from_fd (lastslash ? lastslash + 1 : p, NULL,
                                        memobj, strdup (p), 0);
 
            /* Squirrel away the memory object port where it