Signal la_objopen for ld.so with dlmopen (RHEL-49549)
Resolves: RHEL-49549
This commit is contained in:
parent
7c82c40390
commit
97ea51322d
55
glibc-RHEL-49549-1.patch
Normal file
55
glibc-RHEL-49549-1.patch
Normal file
@ -0,0 +1,55 @@
|
||||
commit 152f863926e77c6f9c9a8b8779c8084eb844ec44
|
||||
Author: Andreas Schwab <schwab@suse.de>
|
||||
Date: Thu Mar 23 16:18:50 2023 +0100
|
||||
|
||||
_dl_map_object_from_fd: Remove unnecessary debugger notification in error path
|
||||
|
||||
After commit ed3ce71f5c ("elf: Move la_activity (LA_ACT_ADD) after
|
||||
_dl_add_to_namespace_list() (BZ #28062)") it is no longer necessary to
|
||||
reset the debugger state in the error case, since the debugger
|
||||
notification only happens after no more errors can occur.
|
||||
|
||||
diff --git a/elf/dl-load.c b/elf/dl-load.c
|
||||
index 5b0734c816b351f0..98a91d40b74cb76b 100644
|
||||
--- a/elf/dl-load.c
|
||||
+++ b/elf/dl-load.c
|
||||
@@ -950,8 +950,6 @@ _dl_map_object_from_fd (const char *name, const char *origname, int fd,
|
||||
/* Initialize to keep the compiler happy. */
|
||||
const char *errstring = NULL;
|
||||
int errval = 0;
|
||||
- struct r_debug *r = _dl_debug_update (nsid);
|
||||
- bool make_consistent = false;
|
||||
|
||||
/* Get file information. To match the kernel behavior, do not fill
|
||||
in this information for the executable in case of an explicit
|
||||
@@ -983,14 +981,6 @@ _dl_map_object_from_fd (const char *name, const char *origname, int fd,
|
||||
free ((void *) l->l_phdr);
|
||||
free (l);
|
||||
free (realname);
|
||||
-
|
||||
- if (make_consistent && r != NULL)
|
||||
- {
|
||||
- r->r_state = RT_CONSISTENT;
|
||||
- _dl_debug_state ();
|
||||
- LIBC_PROBE (map_failed, 2, nsid, r);
|
||||
- }
|
||||
-
|
||||
_dl_signal_error (errval, name, NULL, errstring);
|
||||
}
|
||||
|
||||
@@ -1476,6 +1466,7 @@ cannot enable executable stack as shared object requires");
|
||||
_dl_add_to_namespace_list (l, nsid);
|
||||
|
||||
/* Signal that we are going to add new objects. */
|
||||
+ struct r_debug *r = _dl_debug_update (nsid);
|
||||
if (r->r_state == RT_CONSISTENT)
|
||||
{
|
||||
#ifdef SHARED
|
||||
@@ -1492,7 +1483,6 @@ cannot enable executable stack as shared object requires");
|
||||
r->r_state = RT_ADD;
|
||||
_dl_debug_state ();
|
||||
LIBC_PROBE (map_start, 2, nsid, r);
|
||||
- make_consistent = true;
|
||||
}
|
||||
else
|
||||
assert (r->r_state == RT_ADD);
|
||||
174
glibc-RHEL-49549-2.patch
Normal file
174
glibc-RHEL-49549-2.patch
Normal file
@ -0,0 +1,174 @@
|
||||
commit ab5aa2ee3d3f978e474803cbbc5fe805ad30e293
|
||||
Author: Andreas Schwab <schwab@suse.de>
|
||||
Date: Thu Mar 23 16:46:20 2023 +0100
|
||||
|
||||
dlopen: skip debugger notification for DSO loaded from sprof (bug 30258)
|
||||
|
||||
Avoid inconsistent state in the debugger interface.
|
||||
|
||||
Conflicts:
|
||||
elf/Makefile: Test differences.
|
||||
|
||||
diff --git a/elf/Makefile b/elf/Makefile
|
||||
index 86d4dd9960088ee1..721f254d121118c0 100644
|
||||
--- a/elf/Makefile
|
||||
+++ b/elf/Makefile
|
||||
@@ -528,6 +528,7 @@ tests-container += \
|
||||
|
||||
test-srcs = \
|
||||
tst-pathopt \
|
||||
+ tst-sprof-basic \
|
||||
# tests-srcs
|
||||
|
||||
ifeq (yes,$(have-fpie))
|
||||
@@ -860,6 +861,7 @@ modules-names = \
|
||||
tst-sonamemove-linkmod1 \
|
||||
tst-sonamemove-runmod1 \
|
||||
tst-sonamemove-runmod2 \
|
||||
+ tst-sprof-mod \
|
||||
tst-tls19mod1 \
|
||||
tst-tls19mod2 \
|
||||
tst-tls19mod3 \
|
||||
@@ -1114,6 +1116,7 @@ tests-special += \
|
||||
$(objpfx)tst-rtld-help.out \
|
||||
$(objpfx)tst-rtld-load-self.out \
|
||||
$(objpfx)tst-rtld-preload.out \
|
||||
+ $(objpfx)tst-sprof-basic.out \
|
||||
# tests-special
|
||||
endif
|
||||
tests-special += \
|
||||
@@ -2946,3 +2949,11 @@ $(objpfx)tst-dlopen-constructor-null: \
|
||||
$(objpfx)tst-dlopen-constructor-null-mod2.so
|
||||
$(objpfx)tst-dlopen-constructor-null-mod2.so: \
|
||||
$(objpfx)tst-dlopen-constructor-null-mod1.so
|
||||
+
|
||||
+LDFLAGS-tst-sprof-mod.so = -Wl,-soname,tst-sprof-mod.so
|
||||
+$(objpfx)tst-sprof-basic: $(objpfx)tst-sprof-mod.so
|
||||
+$(objpfx)tst-sprof-basic.out: tst-sprof-basic.sh $(objpfx)tst-sprof-basic
|
||||
+ $(SHELL) $< $(common-objpfx) '$(test-wrapper-env)' \
|
||||
+ '$(run-program-env)' > $@; \
|
||||
+ $(evaluate-test)
|
||||
+generated += tst-sprof-mod.so.profile
|
||||
diff --git a/elf/dl-load.c b/elf/dl-load.c
|
||||
index 98a91d40b74cb76b..5c1be6e80cd52e2f 100644
|
||||
--- a/elf/dl-load.c
|
||||
+++ b/elf/dl-load.c
|
||||
@@ -1465,6 +1465,10 @@ cannot enable executable stack as shared object requires");
|
||||
/* Now that the object is fully initialized add it to the object list. */
|
||||
_dl_add_to_namespace_list (l, nsid);
|
||||
|
||||
+ /* Skip auditing and debugger notification when called from 'sprof'. */
|
||||
+ if (mode & __RTLD_SPROF)
|
||||
+ return l;
|
||||
+
|
||||
/* Signal that we are going to add new objects. */
|
||||
struct r_debug *r = _dl_debug_update (nsid);
|
||||
if (r->r_state == RT_CONSISTENT)
|
||||
diff --git a/elf/tst-sprof-basic.c b/elf/tst-sprof-basic.c
|
||||
new file mode 100644
|
||||
index 0000000000000000..5e4083305a4acdd6
|
||||
--- /dev/null
|
||||
+++ b/elf/tst-sprof-basic.c
|
||||
@@ -0,0 +1,25 @@
|
||||
+/* Copyright (C) 2023 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/>. */
|
||||
+
|
||||
+void hello (void);
|
||||
+
|
||||
+int
|
||||
+main (void)
|
||||
+{
|
||||
+ hello ();
|
||||
+ return 0;
|
||||
+}
|
||||
diff --git a/elf/tst-sprof-basic.sh b/elf/tst-sprof-basic.sh
|
||||
new file mode 100755
|
||||
index 0000000000000000..901db61708c1b8ec
|
||||
--- /dev/null
|
||||
+++ b/elf/tst-sprof-basic.sh
|
||||
@@ -0,0 +1,41 @@
|
||||
+#!/bin/sh
|
||||
+# Test basic functionality of sprof
|
||||
+# Copyright (C) 2023 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/>.
|
||||
+
|
||||
+set -e
|
||||
+
|
||||
+common_objpfx=$1
|
||||
+test_wrapper_env=$2
|
||||
+run_program_env=$3
|
||||
+
|
||||
+sprof_mod=tst-sprof-mod.so
|
||||
+
|
||||
+${test_wrapper_env} \
|
||||
+${run_program_env} \
|
||||
+LD_PROFILE=$sprof_mod \
|
||||
+LD_PROFILE_OUTPUT=${common_objpfx}elf \
|
||||
+LD_LIBRARY_PATH=${common_objpfx}.:${common_objpfx}elf \
|
||||
+ ${common_objpfx}elf/ld.so ${common_objpfx}elf/tst-sprof-basic
|
||||
+
|
||||
+${test_wrapper_env} \
|
||||
+${run_program_env} \
|
||||
+LD_LIBRARY_PATH=${common_objpfx}.:${common_objpfx}elf \
|
||||
+ ${common_objpfx}elf/ld.so ${common_objpfx}elf/sprof -p $sprof_mod \
|
||||
+ ${common_objpfx}elf/${sprof_mod}.profile
|
||||
+
|
||||
+exit $?
|
||||
diff --git a/elf/tst-sprof-mod.c b/elf/tst-sprof-mod.c
|
||||
new file mode 100644
|
||||
index 0000000000000000..8b3f5e8e07f42ae6
|
||||
--- /dev/null
|
||||
+++ b/elf/tst-sprof-mod.c
|
||||
@@ -0,0 +1,24 @@
|
||||
+/* Copyright (C) 2023 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>
|
||||
+
|
||||
+void
|
||||
+hello (void)
|
||||
+{
|
||||
+ printf ("Hello World\n");
|
||||
+}
|
||||
30
glibc-RHEL-49549-3.patch
Normal file
30
glibc-RHEL-49549-3.patch
Normal file
@ -0,0 +1,30 @@
|
||||
commit f563971b5bf7191acfdd5702fe00878752c2056d
|
||||
Author: Florian Weimer <fweimer@redhat.com>
|
||||
Date: Tue Sep 26 11:40:12 2023 +0200
|
||||
|
||||
elf: Add dummy declaration of _dl_audit_objclose for !SHARED
|
||||
|
||||
This allows us to avoid some #ifdef SHARED conditionals.
|
||||
|
||||
Reviewed-by: Carlos O'Donell <carlos@redhat.com>
|
||||
|
||||
diff --git a/sysdeps/generic/ldsodefs.h b/sysdeps/generic/ldsodefs.h
|
||||
index 3d9b90a22bfa6a7d..21dbe2d21ed8e605 100644
|
||||
--- a/sysdeps/generic/ldsodefs.h
|
||||
+++ b/sysdeps/generic/ldsodefs.h
|
||||
@@ -1457,7 +1457,14 @@ void DL_ARCH_FIXUP_ATTRIBUTE _dl_audit_pltexit (struct link_map *l,
|
||||
const void *inregs,
|
||||
void *outregs)
|
||||
attribute_hidden;
|
||||
-#endif /* SHARED */
|
||||
+
|
||||
+#else /* !SHARED */
|
||||
+static inline void
|
||||
+_dl_audit_objclose (struct link_map *l)
|
||||
+{
|
||||
+ /* No audit implementation for !SHARED. */
|
||||
+}
|
||||
+#endif /* !SHARED */
|
||||
|
||||
#if PTHREAD_IN_LIBC && defined SHARED
|
||||
/* Recursive locking implementation for use within the dynamic loader.
|
||||
102
glibc-RHEL-49549-4.patch
Normal file
102
glibc-RHEL-49549-4.patch
Normal file
@ -0,0 +1,102 @@
|
||||
commit ed2b8d3a866eb37e069f6a71bdf10421cd4c5e54
|
||||
Author: Adam Sampson <ats@offog.org>
|
||||
Date: Mon May 6 18:16:32 2024 +0100
|
||||
|
||||
ldconfig: Move endswithn into a new header file
|
||||
|
||||
is_gdb_python_file is doing a similar test, so it can use this helper
|
||||
function as well.
|
||||
|
||||
Signed-off-by: Adam Sampson <ats@offog.org>
|
||||
Reviewed-by: Adhemerval Zanella <adhemerval.zanella@linaro.org>
|
||||
|
||||
diff --git a/elf/endswith.h b/elf/endswith.h
|
||||
new file mode 100644
|
||||
index 0000000000000000..c6430c48be0c1071
|
||||
--- /dev/null
|
||||
+++ b/elf/endswith.h
|
||||
@@ -0,0 +1,33 @@
|
||||
+/* Copyright (C) 2023-2024 Free Software Foundation, Inc.
|
||||
+ This file is part of the GNU C Library.
|
||||
+
|
||||
+ This program is free software; you can redistribute it and/or modify
|
||||
+ it under the terms of the GNU General Public License as published
|
||||
+ by the Free Software Foundation; version 2 of the License, or
|
||||
+ (at your option) any later version.
|
||||
+
|
||||
+ This program 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 General Public License for more details.
|
||||
+
|
||||
+ You should have received a copy of the GNU General Public License
|
||||
+ along with this program; if not, see <https://www.gnu.org/licenses/>. */
|
||||
+
|
||||
+#ifndef _ENDSWITH_H
|
||||
+#define _ENDSWITH_H
|
||||
+
|
||||
+#include <string.h>
|
||||
+
|
||||
+/* Return true if the N bytes at NAME end with with the characters in
|
||||
+ the string SUFFIX. (NAME[N + 1] does not have to be a null byte.)
|
||||
+ Expected to be called with a string literal for SUFFIX. */
|
||||
+static inline bool
|
||||
+endswithn (const char *name, size_t n, const char *suffix)
|
||||
+{
|
||||
+ return (n >= strlen (suffix)
|
||||
+ && memcmp (name + n - strlen (suffix), suffix,
|
||||
+ strlen (suffix)) == 0);
|
||||
+}
|
||||
+
|
||||
+#endif /* _ENDSWITH_H */
|
||||
diff --git a/elf/ldconfig.c b/elf/ldconfig.c
|
||||
index 4a96c409994d96c8..185c8115ae6b4060 100644
|
||||
--- a/elf/ldconfig.c
|
||||
+++ b/elf/ldconfig.c
|
||||
@@ -41,6 +41,7 @@
|
||||
#include <libgen.h>
|
||||
|
||||
#include <ldconfig.h>
|
||||
+#include <endswith.h>
|
||||
#include <dl-cache.h>
|
||||
#include <dl-hwcaps.h>
|
||||
#include <dl-is_dso.h>
|
||||
@@ -778,17 +779,6 @@ struct dlib_entry
|
||||
struct dlib_entry *next;
|
||||
};
|
||||
|
||||
-/* Return true if the N bytes at NAME end with with the characters in
|
||||
- the string SUFFIX. (NAME[N + 1] does not have to be a null byte.)
|
||||
- Expected to be called with a string literal for SUFFIX. */
|
||||
-static inline bool
|
||||
-endswithn (const char *name, size_t n, const char *suffix)
|
||||
-{
|
||||
- return (n >= strlen (suffix)
|
||||
- && memcmp (name + n - strlen (suffix), suffix,
|
||||
- strlen (suffix)) == 0);
|
||||
-}
|
||||
-
|
||||
/* Skip some temporary DSO files. These files may be partially written
|
||||
and lead to ldconfig crashes when examined. */
|
||||
static bool
|
||||
diff --git a/elf/readlib.c b/elf/readlib.c
|
||||
index 8901de2684835653..2701535e3f24a201 100644
|
||||
--- a/elf/readlib.c
|
||||
+++ b/elf/readlib.c
|
||||
@@ -35,6 +35,7 @@
|
||||
#include <gnu/lib-names.h>
|
||||
|
||||
#include <ldconfig.h>
|
||||
+#include <endswith.h>
|
||||
|
||||
#define Elf32_CLASS ELFCLASS32
|
||||
#define Elf64_CLASS ELFCLASS64
|
||||
@@ -68,7 +69,7 @@ static bool
|
||||
is_gdb_python_file (const char *name)
|
||||
{
|
||||
size_t len = strlen (name);
|
||||
- return len > 7 && strcmp (name + len - 7, "-gdb.py") == 0;
|
||||
+ return endswithn (name, len, "-gdb.py");
|
||||
}
|
||||
|
||||
/* Returns 0 if everything is ok, != 0 in case of error. */
|
||||
76
glibc-RHEL-49549-5.patch
Normal file
76
glibc-RHEL-49549-5.patch
Normal file
@ -0,0 +1,76 @@
|
||||
commit 4a50fdf8b2c1106b50cd9056b4c6f3a72cdeed5f
|
||||
Author: Florian Weimer <fweimer@redhat.com>
|
||||
Date: Tue Sep 3 17:52:47 2024 +0200
|
||||
|
||||
elf: Update DSO list, write audit log to elf/tst-audit23.out
|
||||
|
||||
After commit 1d5024f4f052c12e404d42d3b5bfe9c3e9fd27c4
|
||||
("support: Build with exceptions and asynchronous unwind tables
|
||||
[BZ #30587]"), libgcc_s is expected to show up in the DSO
|
||||
list on 32-bit Arm. Do not update max_objs because vdso is not
|
||||
tracked (and which is the reason why the test currently passes
|
||||
even with libgcc_s present).
|
||||
|
||||
Also write the log output from the auditor to standard output,
|
||||
for easier test debugging.
|
||||
|
||||
Reviewed-by: Adhemerval Zanella <adhemerval.zanella@linaro.org>
|
||||
|
||||
diff --git a/elf/tst-audit23.c b/elf/tst-audit23.c
|
||||
index 4904cf1340a97ee1..6ac1f20af60a2ebb 100644
|
||||
--- a/elf/tst-audit23.c
|
||||
+++ b/elf/tst-audit23.c
|
||||
@@ -85,13 +85,28 @@ do_test (int argc, char *argv[])
|
||||
= support_capture_subprogram (spargv[0], spargv);
|
||||
support_capture_subprocess_check (&result, "tst-audit22", 0, sc_allow_stderr);
|
||||
|
||||
+ {
|
||||
+ FILE *fp = fmemopen (result.err.buffer, result.err.length, "r");
|
||||
+ TEST_VERIFY (fp != NULL);
|
||||
+ unsigned int line = 0;
|
||||
+ char *buffer = NULL;
|
||||
+ size_t buffer_length = 0;
|
||||
+ puts ("info: *** audit log start ***");
|
||||
+ while (xgetline (&buffer, &buffer_length, fp))
|
||||
+ printf ("%6u\t%s", ++line, buffer);
|
||||
+ puts ("info: *** audit log end ***");
|
||||
+ free (buffer);
|
||||
+ xfclose (fp);
|
||||
+ }
|
||||
+
|
||||
/* The expected la_objopen/la_objclose:
|
||||
1. executable
|
||||
2. loader
|
||||
3. libc.so
|
||||
- 4. tst-audit23mod.so
|
||||
- 5. libc.so (LM_ID_NEWLM).
|
||||
- 6. vdso (optional and ignored). */
|
||||
+ 4. libgcc_s.so (one some architectures, for libsupport)
|
||||
+ 5. tst-audit23mod.so
|
||||
+ 6. libc.so (LM_ID_NEWLM).
|
||||
+ vdso (optional and ignored). */
|
||||
enum { max_objs = 6 };
|
||||
struct la_obj_t
|
||||
{
|
||||
@@ -115,8 +130,10 @@ do_test (int argc, char *argv[])
|
||||
TEST_VERIFY (out != NULL);
|
||||
char *buffer = NULL;
|
||||
size_t buffer_length = 0;
|
||||
+ unsigned int line = 0;
|
||||
while (xgetline (&buffer, &buffer_length, out))
|
||||
{
|
||||
+ ++line;
|
||||
if (startswith (buffer, "la_activity: "))
|
||||
{
|
||||
uintptr_t cookie;
|
||||
@@ -174,8 +191,8 @@ do_test (int argc, char *argv[])
|
||||
if (is_vdso (lname))
|
||||
continue;
|
||||
if (nobjs == max_objs)
|
||||
- FAIL_EXIT1 ("non expected la_objopen: %s %"PRIxPTR" %ld",
|
||||
- lname, laddr, lmid);
|
||||
+ FAIL_EXIT1 ("(line %u) non expected la_objopen: %s %"PRIxPTR" %ld",
|
||||
+ line, lname, laddr, lmid);
|
||||
objs[nobjs].lname = lname;
|
||||
objs[nobjs].laddr = laddr;
|
||||
objs[nobjs].lmid = lmid;
|
||||
34
glibc-RHEL-49549-6.patch
Normal file
34
glibc-RHEL-49549-6.patch
Normal file
@ -0,0 +1,34 @@
|
||||
commit a20bc2f6233a726c7df8eaa332b6e498bd59321f
|
||||
Author: Florian Weimer <fweimer@redhat.com>
|
||||
Date: Fri Nov 29 15:36:40 2024 +0100
|
||||
|
||||
elf: Add the endswith function to <endswith.h>
|
||||
|
||||
And include <stdbool.h> for a definition of bool.
|
||||
|
||||
Reviewed-by: Adhemerval Zanella <adhemerval.zanella@linaro.org>
|
||||
|
||||
diff --git a/elf/endswith.h b/elf/endswith.h
|
||||
index c6430c48be0c1071..3954e57f8eff0faa 100644
|
||||
--- a/elf/endswith.h
|
||||
+++ b/elf/endswith.h
|
||||
@@ -17,6 +17,7 @@
|
||||
#ifndef _ENDSWITH_H
|
||||
#define _ENDSWITH_H
|
||||
|
||||
+#include <stdbool.h>
|
||||
#include <string.h>
|
||||
|
||||
/* Return true if the N bytes at NAME end with with the characters in
|
||||
@@ -30,4 +31,11 @@ endswithn (const char *name, size_t n, const char *suffix)
|
||||
strlen (suffix)) == 0);
|
||||
}
|
||||
|
||||
+/* Same as endswithn, but uses the entire SUBJECT for matching. */
|
||||
+static inline bool
|
||||
+endswith (const char *subject, const char *suffix)
|
||||
+{
|
||||
+ return endswithn (subject, strlen (subject), suffix);
|
||||
+}
|
||||
+
|
||||
#endif /* _ENDSWITH_H */
|
||||
131
glibc-RHEL-49549-7.patch
Normal file
131
glibc-RHEL-49549-7.patch
Normal file
@ -0,0 +1,131 @@
|
||||
commit 8f36b1469677afe37168f9af1b77402d7a70c673
|
||||
Author: Florian Weimer <fweimer@redhat.com>
|
||||
Date: Fri Aug 9 15:31:18 2024 +0200
|
||||
|
||||
elf: Signal la_objopen for the proxy link map in dlmopen (bug 31985)
|
||||
|
||||
Previously, the ld.so link map was silently added to the namespace.
|
||||
This change produces an auditing event for it.
|
||||
|
||||
Reviewed-by: Adhemerval Zanella <adhemerval.zanella@linaro.org>
|
||||
|
||||
diff --git a/elf/dl-load.c b/elf/dl-load.c
|
||||
index 5c1be6e80cd52e2f..6714807946b60188 100644
|
||||
--- a/elf/dl-load.c
|
||||
+++ b/elf/dl-load.c
|
||||
@@ -928,6 +928,37 @@ _dl_process_pt_gnu_property (struct link_map *l, int fd, const ElfW(Phdr) *ph)
|
||||
}
|
||||
}
|
||||
|
||||
+static void
|
||||
+_dl_notify_new_object (int mode, Lmid_t nsid, struct link_map *l)
|
||||
+{
|
||||
+ /* Signal that we are going to add new objects. */
|
||||
+ struct r_debug *r = _dl_debug_update (nsid);
|
||||
+ if (r->r_state == RT_CONSISTENT)
|
||||
+ {
|
||||
+#ifdef SHARED
|
||||
+ /* Auditing checkpoint: we are going to add new objects. Since this
|
||||
+ is called after _dl_add_to_namespace_list the namespace is guaranteed
|
||||
+ to not be empty. */
|
||||
+ if ((mode & __RTLD_AUDIT) == 0)
|
||||
+ _dl_audit_activity_nsid (nsid, LA_ACT_ADD);
|
||||
+#endif
|
||||
+
|
||||
+ /* Notify the debugger we have added some objects. We need to
|
||||
+ call _dl_debug_initialize in a static program in case dynamic
|
||||
+ linking has not been used before. */
|
||||
+ r->r_state = RT_ADD;
|
||||
+ _dl_debug_state ();
|
||||
+ LIBC_PROBE (map_start, 2, nsid, r);
|
||||
+ }
|
||||
+ else
|
||||
+ assert (r->r_state == RT_ADD);
|
||||
+
|
||||
+#ifdef SHARED
|
||||
+ /* Auditing checkpoint: we have a new object. */
|
||||
+ if (!GL(dl_ns)[l->l_ns]._ns_loaded->l_auditing)
|
||||
+ _dl_audit_objopen (l, nsid);
|
||||
+#endif
|
||||
+}
|
||||
|
||||
/* Map in the shared object NAME, actually located in REALNAME, and already
|
||||
opened on FD. */
|
||||
@@ -1024,6 +1055,8 @@ _dl_map_object_from_fd (const char *name, const char *origname, int fd,
|
||||
/* Add the map for the mirrored object to the object list. */
|
||||
_dl_add_to_namespace_list (l, nsid);
|
||||
|
||||
+ _dl_notify_new_object (mode, nsid, l);
|
||||
+
|
||||
return l;
|
||||
}
|
||||
#endif
|
||||
@@ -1469,33 +1502,7 @@ cannot enable executable stack as shared object requires");
|
||||
if (mode & __RTLD_SPROF)
|
||||
return l;
|
||||
|
||||
- /* Signal that we are going to add new objects. */
|
||||
- struct r_debug *r = _dl_debug_update (nsid);
|
||||
- if (r->r_state == RT_CONSISTENT)
|
||||
- {
|
||||
-#ifdef SHARED
|
||||
- /* Auditing checkpoint: we are going to add new objects. Since this
|
||||
- is called after _dl_add_to_namespace_list the namespace is guaranteed
|
||||
- to not be empty. */
|
||||
- if ((mode & __RTLD_AUDIT) == 0)
|
||||
- _dl_audit_activity_nsid (nsid, LA_ACT_ADD);
|
||||
-#endif
|
||||
-
|
||||
- /* Notify the debugger we have added some objects. We need to
|
||||
- call _dl_debug_initialize in a static program in case dynamic
|
||||
- linking has not been used before. */
|
||||
- r->r_state = RT_ADD;
|
||||
- _dl_debug_state ();
|
||||
- LIBC_PROBE (map_start, 2, nsid, r);
|
||||
- }
|
||||
- else
|
||||
- assert (r->r_state == RT_ADD);
|
||||
-
|
||||
-#ifdef SHARED
|
||||
- /* Auditing checkpoint: we have a new object. */
|
||||
- if (!GL(dl_ns)[l->l_ns]._ns_loaded->l_auditing)
|
||||
- _dl_audit_objopen (l, nsid);
|
||||
-#endif
|
||||
+ _dl_notify_new_object (mode, nsid, l);
|
||||
|
||||
return l;
|
||||
}
|
||||
diff --git a/elf/tst-audit23.c b/elf/tst-audit23.c
|
||||
index 6ac1f20af60a2ebb..0c7ca3112381a31e 100644
|
||||
--- a/elf/tst-audit23.c
|
||||
+++ b/elf/tst-audit23.c
|
||||
@@ -17,6 +17,7 @@
|
||||
<https://www.gnu.org/licenses/>. */
|
||||
|
||||
#include <array_length.h>
|
||||
+#include <endswith.h>
|
||||
#include <errno.h>
|
||||
#include <getopt.h>
|
||||
#include <link.h>
|
||||
@@ -106,8 +107,9 @@ do_test (int argc, char *argv[])
|
||||
4. libgcc_s.so (one some architectures, for libsupport)
|
||||
5. tst-audit23mod.so
|
||||
6. libc.so (LM_ID_NEWLM).
|
||||
+ 7. loader (proxy link map in new namespace)
|
||||
vdso (optional and ignored). */
|
||||
- enum { max_objs = 6 };
|
||||
+ enum { max_objs = 7 };
|
||||
struct la_obj_t
|
||||
{
|
||||
char *lname;
|
||||
@@ -236,7 +238,9 @@ do_test (int argc, char *argv[])
|
||||
|
||||
for (size_t i = 0; i < nobjs; i++)
|
||||
{
|
||||
- TEST_COMPARE (objs[i].closed, true);
|
||||
+ /* This subtest currently does not pass because of bug 32065. */
|
||||
+ if (! (endswith (objs[i].lname, LD_SO) && objs[i].lmid != LM_ID_BASE))
|
||||
+ TEST_COMPARE (objs[i].closed, true);
|
||||
free (objs[i].lname);
|
||||
}
|
||||
|
||||
76
glibc-RHEL-49549-8.patch
Normal file
76
glibc-RHEL-49549-8.patch
Normal file
@ -0,0 +1,76 @@
|
||||
commit c4b160744cb39eca20dc36b39c7fa6e10352706c
|
||||
Author: Florian Weimer <fweimer@redhat.com>
|
||||
Date: Fri Aug 9 16:06:40 2024 +0200
|
||||
|
||||
elf: Call la_objclose for proxy link maps in _dl_fini (bug 32065)
|
||||
|
||||
Reviewed-by: Adhemerval Zanella <adhemerval.zanella@linaro.org>
|
||||
|
||||
diff --git a/elf/dl-fini.c b/elf/dl-fini.c
|
||||
index fa876da0ffa1cf97..133dbac385b34fbb 100644
|
||||
--- a/elf/dl-fini.c
|
||||
+++ b/elf/dl-fini.c
|
||||
@@ -74,6 +74,7 @@ _dl_fini (void)
|
||||
|
||||
unsigned int i;
|
||||
struct link_map *l;
|
||||
+ struct link_map *proxy_link_map = NULL;
|
||||
assert (nloaded != 0 || GL(dl_ns)[ns]._ns_loaded == NULL);
|
||||
for (l = GL(dl_ns)[ns]._ns_loaded, i = 0; l != NULL; l = l->l_next)
|
||||
/* Do not handle ld.so in secondary namespaces. */
|
||||
@@ -89,6 +90,11 @@ _dl_fini (void)
|
||||
are not dlclose()ed from underneath us. */
|
||||
++l->l_direct_opencount;
|
||||
}
|
||||
+ else
|
||||
+ /* Used below to call la_objclose for the ld.so proxy
|
||||
+ link map. */
|
||||
+ proxy_link_map = l;
|
||||
+
|
||||
assert (ns != LM_ID_BASE || i == nloaded);
|
||||
assert (ns == LM_ID_BASE || i == nloaded || i == nloaded - 1);
|
||||
unsigned int nmaps = i;
|
||||
@@ -158,6 +164,9 @@ _dl_fini (void)
|
||||
--l->l_direct_opencount;
|
||||
}
|
||||
|
||||
+ if (proxy_link_map != NULL)
|
||||
+ _dl_audit_objclose (proxy_link_map);
|
||||
+
|
||||
#ifdef SHARED
|
||||
_dl_audit_activity_nsid (ns, LA_ACT_CONSISTENT);
|
||||
#endif
|
||||
diff --git a/elf/tst-audit23.c b/elf/tst-audit23.c
|
||||
index 0c7ca3112381a31e..d5137fd44dacde3c 100644
|
||||
--- a/elf/tst-audit23.c
|
||||
+++ b/elf/tst-audit23.c
|
||||
@@ -236,13 +236,26 @@ do_test (int argc, char *argv[])
|
||||
}
|
||||
}
|
||||
|
||||
+ Lmid_t lmid_other = LM_ID_NEWLM;
|
||||
+ unsigned int other_namespace_count = 0;
|
||||
for (size_t i = 0; i < nobjs; i++)
|
||||
{
|
||||
- /* This subtest currently does not pass because of bug 32065. */
|
||||
- if (! (endswith (objs[i].lname, LD_SO) && objs[i].lmid != LM_ID_BASE))
|
||||
- TEST_COMPARE (objs[i].closed, true);
|
||||
+ if (objs[i].lmid != LM_ID_BASE)
|
||||
+ {
|
||||
+ if (lmid_other == LM_ID_NEWLM)
|
||||
+ lmid_other = objs[i].lmid;
|
||||
+ TEST_COMPARE (objs[i].lmid, lmid_other);
|
||||
+ ++other_namespace_count;
|
||||
+ if (!(endswith (objs[i].lname, "/" LIBC_SO)
|
||||
+ || endswith (objs[i].lname, "/" LD_SO)))
|
||||
+ FAIL ("unexpected object in secondary namespace: %s",
|
||||
+ objs[i].lname);
|
||||
+ }
|
||||
+ TEST_COMPARE (objs[i].closed, true);
|
||||
free (objs[i].lname);
|
||||
}
|
||||
+ /* Both libc.so and ld.so should be present. */
|
||||
+ TEST_COMPARE (other_namespace_count, 2);
|
||||
|
||||
/* la_activity(LA_ACT_CONSISTENT) should be the last callback received.
|
||||
Since only one link map may be not-CONSISTENT at a time, this also
|
||||
140
glibc-RHEL-49549-9.patch
Normal file
140
glibc-RHEL-49549-9.patch
Normal file
@ -0,0 +1,140 @@
|
||||
commit 495b96e064da605630a23092d1e484ade4bdc093
|
||||
Author: Florian Weimer <fweimer@redhat.com>
|
||||
Date: Tue Sep 3 17:57:46 2024 +0200
|
||||
|
||||
elf: Reorder audit events in dlcose to match _dl_fini (bug 32066)
|
||||
|
||||
This was discovered after extending elf/tst-audit23 to cover
|
||||
dlclose of the dlmopen namespace.
|
||||
|
||||
Auditors already experience the new order during process
|
||||
shutdown (_dl_fini), so no LAV_CURRENT bump or backwards
|
||||
compatibility code seems necessary.
|
||||
|
||||
Reviewed-by: Adhemerval Zanella <adhemerval.zanella@linaro.org>
|
||||
|
||||
diff --git a/elf/dl-close.c b/elf/dl-close.c
|
||||
index 8a4c3528a124d4e7..236d89f67f3bf410 100644
|
||||
--- a/elf/dl-close.c
|
||||
+++ b/elf/dl-close.c
|
||||
@@ -303,6 +303,12 @@ _dl_close_worker (struct link_map *map, bool force)
|
||||
}
|
||||
|
||||
#ifdef SHARED
|
||||
+ /* Auditing checkpoint: we will start deleting objects.
|
||||
+ This is supposed to happen before la_objclose (see _dl_fini),
|
||||
+ but only once per non-recursive dlclose call. */
|
||||
+ if (!unload_any)
|
||||
+ _dl_audit_activity_nsid (nsid, LA_ACT_DELETE);
|
||||
+
|
||||
/* Auditing checkpoint: we remove an object. */
|
||||
_dl_audit_objclose (imap);
|
||||
#endif
|
||||
@@ -463,12 +469,8 @@ _dl_close_worker (struct link_map *map, bool force)
|
||||
if (!unload_any)
|
||||
goto out;
|
||||
|
||||
-#ifdef SHARED
|
||||
- /* Auditing checkpoint: we will start deleting objects. */
|
||||
- _dl_audit_activity_nsid (nsid, LA_ACT_DELETE);
|
||||
-#endif
|
||||
-
|
||||
- /* Notify the debugger we are about to remove some loaded objects. */
|
||||
+ /* Notify the debugger we are about to remove some loaded objects.
|
||||
+ LA_ACT_DELETE has already been signalled above for !unload_any. */
|
||||
struct r_debug *r = _dl_debug_update (nsid);
|
||||
r->r_state = RT_DELETE;
|
||||
_dl_debug_state ();
|
||||
diff --git a/elf/tst-audit23.c b/elf/tst-audit23.c
|
||||
index d5137fd44dacde3c..5e3afd397bb2d3d1 100644
|
||||
--- a/elf/tst-audit23.c
|
||||
+++ b/elf/tst-audit23.c
|
||||
@@ -31,16 +31,21 @@
|
||||
#include <support/xstdio.h>
|
||||
#include <support/xdlfcn.h>
|
||||
#include <support/support.h>
|
||||
+#include <support/test-driver.h>
|
||||
|
||||
static int restart;
|
||||
+static int do_dlclose;
|
||||
#define CMDLINE_OPTIONS \
|
||||
- { "restart", no_argument, &restart, 1 },
|
||||
+ { "restart", no_argument, &restart, 1 }, \
|
||||
+ { "dlclose", no_argument, &do_dlclose, 1 }, \
|
||||
|
||||
static int
|
||||
handle_restart (void)
|
||||
{
|
||||
xdlopen ("tst-audit23mod.so", RTLD_NOW);
|
||||
- xdlmopen (LM_ID_NEWLM, LIBC_SO, RTLD_NOW);
|
||||
+ void *handle = xdlmopen (LM_ID_NEWLM, LIBC_SO, RTLD_NOW);
|
||||
+ if (do_dlclose)
|
||||
+ xdlclose (handle);
|
||||
|
||||
return 0;
|
||||
}
|
||||
@@ -60,8 +65,8 @@ is_vdso (const char *str)
|
||||
|| startswith (str, "linux-vdso");
|
||||
}
|
||||
|
||||
-static int
|
||||
-do_test (int argc, char *argv[])
|
||||
+static void
|
||||
+do_one_test (int argc, char *argv[], bool pass_dlclose_flag)
|
||||
{
|
||||
/* We must have either:
|
||||
- One or four parameters left if called initially:
|
||||
@@ -69,16 +74,15 @@ do_test (int argc, char *argv[])
|
||||
+ "--library-path" optional
|
||||
+ the library path optional
|
||||
+ the application name */
|
||||
- if (restart)
|
||||
- return handle_restart ();
|
||||
-
|
||||
- char *spargv[9];
|
||||
+ char *spargv[10];
|
||||
TEST_VERIFY_EXIT (((argc - 1) + 3) < array_length (spargv));
|
||||
int i = 0;
|
||||
for (; i < argc - 1; i++)
|
||||
spargv[i] = argv[i + 1];
|
||||
spargv[i++] = (char *) "--direct";
|
||||
spargv[i++] = (char *) "--restart";
|
||||
+ if (pass_dlclose_flag)
|
||||
+ spargv[i++] = (char *) "--dlclose";
|
||||
spargv[i] = NULL;
|
||||
|
||||
setenv ("LD_AUDIT", "tst-auditmod23.so", 0);
|
||||
@@ -146,8 +150,14 @@ do_test (int argc, char *argv[])
|
||||
|
||||
/* The cookie identifies the object at the head of the link map,
|
||||
so we only add a new namespace if it changes from the previous
|
||||
- one. This works since dlmopen is the last in the test body. */
|
||||
- if (cookie != last_act_cookie && last_act_cookie != -1)
|
||||
+ one. This works since dlmopen is the last in the test body.
|
||||
+
|
||||
+ Currently, this does not work as expected because there
|
||||
+ is no head link map if a namespace is completely deleted.
|
||||
+ No LA_ACT_CONSISTENT event is generated in that case.
|
||||
+ See the comment in _dl_audit_activity_nsid and bug 32068. */
|
||||
+ if (cookie != last_act_cookie && last_act_cookie != -1
|
||||
+ && !pass_dlclose_flag)
|
||||
TEST_COMPARE (last_act, LA_ACT_CONSISTENT);
|
||||
|
||||
if (this_act == LA_ACT_ADD && acts[nacts] != cookie)
|
||||
@@ -265,7 +275,16 @@ do_test (int argc, char *argv[])
|
||||
|
||||
free (buffer);
|
||||
xfclose (out);
|
||||
+}
|
||||
+
|
||||
+static int
|
||||
+do_test (int argc, char *argv[])
|
||||
+{
|
||||
+ if (restart)
|
||||
+ return handle_restart ();
|
||||
|
||||
+ do_one_test (argc, argv, false);
|
||||
+ do_one_test (argc, argv, true);
|
||||
return 0;
|
||||
}
|
||||
|
||||
14
glibc.spec
14
glibc.spec
@ -157,7 +157,7 @@ end \
|
||||
Summary: The GNU libc libraries
|
||||
Name: glibc
|
||||
Version: %{glibcversion}
|
||||
Release: 213%{?dist}
|
||||
Release: 214%{?dist}
|
||||
|
||||
# In general, GPLv2+ is used by programs, LGPLv2+ is used for
|
||||
# libraries.
|
||||
@ -1291,6 +1291,15 @@ Patch981: glibc-RHEL-47403-9.patch
|
||||
Patch982: glibc-RHEL-47403-10.patch
|
||||
Patch983: glibc-RHEL-47403-11.patch
|
||||
Patch984: glibc-RHEL-95247.patch
|
||||
Patch985: glibc-RHEL-49549-1.patch
|
||||
Patch986: glibc-RHEL-49549-2.patch
|
||||
Patch987: glibc-RHEL-49549-3.patch
|
||||
Patch988: glibc-RHEL-49549-4.patch
|
||||
Patch989: glibc-RHEL-49549-5.patch
|
||||
Patch990: glibc-RHEL-49549-6.patch
|
||||
Patch991: glibc-RHEL-49549-7.patch
|
||||
Patch992: glibc-RHEL-49549-8.patch
|
||||
Patch993: glibc-RHEL-49549-9.patch
|
||||
|
||||
##############################################################################
|
||||
# Continued list of core "glibc" package information:
|
||||
@ -3288,6 +3297,9 @@ update_gconv_modules_cache ()
|
||||
%endif
|
||||
|
||||
%changelog
|
||||
* Wed Jul 09 2025 Arjun Shankar <arjun@redhat.com> - 2.34-214
|
||||
- Signal la_objopen for ld.so with dlmopen (RHEL-49549)
|
||||
|
||||
* Wed Jul 09 2025 Arjun Shankar <arjun@redhat.com> - 2.34-213
|
||||
- Reduce spurious rebuilds while running tests (RHEL-95247)
|
||||
|
||||
|
||||
Loading…
Reference in New Issue
Block a user