mirror of
https://sourceware.org/git/glibc.git
synced 2025-07-29 11:41:21 +03:00
elf: Move vDSO setup to rtld (BZ#24967)
This patch moves the vDSO setup from libc to loader code, just after the vDSO link_map setup. For static case the initialization is moved to _dl_non_dynamic_init instead. Instead of using the mangled pointer, the vDSO data is set as attribute_relro (on _rtld_global_ro for shared or _dl_vdso_* for static). It is read-only even with partial relro. It fixes BZ#24967 now that the vDSO pointer is setup earlier than malloc interposition is called. Also, vDSO calls should not be a problem for static dlopen as indicated by BZ#20802. The vDSO pointer would be zero-initialized and the syscall will be issued instead. Checked on x86_64-linux-gnu, i686-linux-gnu, aarch64-linux-gnu, arm-linux-gnueabihf, powerpc64le-linux-gnu, powerpc64-linux-gnu, powerpc-linux-gnu, s390x-linux-gnu, sparc64-linux-gnu, and sparcv9-linux-gnu. I also run some tests on mips. Reviewed-by: Siddhesh Poyarekar <siddhesh@sourceware.org>
This commit is contained in:
@ -13,7 +13,6 @@ gen-as-const-headers += ucontext_i.sym
|
||||
endif
|
||||
|
||||
ifeq ($(subdir),elf)
|
||||
sysdep_routines += dl-vdso
|
||||
ifeq ($(build-shared),yes)
|
||||
# This is needed for DSO loading from static binaries.
|
||||
sysdep-dl-routines += dl-static
|
||||
|
@ -21,7 +21,7 @@
|
||||
|
||||
#include <libc-internal.h>
|
||||
#include <not-cancel.h>
|
||||
#include <libc-vdso.h>
|
||||
#include <sysdep-vdso.h>
|
||||
|
||||
static uint64_t
|
||||
get_timebase_freq_fallback (void)
|
||||
@ -101,8 +101,7 @@ uint64_t
|
||||
__get_timebase_freq (void)
|
||||
{
|
||||
/* The vDSO does not have a fallback mechanism (such calling a syscall). */
|
||||
__typeof (VDSO_SYMBOL (get_tbfreq)) vdsop = VDSO_SYMBOL (get_tbfreq);
|
||||
PTR_DEMANGLE (vdsop);
|
||||
uint64_t (*vdsop)(void) = GLRO(dl_vdso_get_tbfreq);
|
||||
if (vdsop == NULL)
|
||||
return get_timebase_freq_fallback ();
|
||||
|
||||
|
@ -1,50 +0,0 @@
|
||||
/* Initialization code run first thing by the ELF startup code. Linux/PowerPC.
|
||||
Copyright (C) 2007-2020 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 <dl-vdso.h>
|
||||
#include <libc-vdso.h>
|
||||
|
||||
unsigned long long (*VDSO_SYMBOL(get_tbfreq)) (void) attribute_hidden;
|
||||
#if defined(__PPC64__) || defined(__powerpc64__)
|
||||
void *VDSO_SYMBOL(sigtramp_rt64) attribute_hidden;
|
||||
#else
|
||||
void *VDSO_SYMBOL(sigtramp32) attribute_hidden;
|
||||
void *VDSO_SYMBOL(sigtramp_rt32) attribute_hidden;
|
||||
#endif
|
||||
|
||||
static inline void
|
||||
__libc_vdso_platform_setup_arch (void)
|
||||
{
|
||||
VDSO_SYMBOL (get_tbfreq) = get_vdso_mangle_symbol (HAVE_GET_TBFREQ);
|
||||
|
||||
/* PPC64 uses only one signal trampoline symbol, while PPC32 will use
|
||||
two depending if SA_SIGINFO is used (__kernel_sigtramp_rt32) or not
|
||||
(__kernel_sigtramp32).
|
||||
There is no need to pointer mangle these symbol because they will
|
||||
used only for pointer comparison. */
|
||||
#if defined(__PPC64__) || defined(__powerpc64__)
|
||||
VDSO_SYMBOL(sigtramp_rt64) = get_vdso_symbol (HAVE_SIGTRAMP_RT64);
|
||||
#else
|
||||
VDSO_SYMBOL(sigtramp32) = get_vdso_symbol (HAVE_SIGTRAMP_32);
|
||||
VDSO_SYMBOL(sigtramp_rt32) = get_vdso_symbol (HAVE_SIGTRAMP_RT32);
|
||||
#endif
|
||||
}
|
||||
|
||||
#define VDSO_SETUP_ARCH __libc_vdso_platform_setup_arch
|
||||
|
||||
#include <sysdeps/unix/sysv/linux/init-first.c>
|
@ -54,14 +54,4 @@
|
||||
# define VDSO_IFUNC_RET(value) ((void *) (value))
|
||||
#endif
|
||||
|
||||
#include_next <libc-vdso.h>
|
||||
|
||||
extern unsigned long long (*VDSO_SYMBOL(get_tbfreq)) (void);
|
||||
#if defined(__PPC64__) || defined(__powerpc64__)
|
||||
extern void *VDSO_SYMBOL(sigtramp_rt64);
|
||||
#else
|
||||
extern void *VDSO_SYMBOL(sigtramp32);
|
||||
extern void *VDSO_SYMBOL(sigtramp_rt32);
|
||||
#endif
|
||||
|
||||
#endif /* _LIBC_VDSO_H */
|
||||
|
Reference in New Issue
Block a user