It can happen under certain cases that the DSO had refcount 0,
but was already loaded. (NODELETE flag is set, or it is pulled
in via both NEEDED dependency and explicit dlopen()).

In these cases we must not re-add the DSO to the global symbol
scope as it is already there. Or we end up corrupting the linked
list and further dlsym lookups will hang.

Signed-off-by: Timo Teräs <timo.te...@iki.fi>
---
 ldso/libdl/libdl.c | 18 +++++++++++++-----
 1 file changed, 13 insertions(+), 5 deletions(-)

diff --git a/ldso/libdl/libdl.c b/ldso/libdl/libdl.c
index c451b63..c901512 100644
--- a/ldso/libdl/libdl.c
+++ b/ldso/libdl/libdl.c
@@ -543,15 +543,23 @@ static void *do_dlopen(const char *libname, int flag, 
ElfW(Addr) from)
 
 #ifdef SHARED
        /*
-        * Get the tail of the list.
         * In the static case doesn't need to extend the global scope, it is
         * ready to be used as it is, because _dl_loaded_modules already points
         * to the dlopened library.
+        *
+        * Extend the global scope by adding the local scope of the dlopened 
DSO.
+        * But only if it's not there. It can happen under certain cases that 
the
+        * DSO had refcount = 0, but was already loaded. (NODELETE flag is set, 
or
+        * it is pulled in via both NEEDED dependency and explicit dlopen()).
         */
-       for (ls = &_dl_loaded_modules->symbol_scope; ls && ls->next; ls = 
ls->next);
-
-       /* Extend the global scope by adding the local scope of the dlopened 
DSO. */
-       ls->next = &dyn_chain->dyn->symbol_scope;
+       for (ls = &_dl_loaded_modules->symbol_scope; ; ls = ls->next) {
+               if (ls == &dyn_chain->dyn->symbol_scope)
+                       break;
+               if (ls->next == NULL) {
+                       ls->next = &dyn_chain->dyn->symbol_scope;
+                       break;
+               }
+       }
 #endif
 #ifdef __mips__
        /*
-- 
1.8.3.1

_______________________________________________
uClibc mailing list
uClibc@uclibc.org
http://lists.busybox.net/mailman/listinfo/uclibc

Reply via email to