Skip site navigation (1)Skip section navigation (2)
Date:      Sun, 16 Jul 2023 12:34:51 GMT
From:      Konstantin Belousov <kib@FreeBSD.org>
To:        src-committers@FreeBSD.org, dev-commits-src-all@FreeBSD.org, dev-commits-src-main@FreeBSD.org
Subject:   git: 1005d3d05362 - main - rtld: fix dlopen() for an object that is already mapped but not yet initialized
Message-ID:  <202307161234.36GCYplB082296@gitrepo.freebsd.org>

next in thread | raw e-mail | index | archive | help
The branch main has been updated by kib:

URL: https://cgit.FreeBSD.org/src/commit/?id=1005d3d05362de368b1ea7aeb8eb20cee993e122

commit 1005d3d05362de368b1ea7aeb8eb20cee993e122
Author:     Konstantin Belousov <kib@FreeBSD.org>
AuthorDate: 2023-07-14 13:38:03 +0000
Commit:     Konstantin Belousov <kib@FreeBSD.org>
CommitDate: 2023-07-16 12:34:34 +0000

    rtld: fix dlopen() for an object that is already mapped but not yet initialized
    
    For instance, dso might be mapped as needed but not yet initialized from
    the other subtree of needed objects, while current object' constructor
    does dlopen() for the dso.  Right now rtld does relocations and other
    processing based on the arrival of new objects in the global list, which
    is not happens there.  Directly check for the initialization state of
    the object, for which we would return the handle.
    
    One practical use case of this support is e.g. dlopen("libthr.so",
    RTLD_NOLOAD) by libraries that are threading-aware but happy to live
    with libc pthread shims if the program is not multithreaded.
    
    Reviewed by:    tijl
    Sponsored by:   The FreeBSD Foundation
    MFC after:      2 weeks
---
 libexec/rtld-elf/rtld.c | 8 +++-----
 1 file changed, 3 insertions(+), 5 deletions(-)

diff --git a/libexec/rtld-elf/rtld.c b/libexec/rtld-elf/rtld.c
index 5c96405be62c..83315d5023ba 100644
--- a/libexec/rtld-elf/rtld.c
+++ b/libexec/rtld-elf/rtld.c
@@ -3714,7 +3714,6 @@ static Obj_Entry *
 dlopen_object(const char *name, int fd, Obj_Entry *refobj, int lo_flags,
     int mode, RtldLockState *lockstate)
 {
-    Obj_Entry *old_obj_tail;
     Obj_Entry *obj;
     Objlist initlist;
     RtldLockState mlockstate;
@@ -3731,7 +3730,6 @@ dlopen_object(const char *name, int fd, Obj_Entry *refobj, int lo_flags,
     }
     GDB_STATE(RT_ADD,NULL);
 
-    old_obj_tail = globallist_curr(TAILQ_LAST(&obj_list, obj_entry_q));
     obj = NULL;
     if (name == NULL && fd == -1) {
 	obj = obj_main;
@@ -3744,9 +3742,9 @@ dlopen_object(const char *name, int fd, Obj_Entry *refobj, int lo_flags,
 	obj->dl_refcount++;
 	if (mode & RTLD_GLOBAL && objlist_find(&list_global, obj) == NULL)
 	    objlist_push_tail(&list_global, obj);
-	if (globallist_next(old_obj_tail) != NULL) {
-	    /* We loaded something new. */
-	    assert(globallist_next(old_obj_tail) == obj);
+
+	if (!obj->init_done) {
+	    /* We loaded something new and have to init something. */
 	    if ((lo_flags & RTLD_LO_DEEPBIND) != 0)
 		obj->symbolic = true;
 	    result = 0;



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