[glibc/azanella/ld-audit-fixes] elf: Add main application on main_map l_name
Adhemerval Zanella
azanella@sourceware.org
Tue Nov 16 13:58:36 GMT 2021
https://sourceware.org/git/gitweb.cgi?p=glibc.git;h=c75cfec06e40298c06530c80df135b57513a808e
commit c75cfec06e40298c06530c80df135b57513a808e
Author: Adhemerval Zanella <adhemerval.zanella@linaro.org>
Date: Wed Jul 21 15:49:12 2021 -0300
elf: Add main application on main_map l_name
For the la_objopen() the path listed in link_map->l_name for the main
application binary is empty, even though dladdr() is able to recover the
correct path.
By setting the expected application name on l_name, it allows to
simplify the code to handle the special case and make the API that
return such information (la_objopen(), dladdr() and dlinfo() to have
similar semantic.
Checked on x86_64-linux-gnu.
Diff:
---
dlfcn/Makefile | 4 +++-
dlfcn/tst-dladdr-self.c | 55 +++++++++++++++++++++++++++++++++++++++++++++++++
elf/dl-addr.c | 5 -----
elf/dl-dst.h | 2 +-
elf/dl-init.c | 3 +--
elf/dl-misc.c | 1 +
elf/rtld.c | 6 +-----
elf/tst-audit22.c | 4 ++++
elf/tst-auditmod22.c | 8 +++++++
gmon/gmon.c | 10 ++++-----
10 files changed, 79 insertions(+), 19 deletions(-)
diff --git a/dlfcn/Makefile b/dlfcn/Makefile
index 6bbfbb8344..bceb2b2885 100644
--- a/dlfcn/Makefile
+++ b/dlfcn/Makefile
@@ -51,7 +51,7 @@ endif
ifeq (yes,$(build-shared))
tests = glrefmain failtest tst-dladdr default errmsg1 tstcxaatexit \
bug-dlopen1 bug-dlsym1 tst-dlinfo bug-atexit1 bug-atexit2 \
- bug-atexit3 tstatexit bug-dl-leaf tst-rec-dlopen
+ bug-atexit3 tstatexit bug-dl-leaf tst-rec-dlopen tst-dladdr-self
endif
modules-names = glreflib1 glreflib2 glreflib3 failtestmod defaultmod1 \
defaultmod2 errmsg1mod modatexit modcxaatexit \
@@ -143,3 +143,5 @@ $(objpfx)bug-dl-leaf.out: $(objpfx)bug-dl-leaf-lib-cb.so
$(objpfx)bug-dl-leaf-lib-cb.so: $(objpfx)bug-dl-leaf-lib.so
$(objpfx)tst-rec-dlopen.out: $(objpfx)moddummy1.so $(objpfx)moddummy2.so
+
+LDFLAGS-tst-dladdr-self = -rdynamic
diff --git a/dlfcn/tst-dladdr-self.c b/dlfcn/tst-dladdr-self.c
new file mode 100644
index 0000000000..0eddaf1cd7
--- /dev/null
+++ b/dlfcn/tst-dladdr-self.c
@@ -0,0 +1,55 @@
+/* Check dladdr with the reference to own exectuable.
+ Copyright (C) 2021 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
+ <https://www.gnu.org/licenses/>. */
+
+#include <stdio.h>
+#include <string.h>
+#include <stdint.h>
+#include <support/check.h>
+#include <support/xdlfcn.h>
+
+void
+test_symbol (void)
+{
+}
+
+static int
+do_test (void)
+{
+ void *handle = xdlopen (NULL, RTLD_NOW);
+ int (*sym)(void) = xdlsym (handle, "test_symbol");
+
+ Dl_info info = { 0 };
+ {
+ int r = dladdr (sym, &info);
+ TEST_VERIFY_EXIT (r != 0);
+ }
+
+ {
+ const char *p = strrchr (info.dli_fname, '/');
+ const char *dli_name = p == NULL ? info.dli_fname : p + 1;
+
+ TEST_COMPARE_STRING (dli_name, "tst-dladdr-self");
+ }
+
+ TEST_COMPARE_STRING (info.dli_sname, "test_symbol");
+ TEST_COMPARE ((uintptr_t) info.dli_saddr, (uintptr_t) test_symbol);
+
+ return 0;
+}
+
+#include <support/test-driver.c>
diff --git a/elf/dl-addr.c b/elf/dl-addr.c
index 3226880d48..c2c93c63ad 100644
--- a/elf/dl-addr.c
+++ b/elf/dl-addr.c
@@ -30,11 +30,6 @@ determine_info (const ElfW(Addr) addr, struct link_map *match, Dl_info *info,
info->dli_fname = match->l_name;
info->dli_fbase = (void *) match->l_map_start;
- /* If this is the main program the information is incomplete. */
- if (__builtin_expect (match->l_name[0], 'a') == '\0'
- && match->l_type == lt_executable)
- info->dli_fname = _dl_argv[0];
-
const ElfW(Sym) *symtab
= (const ElfW(Sym) *) D_PTR (match, l_info[DT_SYMTAB]);
const char *strtab = (const char *) D_PTR (match, l_info[DT_STRTAB]);
diff --git a/elf/dl-dst.h b/elf/dl-dst.h
index 34bbaf65dc..a1e9af5a06 100644
--- a/elf/dl-dst.h
+++ b/elf/dl-dst.h
@@ -44,7 +44,7 @@
auditing, in ld.so. */ \
if ((l)->l_origin == NULL) \
{ \
- assert ((l)->l_name[0] == '\0' || IS_RTLD (l)); \
+ assert ((l)->l_type == lt_executable || IS_RTLD (l)); \
(l)->l_origin = _dl_get_origin (); \
dst_len = ((l)->l_origin && (l)->l_origin != (char *) -1 \
? strlen ((l)->l_origin) : 0); \
diff --git a/elf/dl-init.c b/elf/dl-init.c
index f924d26642..9fa8403290 100644
--- a/elf/dl-init.c
+++ b/elf/dl-init.c
@@ -39,8 +39,7 @@ call_init (struct link_map *l, int argc, char **argv, char **env)
l->l_init_called = 1;
/* Check for object which constructors we do not run here. */
- if (__builtin_expect (l->l_name[0], 'a') == '\0'
- && l->l_type == lt_executable)
+ if (l->l_type == lt_executable)
return;
/* Print a debug message if wanted. */
diff --git a/elf/dl-misc.c b/elf/dl-misc.c
index b256d792c6..b62bbcb8b4 100644
--- a/elf/dl-misc.c
+++ b/elf/dl-misc.c
@@ -338,6 +338,7 @@ rtld_hidden_def (_dl_fatal_printf)
int
_dl_name_match_p (const char *name, const struct link_map *map)
{
+ /* Filter out the main executable. */
if (strcmp (name, map->l_name) == 0)
return 1;
diff --git a/elf/rtld.c b/elf/rtld.c
index 55b4eb91f2..29a37f51d3 100644
--- a/elf/rtld.c
+++ b/elf/rtld.c
@@ -1361,11 +1361,6 @@ dl_main (const ElfW(Phdr) *phdr,
phdr = main_map->l_phdr;
phnum = main_map->l_phnum;
- /* We overwrite here a pointer to a malloc()ed string. But since
- the malloc() implementation used at this point is the dummy
- implementations which has no real free() function it does not
- makes sense to free the old string first. */
- main_map->l_name = (char *) "";
*user_entry = main_map->l_entry;
/* Set bit indicating this is the main program map. */
@@ -1431,6 +1426,7 @@ dl_main (const ElfW(Phdr) *phdr,
information for the program. */
}
+ main_map->l_name = _dl_argv[0];
main_map->l_map_end = 0;
main_map->l_text_end = 0;
/* Perhaps the executable has no PT_LOAD header entries at all. */
diff --git a/elf/tst-audit22.c b/elf/tst-audit22.c
index f136f25a32..f5e16c69fe 100644
--- a/elf/tst-audit22.c
+++ b/elf/tst-audit22.c
@@ -94,6 +94,7 @@ do_test (int argc, char *argv[])
uintptr_t vdso_process = 0;
bool vdso_audit_found = false;
uintptr_t vdso_audit = 0;
+ bool mainapp_found = false;
FILE *out = fmemopen (result.err.buffer, result.err.length, "r");
TEST_VERIFY (out != NULL);
@@ -108,11 +109,14 @@ do_test (int argc, char *argv[])
vdso_audit = parse_address (buffer + strlen ("vdso found: "));
vdso_audit_found = true;
}
+ else if (startswith (buffer, "mainapp found"))
+ mainapp_found = true;
}
TEST_COMPARE (vdso_audit_found, true);
if (vdso_audit != 0)
TEST_COMPARE (vdso_process, vdso_audit);
+ TEST_COMPARE (mainapp_found, true);
free (buffer);
xfclose (out);
diff --git a/elf/tst-auditmod22.c b/elf/tst-auditmod22.c
index 8e05ce8cbb..687789ab34 100644
--- a/elf/tst-auditmod22.c
+++ b/elf/tst-auditmod22.c
@@ -21,6 +21,7 @@
#include <stdbool.h>
#include <string.h>
#include <stdio.h>
+#include <string.h>
#include <sys/auxv.h>
static inline bool
@@ -47,5 +48,12 @@ la_objopen (struct link_map *map, Lmid_t lmid, uintptr_t *cookie)
else if (map->l_addr == getauxval (AT_SYSINFO_EHDR))
fprintf (stderr, "vdso found: %p\n", (void*) map->l_addr);
+ {
+ const char *p = strrchr (map->l_name, '/');
+ const char *l_name = p == NULL ? map->l_name : p + 1;
+ if (strcmp (l_name, "tst-audit22") == 0)
+ fprintf (stderr, "mainapp found\n");
+ }
+
return 0;
}
diff --git a/gmon/gmon.c b/gmon/gmon.c
index dee64803ad..cb8327b8e4 100644
--- a/gmon/gmon.c
+++ b/gmon/gmon.c
@@ -48,16 +48,16 @@
#ifdef PIC
# include <link.h>
+# include <ldsodefs.h>
static int
callback (struct dl_phdr_info *info, size_t size, void *data)
{
- if (info->dlpi_name[0] == '\0')
+ if (info->dlpi_name == _dl_argv[0])
{
- /* The link map for the executable is created by calling
- _dl_new_object with "" as filename. dl_iterate_phdr
- calls the callback function with filename from the
- link map as dlpi_name. */
+ /* The link map l_name for the executable is set to the _dl_argv[0]
+ after argument processing. dl_iterate_phdr() calls the callback
+ function with filename from the link map as dlpi_name. */
u_long *load_address = data;
*load_address = (u_long) info->dlpi_addr;
return 1;
More information about the Glibc-cvs
mailing list