mirror of
https://sourceware.org/git/glibc.git
synced 2024-11-08 14:20:07 +00:00
elf: Always set l in _dl_init_paths (bug 23462)
After d1d5471579
("Remove dead
DL_DST_REQ_STATIC code.") we always setup the link map l to make the
static and shared cases the same. The bug is that in elf/dl-load.c
(_dl_init_paths) we conditionally set l only in the #ifdef SHARED
case, but unconditionally use it later. The simple solution is to
remove the #ifdef SHARED conditional, because it's no longer needed,
and unconditionally setup l for both the static and shared cases. A
regression test is added to run a static binary with
LD_LIBRARY_PATH='$ORIGIN' which crashes before the fix and runs after
the fix.
Co-Authored-By: Florian Weimer <fweimer@redhat.com>
This commit is contained in:
parent
08a0ebb20e
commit
3324213125
@ -164,7 +164,8 @@ tests-static-normal := tst-leaks1-static tst-array1-static tst-array5-static \
|
||||
tst-dl-iter-static \
|
||||
tst-tlsalign-static tst-tlsalign-extern-static \
|
||||
tst-linkall-static tst-env-setuid tst-env-setuid-tunables \
|
||||
tst-single_threaded-static tst-single_threaded-pthread-static
|
||||
tst-single_threaded-static tst-single_threaded-pthread-static \
|
||||
tst-dst-static
|
||||
|
||||
tests-static-internal := tst-tls1-static tst-tls2-static \
|
||||
tst-ptrguard1-static tst-stackguard1-static \
|
||||
@ -1904,3 +1905,5 @@ $(objpfx)list-tunables.out: tst-rtld-list-tunables.sh $(objpfx)ld.so
|
||||
cmp tst-rtld-list-tunables.exp \
|
||||
$(objpfx)/tst-rtld-list-tunables.out > $@; \
|
||||
$(evaluate-test)
|
||||
|
||||
tst-dst-static-ENV = LD_LIBRARY_PATH='$$ORIGIN'
|
||||
|
@ -758,50 +758,45 @@ _dl_init_paths (const char *llp, const char *source,
|
||||
max_dirnamelen = SYSTEM_DIRS_MAX_LEN;
|
||||
*aelem = NULL;
|
||||
|
||||
#ifdef SHARED
|
||||
/* This points to the map of the main object. */
|
||||
l = GL(dl_ns)[LM_ID_BASE]._ns_loaded;
|
||||
if (l != NULL)
|
||||
{
|
||||
assert (l->l_type != lt_loaded);
|
||||
assert (l->l_type != lt_loaded);
|
||||
|
||||
if (l->l_info[DT_RUNPATH])
|
||||
if (l->l_info[DT_RUNPATH])
|
||||
{
|
||||
/* Allocate room for the search path and fill in information
|
||||
from RUNPATH. */
|
||||
decompose_rpath (&l->l_runpath_dirs,
|
||||
(const void *) (D_PTR (l, l_info[DT_STRTAB])
|
||||
+ l->l_info[DT_RUNPATH]->d_un.d_val),
|
||||
l, "RUNPATH");
|
||||
/* During rtld init the memory is allocated by the stub malloc,
|
||||
prevent any attempt to free it by the normal malloc. */
|
||||
l->l_runpath_dirs.malloced = 0;
|
||||
|
||||
/* The RPATH is ignored. */
|
||||
l->l_rpath_dirs.dirs = (void *) -1;
|
||||
}
|
||||
else
|
||||
{
|
||||
l->l_runpath_dirs.dirs = (void *) -1;
|
||||
|
||||
if (l->l_info[DT_RPATH])
|
||||
{
|
||||
/* Allocate room for the search path and fill in information
|
||||
from RUNPATH. */
|
||||
decompose_rpath (&l->l_runpath_dirs,
|
||||
from RPATH. */
|
||||
decompose_rpath (&l->l_rpath_dirs,
|
||||
(const void *) (D_PTR (l, l_info[DT_STRTAB])
|
||||
+ l->l_info[DT_RUNPATH]->d_un.d_val),
|
||||
l, "RUNPATH");
|
||||
/* During rtld init the memory is allocated by the stub malloc,
|
||||
prevent any attempt to free it by the normal malloc. */
|
||||
l->l_runpath_dirs.malloced = 0;
|
||||
|
||||
/* The RPATH is ignored. */
|
||||
l->l_rpath_dirs.dirs = (void *) -1;
|
||||
+ l->l_info[DT_RPATH]->d_un.d_val),
|
||||
l, "RPATH");
|
||||
/* During rtld init the memory is allocated by the stub
|
||||
malloc, prevent any attempt to free it by the normal
|
||||
malloc. */
|
||||
l->l_rpath_dirs.malloced = 0;
|
||||
}
|
||||
else
|
||||
{
|
||||
l->l_runpath_dirs.dirs = (void *) -1;
|
||||
|
||||
if (l->l_info[DT_RPATH])
|
||||
{
|
||||
/* Allocate room for the search path and fill in information
|
||||
from RPATH. */
|
||||
decompose_rpath (&l->l_rpath_dirs,
|
||||
(const void *) (D_PTR (l, l_info[DT_STRTAB])
|
||||
+ l->l_info[DT_RPATH]->d_un.d_val),
|
||||
l, "RPATH");
|
||||
/* During rtld init the memory is allocated by the stub
|
||||
malloc, prevent any attempt to free it by the normal
|
||||
malloc. */
|
||||
l->l_rpath_dirs.malloced = 0;
|
||||
}
|
||||
else
|
||||
l->l_rpath_dirs.dirs = (void *) -1;
|
||||
}
|
||||
l->l_rpath_dirs.dirs = (void *) -1;
|
||||
}
|
||||
#endif /* SHARED */
|
||||
|
||||
if (llp != NULL && *llp != '\0')
|
||||
{
|
||||
|
32
elf/tst-dst-static.c
Normal file
32
elf/tst-dst-static.c
Normal file
@ -0,0 +1,32 @@
|
||||
/* Test DST expansion for static binaries doesn't carsh. Bug 23462.
|
||||
Copyright (C) 2021 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/>. */
|
||||
|
||||
/* The purpose of this test is to exercise the code in elf/dl-loac.c
|
||||
(_dl_init_paths) or thereabout and ensure that static binaries
|
||||
don't crash when expanding DSTs.
|
||||
|
||||
If the dynamic loader code linked into the static binary cannot
|
||||
handle expanding the DSTs e.g. null-deref on an incomplete link
|
||||
map, then it will crash before reaching main, so the test harness
|
||||
is unnecessary. */
|
||||
|
||||
int
|
||||
main (void)
|
||||
{
|
||||
return 0;
|
||||
}
|
Loading…
Reference in New Issue
Block a user