Skip site navigation (1)Skip section navigation (2)
Date:      24 Feb 2002 00:21:49 +0100
From:      Dag-Erling Smorgrav <des@ofug.org>
To:        arch@freebsd.org
Subject:   bin/25059 (rtld bug)
Message-ID:  <xzpu1s7n5rm.fsf@flood.ping.uio.no>

next in thread | raw e-mail | index | archive | help
--=-=-=

Our dlopen(3) man page states:

     RTLD_GLOBAL   Symbols from this shared object and its directed acyclic
                   graph (DAG) of needed objects will be available for resolv
                   ing undefined references from all other shared objects.

but this is a lie - only the object itself is searched, not its DAG.

The attached patch fixes this by adding a flag to the Obj_Entry
structure that marks an object as global, and changing symlook_list()
to search each global object's DAG if the object itself doesn't have
the requested symbol.  With this patch applied, the test program
referenced in the PR works.

(some might argue that symlook_obj() should be changed instead - but
changing symlook_list() was simpler, and the only difference it makes
is, in the worst case, a slightly longer search)

DES
-- 
Dag-Erling Smorgrav - des@ofug.org


--=-=-=
Content-Type: text/x-patch
Content-Disposition: attachment; filename=rtld.diff

Index: rtld.c
===================================================================
RCS file: /home/ncvs/src/libexec/rtld-elf/rtld.c,v
retrieving revision 1.60
diff -u -r1.60 rtld.c
--- rtld.c	17 Feb 2002 07:00:25 -0000	1.60
+++ rtld.c	23 Feb 2002 23:21:28 -0000
@@ -1329,6 +1329,7 @@
     elm = NEW(Objlist_Entry);
     elm->obj = obj;
     STAILQ_INSERT_TAIL(list, elm, link);
+    obj->global = true;
 }
 
 static void
@@ -1581,7 +1582,7 @@
 
     if (obj) {
 	obj->dl_refcount++;
-	if (mode & RTLD_GLOBAL && objlist_find(&list_global, obj) == NULL)
+	if (mode & RTLD_GLOBAL && !obj->global)
 	    objlist_push_tail(&list_global, obj);
 	mode &= RTLD_MODEMASK;
 	if (*old_obj_tail != NULL) {		/* We loaded something new. */
@@ -1915,7 +1916,7 @@
 	}
     }
 
-    /* Search all RTLD_GLOBAL objects. */
+    /* Search all RTLD_GLOBAL objects and their DAGs. */
     if (def == NULL || ELF_ST_BIND(def->st_info) == STB_WEAK) {
 	symp = symlook_list(name, hash, &list_global, &obj, in_plt, &donelist);
 	if (symp != NULL &&
@@ -1965,6 +1966,12 @@
 		if (ELF_ST_BIND(def->st_info) != STB_WEAK)
 		    break;
 	    }
+	} else if (elm->obj->global) {
+	    /* search the DAGs of global objects */
+	    symp = symlook_list(name, hash, &elm->obj->dagmembers,
+	      defobj_out, in_plt, dlp);
+	    if (symp != NULL)
+		return symp;
 	}
     }
     if (def != NULL)
Index: rtld.h
===================================================================
RCS file: /home/ncvs/src/libexec/rtld-elf/rtld.h,v
retrieving revision 1.24
diff -u -r1.24 rtld.h
--- rtld.h	29 Oct 2001 10:10:02 -0000	1.24
+++ rtld.h	23 Feb 2002 23:02:18 -0000
@@ -155,6 +155,7 @@
     bool traced;		/* Already printed in ldd trace output */
     bool jmpslots_done;		/* Already have relocated the jump slots */
     bool init_done;		/* Already have added object to init list */
+    bool global;		/* This object is on the global list */
 
     struct link_map linkmap;	/* for GDB */
     Objlist dldags;		/* Object belongs to these dlopened DAGs (%) */

--=-=-=--

To Unsubscribe: send mail to majordomo@FreeBSD.org
with "unsubscribe freebsd-arch" in the body of the message




Want to link to this message? Use this URL: <https://mail-archive.FreeBSD.org/cgi/mid.cgi?xzpu1s7n5rm.fsf>