Skip site navigation (1)Skip section navigation (2)
Date:      Mon, 29 Jul 2024 23:58:59 GMT
From:      Konstantin Belousov <kib@FreeBSD.org>
To:        src-committers@FreeBSD.org, dev-commits-src-all@FreeBSD.org, dev-commits-src-main@FreeBSD.org
Subject:   git: 860c4d94ac46 - main - rtld: add LD_NO_DL_ITERATE_PHDR_AFTER_FORK env var
Message-ID:  <202407292358.46TNwx6r051708@gitrepo.freebsd.org>

next in thread | raw e-mail | index | archive | help
The branch main has been updated by kib:

URL: https://cgit.FreeBSD.org/src/commit/?id=860c4d94ac46cee35a678cf3c9cdbd437dfed75e

commit 860c4d94ac46cee35a678cf3c9cdbd437dfed75e
Author:     Konstantin Belousov <kib@FreeBSD.org>
AuthorDate: 2024-07-17 04:05:33 +0000
Commit:     Konstantin Belousov <kib@FreeBSD.org>
CommitDate: 2024-07-29 23:57:33 +0000

    rtld: add LD_NO_DL_ITERATE_PHDR_AFTER_FORK env var
    
    which makes threaded fork ignore the phdr rtld lock, in particular
    allowing the dl_iterate_phdr() to block in callback.  The cost is that
    the image started in this mode cannot use dl_iterate_phdr() after fork.
    
    PR:     280318
    Sponsored by:   The FreeBSD Foundation
    MFC after:      1 week
---
 libexec/rtld-elf/rtld.1      | 10 +++++++++-
 libexec/rtld-elf/rtld.c      |  1 +
 libexec/rtld-elf/rtld.h      |  1 +
 libexec/rtld-elf/rtld_lock.c |  7 +++++--
 4 files changed, 16 insertions(+), 3 deletions(-)

diff --git a/libexec/rtld-elf/rtld.1 b/libexec/rtld-elf/rtld.1
index 992138b1ffc0..31e046a5cdc4 100644
--- a/libexec/rtld-elf/rtld.1
+++ b/libexec/rtld-elf/rtld.1
@@ -26,7 +26,7 @@
 .\" (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
 .\" THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
 .\"
-.Dd April 28, 2024
+.Dd July 24, 2025
 .Dt RTLD 1
 .Os
 .Sh NAME
@@ -329,6 +329,14 @@ The static TLS extra space is used when loading objects compiled for
 initial-exec TLS code model with
 .Xr dlopen 3 .
 The minimum value that can be specified is \'128\'.
+.It Ev LD_NO_DL_ITERATE_PHDR_AFTER_FORK
+Allow
+.Xr dl_iterate_phdr 3
+to block in callback, without causing deadlock with the
+.Xr fork 2 .
+The drawback is that the image started in this mode cannot use
+.Xr dl_iterate_phdr 3
+after fork.
 .El
 .Sh DIRECT EXECUTION MODE
 .Nm
diff --git a/libexec/rtld-elf/rtld.c b/libexec/rtld-elf/rtld.c
index f49c429d0061..1f0c59722ac6 100644
--- a/libexec/rtld-elf/rtld.c
+++ b/libexec/rtld-elf/rtld.c
@@ -375,6 +375,7 @@ static struct ld_env_var_desc ld_env_vars[] = {
 	LD_ENV_DESC(TRACE_LOADED_OBJECTS_ALL, false),
 	LD_ENV_DESC(SHOW_AUXV, false),
 	LD_ENV_DESC(STATIC_TLS_EXTRA, false),
+	LD_ENV_DESC(NO_DL_ITERATE_PHDR_AFTER_FORK, false),
 };
 
 const char *
diff --git a/libexec/rtld-elf/rtld.h b/libexec/rtld-elf/rtld.h
index fcd42f3841b3..656e980c6261 100644
--- a/libexec/rtld-elf/rtld.h
+++ b/libexec/rtld-elf/rtld.h
@@ -376,6 +376,7 @@ enum {
 	LD_TRACE_LOADED_OBJECTS_ALL,
 	LD_SHOW_AUXV,
 	LD_STATIC_TLS_EXTRA,
+	LD_NO_DL_ITERATE_PHDR_AFTER_FORK,
 };
 
 void _rtld_error(const char *, ...) __printflike(1, 2) __exported;
diff --git a/libexec/rtld-elf/rtld_lock.c b/libexec/rtld-elf/rtld_lock.c
index 0c790450dcec..323bb7494c32 100644
--- a/libexec/rtld-elf/rtld_lock.c
+++ b/libexec/rtld-elf/rtld_lock.c
@@ -463,6 +463,7 @@ _rtld_atfork_pre(int *locks)
 
 	if (locks == NULL)
 		return;
+	bzero(ls, sizeof(ls));
 
 	/*
 	 * Warning: this did not worked well with the rtld compat
@@ -472,7 +473,8 @@ _rtld_atfork_pre(int *locks)
 	 * _rtld_atfork_pre() must provide the working implementation
 	 * of the locks anyway, and libthr locks are fine.
 	 */
-	wlock_acquire(rtld_phdr_lock, &ls[0]);
+	if (ld_get_env_var(LD_NO_DL_ITERATE_PHDR_AFTER_FORK) == NULL)
+		wlock_acquire(rtld_phdr_lock, &ls[0]);
 	wlock_acquire(rtld_bind_lock, &ls[1]);
 
 	/* XXXKIB: I am really sorry for this. */
@@ -492,5 +494,6 @@ _rtld_atfork_post(int *locks)
 	ls[0].lockstate = locks[2];
 	ls[1].lockstate = locks[0];
 	lock_release(rtld_bind_lock, &ls[1]);
-	lock_release(rtld_phdr_lock, &ls[0]);
+	if (ld_get_env_var(LD_NO_DL_ITERATE_PHDR_AFTER_FORK) == NULL)
+		lock_release(rtld_phdr_lock, &ls[0]);
 }



Want to link to this message? Use this URL: <https://mail-archive.FreeBSD.org/cgi/mid.cgi?202407292358.46TNwx6r051708>