On 27/06/2013 8.34, Timo Teräs wrote: > 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>
Acked-by: Carmelo Amoroso <carmelo.amor...@st.com> Cheers, Carmelo > --- > 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__ > /* > _______________________________________________ uClibc mailing list uClibc@uclibc.org http://lists.busybox.net/mailman/listinfo/uclibc