diff options
author | Florian Weimer <fweimer@redhat.com> | 2020-04-29 15:44:03 +0200 |
---|---|---|
committer | Florian Weimer <fweimer@redhat.com> | 2020-04-29 15:44:03 +0200 |
commit | 03e187a41d91069543cfcf33469a05912e555447 (patch) | |
tree | a2f3afcc3e41af612e40fc9cab1ba9b3a811ce38 | |
parent | 2ad5d0845d80589d0adf86593bd36a7c71a521f8 (diff) | |
download | glibc-03e187a41d91069543cfcf33469a05912e555447.tar.gz glibc-03e187a41d91069543cfcf33469a05912e555447.tar.xz glibc-03e187a41d91069543cfcf33469a05912e555447.zip |
elf: Add initial flag argument to __libc_early_init
The rseq initialization should happen only for the libc in the base namespace (in the dynamic case) or the statically linked libc. The __libc_multiple_libcs flag does not quite cover this case at present, so this commit introduces a flag argument to __libc_early_init, indicating whether the libc being libc is the primary one (of the main program). Reviewed-by: Carlos O'Donell <carlos@redhat.com>
-rw-r--r-- | csu/libc-start.c | 3 | ||||
-rw-r--r-- | elf/dl-call-libc-early-init.c | 4 | ||||
-rw-r--r-- | elf/dl-open.c | 17 | ||||
-rw-r--r-- | elf/libc-early-init.h | 11 | ||||
-rw-r--r-- | elf/libc_early_init.c | 2 | ||||
-rw-r--r-- | elf/rtld.c | 6 |
6 files changed, 31 insertions, 12 deletions
diff --git a/csu/libc-start.c b/csu/libc-start.c index ccc743c9d1..4005caf84a 100644 --- a/csu/libc-start.c +++ b/csu/libc-start.c @@ -23,6 +23,7 @@ #include <exit-thread.h> #include <libc-internal.h> #include <elf/libc-early-init.h> +#include <stdbool.h> #include <elf/dl-tunables.h> @@ -241,7 +242,7 @@ LIBC_START_MAIN (int (*main) (int, char **, char ** MAIN_AUXVEC_DECL), #ifndef SHARED /* Perform early initialization. In the shared case, this function is called from the dynamic loader as early as possible. */ - __libc_early_init (); + __libc_early_init (true); /* Call the initializer of the libc. This is only needed here if we are compiling for the static library in which case we haven't diff --git a/elf/dl-call-libc-early-init.c b/elf/dl-call-libc-early-init.c index 41e9ad9aad..9a84680a1c 100644 --- a/elf/dl-call-libc-early-init.c +++ b/elf/dl-call-libc-early-init.c @@ -23,7 +23,7 @@ #include <stddef.h> void -_dl_call_libc_early_init (struct link_map *libc_map) +_dl_call_libc_early_init (struct link_map *libc_map, _Bool initial) { /* There is nothing to do if we did not actually load libc.so. */ if (libc_map == NULL) @@ -37,5 +37,5 @@ _dl_call_libc_early_init (struct link_map *libc_map) assert (sym != NULL); __typeof (__libc_early_init) *early_init = DL_SYMBOL_ADDRESS (libc_map, sym); - early_init (); + early_init (initial); } diff --git a/elf/dl-open.c b/elf/dl-open.c index ac7ab495e4..ddcb8b53fc 100644 --- a/elf/dl-open.c +++ b/elf/dl-open.c @@ -748,9 +748,22 @@ dl_open_worker (void *a) LIBC_PROBE (reloc_complete, 3, args->nsid, r, new); /* If libc.so was not there before, attempt to call its early - initialization routine. */ + initialization routine. Indicate to the initialization routine + whether the libc being initialized is the one in the base + namespace. */ if (!args->libc_already_loaded) - _dl_call_libc_early_init (GL(dl_ns)[args->nsid].libc_map); + { + struct link_map *libc_map = GL(dl_ns)[args->nsid].libc_map; +#ifdef SHARED + bool initial = libc_map->l_ns == LM_ID_BASE; +#else + /* In the static case, there is only one namespace, but it + contains a secondary libc (the primary libc is statically + linked). */ + bool initial = false; +#endif + _dl_call_libc_early_init (libc_map, initial); + } #ifndef SHARED DL_STATIC_INIT (new); diff --git a/elf/libc-early-init.h b/elf/libc-early-init.h index 5185fa8895..8f7836dcea 100644 --- a/elf/libc-early-init.h +++ b/elf/libc-early-init.h @@ -22,14 +22,17 @@ struct link_map; /* If LIBC_MAP is not NULL, look up the __libc_early_init symbol in it - and call this function. */ -void _dl_call_libc_early_init (struct link_map *libc_map) attribute_hidden; + and call this function, with INITIAL as the argument. */ +void _dl_call_libc_early_init (struct link_map *libc_map, _Bool initial) + attribute_hidden; /* In the shared case, this function is defined in libc.so and invoked from ld.so (or on the fist static dlopen) after complete relocation of a new loaded libc.so, but before user-defined ELF constructors run. In the static case, this function is called directly from the - startup code. */ -void __libc_early_init (void); + startup code. If INITIAL is true, the libc being initialized is + the libc for the main program. INITIAL is false for libcs loaded + for audit modules, dlmopen, and static dlopen. */ +void __libc_early_init (_Bool initial); #endif /* _LIBC_EARLY_INIT_H */ diff --git a/elf/libc_early_init.c b/elf/libc_early_init.c index 7f4ca332b8..e6c64fb526 100644 --- a/elf/libc_early_init.c +++ b/elf/libc_early_init.c @@ -20,7 +20,7 @@ #include <libc-early-init.h> void -__libc_early_init (void) +__libc_early_init (_Bool initial) { /* Initialize ctype data. */ __ctype_init (); diff --git a/elf/rtld.c b/elf/rtld.c index 0016db86a7..5ccc3c2dbb 100644 --- a/elf/rtld.c +++ b/elf/rtld.c @@ -2373,8 +2373,10 @@ ERROR: '%s': cannot process note segment.\n", _dl_argv[0]); rtld_timer_accum (&relocate_time, start); } - /* Relocation is complete. Perform early libc initialization. */ - _dl_call_libc_early_init (GL(dl_ns)[LM_ID_BASE].libc_map); + /* Relocation is complete. Perform early libc initialization. This + is the initial libc, even if audit modules have been loaded with + other libcs. */ + _dl_call_libc_early_init (GL(dl_ns)[LM_ID_BASE].libc_map, true); /* Do any necessary cleanups for the startup OS interface code. We do these now so that no calls are made after rtld re-relocation |