git: c4ca9a566068 - stable/13 - rtld: ignore load_filtees() calls if we already loading filtees for the obj

From: Konstantin Belousov <kib_at_FreeBSD.org>
Date: Thu, 29 Feb 2024 00:26:17 UTC
The branch stable/13 has been updated by kib:

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

commit c4ca9a5660680109ce0f2fda4f0b5188e979cd67
Author:     Konstantin Belousov <kib@FreeBSD.org>
AuthorDate: 2024-02-13 01:09:03 +0000
Commit:     Konstantin Belousov <kib@FreeBSD.org>
CommitDate: 2024-02-29 00:24:43 +0000

    rtld: ignore load_filtees() calls if we already loading filtees for the obj
    
    (cherry picked from commit 968a18975adc9c2a619bb52aa2f009de99fc9e24)
---
 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 a4278e70e872..3ef686441fab 100644
--- a/libexec/rtld-elf/rtld.c
+++ b/libexec/rtld-elf/rtld.c
@@ -2616,12 +2616,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 3111e54a2e08..8cf8b2771a24 100644
--- a/libexec/rtld-elf/rtld.h
+++ b/libexec/rtld-elf/rtld.h
@@ -268,6 +268,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 */