Increase robustness of internal dlopen() by using RTLD_NOW [BZ #22766]

Message ID 20180425124256.6562-1-tuliom@linux.ibm.com
State Superseded
Delegated to: Carlos O'Donell
Headers

Commit Message

Tulio Magno Quites Machado Filho April 25, 2018, 12:42 p.m. UTC
  Prevent random runtime crashes due to missing symbols caused by mixed
libnss_* versions.

2018-04-25  Tulio Magno Quites Machado Filho  <tuliom@linux.ibm.com>

	[BZ #22766]
	* include/dlfcn.h [__libc_dl_open]: Replace RTLD_LAZY with RTLD_NOW.

Signed-off-by: Tulio Magno Quites Machado Filho <tuliom@linux.ibm.com>
---
 include/dlfcn.h | 2 +-
 1 file changed, 1 insertion(+), 1 deletion(-)
  

Comments

Carlos O'Donell April 25, 2018, 1:08 p.m. UTC | #1
On 04/25/2018 07:42 AM, Tulio Magno Quites Machado Filho wrote:
> Prevent random runtime crashes due to missing symbols caused by mixed
> libnss_* versions.

You are arguing that this should fail at the first call into the NSS
service, which causes the initial dlopen? That is OK with me.

An even further patch would be to load all NSS modules early, and that's
something Florian and I have discussed. However, I'm not recommending
you do that now, but I wanted to be clear about a direction that this
code might take. Eventually we need a mechanism that will also work for
static applications since we have deprecated dlopen there, but I'm not
sure what Florian's ideas might be in this area.

> 2018-04-25  Tulio Magno Quites Machado Filho  <tuliom@linux.ibm.com>
> 
> 	[BZ #22766]
> 	* include/dlfcn.h [__libc_dl_open]: Replace RTLD_LAZY with RTLD_NOW.
> 
> Signed-off-by: Tulio Magno Quites Machado Filho <tuliom@linux.ibm.com>
> ---
>  include/dlfcn.h | 2 +-
>  1 file changed, 1 insertion(+), 1 deletion(-)
> 
> diff --git a/include/dlfcn.h b/include/dlfcn.h
> index 12ef913e19..2c4bfe86b4 100644
> --- a/include/dlfcn.h
> +++ b/include/dlfcn.h
> @@ -32,7 +32,7 @@ extern char **__libc_argv attribute_hidden;
>  /* Now define the internal interfaces.  */
>  
>  #define __libc_dlopen(name) \
> -  __libc_dlopen_mode (name, RTLD_LAZY | __RTLD_DLOPEN)
> +  __libc_dlopen_mode (name, RTLD_NOW | __RTLD_DLOPEN)
>  extern void *__libc_dlopen_mode  (const char *__name, int __mode);
>  extern void *__libc_dlsym   (void *__map, const char *__name);
>  extern void *__libc_dlvsym (void *map, const char *name, const char *version);
> 

We should cleanup more.

sysdeps/gnu/unwind-resume.c:  handle = __libc_dlopen_mode (LIBGCC_S_SO, RTLD_NOW | __RTLD_DLOPEN);
sysdeps/nptl/unwind-forcedunwind.c:  handle = __libc_dlopen_mode (LIBGCC_S_SO, RTLD_NOW | __RTLD_DLOPEN);

Since we are now using RTLD_NOW:

* Switch back to __libc_dlopen (effectively reverting part of 
  Florian's 08c6e95234c, but leave the comments)
* Add a big comment in dlfcn.h to explain why RTLD_NOW is needed:
  * Same comment as in commit 08c6e95234c, plus NSS case.

Thoughts?
  

Patch

diff --git a/include/dlfcn.h b/include/dlfcn.h
index 12ef913e19..2c4bfe86b4 100644
--- a/include/dlfcn.h
+++ b/include/dlfcn.h
@@ -32,7 +32,7 @@  extern char **__libc_argv attribute_hidden;
 /* Now define the internal interfaces.  */
 
 #define __libc_dlopen(name) \
-  __libc_dlopen_mode (name, RTLD_LAZY | __RTLD_DLOPEN)
+  __libc_dlopen_mode (name, RTLD_NOW | __RTLD_DLOPEN)
 extern void *__libc_dlopen_mode  (const char *__name, int __mode);
 extern void *__libc_dlsym   (void *__map, const char *__name);
 extern void *__libc_dlvsym (void *map, const char *name, const char *version);