ldconfig is using an aux-cache to speed up the ld.so.cache update. It
is read by mmaping the file to a structure which contains data offsets
used as pointers. As they are not checked, it is not hard to get
ldconfig to segfault with a corrupted file. This happens for instance if
the file is truncated, which is common following a filesystem check
following a system crash.
This can be reproduced for example by truncating the file to roughly
half of it's size.
There is already some code in elf/cache.c (load_aux_cache) to check
for a corrupted aux cache, but it happens to be broken and not enough.
The test (aux_cache->nlibs >= aux_cache_size) compares the number of
libs entry with the cache size. It's a non sense, as it basically
assumes that each library entry is a 1 byte... Instead this commit
computes the theoretical cache size using the headers and compares it
to the real size.
With copy relocation, address of protected data defined in the shared
library may be external. Compiler shouldn't asssume protected data will
be local. But due to
https://gcc.gnu.org/bugzilla/show_bug.cgi?id=65248
__attribute__((visibility("protected"))) doesn't work correctly, we need
to use asm (".protected xxx") instead.
* elf/ifuncdep2.c (global): Replace
__attribute__((visibility("protected"))) with
asm (".protected global").
* elf/ifuncmod1.c (global): Likewise.
* elf/ifuncmod5.c (global): Likewise.
Protocted symbol in shared library can only be accessed from PIE
or shared library. Linker in binutils 2.26 enforces it. We must
compile vismain with -fPIE and link it with -pie.
[BZ #17711]
* elf/Makefile (tests): Add vismain only if PIE is enabled.
(tests-pie): Add vismain.
(CFLAGS-vismain.c): New.
* elf/vismain.c: Add comments for PIE requirement.
We are replacing all of the bespoke alignment code with
ALIGN_UP, ALIGN_DOWN, PTR_ALIGN_UP, and PTR_ALIGN_DOWN.
This cleans up malloc/malloc.c, malloc/arena.c, and
elf/dl-reloc.c. It also makes all the code consistently
use pagesize, and powerof2 as required.
Code size is reduced with the removal of precomputed
pagemask, and use of pagesize instead. No measurable
difference in performance.
No regressions on x86_64.
The ability to recursively call dlopen is useful for malloc
implementations that wish to load other dynamic modules that
implement reentrant/AS-safe functions to use in their own
implementation.
Given that a user malloc implementation may be called by an
ongoing dlopen to allocate memory the user malloc
implementation interrupts dlopen and if it calls dlopen again
that's a reentrant call.
This patch fixes the issues with the ld.so.cache mapping
and the _r_debug assertion which prevent this from working
as expected.
See:
https://sourceware.org/ml/libc-alpha/2014-12/msg00446.html
__tls_get_addr/___tls_get_addr is always defined in ld.so. There is
no need to call them via PLT inside ld.so. This patch adds the hidden
__tls_get_addr/___tls_get_addr aliases and calls them directly from
_dl_tlsdesc_dynamic. There is no need to set up the EBX register in
i386 _dl_tlsdesc_dynamic when calling the hidden ___tls_get_addr.
* elf/dl-tls.c (__tls_get_addr): Provide the hidden definition
if not defined.
* sysdeps/i386/dl-tls.h (___tls_get_addr): Provide the hidden
definition.
* sysdeps/i386/dl-tlsdesc.S (_dl_tlsdesc_dynamic): Call the
hidden ___tls_get_addr.
* sysdeps/x86_64/dl-tlsdesc.S (_dl_tlsdesc_dynamic): Call the
hidden __tls_get_addr.
* sysdeps/generic/localplt.data (__tls_get_addr): Removed.
* sysdeps/unix/sysv/linux/i386/localplt.data (___tls_get_addr):
Likewise.
This patch fixes a warning "tst-unique4lib.cc:17:12: warning: 'b'
defined but not used [-Wunused-variable]". I'm not sure exactly what
aspects of the test are or are not significant for the issue it is
testing for; the patch makes the minimal change of marking the
variable with __attribute__ ((used)).
Tested for x86_64.
* elf/tst-unique4lib.cc (b): Mark with __attribute__ ((used)).
Developers creating development packages must take care
to have their static linker DSO link point to the actual
SONAME file. This allows ldconfig to correctly create
the required links for the SONAME. The behaviour is now
more clearly documented in a code comment added by this
patch.
This patch changes _dl_allocate_tls_init to resize DTV if the current DTV
isn't big enough. Tested on X86-64, x32 and ia32.
[BZ #13862]
* elf/dl-tls.c: Include <atomic.h>.
(oom): Remove #ifdef SHARED/#endif.
(_dl_static_dtv, _dl_initial_dtv): Moved before ...
(_dl_resize_dtv): This. Extracted from _dl_update_slotinfo.
(_dl_allocate_tls_init): Resize DTV if the current DTV isn't
big enough.
(_dl_update_slotinfo): Call _dl_resize_dtv to resize DTV.
* nptl/Makefile (tests): Add tst-stack4.
(modules-names): Add tst-stack4mod.
($(objpfx)tst-stack4): New.
(tst-stack4mod.sos): Likewise.
($(objpfx)tst-stack4.out): Likewise.
($(tst-stack4mod.sos)): Likewise.
(clean): Likewise.
* nptl/tst-stack4.c: New file.
* nptl/tst-stack4mod.c: Likewise.
Replace with IS_IN (ldconfig). No change in generated code.
* elf/Makefile (CFLAGS-ldconfig.c): Remove definition of
IS_IN_ldconfig.
* sysdeps/unix/sysv/linux/x86_64/dl-procinfo.c: Use IS_IN.
* sysdeps/unix/sysv/linux/x86_64/dl-procinfo.h: Likewise.
Make sure that all instances where NOT_IN_libc is defined also defines
IN_MODULE to facilitate removal NOT_IN_libc in future passes.
Verified that the generated code is unchanged on x86_64.
* elf/Makefile (libof-sotruss-lib): Set as extramodules.
Replace with IS_IN and IS_IN_LIB macros instead. This change results
in a change in generated code, because it fixes a subtle bug. The bug
was introduced when systemtap probes were added to lowlevellock.h,
which resulted in stap-probe.h being included in a number of places.
stap-probe.h always defines IN_LIB, which breaks a check in errno.h
and netdb.h since they rely on that macro to decide whether to
implement an internal version of a declaration or an external one.
The components that see a code change due to this are:
iconv_prog
libmemusage.so
libpcprofile.so
libSegFault.so
libutil.so.1
locale
localedef
nscd
All other built components (i.e. libc, libpthread, etc.) remain
unchanged by this on x86_64.
* elf/Makefile (CPPFLAGS-.os): Remove IN_LIB.
* elf/rtld-Rules (rtld-CPPFLAGS): Likewise.
* extra-lib.mk (CPPFLAGS-$(lib)): Likewise.
* include/libc-symbols.h (IS_IN_LIB): New macro.
* include/errno.h: Use IS_IN_LIB instead of IN_LIB.
* include/netdb.h: Likewise.
* include/stap-probe.h: Remove all uses of IN_LIB.
The latest version of the binutils ELF header defines a new set of
dynamic relocations for ILP32 and renames some to make the naming
more uniform.
ChangeLog:
2014-11-21 Will Newton <will.newton@linaro.org>
Andrew Pinski <andrew.pinski@caviumnetworks.com>
* elf/elf.h (R_AARCH64_P32_ABS32, R_AARCH64_P32_COPY,
R_AARCH64_P32_GLOB_DAT, R_AARCH64_P32_JUMP_SLOT,
R_AARCH64_P32_RELATIVE, R_AARCH64_P32_TLS_DTPMOD,
R_AARCH64_P32_TLS_DTPREL, R_AARCH64_P32_TLS_TPREL,
R_AARCH64_P32_TLSDESC, R_AARCH64_P32_IRELATIVE): Define.
(R_AARCH64_TLS_DTPMOD64): Rename to ..
(R_AARCH64_TLS_DTPMOD): This.
(R_AARCH64_TLS_DTPREL64): Rename to ...
(R_AARCH64_TLS_DTPREL): This.
(R_AARCH64_TLS_TPREL64): Rename to ...
(R_AARCH64_TLS_TPREL): This.
* sysdeps/aarch64/dl-machine.h (elf_machine_type_class): Update
R_AARCH64_TLS_DTPMOD64, R_AARCH64_TLS_DTPREL64, and
R_AARCH64_TLS_TPREL64.
(elf_machine_rela): Likewise.
The current scheme to identify which module a translation unit is
built in depends on defining multiple macros IS_IN_* and also defining
NOT_IN_libc if we're building a non-libc module. In addition, there
is an IN_LIB macro that does effectively the same thing, but for
different modules (notably the systemtap probes). This macro scheme
unifies both ideas to use just one macro IN_MODULE and assign it a
value depending on the module it is being built into. If the module
is not defined, it defaults to MODULE_libc.
Patches that follow will replace uses of IS_IN_* variables with the
IS_IN() macro. libc-symbols.h has been converted already to give an
example of how such a transition will look.
Verified that there are no relevant binary changes. One source change
that will crop up repeatedly is that of nscd_stat, since it uses the
build timestamp as a constant in its logic.
* Makeconfig (in-module): Get value of libof set for the
translation unit.
(CPPFLAGS): Use $(in-module).
* Makerules: Don't suffix routine names for nonlib.
* include/libc-modules.h: New file.
* include/libc-symbols.h: Include libc-modules.h
(IS_IN): New macro to replace IS_IN_* macros.
* elf/Makefile: Set libof-* for each routine.
* elf/rtld-Rules: Likewise.
* extra-modules.mk: Likewise.
* iconv/Makefile: Likewise.
* iconvdata/Makefile: Likewise.
* locale/Makefile: Likewise.
* malloc/Makefile: Likewise.
* nss/Makefile: Likewise.
* sysdeps/gnu/Makefile: Likewise.
* sysdeps/ieee754/ldbl-opt/Makefile: Likewise.
* sysdeps/unix/sysv/linux/Makefile: Likewise.
* sysdeps/s390/s390-64/Makefile: Likewise.
* nscd/Makefile: Set libof-* for each routine. Set CFLAGS and
CPPFLAGS for nscd instead of nonlib.
For maximum paranoia we run ld.so through the normal set
of tests for all of the shared libraries. This includes
running ld.so through check-localplt, check-textrel, and
check-execstack. While none of these should trigger any
failures given the way ld.so is built, it might possibly
fail if a developer does something wrong. This paranoia
was triggered by a discussion over the use of __strcpy
vs. strcpy [1] and if the symbol could leak and use the
libc.so version.
The check-localplt test fails right away because localplt.data
needs updating for all arches. By default we add 6 new symbols:
__tls_get_addr, __libc_memalign, malloc, calloc, realloc and
free. Other machines like i386, power, and s390 require some
different symbol sets e.g. ___tls_get_addr vs. __tls_get_addr
for i386.
Verified for i386
Verified for x86_64
Verified for ppc32
Verified for ppc64
Verified for ppc64le
Verified for arm
Verified for aarch64
Verified for s390
Verified for s390x
Guessed for alpha
Guessed for ia64
Guessed for m68k
Guessed for microblaze
Guessed for sparc32
Guessed for sparc64
Defaults for sh
Defaults for mips
Defaults for hppa
Defaults for tile
Machine manintainers notified to double check the data
used in localplt.data.
[1] https://sourceware.org/ml/libc-alpha/2014-10/msg00548.html
Completing the removal of the obsolete INTDEF / INTUSE mechanism, this
patch removes the final use - that for _dl_starting_up - replacing it
by rtld_hidden_def / rtld_hidden_proto. Having removed the last use,
the mechanism itself is also removed.
Tested for x86_64 that installed stripped shared libraries are
unchanged by the patch. (This is not much of a test since this
variable is only defined and used in the !HAVE_INLINED_SYSCALLS case.)
[BZ #14132]
* include/libc-symbols.h (INTUSE): Remove macro.
(INTDEF): Likewise.
(INTVARDEF): Likewise.
(_INTVARDEF): Likewise.
(INTDEF2): Likewise.
(INTVARDEF2): Likewise.
* elf/rtld.c [!HAVE_INLINED_SYSCALLS] (_dl_starting_up): Use
rtld_hidden_def instead of INTVARDEF.
* sysdeps/generic/ldsodefs.h [IS_IN_rtld]
(_dl_starting_up_internal): Remove declaration.
(_dl_starting_up): Use rtld_hidden_proto.
* elf/dl-init.c [!HAVE_INLINED_SYSCALLS] (_dl_starting_up): Remove
declaration.
[!HAVE_INLINED_SYSCALLS] (_dl_starting_up_internal): Likewise.
(_dl_init) [!HAVE_INLINED_SYSCALLS]: Don't use INTUSE with
_dl_starting_up.
* elf/dl-writev.h (_dl_writev): Likewise.
* sysdeps/powerpc/powerpc64/dl-machine.h [!HAVE_INLINED_SYSCALLS]
(DL_STARTING_UP_DEF): Use __GI__dl_starting_up instead of
_dl_starting_up_internal.
Continuing the removal of the obsolete INTDEF / INTUSE mechanism, this
patch replaces its use for _dl_mcount with use of rtld_hidden_def /
rtld_hidden_proto.
Tested for x86_64 that installed stripped shared libraries are
unchanged by the patch.
[BZ #14132]
* elf/dl-profile.c (_dl_mcount): Use rtld_hidden_def instead of
INTDEF.
* sysdeps/generic/ldsodefs.h (_dl_mcount_internal): Remove
declaration.
(_dl_mcount): Use rtld_hidden_proto.
* elf/dl-runtime.c (_dl_profile_fixup): Don't use INTUSE with
_dl_mcount.
* elf/rtld.c (_rtld_global_ro): Likewise.
Continuing the removal of the obsolete INTDEF / INTUSE mechanism, this
patch eliminates its use for _dl_init. Since _dl_init was already
declared with hidden visibility, creating a second hidden alias for it
was completely pointless, so this patch replaces all uses of
_dl_init_internal with plain _dl_init instead of using hidden_proto /
hidden_def (which are only needed when you want a hidden alias for a
non-hidden symbol; it's quite possible there are cases where they are
used but don't need to be because the symbol in question is not part
of the public ABI and is only used within a single library, so using
attributes_hidden instead would suffice).
Tested for x86_64 that installed stripped shared libraries are
unchanged by the patch.
[BZ #14132]
* elf/dl-init.c (_dl_init): Don't use INTDEF.
* sysdeps/aarch64/dl-machine.h (RTLD_START): Use _dl_init instead
of _dl_init_internal.
* sysdeps/alpha/dl-machine.h (RTLD_START): Likewise.
* sysdeps/arm/dl-machine.h (RTLD_START): Likewise.
* sysdeps/hppa/dl-machine.h (RTLD_START): Likewise.
* sysdeps/i386/dl-machine.h (RTLD_START): Likewise.
* sysdeps/ia64/dl-machine.h (RTLD_START): Likewise.
* sysdeps/m68k/dl-machine.h (RTLD_START): Likewise.
* sysdeps/microblaze/dl-machine.h (RTLD_START): Likewise.
* sysdeps/mips/dl-machine.h (RTLD_START): Likewise.
* sysdeps/powerpc/powerpc32/dl-start.S (_start): Likewise.
* sysdeps/s390/s390-32/dl-machine.h (RTLD_START): Likewise.
* sysdeps/s390/s390-64/dl-machine.h (RTLD_START): Likewise.
* sysdeps/sh/dl-machine.h (RTLD_START): Likewise.
* sysdeps/sparc/sparc32/dl-machine.h (RTLD_START): Likewise.
* sysdeps/sparc/sparc64/dl-machine.h (RTLD_START): Likewise.
* sysdeps/tile/dl-start.S (_start): Likewise.
* sysdeps/x86_64/dl-machine.h (RTLD_START): Likewise.
* sysdeps/x86_64/x32/dl-machine.h (RTLD_START): Likewise.
Continuing the removal of the obsolete INTDEF / INTUSE mechanism, this
patch replaces its use for _dl_argv with rtld_hidden_data_def and
rtld_hidden_proto. Some places in .S files that previously used
_dl_argv_internal or INTUSE(_dl_argv) now use __GI__dl_argv directly
(there are plenty of existing examples of such direct use of __GI_*).
A single place in rtld.c previously used _dl_argv without INTUSE,
apparently accidentally, while the rtld_hidden_proto mechanism avoids
such accidential omissions. As a consequence, this patch *does*
change the contents of stripped ld.so. However, the installed
stripped shared libraries are identical to those you get if instead of
this patch you change that single _dl_argv use to use INTUSE, without
any other changes.
Tested for x86_64 (testsuite as well as comparison of installed
stripped shared libraries as described above).
[BZ #14132]
* sysdeps/generic/ldsodefs.h (_dl_argv): Use rtld_hidden_proto.
[IS_IN_rtld] (_dl_argv_internal): Do not declare.
(rtld_progname): Make macro definition unconditional.
* elf/rtld.c (_dl_argv): Use rtld_hidden_data_def instead of
INTDEF.
(dlmopen_doit): Do not use INTUSE with _dl_argv.
(dl_main): Likewise.
* elf/dl-sysdep.c (_dl_sysdep_start): Likewise.
* sysdeps/alpha/dl-machine.h (RTLD_START): Use __GI__dl_argv
instead of _dl_argv_internal.
* sysdeps/powerpc/powerpc32/dl-start.S (_dl_start_user): Use
__GI__dl_argv instead of INTUSE(_dl_argv).
* sysdeps/powerpc/powerpc64/dl-machine.h (RTLD_START): Use
__GI__dl_argv instead of _dl_argv_internal.
This hook can be used to perform additional compatibility checks
between shared libraries by inspecting custom program header
information.
* elf/dl-machine-reject-phdr.h: New file.
* elf/dl-load.c: #include that.
(open_verify): Call elf_machine_reject_phdr_p and ignore the file
if that returned true.
During a refactoring pass several repeated blocks of code in dl-load.c
were turned into a call to a local function named local_strdup. There
is no need for local_strdup, and the routines should instead call
__strdup. This change does just that. We call the internal symbol
__strdup because calling strdup is unsafe. The user might be
using a standard that doesn't include strdup and may have defined this
symbol in their application. During a static link we might reference
the user defined symbol and crash if it doesn't implement a standards
conforming strdup. The resulting code is simpler to understand, and
makes it easier to debug.
No regressions on x86_64.
2014-10-28 Carlos O'Donell <carlos@redhat.com>
* dl-load.c (local_strdup): Remove.
(expand_dynamic_string_token): Use __strdup.
(decompose_rpath): Likewise.
(_dl_map_object): Likewise.
Continuing the removal of the obsolete INTDEF / INTVARDEF / INTUSE
mechanism, this patch replaces its use for __libc_enable_secure with
the use of rtld_hidden_data_def and rtld_hidden_proto.
Tested for x86_64 that installed stripped shared libraries are
unchanged by the patch.
[BZ #14132]
* elf/dl-sysdep.c (__libc_enable_secure): Use rtld_hidden_data_def
instead of INTVARDEF.
(_dl_sysdep_start): Do not use INTUSE with __libc_enable_secure.
* sysdeps/mach/hurd/dl-sysdep.c (__libc_enable_secure): Use
rtld_hidden_data_def instead of INTVARDEF.
(_dl_sysdep_start): Do not use INTUSE with __libc_enable_secure.
* elf/dl-deps.c (expand_dst): Likewise.
* elf/dl-load.c (_dl_dst_count): Likewise.
(_dl_dst_substitute): Likewise.
(decompose_rpath): Likewise.
(_dl_init_paths): Likewise.
(open_path): Likewise.
(_dl_map_object): Likewise.
* elf/rtld.c (dl_main): Likewise.
(process_dl_audit): Likewise.
(process_envvars): Likewise.
* include/unistd.h [IS_IN_rtld] (__libc_enable_secure_internal):
Remove declaration.
(__libc_enable_secure): Use rtld_hidden_proto.
During auditing or profiling modes the dynamic loader
builds a cache of the relocated PLT entries in order
to reuse them when called again through the same PLT
entry. This way the PLT entry is never completed and
the call into the resolver always results in profiling
or auditing code running.
The problem is that the PLT relocation cache size
is not computed correctly. The size of the cache
should be "Size of a relocation result structure"
x "Number of PLT-related relocations". Instead the
code erroneously computes "Size of a relocation
result" x "Number of bytes worth of PLT-related
relocations". I can only assume this was a mistake
in the understanding of the value of DT_PLTRELSZ
which is the number of bytes of PLT-related relocs.
We do have a DT_RELACOUNT entry, which is a count
for dynamic relative relocs, but we have no
DT_PLTRELCOUNT and thus we need to compute it.
This patch corrects the computation of the size of the
relocation table used by the glibc profiling code.
For more details see:
https://sourceware.org/ml/libc-alpha/2014-09/msg00513.html
[BZ #17411]
* elf/dl-reloc.c (_dl_relocate_object): Allocate correct amount for
l_reloc_result.
Replace it with including an auto-generated linker-runtime.h.
Build-tested on x86_64 and found that there was no change in the
generated code.
* elf/Makefile (CFLAGS-interp.c): Remove.
($(elf-objpfx)runtime-linker.h): Generate header with linker
path string.
* elf/interp.c: Include generated runtime-linker.h
Barring libc.so and libdl.so, none of the libraries have any entry
points, so it is pointless to add a .interp section for them. The
libdl.so entry point (in dlfcn/eval.c) is also defunct, so remove that
file as well.
Build tested for x86_64, ppc64 and s390x. I have not moved
CFLAGS-interp.c to CPPFLAGS-interp.c isnce I'll be removing it
completely in a follow-up patch.
Siddhesh
* Makerules (lib%.so): Don't include $(+interp) in
prerequisites.
* elf/Makefile (CFLAGS-interp.c): Don't define NOT_IN_libc.
* dlfcn/eval.c: Remove file.