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
This commit is contained in:
Konstantin Belousov 2024-02-13 03:09:03 +02:00
parent 30b5f6b33b
commit 968a18975a
2 changed files with 4 additions and 1 deletions

View file

@ -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

View file

@ -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 */