forked from rpms/glibc
Improve compatibility between underlinking and IFUNC resolvers (RHEL-16825)
Resolves: RHEL-16825
This commit is contained in:
parent
8bd47ef1b2
commit
b76a8ebe01
35
glibc-RHEL-16825-1.patch
Normal file
35
glibc-RHEL-16825-1.patch
Normal file
@ -0,0 +1,35 @@
|
||||
commit b893410be304ddcea0bd43f537a13e8b18d37cf2
|
||||
Author: Florian Weimer <fweimer@redhat.com>
|
||||
Date: Mon Nov 27 11:28:07 2023 +0100
|
||||
|
||||
elf: In _dl_relocate_object, skip processing if object is relocated
|
||||
|
||||
This is just a minor optimization. It also makes it more obvious that
|
||||
_dl_relocate_object can be called multiple times.
|
||||
|
||||
Reviewed-by: Carlos O'Donell <carlos@redhat.com>
|
||||
|
||||
diff --git a/elf/dl-reloc.c b/elf/dl-reloc.c
|
||||
index 7d8b2bd2336eecb6..66c9266d7f9d65af 100644
|
||||
--- a/elf/dl-reloc.c
|
||||
+++ b/elf/dl-reloc.c
|
||||
@@ -165,6 +165,9 @@ void
|
||||
_dl_relocate_object (struct link_map *l, struct r_scope_elem *scope[],
|
||||
int reloc_mode, int consider_profiling)
|
||||
{
|
||||
+ if (l->l_relocated)
|
||||
+ return;
|
||||
+
|
||||
struct textrels
|
||||
{
|
||||
caddr_t start;
|
||||
@@ -202,9 +205,6 @@ _dl_relocate_object (struct link_map *l, struct r_scope_elem *scope[],
|
||||
# define consider_symbind 0
|
||||
#endif
|
||||
|
||||
- if (l->l_relocated)
|
||||
- return;
|
||||
-
|
||||
/* If DT_BIND_NOW is set relocate all references in this object. We
|
||||
do not do this if we are profiling, of course. */
|
||||
// XXX Correct for auditing?
|
121
glibc-RHEL-16825-2.patch
Normal file
121
glibc-RHEL-16825-2.patch
Normal file
@ -0,0 +1,121 @@
|
||||
commit a74c2e1cbc8673dd7e97aae2f2705392e2ccc3f6
|
||||
Author: Florian Weimer <fweimer@redhat.com>
|
||||
Date: Mon Nov 27 11:28:10 2023 +0100
|
||||
|
||||
elf: Introduce the _dl_open_relocate_one_object function
|
||||
|
||||
It is extracted from dl_open_worker_begin.
|
||||
|
||||
Reviewed-by: Carlos O'Donell <carlos@redhat.com>
|
||||
|
||||
diff --git a/elf/dl-open.c b/elf/dl-open.c
|
||||
index 7dfb6b680c108c0b..160451790bb88447 100644
|
||||
--- a/elf/dl-open.c
|
||||
+++ b/elf/dl-open.c
|
||||
@@ -466,6 +466,50 @@ activate_nodelete (struct link_map *new)
|
||||
}
|
||||
}
|
||||
|
||||
+/* Relocate the object L. *RELOCATION_IN_PROGRESS controls whether
|
||||
+ the debugger is notified of the start of relocation processing. */
|
||||
+static void
|
||||
+_dl_open_relocate_one_object (struct dl_open_args *args, struct r_debug *r,
|
||||
+ struct link_map *l, int reloc_mode,
|
||||
+ bool *relocation_in_progress)
|
||||
+{
|
||||
+ if (l->l_real->l_relocated)
|
||||
+ return;
|
||||
+
|
||||
+ if (!*relocation_in_progress)
|
||||
+ {
|
||||
+ /* Notify the debugger that relocations are about to happen. */
|
||||
+ LIBC_PROBE (reloc_start, 2, args->nsid, r);
|
||||
+ *relocation_in_progress = true;
|
||||
+ }
|
||||
+
|
||||
+#ifdef SHARED
|
||||
+ if (__glibc_unlikely (GLRO(dl_profile) != NULL))
|
||||
+ {
|
||||
+ /* If this here is the shared object which we want to profile
|
||||
+ make sure the profile is started. We can find out whether
|
||||
+ this is necessary or not by observing the `_dl_profile_map'
|
||||
+ variable. If it was NULL but is not NULL afterwards we must
|
||||
+ start the profiling. */
|
||||
+ struct link_map *old_profile_map = GL(dl_profile_map);
|
||||
+
|
||||
+ _dl_relocate_object (l, l->l_scope, reloc_mode | RTLD_LAZY, 1);
|
||||
+
|
||||
+ if (old_profile_map == NULL && GL(dl_profile_map) != NULL)
|
||||
+ {
|
||||
+ /* We must prepare the profiling. */
|
||||
+ _dl_start_profile ();
|
||||
+
|
||||
+ /* Prevent unloading the object. */
|
||||
+ GL(dl_profile_map)->l_nodelete_active = true;
|
||||
+ }
|
||||
+ }
|
||||
+ else
|
||||
+#endif
|
||||
+ _dl_relocate_object (l, l->l_scope, reloc_mode, 0);
|
||||
+}
|
||||
+
|
||||
+
|
||||
/* struct dl_init_args and call_dl_init are used to call _dl_init with
|
||||
exception handling disabled. */
|
||||
struct dl_init_args
|
||||
@@ -638,7 +682,7 @@ dl_open_worker_begin (void *a)
|
||||
}
|
||||
while (l != NULL);
|
||||
|
||||
- int relocation_in_progress = 0;
|
||||
+ bool relocation_in_progress = false;
|
||||
|
||||
/* Perform relocation. This can trigger lazy binding in IFUNC
|
||||
resolvers. For NODELETE mappings, these dependencies are not
|
||||
@@ -649,44 +693,8 @@ dl_open_worker_begin (void *a)
|
||||
are undefined anyway, so this is not a problem. */
|
||||
|
||||
for (unsigned int i = last; i-- > first; )
|
||||
- {
|
||||
- l = new->l_initfini[i];
|
||||
-
|
||||
- if (l->l_real->l_relocated)
|
||||
- continue;
|
||||
-
|
||||
- if (! relocation_in_progress)
|
||||
- {
|
||||
- /* Notify the debugger that relocations are about to happen. */
|
||||
- LIBC_PROBE (reloc_start, 2, args->nsid, r);
|
||||
- relocation_in_progress = 1;
|
||||
- }
|
||||
-
|
||||
-#ifdef SHARED
|
||||
- if (__glibc_unlikely (GLRO(dl_profile) != NULL))
|
||||
- {
|
||||
- /* If this here is the shared object which we want to profile
|
||||
- make sure the profile is started. We can find out whether
|
||||
- this is necessary or not by observing the `_dl_profile_map'
|
||||
- variable. If it was NULL but is not NULL afterwards we must
|
||||
- start the profiling. */
|
||||
- struct link_map *old_profile_map = GL(dl_profile_map);
|
||||
-
|
||||
- _dl_relocate_object (l, l->l_scope, reloc_mode | RTLD_LAZY, 1);
|
||||
-
|
||||
- if (old_profile_map == NULL && GL(dl_profile_map) != NULL)
|
||||
- {
|
||||
- /* We must prepare the profiling. */
|
||||
- _dl_start_profile ();
|
||||
-
|
||||
- /* Prevent unloading the object. */
|
||||
- GL(dl_profile_map)->l_nodelete_active = true;
|
||||
- }
|
||||
- }
|
||||
- else
|
||||
-#endif
|
||||
- _dl_relocate_object (l, l->l_scope, reloc_mode, 0);
|
||||
- }
|
||||
+ _dl_open_relocate_one_object (args, r, new->l_initfini[i], reloc_mode,
|
||||
+ &relocation_in_progress);
|
||||
|
||||
/* This only performs the memory allocations. The actual update of
|
||||
the scopes happens below, after failure is impossible. */
|
223
glibc-RHEL-16825-3.patch
Normal file
223
glibc-RHEL-16825-3.patch
Normal file
@ -0,0 +1,223 @@
|
||||
commit 78ca44da0160a0b442f0ca1f253e3360f044b2ec
|
||||
Author: Florian Weimer <fweimer@redhat.com>
|
||||
Date: Mon Nov 27 11:28:13 2023 +0100
|
||||
|
||||
elf: Relocate libc.so early during startup and dlmopen (bug 31083)
|
||||
|
||||
This makes it more likely that objects without dependencies can
|
||||
use IFUNC resolvers in libc.so.
|
||||
|
||||
Reviewed-by: Carlos O'Donell <carlos@redhat.com>
|
||||
|
||||
Conflicts:
|
||||
elf/Makefile
|
||||
(differences in test backports)
|
||||
elf/rtld.c
|
||||
(removal of prelink support upstream)
|
||||
|
||||
|
||||
diff --git a/elf/Makefile b/elf/Makefile
|
||||
index 42dc878209b11d29..ebf46a297d241d8f 100644
|
||||
--- a/elf/Makefile
|
||||
+++ b/elf/Makefile
|
||||
@@ -387,6 +387,8 @@ tests += \
|
||||
tst-nodelete2 \
|
||||
tst-nodelete-dlclose \
|
||||
tst-nodelete-opened \
|
||||
+ tst-nodeps1 \
|
||||
+ tst-nodeps2 \
|
||||
tst-noload \
|
||||
tst-null-argv \
|
||||
tst-relsort1 \
|
||||
@@ -743,6 +745,8 @@ modules-names = \
|
||||
tst-nodelete-dlclose-dso \
|
||||
tst-nodelete-dlclose-plugin \
|
||||
tst-nodelete-opened-lib \
|
||||
+ tst-nodeps1-mod \
|
||||
+ tst-nodeps2-mod \
|
||||
tst-null-argv-lib \
|
||||
tst-relsort1mod1 \
|
||||
tst-relsort1mod2 \
|
||||
@@ -889,8 +893,13 @@ modules-execstack-yes = tst-execstack-mod
|
||||
extra-test-objs += $(addsuffix .os,$(strip $(modules-names)))
|
||||
|
||||
# filtmod1.so has a special rule
|
||||
-modules-names-nobuild := filtmod1 \
|
||||
- tst-audit24bmod1 tst-audit24bmod2
|
||||
+modules-names-nobuild += \
|
||||
+ filtmod1 \
|
||||
+ tst-audit24bmod1 \
|
||||
+ tst-audit24bmod2 \
|
||||
+ tst-nodeps1-mod \
|
||||
+ tst-nodeps2-mod \
|
||||
+ # modules-names-nobuild
|
||||
|
||||
tests += $(tests-static)
|
||||
|
||||
@@ -2707,3 +2716,18 @@ $(objpfx)tst-dlclose-lazy: $(libdl)
|
||||
$(objpfx)tst-dlclose-lazy.out: \
|
||||
$(objpfx)tst-dlclose-lazy-mod1.so $(objpfx)tst-dlclose-lazy-mod2.so
|
||||
|
||||
+# The object tst-nodeps1-mod.so has no explicit dependencies on libc.so.
|
||||
+$(objpfx)tst-nodeps1-mod.so: $(objpfx)tst-nodeps1-mod.os
|
||||
+ $(LINK.o) -nostartfiles -nostdlib -shared -o $@ $^
|
||||
+tst-nodeps1.so-no-z-defs = yes
|
||||
+# Link libc.so before the test module with the IFUNC resolver reference.
|
||||
+LDFLAGS-tst-nodeps1 = $(common-objpfx)libc.so $(objpfx)tst-nodeps1-mod.so
|
||||
+$(objpfx)tst-nodeps1: $(objpfx)tst-nodeps1-mod.so
|
||||
+# Reuse the tst-nodeps1 module. Link libc.so before the test module
|
||||
+# with the IFUNC resolver reference.
|
||||
+$(objpfx)tst-nodeps2-mod.so: $(common-objpfx)libc.so \
|
||||
+ $(objpfx)tst-nodeps1-mod.so $(objpfx)tst-nodeps2-mod.os
|
||||
+ $(LINK.o) -Wl,--no-as-needed -nostartfiles -nostdlib -shared -o $@ $^
|
||||
+$(objpfx)tst-nodeps2: $(libdl)
|
||||
+$(objpfx)tst-nodeps2.out: \
|
||||
+ $(objpfx)tst-nodeps1-mod.so $(objpfx)tst-nodeps2-mod.so
|
||||
diff --git a/elf/dl-open.c b/elf/dl-open.c
|
||||
index 160451790bb88447..f32e2fd4ee39db93 100644
|
||||
--- a/elf/dl-open.c
|
||||
+++ b/elf/dl-open.c
|
||||
@@ -692,6 +692,17 @@ dl_open_worker_begin (void *a)
|
||||
them. However, such relocation dependencies in IFUNC resolvers
|
||||
are undefined anyway, so this is not a problem. */
|
||||
|
||||
+ /* Ensure that libc is relocated first. This helps with the
|
||||
+ execution of IFUNC resolvers in libc, and matters only to newly
|
||||
+ created dlmopen namespaces. Do not do this for static dlopen
|
||||
+ because libc has relocations against ld.so, which may not have
|
||||
+ been relocated at this point. */
|
||||
+#ifdef SHARED
|
||||
+ if (GL(dl_ns)[args->nsid].libc_map != NULL)
|
||||
+ _dl_open_relocate_one_object (args, r, GL(dl_ns)[args->nsid].libc_map,
|
||||
+ reloc_mode, &relocation_in_progress);
|
||||
+#endif
|
||||
+
|
||||
for (unsigned int i = last; i-- > first; )
|
||||
_dl_open_relocate_one_object (args, r, new->l_initfini[i], reloc_mode,
|
||||
&relocation_in_progress);
|
||||
diff --git a/elf/rtld.c b/elf/rtld.c
|
||||
index cd2cc4024a3581c2..502d2a1c58505d88 100644
|
||||
--- a/elf/rtld.c
|
||||
+++ b/elf/rtld.c
|
||||
@@ -2414,11 +2414,17 @@ ERROR: '%s': cannot process note segment.\n", _dl_argv[0]);
|
||||
objects. We do not re-relocate the dynamic linker itself in this
|
||||
loop because that could result in the GOT entries for functions we
|
||||
call being changed, and that would break us. It is safe to relocate
|
||||
- the dynamic linker out of order because it has no copy relocs (we
|
||||
- know that because it is self-contained). */
|
||||
+ the dynamic linker out of order because it has no copy relocations.
|
||||
+ Likewise for libc, which is relocated early to ensure that IFUNC
|
||||
+ resolvers in libc work. */
|
||||
|
||||
int consider_profiling = GLRO(dl_profile) != NULL;
|
||||
|
||||
+ if (GL(dl_ns)[LM_ID_BASE].libc_map != NULL)
|
||||
+ _dl_relocate_object (GL(dl_ns)[LM_ID_BASE].libc_map,
|
||||
+ GL(dl_ns)[LM_ID_BASE].libc_map->l_scope,
|
||||
+ GLRO(dl_lazy) ? RTLD_LAZY : 0, consider_profiling);
|
||||
+
|
||||
/* If we are profiling we also must do lazy reloaction. */
|
||||
GLRO(dl_lazy) |= consider_profiling;
|
||||
|
||||
diff --git a/elf/tst-nodeps1-mod.c b/elf/tst-nodeps1-mod.c
|
||||
new file mode 100644
|
||||
index 0000000000000000..45c8e3c631251a89
|
||||
--- /dev/null
|
||||
+++ b/elf/tst-nodeps1-mod.c
|
||||
@@ -0,0 +1,25 @@
|
||||
+/* Test module with no libc.so dependency and string function references.
|
||||
+ 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 <string.h>
|
||||
+
|
||||
+/* Some references to libc symbols which are likely to have IFUNC
|
||||
+ resolvers. If they do not, this module does not exercise bug 31083. */
|
||||
+void *memcpy_pointer = memcpy;
|
||||
+void *memmove_pointer = memmove;
|
||||
+void *memset_pointer = memset;
|
||||
diff --git a/elf/tst-nodeps1.c b/elf/tst-nodeps1.c
|
||||
new file mode 100644
|
||||
index 0000000000000000..1a8bde36cdb71446
|
||||
--- /dev/null
|
||||
+++ b/elf/tst-nodeps1.c
|
||||
@@ -0,0 +1,23 @@
|
||||
+/* Test initially loaded module with implicit libc.so dependency (bug 31083).
|
||||
+ 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/>. */
|
||||
+
|
||||
+/* Testing happens before main. */
|
||||
+int
|
||||
+main (void)
|
||||
+{
|
||||
+}
|
||||
diff --git a/elf/tst-nodeps2-mod.c b/elf/tst-nodeps2-mod.c
|
||||
new file mode 100644
|
||||
index 0000000000000000..4913feee9b56e0e1
|
||||
--- /dev/null
|
||||
+++ b/elf/tst-nodeps2-mod.c
|
||||
@@ -0,0 +1 @@
|
||||
+/* Empty test module which depends on tst-nodeps1-mod.so. */
|
||||
diff --git a/elf/tst-nodeps2.c b/elf/tst-nodeps2.c
|
||||
new file mode 100644
|
||||
index 0000000000000000..0bdc8eeb8cba3a99
|
||||
--- /dev/null
|
||||
+++ b/elf/tst-nodeps2.c
|
||||
@@ -0,0 +1,29 @@
|
||||
+/* Test dlmopen with implicit libc.so dependency (bug 31083).
|
||||
+ 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 <support/xdlfcn.h>
|
||||
+
|
||||
+static int
|
||||
+do_test (void)
|
||||
+{
|
||||
+ void *handle = xdlmopen (LM_ID_NEWLM, "tst-nodeps2-mod.so", RTLD_NOW);
|
||||
+ xdlclose (handle);
|
||||
+ return 0;
|
||||
+}
|
||||
+
|
||||
+#include <support/test-driver.c>
|
41
glibc-RHEL-16825-4.patch
Normal file
41
glibc-RHEL-16825-4.patch
Normal file
@ -0,0 +1,41 @@
|
||||
commit b3bee76c5f59498b9c189608f0a3132e2013fa1a
|
||||
Author: Florian Weimer <fweimer@redhat.com>
|
||||
Date: Fri Dec 8 09:51:34 2023 +0100
|
||||
|
||||
elf: Initialize GLRO(dl_lazy) before relocating libc in dynamic startup
|
||||
|
||||
GLRO(dl_lazy) is used to set the parameters for the early
|
||||
_dl_relocate_object call, so the consider_profiling setting has to
|
||||
be applied before the call.
|
||||
|
||||
Fixes commit 78ca44da0160a0b442f0ca1f253e3360f044b2ec ("elf: Relocate
|
||||
libc.so early during startup and dlmopen (bug 31083)").
|
||||
|
||||
Reviewed-by: Carlos O'Donell <carlos@redhat.com>
|
||||
|
||||
Conflicts:
|
||||
elf/rtld.c
|
||||
(removal of prelink support upstream)
|
||||
|
||||
diff --git a/elf/rtld.c b/elf/rtld.c
|
||||
index 502d2a1c58505d88..4f317a2a874e6af7 100644
|
||||
--- a/elf/rtld.c
|
||||
+++ b/elf/rtld.c
|
||||
@@ -2420,14 +2420,14 @@ ERROR: '%s': cannot process note segment.\n", _dl_argv[0]);
|
||||
|
||||
int consider_profiling = GLRO(dl_profile) != NULL;
|
||||
|
||||
+ /* If we are profiling we also must do lazy reloaction. */
|
||||
+ GLRO(dl_lazy) |= consider_profiling;
|
||||
+
|
||||
if (GL(dl_ns)[LM_ID_BASE].libc_map != NULL)
|
||||
_dl_relocate_object (GL(dl_ns)[LM_ID_BASE].libc_map,
|
||||
GL(dl_ns)[LM_ID_BASE].libc_map->l_scope,
|
||||
GLRO(dl_lazy) ? RTLD_LAZY : 0, consider_profiling);
|
||||
|
||||
- /* If we are profiling we also must do lazy reloaction. */
|
||||
- GLRO(dl_lazy) |= consider_profiling;
|
||||
-
|
||||
RTLD_TIMING_VAR (start);
|
||||
rtld_timer_start (&start);
|
||||
unsigned i = main_map->l_searchlist.r_nlist;
|
@ -1,6 +1,6 @@
|
||||
%define glibcsrcdir glibc-2.28
|
||||
%define glibcversion 2.28
|
||||
%define glibcrelease 244%{?dist}
|
||||
%define glibcrelease 245%{?dist}
|
||||
# Pre-release tarballs are pulled in from git using a command that is
|
||||
# effectively:
|
||||
#
|
||||
@ -1061,6 +1061,10 @@ Patch873: glibc-RHEL-10481.patch
|
||||
Patch874: glibc-RHEL-13720-1.patch
|
||||
Patch875: glibc-RHEL-13720-2.patch
|
||||
Patch876: glibc-RHEL-15867.patch
|
||||
Patch877: glibc-RHEL-16825-1.patch
|
||||
Patch878: glibc-RHEL-16825-2.patch
|
||||
Patch879: glibc-RHEL-16825-3.patch
|
||||
Patch880: glibc-RHEL-16825-4.patch
|
||||
|
||||
##############################################################################
|
||||
# Continued list of core "glibc" package information:
|
||||
@ -2892,6 +2896,9 @@ fi
|
||||
%files -f compat-libpthread-nonshared.filelist -n compat-libpthread-nonshared
|
||||
|
||||
%changelog
|
||||
* Fri Dec 8 2023 Florian Weimer <fweimer@redhat.com> - 2.28-245
|
||||
- Improve compatibility between underlinking and IFUNC resolvers (RHEL-16825)
|
||||
|
||||
* Fri Nov 24 2023 Florian Weimer <fweimer@redhat.com> - 2.28-244
|
||||
- Restore <sys/cdefs.h> compatibility with C90 compilers (RHEL-15867)
|
||||
|
||||
|
Loading…
Reference in New Issue
Block a user