diff options
| author | Rich Felker <dalias@aerifal.cx> | 2015-06-07 20:55:23 +0000 | 
|---|---|---|
| committer | Rich Felker <dalias@aerifal.cx> | 2015-06-07 21:23:23 +0000 | 
| commit | 75ce4503950621b11fcc7f1fd1187dbcf3cde312 (patch) | |
| tree | 7a2f3c2d25e88d08af7c50a24dc0f4b648f6cd07 /src | |
| parent | 32f3c4f70633488550c29a2444f819aafdf345ff (diff) | |
| download | musl-75ce4503950621b11fcc7f1fd1187dbcf3cde312.tar.gz | |
fix regression in pre-v7 arm on kernels with kuser helper removed
the arm atomics/TLS runtime selection code is called from
__set_thread_area and depends on having libc.auxv and __hwcap
available. commit 71f099cb7db821c51d8f39dfac622c61e54d794c moved the
first call to __set_thread_area to the top of dynamic linking stage 3,
before this data is made available, causing the runtime detection code
to always see __hwcap as zero and thereby select the atomics/TLS
implementations based on kuser helper.
upcoming work on superh will use similar runtime detection.
ideally this early-init code should be cleanly refactored and shared
between the dynamic linker and static-linked startup.
Diffstat (limited to 'src')
| -rw-r--r-- | src/ldso/dynlink.c | 31 | 
1 files changed, 14 insertions, 17 deletions
| diff --git a/src/ldso/dynlink.c b/src/ldso/dynlink.c index 42b056d2..71252d03 100644 --- a/src/ldso/dynlink.c +++ b/src/ldso/dynlink.c @@ -1192,6 +1192,17 @@ _Noreturn void __dls3(size_t *sp)  	char **argv_orig = argv;  	char **envp = argv+argc+1; +	/* Find aux vector just past environ[] and use it to initialize +	 * global data that may be needed before we can make syscalls. */ +	__environ = envp; +	for (i=argc+1; argv[i]; i++); +	libc.auxv = auxv = (void *)(argv+i+1); +	decode_vec(auxv, aux, AUX_CNT); +	__hwcap = aux[AT_HWCAP]; +	libc.page_size = aux[AT_PAGESZ]; +	libc.secure = ((aux[0]&0x7800)!=0x7800 || aux[AT_UID]!=aux[AT_EUID] +		|| aux[AT_GID]!=aux[AT_EGID] || aux[AT_SECURE]); +  	/* Setup early thread pointer in builtin_tls for ldso/libc itself to  	 * use during dynamic linking. If possible it will also serve as the  	 * thread pointer at runtime. */ @@ -1200,25 +1211,11 @@ _Noreturn void __dls3(size_t *sp)  		a_crash();  	} -	/* Find aux vector just past environ[] */ -	for (i=argc+1; argv[i]; i++) -		if (!memcmp(argv[i], "LD_LIBRARY_PATH=", 16)) -			env_path = argv[i]+16; -		else if (!memcmp(argv[i], "LD_PRELOAD=", 11)) -			env_preload = argv[i]+11; -	auxv = (void *)(argv+i+1); - -	decode_vec(auxv, aux, AUX_CNT); -  	/* Only trust user/env if kernel says we're not suid/sgid */ -	if ((aux[0]&0x7800)!=0x7800 || aux[AT_UID]!=aux[AT_EUID] -	  || aux[AT_GID]!=aux[AT_EGID] || aux[AT_SECURE]) { -		env_path = 0; -		env_preload = 0; -		libc.secure = 1; +	if (!libc.secure) { +		env_path = getenv("LD_LIBRARY_PATH"); +		env_preload = getenv("LD_PRELOAD");  	} -	libc.page_size = aux[AT_PAGESZ]; -	libc.auxv = auxv;  	/* If the main program was already loaded by the kernel,  	 * AT_PHDR will point to some location other than the dynamic | 
