update to glibc-2.28-151.el8.src.rpm
Signed-off-by: Liwei Ge <geliwei@openanolis.org>
This commit is contained in:
parent
ba6a26df65
commit
37da1d0798
284 changed files with 62546 additions and 13 deletions
408
glibc-rh1817513-19.patch
Normal file
408
glibc-rh1817513-19.patch
Normal file
|
@ -0,0 +1,408 @@
|
|||
commit 3b856d093f5197637a5927c37d6c07dad8c86d45
|
||||
Author: Florian Weimer <fweimer@redhat.com>
|
||||
Date: Tue Feb 12 13:36:56 2019 +0100
|
||||
|
||||
elf: Ignore LD_AUDIT interfaces if la_version returns 0 [BZ #24122]
|
||||
|
||||
This change moves the audit module loading and early notification into
|
||||
separate functions out of dl_main.
|
||||
|
||||
It restores the bug fix from commit
|
||||
8e889c5da3c5981c5a46a93fec02de40131ac5a6 ("elf: Fix LD_AUDIT for
|
||||
modules with invalid version (BZ#24122)") which was reverted in commit
|
||||
83e6b59625f45db1eee93e5684091f740c52a083 ("[elf] Revert 8e889c5da3
|
||||
(BZ#24122)").
|
||||
|
||||
The actual bug fix is the separate error message for the case when
|
||||
la_version returns zero. The dynamic linker error message (which is
|
||||
NULL in this case) is no longer used. Based on the intended use of
|
||||
version zero (ignore this module due to explicit request), the message
|
||||
is only printed if debugging is enabled.
|
||||
|
||||
diff --git a/elf/rtld.c b/elf/rtld.c
|
||||
index 8bb5f548a0ff8eb4..375e0de8fa2e049e 100644
|
||||
--- a/elf/rtld.c
|
||||
+++ b/elf/rtld.c
|
||||
@@ -864,6 +864,205 @@ handle_preload_list (const char *preloadlist, struct link_map *main_map,
|
||||
return npreloads;
|
||||
}
|
||||
|
||||
+/* Called if the audit DSO cannot be used: if it does not have the
|
||||
+ appropriate interfaces, or it expects a more recent version library
|
||||
+ version than what the dynamic linker provides. */
|
||||
+static void
|
||||
+unload_audit_module (struct link_map *map, int original_tls_idx)
|
||||
+{
|
||||
+#ifndef NDEBUG
|
||||
+ Lmid_t ns = map->l_ns;
|
||||
+#endif
|
||||
+ _dl_close (map);
|
||||
+
|
||||
+ /* Make sure the namespace has been cleared entirely. */
|
||||
+ assert (GL(dl_ns)[ns]._ns_loaded == NULL);
|
||||
+ assert (GL(dl_ns)[ns]._ns_nloaded == 0);
|
||||
+
|
||||
+ GL(dl_tls_max_dtv_idx) = original_tls_idx;
|
||||
+}
|
||||
+
|
||||
+/* Called to print an error message if loading of an audit module
|
||||
+ failed. */
|
||||
+static void
|
||||
+report_audit_module_load_error (const char *name, const char *err_str,
|
||||
+ bool malloced)
|
||||
+{
|
||||
+ _dl_error_printf ("\
|
||||
+ERROR: ld.so: object '%s' cannot be loaded as audit interface: %s; ignored.\n",
|
||||
+ name, err_str);
|
||||
+ if (malloced)
|
||||
+ free ((char *) err_str);
|
||||
+}
|
||||
+
|
||||
+/* Load one audit module. */
|
||||
+static void
|
||||
+load_audit_module (const char *name, struct audit_ifaces **last_audit)
|
||||
+{
|
||||
+ int original_tls_idx = GL(dl_tls_max_dtv_idx);
|
||||
+
|
||||
+ struct dlmopen_args dlmargs;
|
||||
+ dlmargs.fname = name;
|
||||
+ dlmargs.map = NULL;
|
||||
+
|
||||
+ const char *objname;
|
||||
+ const char *err_str = NULL;
|
||||
+ bool malloced;
|
||||
+ _dl_catch_error (&objname, &err_str, &malloced, dlmopen_doit, &dlmargs);
|
||||
+ if (__glibc_unlikely (err_str != NULL))
|
||||
+ {
|
||||
+ report_audit_module_load_error (name, err_str, malloced);
|
||||
+ return;
|
||||
+ }
|
||||
+
|
||||
+ struct lookup_args largs;
|
||||
+ largs.name = "la_version";
|
||||
+ largs.map = dlmargs.map;
|
||||
+ _dl_catch_error (&objname, &err_str, &malloced, lookup_doit, &largs);
|
||||
+ if (__glibc_likely (err_str != NULL))
|
||||
+ {
|
||||
+ unload_audit_module (dlmargs.map, original_tls_idx);
|
||||
+ report_audit_module_load_error (name, err_str, malloced);
|
||||
+ return;
|
||||
+ }
|
||||
+
|
||||
+ unsigned int (*laversion) (unsigned int) = largs.result;
|
||||
+
|
||||
+ /* A null symbol indicates that something is very wrong with the
|
||||
+ loaded object because defined symbols are supposed to have a
|
||||
+ valid, non-null address. */
|
||||
+ assert (laversion != NULL);
|
||||
+
|
||||
+ unsigned int lav = laversion (LAV_CURRENT);
|
||||
+ if (lav == 0)
|
||||
+ {
|
||||
+ /* Only print an error message if debugging because this can
|
||||
+ happen deliberately. */
|
||||
+ if (GLRO(dl_debug_mask) & DL_DEBUG_FILES)
|
||||
+ _dl_debug_printf ("\
|
||||
+file=%s [%lu]; audit interface function la_version returned zero; ignored.\n",
|
||||
+ dlmargs.map->l_name, dlmargs.map->l_ns);
|
||||
+ unload_audit_module (dlmargs.map, original_tls_idx);
|
||||
+ return;
|
||||
+ }
|
||||
+
|
||||
+ if (lav > LAV_CURRENT)
|
||||
+ {
|
||||
+ _dl_debug_printf ("\
|
||||
+ERROR: audit interface '%s' requires version %d (maximum supported version %d); ignored.\n",
|
||||
+ name, lav, LAV_CURRENT);
|
||||
+ unload_audit_module (dlmargs.map, original_tls_idx);
|
||||
+ return;
|
||||
+ }
|
||||
+
|
||||
+ enum { naudit_ifaces = 8 };
|
||||
+ union
|
||||
+ {
|
||||
+ struct audit_ifaces ifaces;
|
||||
+ void (*fptr[naudit_ifaces]) (void);
|
||||
+ } *newp = malloc (sizeof (*newp));
|
||||
+ if (newp == NULL)
|
||||
+ _dl_fatal_printf ("Out of memory while loading audit modules\n");
|
||||
+
|
||||
+ /* Names of the auditing interfaces. All in one
|
||||
+ long string. */
|
||||
+ static const char audit_iface_names[] =
|
||||
+ "la_activity\0"
|
||||
+ "la_objsearch\0"
|
||||
+ "la_objopen\0"
|
||||
+ "la_preinit\0"
|
||||
+#if __ELF_NATIVE_CLASS == 32
|
||||
+ "la_symbind32\0"
|
||||
+#elif __ELF_NATIVE_CLASS == 64
|
||||
+ "la_symbind64\0"
|
||||
+#else
|
||||
+# error "__ELF_NATIVE_CLASS must be defined"
|
||||
+#endif
|
||||
+#define STRING(s) __STRING (s)
|
||||
+ "la_" STRING (ARCH_LA_PLTENTER) "\0"
|
||||
+ "la_" STRING (ARCH_LA_PLTEXIT) "\0"
|
||||
+ "la_objclose\0";
|
||||
+ unsigned int cnt = 0;
|
||||
+ const char *cp = audit_iface_names;
|
||||
+ do
|
||||
+ {
|
||||
+ largs.name = cp;
|
||||
+ _dl_catch_error (&objname, &err_str, &malloced, lookup_doit, &largs);
|
||||
+
|
||||
+ /* Store the pointer. */
|
||||
+ if (err_str == NULL && largs.result != NULL)
|
||||
+ {
|
||||
+ newp->fptr[cnt] = largs.result;
|
||||
+
|
||||
+ /* The dynamic linker link map is statically allocated,
|
||||
+ initialize the data now. */
|
||||
+ GL(dl_rtld_map).l_audit[cnt].cookie = (intptr_t) &GL(dl_rtld_map);
|
||||
+ }
|
||||
+ else
|
||||
+ newp->fptr[cnt] = NULL;
|
||||
+ ++cnt;
|
||||
+
|
||||
+ cp = rawmemchr (cp, '\0') + 1;
|
||||
+ }
|
||||
+ while (*cp != '\0');
|
||||
+ assert (cnt == naudit_ifaces);
|
||||
+
|
||||
+ /* Now append the new auditing interface to the list. */
|
||||
+ newp->ifaces.next = NULL;
|
||||
+ if (*last_audit == NULL)
|
||||
+ *last_audit = GLRO(dl_audit) = &newp->ifaces;
|
||||
+ else
|
||||
+ *last_audit = (*last_audit)->next = &newp->ifaces;
|
||||
+ ++GLRO(dl_naudit);
|
||||
+
|
||||
+ /* Mark the DSO as being used for auditing. */
|
||||
+ dlmargs.map->l_auditing = 1;
|
||||
+}
|
||||
+
|
||||
+/* Notify the the audit modules that the object MAP has already been
|
||||
+ loaded. */
|
||||
+static void
|
||||
+notify_audit_modules_of_loaded_object (struct link_map *map)
|
||||
+{
|
||||
+ struct audit_ifaces *afct = GLRO(dl_audit);
|
||||
+ for (unsigned int cnt = 0; cnt < GLRO(dl_naudit); ++cnt)
|
||||
+ {
|
||||
+ if (afct->objopen != NULL)
|
||||
+ {
|
||||
+ map->l_audit[cnt].bindflags
|
||||
+ = afct->objopen (map, LM_ID_BASE, &map->l_audit[cnt].cookie);
|
||||
+ map->l_audit_any_plt |= map->l_audit[cnt].bindflags != 0;
|
||||
+ }
|
||||
+
|
||||
+ afct = afct->next;
|
||||
+ }
|
||||
+}
|
||||
+
|
||||
+/* Load all audit modules. */
|
||||
+static void
|
||||
+load_audit_modules (struct link_map *main_map)
|
||||
+{
|
||||
+ struct audit_ifaces *last_audit = NULL;
|
||||
+ struct audit_list_iter al_iter;
|
||||
+ audit_list_iter_init (&al_iter);
|
||||
+
|
||||
+ while (true)
|
||||
+ {
|
||||
+ const char *name = audit_list_iter_next (&al_iter);
|
||||
+ if (name == NULL)
|
||||
+ break;
|
||||
+ load_audit_module (name, &last_audit);
|
||||
+ }
|
||||
+
|
||||
+ /* Notify audit modules of the initially loaded modules (the main
|
||||
+ program and the dynamic linker itself). */
|
||||
+ if (GLRO(dl_naudit) > 0)
|
||||
+ {
|
||||
+ notify_audit_modules_of_loaded_object (main_map);
|
||||
+ notify_audit_modules_of_loaded_object (&GL(dl_rtld_map));
|
||||
+ }
|
||||
+}
|
||||
+
|
||||
static void
|
||||
dl_main (const ElfW(Phdr) *phdr,
|
||||
ElfW(Word) phnum,
|
||||
@@ -1402,10 +1601,6 @@ ERROR: '%s': cannot process note segment.\n", _dl_argv[0]);
|
||||
if (__glibc_unlikely (audit_list != NULL)
|
||||
|| __glibc_unlikely (audit_list_string != NULL))
|
||||
{
|
||||
- struct audit_ifaces *last_audit = NULL;
|
||||
- struct audit_list_iter al_iter;
|
||||
- audit_list_iter_init (&al_iter);
|
||||
-
|
||||
/* Since we start using the auditing DSOs right away we need to
|
||||
initialize the data structures now. */
|
||||
tcbp = init_tls ();
|
||||
@@ -1417,164 +1612,7 @@ ERROR: '%s': cannot process note segment.\n", _dl_argv[0]);
|
||||
security_init ();
|
||||
need_security_init = false;
|
||||
|
||||
- while (true)
|
||||
- {
|
||||
- const char *name = audit_list_iter_next (&al_iter);
|
||||
- if (name == NULL)
|
||||
- break;
|
||||
-
|
||||
- int tls_idx = GL(dl_tls_max_dtv_idx);
|
||||
-
|
||||
- /* Now it is time to determine the layout of the static TLS
|
||||
- block and allocate it for the initial thread. Note that we
|
||||
- always allocate the static block, we never defer it even if
|
||||
- no DF_STATIC_TLS bit is set. The reason is that we know
|
||||
- glibc will use the static model. */
|
||||
- struct dlmopen_args dlmargs;
|
||||
- dlmargs.fname = name;
|
||||
- dlmargs.map = NULL;
|
||||
-
|
||||
- const char *objname;
|
||||
- const char *err_str = NULL;
|
||||
- bool malloced;
|
||||
- (void) _dl_catch_error (&objname, &err_str, &malloced, dlmopen_doit,
|
||||
- &dlmargs);
|
||||
- if (__glibc_unlikely (err_str != NULL))
|
||||
- {
|
||||
- not_loaded:
|
||||
- _dl_error_printf ("\
|
||||
-ERROR: ld.so: object '%s' cannot be loaded as audit interface: %s; ignored.\n",
|
||||
- name, err_str);
|
||||
- if (malloced)
|
||||
- free ((char *) err_str);
|
||||
- }
|
||||
- else
|
||||
- {
|
||||
- struct lookup_args largs;
|
||||
- largs.name = "la_version";
|
||||
- largs.map = dlmargs.map;
|
||||
-
|
||||
- /* Check whether the interface version matches. */
|
||||
- (void) _dl_catch_error (&objname, &err_str, &malloced,
|
||||
- lookup_doit, &largs);
|
||||
-
|
||||
- unsigned int (*laversion) (unsigned int);
|
||||
- unsigned int lav;
|
||||
- if (err_str == NULL
|
||||
- && (laversion = largs.result) != NULL
|
||||
- && (lav = laversion (LAV_CURRENT)) > 0
|
||||
- && lav <= LAV_CURRENT)
|
||||
- {
|
||||
- /* Allocate structure for the callback function pointers.
|
||||
- This call can never fail. */
|
||||
- union
|
||||
- {
|
||||
- struct audit_ifaces ifaces;
|
||||
-#define naudit_ifaces 8
|
||||
- void (*fptr[naudit_ifaces]) (void);
|
||||
- } *newp = malloc (sizeof (*newp));
|
||||
-
|
||||
- /* Names of the auditing interfaces. All in one
|
||||
- long string. */
|
||||
- static const char audit_iface_names[] =
|
||||
- "la_activity\0"
|
||||
- "la_objsearch\0"
|
||||
- "la_objopen\0"
|
||||
- "la_preinit\0"
|
||||
-#if __ELF_NATIVE_CLASS == 32
|
||||
- "la_symbind32\0"
|
||||
-#elif __ELF_NATIVE_CLASS == 64
|
||||
- "la_symbind64\0"
|
||||
-#else
|
||||
-# error "__ELF_NATIVE_CLASS must be defined"
|
||||
-#endif
|
||||
-#define STRING(s) __STRING (s)
|
||||
- "la_" STRING (ARCH_LA_PLTENTER) "\0"
|
||||
- "la_" STRING (ARCH_LA_PLTEXIT) "\0"
|
||||
- "la_objclose\0";
|
||||
- unsigned int cnt = 0;
|
||||
- const char *cp = audit_iface_names;
|
||||
- do
|
||||
- {
|
||||
- largs.name = cp;
|
||||
- (void) _dl_catch_error (&objname, &err_str, &malloced,
|
||||
- lookup_doit, &largs);
|
||||
-
|
||||
- /* Store the pointer. */
|
||||
- if (err_str == NULL && largs.result != NULL)
|
||||
- {
|
||||
- newp->fptr[cnt] = largs.result;
|
||||
-
|
||||
- /* The dynamic linker link map is statically
|
||||
- allocated, initialize the data now. */
|
||||
- GL(dl_rtld_map).l_audit[cnt].cookie
|
||||
- = (intptr_t) &GL(dl_rtld_map);
|
||||
- }
|
||||
- else
|
||||
- newp->fptr[cnt] = NULL;
|
||||
- ++cnt;
|
||||
-
|
||||
- cp = (char *) rawmemchr (cp, '\0') + 1;
|
||||
- }
|
||||
- while (*cp != '\0');
|
||||
- assert (cnt == naudit_ifaces);
|
||||
-
|
||||
- /* Now append the new auditing interface to the list. */
|
||||
- newp->ifaces.next = NULL;
|
||||
- if (last_audit == NULL)
|
||||
- last_audit = GLRO(dl_audit) = &newp->ifaces;
|
||||
- else
|
||||
- last_audit = last_audit->next = &newp->ifaces;
|
||||
- ++GLRO(dl_naudit);
|
||||
-
|
||||
- /* Mark the DSO as being used for auditing. */
|
||||
- dlmargs.map->l_auditing = 1;
|
||||
- }
|
||||
- else
|
||||
- {
|
||||
- /* We cannot use the DSO, it does not have the
|
||||
- appropriate interfaces or it expects something
|
||||
- more recent. */
|
||||
-#ifndef NDEBUG
|
||||
- Lmid_t ns = dlmargs.map->l_ns;
|
||||
-#endif
|
||||
- _dl_close (dlmargs.map);
|
||||
-
|
||||
- /* Make sure the namespace has been cleared entirely. */
|
||||
- assert (GL(dl_ns)[ns]._ns_loaded == NULL);
|
||||
- assert (GL(dl_ns)[ns]._ns_nloaded == 0);
|
||||
-
|
||||
- GL(dl_tls_max_dtv_idx) = tls_idx;
|
||||
- goto not_loaded;
|
||||
- }
|
||||
- }
|
||||
- }
|
||||
-
|
||||
- /* If we have any auditing modules, announce that we already
|
||||
- have two objects loaded. */
|
||||
- if (__glibc_unlikely (GLRO(dl_naudit) > 0))
|
||||
- {
|
||||
- struct link_map *ls[2] = { main_map, &GL(dl_rtld_map) };
|
||||
-
|
||||
- for (unsigned int outer = 0; outer < 2; ++outer)
|
||||
- {
|
||||
- struct audit_ifaces *afct = GLRO(dl_audit);
|
||||
- for (unsigned int cnt = 0; cnt < GLRO(dl_naudit); ++cnt)
|
||||
- {
|
||||
- if (afct->objopen != NULL)
|
||||
- {
|
||||
- ls[outer]->l_audit[cnt].bindflags
|
||||
- = afct->objopen (ls[outer], LM_ID_BASE,
|
||||
- &ls[outer]->l_audit[cnt].cookie);
|
||||
-
|
||||
- ls[outer]->l_audit_any_plt
|
||||
- |= ls[outer]->l_audit[cnt].bindflags != 0;
|
||||
- }
|
||||
-
|
||||
- afct = afct->next;
|
||||
- }
|
||||
- }
|
||||
- }
|
||||
+ load_audit_modules (main_map);
|
||||
}
|
||||
|
||||
/* Keep track of the currently loaded modules to count how many
|
Loading…
Add table
Add a link
Reference in a new issue