[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