rtld: do not call into ifunc resolvers with the bind lock write-locked

If filter needs to be loader, we restart after the lock upgrade.  But
possible binds in the resolver itself would try to recurse on the lock,
which can be only done for the read locks.

PR:	286502
Sponsored by:	The FreeBSD Foundation
MFC after:	1 week
This commit is contained in:
Konstantin Belousov
2025-05-01 18:44:12 +03:00
parent bcbc19335a
commit c66c0a8479
+8 -2
View File
@@ -1040,6 +1040,7 @@ _rtld_bind(Obj_Entry *obj, Elf_Size reloff)
Elf_Addr target;
RtldLockState lockstate;
relock:
rlock_acquire(rtld_bind_lock, &lockstate);
if (sigsetjmp(lockstate.env, 0) != 0)
lock_upgrade(rtld_bind_lock, &lockstate);
@@ -1053,10 +1054,15 @@ _rtld_bind(Obj_Entry *obj, Elf_Size reloff)
NULL, &lockstate);
if (def == NULL)
rtld_die();
if (ELF_ST_TYPE(def->st_info) == STT_GNU_IFUNC)
if (ELF_ST_TYPE(def->st_info) == STT_GNU_IFUNC) {
if (lockstate_wlocked(&lockstate)) {
lock_release(rtld_bind_lock, &lockstate);
goto relock;
}
target = (Elf_Addr)rtld_resolve_ifunc(defobj, def);
else
} else {
target = (Elf_Addr)(defobj->relocbase + def->st_value);
}
dbg("\"%s\" in \"%s\" ==> %p in \"%s\"", defobj->strtab + def->st_name,
obj->path == NULL ? NULL : basename(obj->path), (void *)target,