From: Todd C. Miller Date: Wed, 9 May 2012 13:46:38 +0000 (-0400) Subject: Implement RTLD_NEXT and fix RTLD_DEFAULT for HP-UX. X-Git-Tag: SUDO_1_8_5~1^2~9 X-Git-Url: https://granicus.if.org/sourcecode?a=commitdiff_plain;h=aa7ac09faaf76cf7b49f4d367fde33c4e216f06b;p=sudo Implement RTLD_NEXT and fix RTLD_DEFAULT for HP-UX. --- diff --git a/compat/dlopen.c b/compat/dlopen.c index 73c7a9440..f5f62feb3 100644 --- a/compat/dlopen.c +++ b/compat/dlopen.c @@ -77,13 +77,26 @@ sudo_dlsym(void *vhandle, const char *symbol) shl_t handle = vhandle; void *value = NULL; - /* RTLD_NEXT is not unsupported with shl_findsym(). */ - if (vhandle == RTLD_DEFAULT) - (void)shl_findsym(NULL, symbol, TYPE_UNDEFINED, &value); - else if (vhandle == RTLD_SELF) - (void)shl_findsym(PROG_HANDLE, symbol, TYPE_UNDEFINED, &value); - else if (vhandle != RTLD_NEXT) + /* + * Note that the behavior of of RTLD_NEXT and RTLD_SELF + * differs from most implementations when called from + * a shared library. + */ + if (vhandle == RTLD_NEXT) { + /* Iterate over all shared libs looking for symbol. */ + struct shl_descriptor *desc; + int idx = 0; + while (shl_get(idx++, &desc) == 0) { + if (shl_findsym(&desc->handle, symbol, TYPE_UNDEFINED, &value) == 0) + break; + } + } else { + if (vhandle == RTLD_DEFAULT) + handle = NULL; + else if (vhandle == RTLD_SELF) + handle = PROG_HANDLE; (void)shl_findsym(&handle, symbol, TYPE_UNDEFINED, &value); + } return value; }