[PATCH] ldso: fix dlsym hang when reloading DSOs
Carmelo AMOROSO
carmelo.amoroso at st.com
Thu Jun 27 10:03:08 UTC 2013
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.teras at iki.fi>
Acked-by: Carmelo Amoroso <carmelo.amoroso at 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__
> /*
>
More information about the uClibc
mailing list