dlsym call fails

Kevin Cernekee cernekee at gmail.com
Fri Jul 22 01:36:57 UTC 2011


On Thu, Jul 21, 2011 at 2:52 AM, manish kumar <deliver2manish at gmail.com> wrote:
>        if(!libc_malloc)
>                libc_malloc = (void *(*)(size_t))dlsym(RTLD_NEXT, "malloc"); dlerror();

You probably want braces here, but that is not a likely cause of the
reported problem.

I have seen cases where uClibc dlsym(RTLD_NEXT, ...) will find an
undefined symbol and return an unusable pointer.  I suspect that this
is not the behavior intended by the authors.  For example, on an
application linked with these libraries:

$ readelf -s libuClibc-0.9.32.so  | grep -E "\<malloc\>"
  1225: 00036c90  2488 FUNC    GLOBAL DEFAULT    7 malloc

$ readelf -s libfoo.so  | grep malloc
    74: 00003140     0 FUNC    GLOBAL DEFAULT  UND malloc

dlsym(RTLD_NEXT, ...) might find the libfoo entry instead of the
libuClibc entry.  The returned pointer will not really reach malloc().

I noticed that when dlsym() calls _dl_find_hash(), it uses type_class
0.  If it used type_class ELF_RTYPE_CLASS_DLSYM that would make more
sense to me (although it would not fix this problem), because nobody
else seems to pass in ELF_RTYPE_CLASS_DLSYM.  If it used type_class
ELF_RTYPE_CLASS_PLT I do suspect it would fix your problem, but it
might break other things like data references.  check_match() will not
match an undefined symbol, as long as (type_class & 1) == 1.

Would it be safe to pass in a bitmask of the desired types?  ala:

diff --git a/ldso/libdl/libdl.c b/ldso/libdl/libdl.c
index 52c77b0..e256f86 100644
--- a/ldso/libdl/libdl.c
+++ b/ldso/libdl/libdl.c
@@ -667,7 +667,7 @@ void *dlsym(void *vhandle, const char *name)
        tpnt = NULL;
        if (handle == _dl_symbol_tables)
                tpnt = handle->dyn; /* Only search RTLD_GLOBAL objs if
global object */
-       ret = _dl_find_hash(name2, handle, tpnt, 0, &sym_ref);
+       ret = _dl_find_hash(name2, handle, tpnt, ELF_RTYPE_CLASS_PLT |
ELF_RTYPE_CLASS_COPY, &sym_ref);

 #if defined(USE_TLS) && USE_TLS && defined SHARED
        if (sym_ref.tpnt) {


More information about the uClibc mailing list