git: ef758b59a44e - main - rtld: release rtld_bind_lock around calls to .preinit_array initializers
- Go to: [ bottom of page ] [ top of archives ] [ this month ]
Date: Sat, 10 Oct 2026 17:03:36 UTC
The branch main has been updated by kib:
URL: https://cgit.FreeBSD.org/src/commit/?id=ef758b59a44e6b5b2d2dc178b97c01cde1b34570
commit ef758b59a44e6b5b2d2dc178b97c01cde1b34570
Author: Konstantin Belousov <kib@FreeBSD.org>
AuthorDate: 2026-10-10 15:05:55 +0000
Commit: Konstantin Belousov <kib@FreeBSD.org>
CommitDate: 2026-10-10 17:03:01 +0000
rtld: release rtld_bind_lock around calls to .preinit_array initializers
We unlock the bind lock around .init calls anyway. Also, the main
object cannot be unloaded.
Reported and reviewed by: dim
PR: 298943
Sponsored by: The FreeBSD Foundation
MFC after: 1 week
Differential revision: https://reviews.freebsd.org/D60588
---
libexec/rtld-elf/rtld.c | 8 +++++---
1 file changed, 5 insertions(+), 3 deletions(-)
diff --git a/libexec/rtld-elf/rtld.c b/libexec/rtld-elf/rtld.c
index c64fb689276d..b637a3032218 100644
--- a/libexec/rtld-elf/rtld.c
+++ b/libexec/rtld-elf/rtld.c
@@ -187,7 +187,7 @@ static char *origin_subst_one(Obj_Entry *, char *, const char *, const char *,
bool);
static char *origin_subst(Obj_Entry *, const char *);
static bool obj_resolve_origin(Obj_Entry *obj);
-static void preinit_main(void);
+static void preinit_main(RtldLockState *lockstate);
static void rtld_recalc_bind_not(const char *);
static void rtld_recalc_dangerous_ld_env(void);
static void rtld_recalc_debug(const char *);
@@ -1005,7 +1005,7 @@ _rtld(Elf_Addr *sp, func_ptr_type *exit_proc, Obj_Entry **objp)
rtld_exit_ptr = rtld_exit;
if (obj_main->crt_no_init)
- preinit_main();
+ preinit_main(&lockstate);
objlist_call_init(&initlist, &lockstate);
_r_debug_postinit(&obj_main->linkmap);
objlist_clear(&initlist);
@@ -3122,7 +3122,7 @@ obj_from_addr(const void *addr)
}
static void
-preinit_main(void)
+preinit_main(RtldLockState *lockstate)
{
uintptr_t *preinit_addr;
int index;
@@ -3131,6 +3131,7 @@ preinit_main(void)
if (preinit_addr == NULL)
return;
+ lock_release(rtld_bind_lock, lockstate);
for (index = 0; index < obj_main->preinit_array_num; index++) {
if (preinit_addr[index] != 0 && preinit_addr[index] != 1) {
dbg("calling preinit function for %s at %p",
@@ -3140,6 +3141,7 @@ preinit_main(void)
call_init_pointer(obj_main, preinit_addr[index]);
}
}
+ wlock_acquire(rtld_bind_lock, lockstate);
}
/*