diff options
-rw-r--r-- | ChangeLog | 19 | ||||
-rw-r--r-- | csu/libc-start.c | 29 | ||||
-rw-r--r-- | csu/libc-tls.c | 17 | ||||
-rw-r--r-- | nptl/nptl-init.c | 16 | ||||
-rw-r--r-- | sysdeps/generic/ldsodefs.h | 11 |
5 files changed, 49 insertions, 43 deletions
diff --git a/ChangeLog b/ChangeLog index f1b95e0e79..f17669931b 100644 --- a/ChangeLog +++ b/ChangeLog @@ -1,4 +1,23 @@ 2016-12-26 Nick Alcock <nick.alcock@oracle.com> + Florian Weimer <fweimer@redhat.com> + + [BZ #7065] + Initialize the stack guard earlier when linking statically. + * sysdeps/generic/ldsodefs.h (__libc_setup_tls) + (__pthread_initialize_minimal): Declare. + * csu/libc-start.c (__pthread_initialize_minimal): Remove + declaration. + (LIBC_START_MAIN): Call __libc_setup_tls early and directly. Move + stack canary and apply_irel initialization up. Call + __pthread_initialize_minimal only if linked in. + * csu/libc-tls.c (__libc_setup_tls): Replace arguments with their + constant values. + (__pthread_initialize_minimal): Remove. + * nptl/nptl-init.c (__libc_setup_tls): Remove declaration. + (__pthread_initialize_minimal_internal): Do not call + __libc_setup_tls. + +2016-12-26 Nick Alcock <nick.alcock@oracle.com> [BZ #7065] * configure.ac (libc_cv_ssp): Move up. diff --git a/csu/libc-start.c b/csu/libc-start.c index 99c040ab97..cc59073abe 100644 --- a/csu/libc-start.c +++ b/csu/libc-start.c @@ -29,7 +29,6 @@ extern int __libc_multiple_libcs; #include <tls.h> #ifndef SHARED # include <dl-osinfo.h> -extern void __pthread_initialize_minimal (void); # ifndef THREAD_SET_STACK_GUARD /* Only exported for architectures that don't store the stack guard canary in thread local area. */ @@ -175,22 +174,11 @@ LIBC_START_MAIN (int (*main) (int, char **, char ** MAIN_AUXVEC_DECL), } } -# ifdef DL_SYSDEP_OSCHECK - if (!__libc_multiple_libcs) - { - /* This needs to run to initiliaze _dl_osversion before TLS - setup might check it. */ - DL_SYSDEP_OSCHECK (__libc_fatal); - } -# endif - /* Perform IREL{,A} relocations. */ apply_irel (); - /* Initialize the thread library at least a bit since the libgcc - functions are using thread functions if these are available and - we need to setup errno. */ - __pthread_initialize_minimal (); + /* The stack guard goes into the TCB, so initialize it early. */ + __libc_setup_tls (); /* Set up the stack checker's canary. */ uintptr_t stack_chk_guard = _dl_setup_stack_chk_guard (_dl_random); @@ -200,6 +188,19 @@ LIBC_START_MAIN (int (*main) (int, char **, char ** MAIN_AUXVEC_DECL), __stack_chk_guard = stack_chk_guard; # endif +# ifdef DL_SYSDEP_OSCHECK + if (!__libc_multiple_libcs) + { + /* This needs to run to initiliaze _dl_osversion before TLS + setup might check it. */ + DL_SYSDEP_OSCHECK (__libc_fatal); + } +# endif + + /* Initialize libpthread if linked in. */ + if (__pthread_initialize_minimal != NULL) + __pthread_initialize_minimal (); + /* Set up the pointer guard value. */ uintptr_t pointer_chk_guard = _dl_setup_pointer_guard (_dl_random, stack_chk_guard); diff --git a/csu/libc-tls.c b/csu/libc-tls.c index 8f922341de..454f165457 100644 --- a/csu/libc-tls.c +++ b/csu/libc-tls.c @@ -102,14 +102,14 @@ init_static_tls (size_t memsz, size_t align) } void -__libc_setup_tls (size_t tcbsize, size_t tcbalign) +__libc_setup_tls (void) { void *tlsblock; size_t memsz = 0; size_t filesz = 0; void *initimage = NULL; size_t align = 0; - size_t max_align = tcbalign; + size_t max_align = TCB_ALIGNMENT; size_t tcb_offset; const ElfW(Phdr) *phdr; @@ -142,9 +142,9 @@ __libc_setup_tls (size_t tcbsize, size_t tcbalign) _dl_allocate_tls_storage (in elf/dl-tls.c) does using __libc_memalign and dl_tls_static_align. */ tcb_offset = roundup (memsz + GL(dl_tls_static_size), max_align); - tlsblock = __sbrk (tcb_offset + tcbsize + max_align); + tlsblock = __sbrk (tcb_offset + TLS_INIT_TCB_SIZE + max_align); #elif TLS_DTV_AT_TP - tcb_offset = roundup (tcbsize, align ?: 1); + tcb_offset = roundup (TLS_INIT_TCB_SIZE, align ?: 1); tlsblock = __sbrk (tcb_offset + memsz + max_align + TLS_PRE_TCB_SIZE + GL(dl_tls_static_size)); tlsblock += TLS_PRE_TCB_SIZE; @@ -215,12 +215,3 @@ __libc_setup_tls (size_t tcbsize, size_t tcbalign) init_static_tls (memsz, MAX (TLS_TCB_ALIGN, max_align)); } - -/* This is the minimal initialization function used when libpthread is - not used. */ -void -__attribute__ ((weak)) -__pthread_initialize_minimal (void) -{ - __libc_setup_tls (TLS_INIT_TCB_SIZE, TLS_INIT_TCB_ALIGN); -} diff --git a/nptl/nptl-init.c b/nptl/nptl-init.c index 0fd54a0a93..8494b26115 100644 --- a/nptl/nptl-init.c +++ b/nptl/nptl-init.c @@ -70,10 +70,6 @@ int __have_futex_clock_realtime; static const char nptl_version[] __attribute_used__ = VERSION; -#ifndef SHARED -extern void __libc_setup_tls (size_t tcbsize, size_t tcbalign); -#endif - #ifdef SHARED static #else @@ -288,18 +284,6 @@ static bool __nptl_initial_report_events __attribute_used__; void __pthread_initialize_minimal_internal (void) { -#ifndef SHARED - /* Unlike in the dynamically linked case the dynamic linker has not - taken care of initializing the TLS data structures. */ - __libc_setup_tls (TLS_TCB_SIZE, TLS_TCB_ALIGN); - - /* We must prevent gcc from being clever and move any of the - following code ahead of the __libc_setup_tls call. This function - will initialize the thread register which is subsequently - used. */ - __asm __volatile (""); -#endif - /* Minimal initialization of the thread descriptor. */ struct pthread *pd = THREAD_SELF; __pthread_initialize_pids (pd); diff --git a/sysdeps/generic/ldsodefs.h b/sysdeps/generic/ldsodefs.h index 34d7ec152d..bb67840b22 100644 --- a/sysdeps/generic/ldsodefs.h +++ b/sysdeps/generic/ldsodefs.h @@ -994,6 +994,17 @@ extern size_t _dl_count_modids (void) internal_function attribute_hidden; /* Calculate offset of the TLS blocks in the static TLS block. */ extern void _dl_determine_tlsoffset (void) internal_function attribute_hidden; +#ifndef SHARED +/* Set up the TCB for statically linked applications. This is called + early during startup because we always use TLS (for errno and the + stack protector, among other things). */ +void __libc_setup_tls (void); + +/* Initialization of libpthread for statically linked applications. + If libpthread is not linked in, this is an empty function. */ +void __pthread_initialize_minimal (void) weak_function; +#endif + /* Allocate memory for static TLS block (unless MEM is nonzero) and dtv. */ extern void *_dl_allocate_tls (void *mem) internal_function; rtld_hidden_proto (_dl_allocate_tls) |