diff --git a/ChangeLog b/ChangeLog index f1b95e0e79..f17669931b 100644 --- a/ChangeLog +++ b/ChangeLog @@ -1,3 +1,22 @@ +2016-12-26 Nick Alcock + Florian Weimer + + [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 [BZ #7065] 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 #ifndef SHARED # include -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,6 +174,20 @@ LIBC_START_MAIN (int (*main) (int, char **, char ** MAIN_AUXVEC_DECL), } } + /* Perform IREL{,A} relocations. */ + apply_irel (); + + /* 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); +# ifdef THREAD_SET_STACK_GUARD + THREAD_SET_STACK_GUARD (stack_chk_guard); +# else + __stack_chk_guard = stack_chk_guard; +# endif + # ifdef DL_SYSDEP_OSCHECK if (!__libc_multiple_libcs) { @@ -184,21 +197,9 @@ LIBC_START_MAIN (int (*main) (int, char **, char ** MAIN_AUXVEC_DECL), } # 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 (); - - /* Set up the stack checker's canary. */ - uintptr_t stack_chk_guard = _dl_setup_stack_chk_guard (_dl_random); -# ifdef THREAD_SET_STACK_GUARD - THREAD_SET_STACK_GUARD (stack_chk_guard); -# else - __stack_chk_guard = stack_chk_guard; -# 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, 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)