mirror of
https://sourceware.org/git/glibc.git
synced 2024-11-23 21:40:12 +00:00
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>
This commit is contained in:
parent
a74c2e1cbc
commit
78ca44da01
21
elf/Makefile
21
elf/Makefile
@ -433,6 +433,8 @@ tests += \
|
|||||||
tst-nodelete-dlclose \
|
tst-nodelete-dlclose \
|
||||||
tst-nodelete-opened \
|
tst-nodelete-opened \
|
||||||
tst-nodelete2 \
|
tst-nodelete2 \
|
||||||
|
tst-nodeps1 \
|
||||||
|
tst-nodeps2 \
|
||||||
tst-noload \
|
tst-noload \
|
||||||
tst-non-directory-path \
|
tst-non-directory-path \
|
||||||
tst-null-argv \
|
tst-null-argv \
|
||||||
@ -863,6 +865,8 @@ modules-names += \
|
|||||||
tst-nodelete-dlclose-plugin \
|
tst-nodelete-dlclose-plugin \
|
||||||
tst-nodelete-opened-lib \
|
tst-nodelete-opened-lib \
|
||||||
tst-nodelete2mod \
|
tst-nodelete2mod \
|
||||||
|
tst-nodeps1-mod \
|
||||||
|
tst-nodeps2-mod \
|
||||||
tst-non-directory-mod \
|
tst-non-directory-mod \
|
||||||
tst-null-argv-lib \
|
tst-null-argv-lib \
|
||||||
tst-p_alignmod-base \
|
tst-p_alignmod-base \
|
||||||
@ -1030,6 +1034,8 @@ modules-names-nobuild += \
|
|||||||
tst-audit24bmod1 \
|
tst-audit24bmod1 \
|
||||||
tst-audit24bmod2 \
|
tst-audit24bmod2 \
|
||||||
tst-big-note-lib \
|
tst-big-note-lib \
|
||||||
|
tst-nodeps1-mod \
|
||||||
|
tst-nodeps2-mod \
|
||||||
tst-ro-dynamic-mod \
|
tst-ro-dynamic-mod \
|
||||||
# modules-names-nobuild
|
# modules-names-nobuild
|
||||||
|
|
||||||
@ -3009,3 +3015,18 @@ tst-env-setuid-ARGS = -- $(host-test-program-cmd)
|
|||||||
|
|
||||||
# Reuse a module with a SONAME, to specific as the LD_PROFILE.
|
# Reuse a module with a SONAME, to specific as the LD_PROFILE.
|
||||||
$(objpfx)tst-env-setuid: $(objpfx)tst-sonamemove-runmod2.so
|
$(objpfx)tst-env-setuid: $(objpfx)tst-sonamemove-runmod2.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.out: \
|
||||||
|
$(objpfx)tst-nodeps1-mod.so $(objpfx)tst-nodeps2-mod.so
|
||||||
|
@ -708,6 +708,17 @@ dl_open_worker_begin (void *a)
|
|||||||
them. However, such relocation dependencies in IFUNC resolvers
|
them. However, such relocation dependencies in IFUNC resolvers
|
||||||
are undefined anyway, so this is not a problem. */
|
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; )
|
for (unsigned int i = last; i-- > first; )
|
||||||
_dl_open_relocate_one_object (args, r, new->l_initfini[i], reloc_mode,
|
_dl_open_relocate_one_object (args, r, new->l_initfini[i], reloc_mode,
|
||||||
&relocation_in_progress);
|
&relocation_in_progress);
|
||||||
|
10
elf/rtld.c
10
elf/rtld.c
@ -2272,11 +2272,17 @@ dl_main (const ElfW(Phdr) *phdr,
|
|||||||
objects. We do not re-relocate the dynamic linker itself in this
|
objects. We do not re-relocate the dynamic linker itself in this
|
||||||
loop because that could result in the GOT entries for functions we
|
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
|
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
|
the dynamic linker out of order because it has no copy relocations.
|
||||||
know that because it is self-contained). */
|
Likewise for libc, which is relocated early to ensure that IFUNC
|
||||||
|
resolvers in libc work. */
|
||||||
|
|
||||||
int consider_profiling = GLRO(dl_profile) != NULL;
|
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. */
|
/* If we are profiling we also must do lazy reloaction. */
|
||||||
GLRO(dl_lazy) |= consider_profiling;
|
GLRO(dl_lazy) |= consider_profiling;
|
||||||
|
|
||||||
|
25
elf/tst-nodeps1-mod.c
Normal file
25
elf/tst-nodeps1-mod.c
Normal file
@ -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;
|
23
elf/tst-nodeps1.c
Normal file
23
elf/tst-nodeps1.c
Normal file
@ -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)
|
||||||
|
{
|
||||||
|
}
|
1
elf/tst-nodeps2-mod.c
Normal file
1
elf/tst-nodeps2-mod.c
Normal file
@ -0,0 +1 @@
|
|||||||
|
/* Empty test module which depends on tst-nodeps1-mod.so. */
|
29
elf/tst-nodeps2.c
Normal file
29
elf/tst-nodeps2.c
Normal file
@ -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>
|
Loading…
Reference in New Issue
Block a user