Skip site navigation (1)Skip section navigation (2)
Date:      Tue, 13 Feb 2024 14:24:41 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: 968a18975adc - main - rtld: ignore load_filtees() calls if we already loading filtees for the obj
Message-ID:  <202402131424.41DEOfTj001389@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=968a18975adc9c2a619bb52aa2f009de99fc9e24

commit 968a18975adc9c2a619bb52aa2f009de99fc9e24
Author:     Konstantin Belousov <kib@FreeBSD.org>
AuthorDate: 2024-02-13 01:09:03 +0000
Commit:     Konstantin Belousov <kib@FreeBSD.org>
CommitDate: 2024-02-13 14:24:01 +0000

    rtld: ignore load_filtees() calls if we already loading filtees for the obj
    
    in addition to avoiding it for already loaded filtees. Issue is that
    during load, rtld needs to resolve some special ABI symbols, like
    executable stack fixer and static TLS initializer, which might trigger
    recursion.
    
    Example is libthr which is filter for libsys, and which exports
    __pthread_distribute_static_tls.
    
    Tested by:      kevans, krion
    Reviewed by:    markj
    Sponsored by:   The FreeBSD Foundation
    MFC after:      1 week
    Differential revision:  https://reviews.freebsd.org/D43858
---
 libexec/rtld-elf/rtld.c | 4 +++-
 libexec/rtld-elf/rtld.h | 1 +
 2 files changed, 4 insertions(+), 1 deletion(-)

diff --git a/libexec/rtld-elf/rtld.c b/libexec/rtld-elf/rtld.c
index dfd9e74407ed..7d6b8ae52703 100644
--- a/libexec/rtld-elf/rtld.c
+++ b/libexec/rtld-elf/rtld.c
@@ -2582,12 +2582,14 @@ load_filtee1(Obj_Entry *obj, Needed_Entry *needed, int flags,
 static void
 load_filtees(Obj_Entry *obj, int flags, RtldLockState *lockstate)
 {
-	if (obj->filtees_loaded)
+	if (obj->filtees_loaded || obj->filtees_loading)
 		return;
 	lock_restart_for_upgrade(lockstate);
+	obj->filtees_loading = true;
 	load_filtee1(obj, obj->needed_filtees, flags, lockstate);
 	load_filtee1(obj, obj->needed_aux_filtees, flags, lockstate);
 	obj->filtees_loaded = true;
+	obj->filtees_loading = false;
 }
 
 static int
diff --git a/libexec/rtld-elf/rtld.h b/libexec/rtld-elf/rtld.h
index e8b15095812b..6311b3e6cc7f 100644
--- a/libexec/rtld-elf/rtld.h
+++ b/libexec/rtld-elf/rtld.h
@@ -263,6 +263,7 @@ typedef struct Struct_Obj_Entry {
     bool on_fini_list: 1;	/* Object is already on fini list. */
     bool dag_inited : 1;	/* Object has its DAG initialized. */
     bool filtees_loaded : 1;	/* Filtees loaded */
+    bool filtees_loading : 1;	/* In process of filtees loading */
     bool irelative : 1;		/* Object has R_MACHDEP_IRELATIVE relocs */
     bool irelative_nonplt : 1;	/* Object has R_MACHDEP_IRELATIVE non-plt relocs */
     bool gnu_ifunc : 1;		/* Object has references to STT_GNU_IFUNC */



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