An ifunc resolver enters _rtld_bind, which attempts to acquire _rtld_bind_lock. But since we are in the middle of dlopen, the lock has been acquired already, hence deadlocking. This is similar to bug #286502 but does not involve filter libraries. Tested on AArch64 but should be reproducible on AMD64. pthread required. Commands: cc main.c -lthr -Wl,-rpath=. -o main cc foo.c -shared -o foo.so ./main Setup: $ cat main.c #include <dlfcn.h> int main() { dlopen("foo.so", RTLD_LAZY); } $ cat foo.c #include <stdio.h> static void foo_impl() { } static void *foo_resolver() { puts("foo_resolver()"); return &foo_impl; } void foo() __attribute__((ifunc("foo_resolver"))); void (*foo_ptr)() = &foo;
Created attachment 260061 [details] libthr: implement mask for rtld locks
(In reply to Konstantin Belousov from comment #1) Thanks. Just for my own understanding, does the patch essentially permit a thread to take the same lock more than once? If so, would it still be necessary to have the lock_release/wlock_acquire pair around rtld_resolve_ifunc in reloc_gnu_ifunc_plt?
(In reply to Dapeng Gao from comment #2) In some sense, yes. We already recurse on read locks (as any r/w lock allows). Being able to rlock when wlock is already owned is also not a crime, just that most current r/w locks implementations optimizations do not allow that. But dropping rtld locks around calls into the user code is generally good, since it avoids lot of problems besides rtld own locking. So yes, my intent is to keep that unlocks. Unfortunately, it is not easy to do for the ifunc resolvers in dlopen_object().
So I concluded that the approach is too flawed to try to make it work properly. Instead I decided to fix the thr_rtld locks implementation to allow reader locks while owning the lock for write. This passed the libthr tests. https://reviews.freebsd.org/D50117
A commit in branch main references this bug: URL: https://cgit.FreeBSD.org/src/commit/?id=812c4bf3f17024f192980bbb8a781676cb9cf6b6 commit 812c4bf3f17024f192980bbb8a781676cb9cf6b6 Author: Konstantin Belousov <kib@FreeBSD.org> AuthorDate: 2025-05-02 15:09:46 +0000 Commit: Konstantin Belousov <kib@FreeBSD.org> CommitDate: 2025-05-02 18:08:09 +0000 thr_rtld: accept read lock requests while owning the lock for write PR: 286505 Reviewed by: olce Sponsored by: The FreeBSD Foundation MFC after: 1 week Differential revision: https://reviews.freebsd.org/D50117 lib/libthr/thread/thr_rtld.c | 26 +++++++++++++++++++++----- 1 file changed, 21 insertions(+), 5 deletions(-)
A commit in branch stable/14 references this bug: URL: https://cgit.FreeBSD.org/src/commit/?id=7865d159c5e1b825286777ec236b502ec1261dc0 commit 7865d159c5e1b825286777ec236b502ec1261dc0 Author: Konstantin Belousov <kib@FreeBSD.org> AuthorDate: 2025-05-02 15:09:46 +0000 Commit: Konstantin Belousov <kib@FreeBSD.org> CommitDate: 2025-05-10 18:57:45 +0000 thr_rtld: accept read lock requests while owning the lock for write PR: 286505 (cherry picked from commit 812c4bf3f17024f192980bbb8a781676cb9cf6b6) lib/libthr/thread/thr_rtld.c | 26 +++++++++++++++++++++----- 1 file changed, 21 insertions(+), 5 deletions(-)
^Triage: assign to committer who resolved.