Increase robustness of internal dlopen() by using RTLD_NOW [BZ #22766]
Commit Message
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
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?
@@ -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);