Message ID | 20200626193228.1953-2-danielwa@cisco.com |
---|---|
State | New |
Headers | show |
Series | implement dlmopen hooks for gdb | expand |
On 6/26/20 3:32 PM, Daniel Walker via Libc-alpha wrote: > From: Conan C Huang <conhuang@cisco.com> > > GLIBC Bugzilla: 18684 > > When a dlmopenend library calls dlopen with RTLD_GLOBAL flag, > dynamic loader segfaults. Loader is trying to add new linkmap into > new namespaces _ns_main_searchlist. But this _ns_main_searchlist is > not initialized during dmopen call (when namespace was created). > > Loader needs to initialize _ns_main_searchlist during dlmopen when a > new namespace is created. As well as clean up when that namespace is > deleted. This implies that dlopen with RTLD_GLOBAL in a namespace applies only to the global symbols of that namespace and that it does not promote such a dlopen to the actual LM_ID_BASE global symbols. Please see similar discussions about this from 2015: https://sourceware.org/legacy-ml/libc-alpha/2015-07/msg00474.html This will need tests to verify the change in behaviour is as we expect. > --- > elf/dl-close.c | 7 ++++++- > elf/dl-open.c | 4 ++++ > 2 files changed, 10 insertions(+), 1 deletion(-) > > diff --git a/elf/dl-close.c b/elf/dl-close.c > index 73b2817bbf..675f2fbac8 100644 > --- a/elf/dl-close.c > +++ b/elf/dl-close.c > @@ -802,7 +802,12 @@ _dl_close_worker (struct link_map *map, bool force) > if (__builtin_expect (ns->_ns_loaded == NULL, 0) > && nsid == GL(dl_nns) - 1) > do > - --GL(dl_nns); > + { > + --GL(dl_nns); > + > + /* Clear main search list */ > + GL(dl_ns)[GL(dl_nns)]._ns_main_searchlist = NULL; > + } > while (GL(dl_ns)[GL(dl_nns) - 1]._ns_loaded == NULL); > > /* Notify the debugger those objects are finalized and gone. */ > diff --git a/elf/dl-open.c b/elf/dl-open.c > index 8769e47051..9b3606c491 100644 > --- a/elf/dl-open.c > +++ b/elf/dl-open.c > @@ -921,6 +921,10 @@ no more namespaces available for dlmopen()")); > > assert (_dl_debug_initialize (0, args.nsid)->r_state == RT_CONSISTENT); > > + /* Initialize main search list in new namespace */ > + if (__glibc_unlikely (GL(dl_ns)[nsid]._ns_main_searchlist == NULL)) > + GL(dl_ns)[nsid]._ns_main_searchlist = &(args.map->l_searchlist); > + > /* Release the lock. */ > __rtld_lock_unlock_recursive (GL(dl_load_lock)); > >
diff --git a/elf/dl-close.c b/elf/dl-close.c index 73b2817bbf..675f2fbac8 100644 --- a/elf/dl-close.c +++ b/elf/dl-close.c @@ -802,7 +802,12 @@ _dl_close_worker (struct link_map *map, bool force) if (__builtin_expect (ns->_ns_loaded == NULL, 0) && nsid == GL(dl_nns) - 1) do - --GL(dl_nns); + { + --GL(dl_nns); + + /* Clear main search list */ + GL(dl_ns)[GL(dl_nns)]._ns_main_searchlist = NULL; + } while (GL(dl_ns)[GL(dl_nns) - 1]._ns_loaded == NULL); /* Notify the debugger those objects are finalized and gone. */ diff --git a/elf/dl-open.c b/elf/dl-open.c index 8769e47051..9b3606c491 100644 --- a/elf/dl-open.c +++ b/elf/dl-open.c @@ -921,6 +921,10 @@ no more namespaces available for dlmopen()")); assert (_dl_debug_initialize (0, args.nsid)->r_state == RT_CONSISTENT); + /* Initialize main search list in new namespace */ + if (__glibc_unlikely (GL(dl_ns)[nsid]._ns_main_searchlist == NULL)) + GL(dl_ns)[nsid]._ns_main_searchlist = &(args.map->l_searchlist); + /* Release the lock. */ __rtld_lock_unlock_recursive (GL(dl_load_lock));
From: Conan C Huang <conhuang@cisco.com> GLIBC Bugzilla: 18684 When a dlmopenend library calls dlopen with RTLD_GLOBAL flag, dynamic loader segfaults. Loader is trying to add new linkmap into new namespaces _ns_main_searchlist. But this _ns_main_searchlist is not initialized during dmopen call (when namespace was created). Loader needs to initialize _ns_main_searchlist during dlmopen when a new namespace is created. As well as clean up when that namespace is deleted. --- elf/dl-close.c | 7 ++++++- elf/dl-open.c | 4 ++++ 2 files changed, 10 insertions(+), 1 deletion(-)