mirror of
https://sourceware.org/git/glibc.git
synced 2024-11-24 02:03:35 +08:00
9d7a3741c9
Static PIE extends address space layout randomization to static executables. It provides additional security hardening benefits at the cost of some memory and performance. Dynamic linker, ld.so, is a standalone program which can be loaded at any address. This patch adds a configure option, --enable-static-pie, to embed the part of ld.so in static executable to create static position independent executable (static PIE). A static PIE is similar to static executable, but can be loaded at any address without help from a dynamic linker. When --enable-static-pie is used to configure glibc, libc.a is built as PIE and all static executables, including tests, are built as static PIE. The resulting libc.a can be used together with GCC 8 or above to build static PIE with the compiler option, -static-pie. But GCC 8 isn't required to build glibc with --enable-static-pie. Only GCC with PIE support is needed. When an older GCC is used to build glibc with --enable-static-pie, proper input files are passed to linker to create static executables as static PIE, together with "-z text" to prevent dynamic relocations in read-only segments, which are not allowed in static PIE. The following changes are made for static PIE: 1. Add a new function, _dl_relocate_static_pie, to: a. Get the run-time load address. b. Read the dynamic section. c. Perform dynamic relocations. Dynamic linker also performs these steps. But static PIE doesn't load any shared objects. 2. Call _dl_relocate_static_pie at entrance of LIBC_START_MAIN in libc.a. crt1.o, which is used to create dynamic and non-PIE static executables, is updated to include a dummy _dl_relocate_static_pie. rcrt1.o is added to create static PIE, which will link in the real _dl_relocate_static_pie. grcrt1.o is also added to create static PIE with -pg. GCC 8 has been updated to support rcrt1.o and grcrt1.o for static PIE. Static PIE can work on all architectures which support PIE, provided: 1. Target must support accessing of local functions without dynamic relocations, which is needed in start.S to call __libc_start_main with function addresses of __libc_csu_init, __libc_csu_fini and main. All functions in static PIE are local functions. If PIE start.S can't reach main () defined in a shared object, the code sequence: pass address of local_main to __libc_start_main ... local_main: tail call to main via PLT can be used. 2. start.S is updated to check PIC instead SHARED for PIC code path and avoid dynamic relocation, when PIC is defined and SHARED isn't defined, to support static PIE. 3. All assembly codes are updated check PIC instead SHARED for PIC code path to avoid dynamic relocations in read-only sections. 4. All assembly codes are updated check SHARED instead PIC for static symbol name. 5. elf_machine_load_address in dl-machine.h are updated to support static PIE. 6. __brk works without TLS nor dynamic relocations in read-only section so that it can be used by __libc_setup_tls to initializes TLS in static PIE. NB: When glibc is built with GCC defaulted to PIE, libc.a is compiled with -fPIE, regardless if --enable-static-pie is used to configure glibc. When glibc is configured with --enable-static-pie, libc.a is compiled with -fPIE, regardless whether GCC defaults to PIE or not. The same libc.a can be used to build both static executable and static PIE. There is no need for separate PIE copy of libc.a. On x86-64, the normal static sln: text data bss dec hex filename 625425 8284 5456 639165 9c0bd elf/sln the static PIE sln: text data bss dec hex filename 657626 20636 5392 683654 a6e86 elf/sln The code size is increased by 5% and the binary size is increased by 7%. Linker requirements to build glibc with --enable-static-pie: 1. Linker supports --no-dynamic-linker to remove PT_INTERP segment from static PIE. 2. Linker can create working static PIE. The x86-64 linker needs the fix for https://sourceware.org/bugzilla/show_bug.cgi?id=21782 The i386 linker needs to be able to convert "movl main@GOT(%ebx), %eax" to "leal main@GOTOFF(%ebx), %eax" if main is defined locally. Binutils 2.29 or above are OK for i686 and x86-64. But linker status for other targets need to be verified. 3. Linker should resolve undefined weak symbols to 0 in static PIE: https://sourceware.org/bugzilla/show_bug.cgi?id=22269 4. Many ELF backend linkers incorrectly check bfd_link_pic for TLS relocations, which should check bfd_link_executable instead: https://sourceware.org/bugzilla/show_bug.cgi?id=22263 Tested on aarch64, i686 and x86-64. Using GCC 7 and binutils master branch, build-many-glibcs.py with --enable-static-pie with all patches for static PIE applied have the following build successes: PASS: glibcs-aarch64_be-linux-gnu build PASS: glibcs-aarch64-linux-gnu build PASS: glibcs-armeb-linux-gnueabi-be8 build PASS: glibcs-armeb-linux-gnueabi build PASS: glibcs-armeb-linux-gnueabihf-be8 build PASS: glibcs-armeb-linux-gnueabihf build PASS: glibcs-arm-linux-gnueabi build PASS: glibcs-arm-linux-gnueabihf build PASS: glibcs-arm-linux-gnueabihf-v7a build PASS: glibcs-arm-linux-gnueabihf-v7a-disable-multi-arch build PASS: glibcs-m68k-linux-gnu build PASS: glibcs-microblazeel-linux-gnu build PASS: glibcs-microblaze-linux-gnu build PASS: glibcs-mips64el-linux-gnu-n32 build PASS: glibcs-mips64el-linux-gnu-n32-nan2008 build PASS: glibcs-mips64el-linux-gnu-n32-nan2008-soft build PASS: glibcs-mips64el-linux-gnu-n32-soft build PASS: glibcs-mips64el-linux-gnu-n64 build PASS: glibcs-mips64el-linux-gnu-n64-nan2008 build PASS: glibcs-mips64el-linux-gnu-n64-nan2008-soft build PASS: glibcs-mips64el-linux-gnu-n64-soft build PASS: glibcs-mips64-linux-gnu-n32 build PASS: glibcs-mips64-linux-gnu-n32-nan2008 build PASS: glibcs-mips64-linux-gnu-n32-nan2008-soft build PASS: glibcs-mips64-linux-gnu-n32-soft build PASS: glibcs-mips64-linux-gnu-n64 build PASS: glibcs-mips64-linux-gnu-n64-nan2008 build PASS: glibcs-mips64-linux-gnu-n64-nan2008-soft build PASS: glibcs-mips64-linux-gnu-n64-soft build PASS: glibcs-mipsel-linux-gnu build PASS: glibcs-mipsel-linux-gnu-nan2008 build PASS: glibcs-mipsel-linux-gnu-nan2008-soft build PASS: glibcs-mipsel-linux-gnu-soft build PASS: glibcs-mips-linux-gnu build PASS: glibcs-mips-linux-gnu-nan2008 build PASS: glibcs-mips-linux-gnu-nan2008-soft build PASS: glibcs-mips-linux-gnu-soft build PASS: glibcs-nios2-linux-gnu build PASS: glibcs-powerpc64le-linux-gnu build PASS: glibcs-powerpc64-linux-gnu build PASS: glibcs-tilegxbe-linux-gnu-32 build PASS: glibcs-tilegxbe-linux-gnu build PASS: glibcs-tilegx-linux-gnu-32 build PASS: glibcs-tilegx-linux-gnu build PASS: glibcs-tilepro-linux-gnu build and the following build failures: FAIL: glibcs-alpha-linux-gnu build elf/sln is failed to link due to: assertion fail bfd/elf64-alpha.c:4125 This is caused by linker bug and/or non-PIC code in PIE libc.a. FAIL: glibcs-hppa-linux-gnu build elf/sln is failed to link due to: collect2: fatal error: ld terminated with signal 11 [Segmentation fault] https://sourceware.org/bugzilla/show_bug.cgi?id=22537 FAIL: glibcs-ia64-linux-gnu build elf/sln is failed to link due to: collect2: fatal error: ld terminated with signal 11 [Segmentation fault] FAIL: glibcs-powerpc-linux-gnu build FAIL: glibcs-powerpc-linux-gnu-soft build FAIL: glibcs-powerpc-linux-gnuspe build FAIL: glibcs-powerpc-linux-gnuspe-e500v1 build elf/sln is failed to link due to: ld: read-only segment has dynamic relocations. This is caused by linker bug and/or non-PIC code in PIE libc.a. See: https://sourceware.org/bugzilla/show_bug.cgi?id=22264 FAIL: glibcs-powerpc-linux-gnu-power4 build elf/sln is failed to link due to: findlocale.c:96:(.text+0x22c): @local call to ifunc memchr This is caused by linker bug and/or non-PIC code in PIE libc.a. FAIL: glibcs-s390-linux-gnu build elf/sln is failed to link due to: collect2: fatal error: ld terminated with signal 11 [Segmentation fault], core dumped assertion fail bfd/elflink.c:14299 This is caused by linker bug and/or non-PIC code in PIE libc.a. FAIL: glibcs-sh3eb-linux-gnu build FAIL: glibcs-sh3-linux-gnu build FAIL: glibcs-sh4eb-linux-gnu build FAIL: glibcs-sh4eb-linux-gnu-soft build FAIL: glibcs-sh4-linux-gnu build FAIL: glibcs-sh4-linux-gnu-soft build elf/sln is failed to link due to: ld: read-only segment has dynamic relocations. This is caused by linker bug and/or non-PIC code in PIE libc.a. See: https://sourceware.org/bugzilla/show_bug.cgi?id=22263 Also TLS code sequence in SH assembly syscalls in glibc doesn't match TLS code sequence expected by ld: https://sourceware.org/bugzilla/show_bug.cgi?id=22270 FAIL: glibcs-sparc64-linux-gnu build FAIL: glibcs-sparcv9-linux-gnu build FAIL: glibcs-tilegxbe-linux-gnu build FAIL: glibcs-tilegxbe-linux-gnu-32 build FAIL: glibcs-tilegx-linux-gnu build FAIL: glibcs-tilegx-linux-gnu-32 build FAIL: glibcs-tilepro-linux-gnu build elf/sln is failed to link due to: ld: read-only segment has dynamic relocations. This is caused by linker bug and/or non-PIC code in PIE libc.a. See: https://sourceware.org/bugzilla/show_bug.cgi?id=22263 [BZ #19574] * INSTALL: Regenerated. * Makeconfig (real-static-start-installed-name): New. (pic-default): Updated for --enable-static-pie. (pie-default): New for --enable-static-pie. (default-pie-ldflag): Likewise. (+link-static-before-libc): Replace $(DEFAULT-LDFLAGS-$(@F)) with $(if $($(@F)-no-pie),$(no-pie-ldflag),$(default-pie-ldflag)). Replace $(static-start-installed-name) with $(real-static-start-installed-name). (+prectorT): Updated for --enable-static-pie. (+postctorT): Likewise. (CFLAGS-.o): Add $(pie-default). (CFLAGS-.op): Likewise. * NEWS: Mention --enable-static-pie. * config.h.in (ENABLE_STATIC_PIE): New. * configure.ac (--enable-static-pie): New configure option. (have-no-dynamic-linker): New LIBC_CONFIG_VAR. (have-static-pie): Likewise. Enable static PIE if linker supports --no-dynamic-linker. (ENABLE_STATIC_PIE): New AC_DEFINE. (enable-static-pie): New LIBC_CONFIG_VAR. * configure: Regenerated. * csu/Makefile (omit-deps): Add r$(start-installed-name) and gr$(start-installed-name) for --enable-static-pie. (extra-objs): Likewise. (install-lib): Likewise. (extra-objs): Add static-reloc.o and static-reloc.os ($(objpfx)$(start-installed-name)): Also depend on $(objpfx)static-reloc.o. ($(objpfx)r$(start-installed-name)): New. ($(objpfx)g$(start-installed-name)): Also depend on $(objpfx)static-reloc.os. ($(objpfx)gr$(start-installed-name)): New. * csu/libc-start.c (LIBC_START_MAIN): Call _dl_relocate_static_pie in libc.a. * csu/libc-tls.c (__libc_setup_tls): Add main_map->l_addr to initimage. * csu/static-reloc.c: New file. * elf/Makefile (routines): Add dl-reloc-static-pie. (elide-routines.os): Likewise. (DEFAULT-LDFLAGS-tst-tls1-static-non-pie): Removed. (tst-tls1-static-non-pie-no-pie): New. * elf/dl-reloc-static-pie.c: New file. * elf/dl-support.c (_dl_get_dl_main_map): New function. * elf/dynamic-link.h (ELF_DURING_STARTUP): Also check STATIC_PIE_BOOTSTRAP. * elf/get-dynamic-info.h (elf_get_dynamic_info): Likewise. * gmon/Makefile (tests): Add tst-gmon-static-pie. (tests-static): Likewise. (DEFAULT-LDFLAGS-tst-gmon-static): Removed. (tst-gmon-static-no-pie): New. (CFLAGS-tst-gmon-static-pie.c): Likewise. (CRT-tst-gmon-static-pie): Likewise. (tst-gmon-static-pie-ENV): Likewise. (tests-special): Likewise. ($(objpfx)tst-gmon-static-pie.out): Likewise. (clean-tst-gmon-static-pie-data): Likewise. ($(objpfx)tst-gmon-static-pie-gprof.out): Likewise. * gmon/tst-gmon-static-pie.c: New file. * manual/install.texi: Document --enable-static-pie. * sysdeps/generic/ldsodefs.h (_dl_relocate_static_pie): New. (_dl_get_dl_main_map): Likewise. * sysdeps/i386/configure.ac: Check if linker supports static PIE. * sysdeps/x86_64/configure.ac: Likewise. * sysdeps/i386/configure: Regenerated. * sysdeps/x86_64/configure: Likewise. * sysdeps/mips/Makefile (ASFLAGS-.o): Add $(pie-default). (ASFLAGS-.op): Likewise.
399 lines
11 KiB
C
399 lines
11 KiB
C
/* Support for dynamic linking code in static libc.
|
|
Copyright (C) 1996-2017 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
|
|
<http://www.gnu.org/licenses/>. */
|
|
|
|
/* This file defines some things that for the dynamic linker are defined in
|
|
rtld.c and dl-sysdep.c in ways appropriate to bootstrap dynamic linking. */
|
|
|
|
#include <errno.h>
|
|
#include <libintl.h>
|
|
#include <stdlib.h>
|
|
#include <unistd.h>
|
|
#include <sys/param.h>
|
|
#include <stdint.h>
|
|
#include <ldsodefs.h>
|
|
#include <dl-machine.h>
|
|
#include <libc-lock.h>
|
|
#include <dl-cache.h>
|
|
#include <dl-librecon.h>
|
|
#include <dl-procinfo.h>
|
|
#include <unsecvars.h>
|
|
#include <hp-timing.h>
|
|
#include <stackinfo.h>
|
|
|
|
extern char *__progname;
|
|
char **_dl_argv = &__progname; /* This is checked for some error messages. */
|
|
|
|
/* Name of the architecture. */
|
|
const char *_dl_platform;
|
|
size_t _dl_platformlen;
|
|
|
|
int _dl_debug_mask;
|
|
int _dl_lazy;
|
|
ElfW(Addr) _dl_use_load_bias = -2;
|
|
int _dl_dynamic_weak;
|
|
|
|
/* If nonzero print warnings about problematic situations. */
|
|
int _dl_verbose;
|
|
|
|
/* We never do profiling. */
|
|
const char *_dl_profile;
|
|
const char *_dl_profile_output;
|
|
|
|
/* Names of shared object for which the RUNPATHs and RPATHs should be
|
|
ignored. */
|
|
const char *_dl_inhibit_rpath;
|
|
|
|
/* The map for the object we will profile. */
|
|
struct link_map *_dl_profile_map;
|
|
|
|
/* This is the address of the last stack address ever used. */
|
|
void *__libc_stack_end;
|
|
|
|
/* Path where the binary is found. */
|
|
const char *_dl_origin_path;
|
|
|
|
/* Nonzero if runtime lookup should not update the .got/.plt. */
|
|
int _dl_bind_not;
|
|
|
|
/* A dummy link map for the executable, used by dlopen to access the global
|
|
scope. We don't export any symbols ourselves, so this can be minimal. */
|
|
static struct link_map _dl_main_map =
|
|
{
|
|
.l_name = (char *) "",
|
|
.l_real = &_dl_main_map,
|
|
.l_ns = LM_ID_BASE,
|
|
.l_libname = &(struct libname_list) { .name = "", .dont_free = 1 },
|
|
.l_searchlist =
|
|
{
|
|
.r_list = &(struct link_map *) { &_dl_main_map },
|
|
.r_nlist = 1,
|
|
},
|
|
.l_symbolic_searchlist = { .r_list = &(struct link_map *) { NULL } },
|
|
.l_type = lt_executable,
|
|
.l_scope_mem = { &_dl_main_map.l_searchlist },
|
|
.l_scope_max = (sizeof (_dl_main_map.l_scope_mem)
|
|
/ sizeof (_dl_main_map.l_scope_mem[0])),
|
|
.l_scope = _dl_main_map.l_scope_mem,
|
|
.l_local_scope = { &_dl_main_map.l_searchlist },
|
|
.l_used = 1,
|
|
.l_tls_offset = NO_TLS_OFFSET,
|
|
.l_serial = 1,
|
|
};
|
|
|
|
/* Namespace information. */
|
|
struct link_namespaces _dl_ns[DL_NNS] =
|
|
{
|
|
[LM_ID_BASE] =
|
|
{
|
|
._ns_loaded = &_dl_main_map,
|
|
._ns_nloaded = 1,
|
|
._ns_main_searchlist = &_dl_main_map.l_searchlist,
|
|
}
|
|
};
|
|
size_t _dl_nns = 1;
|
|
|
|
/* Incremented whenever something may have been added to dl_loaded. */
|
|
unsigned long long _dl_load_adds = 1;
|
|
|
|
/* Fake scope of the main application. */
|
|
struct r_scope_elem _dl_initial_searchlist =
|
|
{
|
|
.r_list = &(struct link_map *) { &_dl_main_map },
|
|
.r_nlist = 1,
|
|
};
|
|
|
|
#ifndef HAVE_INLINED_SYSCALLS
|
|
/* Nonzero during startup. */
|
|
int _dl_starting_up = 1;
|
|
#endif
|
|
|
|
/* Random data provided by the kernel. */
|
|
void *_dl_random;
|
|
|
|
/* Get architecture specific initializer. */
|
|
#include <dl-procruntime.c>
|
|
#include <dl-procinfo.c>
|
|
|
|
/* Initial value of the CPU clock. */
|
|
#ifndef HP_TIMING_NONAVAIL
|
|
hp_timing_t _dl_cpuclock_offset;
|
|
#endif
|
|
|
|
void (*_dl_init_static_tls) (struct link_map *) = &_dl_nothread_init_static_tls;
|
|
|
|
size_t _dl_pagesize = EXEC_PAGESIZE;
|
|
|
|
int _dl_inhibit_cache;
|
|
|
|
unsigned int _dl_osversion;
|
|
|
|
/* All known directories in sorted order. */
|
|
struct r_search_path_elem *_dl_all_dirs;
|
|
|
|
/* All directories after startup. */
|
|
struct r_search_path_elem *_dl_init_all_dirs;
|
|
|
|
/* The object to be initialized first. */
|
|
struct link_map *_dl_initfirst;
|
|
|
|
/* Descriptor to write debug messages to. */
|
|
int _dl_debug_fd = STDERR_FILENO;
|
|
|
|
int _dl_correct_cache_id = _DL_CACHE_DEFAULT_ID;
|
|
|
|
ElfW(auxv_t) *_dl_auxv;
|
|
const ElfW(Phdr) *_dl_phdr;
|
|
size_t _dl_phnum;
|
|
uint64_t _dl_hwcap __attribute__ ((nocommon));
|
|
uint64_t _dl_hwcap2 __attribute__ ((nocommon));
|
|
|
|
/* The value of the FPU control word the kernel will preset in hardware. */
|
|
fpu_control_t _dl_fpu_control = _FPU_DEFAULT;
|
|
|
|
#if !HAVE_TUNABLES
|
|
/* This is not initialized to HWCAP_IMPORTANT, matching the definition
|
|
of _dl_important_hwcaps, below, where no hwcap strings are ever
|
|
used. This mask is still used to mediate the lookups in the cache
|
|
file. Since there is no way to set this nonzero (we don't grok the
|
|
LD_HWCAP_MASK environment variable here), there is no real point in
|
|
setting _dl_hwcap nonzero below, but we do anyway. */
|
|
uint64_t _dl_hwcap_mask __attribute__ ((nocommon));
|
|
#endif
|
|
|
|
/* Prevailing state of the stack. Generally this includes PF_X, indicating it's
|
|
* executable but this isn't true for all platforms. */
|
|
ElfW(Word) _dl_stack_flags = DEFAULT_STACK_PERMS;
|
|
|
|
/* If loading a shared object requires that we make the stack executable
|
|
when it was not, we do it by calling this function.
|
|
It returns an errno code or zero on success. */
|
|
int (*_dl_make_stack_executable_hook) (void **) = _dl_make_stack_executable;
|
|
|
|
|
|
/* Function in libpthread to wait for termination of lookups. */
|
|
void (*_dl_wait_lookup_done) (void);
|
|
|
|
struct dl_scope_free_list *_dl_scope_free_list;
|
|
|
|
#ifdef NEED_DL_SYSINFO
|
|
/* Needed for improved syscall handling on at least x86/Linux. */
|
|
uintptr_t _dl_sysinfo = DL_SYSINFO_DEFAULT;
|
|
#endif
|
|
#ifdef NEED_DL_SYSINFO_DSO
|
|
/* Address of the ELF headers in the vsyscall page. */
|
|
const ElfW(Ehdr) *_dl_sysinfo_dso;
|
|
|
|
struct link_map *_dl_sysinfo_map;
|
|
|
|
# include "get-dynamic-info.h"
|
|
#endif
|
|
#include "setup-vdso.h"
|
|
|
|
/* During the program run we must not modify the global data of
|
|
loaded shared object simultanously in two threads. Therefore we
|
|
protect `_dl_open' and `_dl_close' in dl-close.c.
|
|
|
|
This must be a recursive lock since the initializer function of
|
|
the loaded object might as well require a call to this function.
|
|
At this time it is not anymore a problem to modify the tables. */
|
|
__rtld_lock_define_initialized_recursive (, _dl_load_lock)
|
|
/* This lock is used to keep __dl_iterate_phdr from inspecting the
|
|
list of loaded objects while an object is added to or removed from
|
|
that list. */
|
|
__rtld_lock_define_initialized_recursive (, _dl_load_write_lock)
|
|
|
|
|
|
#ifdef HAVE_AUX_VECTOR
|
|
int _dl_clktck;
|
|
|
|
void
|
|
_dl_aux_init (ElfW(auxv_t) *av)
|
|
{
|
|
int seen = 0;
|
|
uid_t uid = 0;
|
|
gid_t gid = 0;
|
|
|
|
_dl_auxv = av;
|
|
for (; av->a_type != AT_NULL; ++av)
|
|
switch (av->a_type)
|
|
{
|
|
case AT_PAGESZ:
|
|
if (av->a_un.a_val != 0)
|
|
GLRO(dl_pagesize) = av->a_un.a_val;
|
|
break;
|
|
case AT_CLKTCK:
|
|
GLRO(dl_clktck) = av->a_un.a_val;
|
|
break;
|
|
case AT_PHDR:
|
|
GL(dl_phdr) = (const void *) av->a_un.a_val;
|
|
break;
|
|
case AT_PHNUM:
|
|
GL(dl_phnum) = av->a_un.a_val;
|
|
break;
|
|
case AT_PLATFORM:
|
|
GLRO(dl_platform) = (void *) av->a_un.a_val;
|
|
break;
|
|
case AT_HWCAP:
|
|
GLRO(dl_hwcap) = (unsigned long int) av->a_un.a_val;
|
|
break;
|
|
case AT_HWCAP2:
|
|
GLRO(dl_hwcap2) = (unsigned long int) av->a_un.a_val;
|
|
break;
|
|
case AT_FPUCW:
|
|
GLRO(dl_fpu_control) = av->a_un.a_val;
|
|
break;
|
|
#ifdef NEED_DL_SYSINFO
|
|
case AT_SYSINFO:
|
|
GL(dl_sysinfo) = av->a_un.a_val;
|
|
break;
|
|
#endif
|
|
#ifdef NEED_DL_SYSINFO_DSO
|
|
case AT_SYSINFO_EHDR:
|
|
GL(dl_sysinfo_dso) = (void *) av->a_un.a_val;
|
|
break;
|
|
#endif
|
|
case AT_UID:
|
|
uid ^= av->a_un.a_val;
|
|
seen |= 1;
|
|
break;
|
|
case AT_EUID:
|
|
uid ^= av->a_un.a_val;
|
|
seen |= 2;
|
|
break;
|
|
case AT_GID:
|
|
gid ^= av->a_un.a_val;
|
|
seen |= 4;
|
|
break;
|
|
case AT_EGID:
|
|
gid ^= av->a_un.a_val;
|
|
seen |= 8;
|
|
break;
|
|
case AT_SECURE:
|
|
seen = -1;
|
|
__libc_enable_secure = av->a_un.a_val;
|
|
__libc_enable_secure_decided = 1;
|
|
break;
|
|
case AT_RANDOM:
|
|
_dl_random = (void *) av->a_un.a_val;
|
|
break;
|
|
# ifdef DL_PLATFORM_AUXV
|
|
DL_PLATFORM_AUXV
|
|
# endif
|
|
}
|
|
if (seen == 0xf)
|
|
{
|
|
__libc_enable_secure = uid != 0 || gid != 0;
|
|
__libc_enable_secure_decided = 1;
|
|
}
|
|
}
|
|
#endif
|
|
|
|
|
|
void
|
|
_dl_non_dynamic_init (void)
|
|
{
|
|
_dl_main_map.l_origin = _dl_get_origin ();
|
|
_dl_main_map.l_phdr = GL(dl_phdr);
|
|
_dl_main_map.l_phnum = GL(dl_phnum);
|
|
|
|
if (HP_SMALL_TIMING_AVAIL)
|
|
HP_TIMING_NOW (_dl_cpuclock_offset);
|
|
|
|
_dl_verbose = *(getenv ("LD_WARN") ?: "") == '\0' ? 0 : 1;
|
|
|
|
/* Set up the data structures for the system-supplied DSO early,
|
|
so they can influence _dl_init_paths. */
|
|
setup_vdso (NULL, NULL);
|
|
|
|
/* Initialize the data structures for the search paths for shared
|
|
objects. */
|
|
_dl_init_paths (getenv ("LD_LIBRARY_PATH"));
|
|
|
|
/* Remember the last search directory added at startup. */
|
|
_dl_init_all_dirs = GL(dl_all_dirs);
|
|
|
|
_dl_lazy = *(getenv ("LD_BIND_NOW") ?: "") == '\0';
|
|
|
|
_dl_bind_not = *(getenv ("LD_BIND_NOT") ?: "") != '\0';
|
|
|
|
_dl_dynamic_weak = *(getenv ("LD_DYNAMIC_WEAK") ?: "") == '\0';
|
|
|
|
_dl_profile_output = getenv ("LD_PROFILE_OUTPUT");
|
|
if (_dl_profile_output == NULL || _dl_profile_output[0] == '\0')
|
|
_dl_profile_output
|
|
= &"/var/tmp\0/var/profile"[__libc_enable_secure ? 9 : 0];
|
|
|
|
if (__libc_enable_secure)
|
|
{
|
|
static const char unsecure_envvars[] =
|
|
UNSECURE_ENVVARS
|
|
#ifdef EXTRA_UNSECURE_ENVVARS
|
|
EXTRA_UNSECURE_ENVVARS
|
|
#endif
|
|
;
|
|
const char *cp = unsecure_envvars;
|
|
|
|
while (cp < unsecure_envvars + sizeof (unsecure_envvars))
|
|
{
|
|
__unsetenv (cp);
|
|
cp = (const char *) __rawmemchr (cp, '\0') + 1;
|
|
}
|
|
|
|
#if !HAVE_TUNABLES
|
|
if (__access ("/etc/suid-debug", F_OK) != 0)
|
|
__unsetenv ("MALLOC_CHECK_");
|
|
#endif
|
|
}
|
|
|
|
#ifdef DL_PLATFORM_INIT
|
|
DL_PLATFORM_INIT;
|
|
#endif
|
|
|
|
#ifdef DL_OSVERSION_INIT
|
|
DL_OSVERSION_INIT;
|
|
#endif
|
|
|
|
/* Now determine the length of the platform string. */
|
|
if (_dl_platform != NULL)
|
|
_dl_platformlen = strlen (_dl_platform);
|
|
|
|
/* Scan for a program header telling us the stack is nonexecutable. */
|
|
if (_dl_phdr != NULL)
|
|
for (uint_fast16_t i = 0; i < _dl_phnum; ++i)
|
|
if (_dl_phdr[i].p_type == PT_GNU_STACK)
|
|
{
|
|
_dl_stack_flags = _dl_phdr[i].p_flags;
|
|
break;
|
|
}
|
|
}
|
|
|
|
#ifdef DL_SYSINFO_IMPLEMENTATION
|
|
DL_SYSINFO_IMPLEMENTATION
|
|
#endif
|
|
|
|
#if ENABLE_STATIC_PIE
|
|
/* Since relocation to hidden _dl_main_map causes relocation overflow on
|
|
aarch64, a function is used to get the address of _dl_main_map. */
|
|
|
|
struct link_map *
|
|
_dl_get_dl_main_map (void)
|
|
{
|
|
return &_dl_main_map;
|
|
}
|
|
#endif
|