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:
@@ -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,
|
||||
|
||||
Reference in New Issue
Block a user