git: 279e543dc707 - stable/14 - rtld: add LD_NO_DL_ITERATE_PHDR_AFTER_FORK env var
- Go to: [ bottom of page ] [ top of archives ] [ this month ]
Date: Mon, 05 Aug 2024 00:32:42 UTC
The branch stable/14 has been updated by kib:
URL: https://cgit.FreeBSD.org/src/commit/?id=279e543dc707ee19b28cee8a00deafea1f8b8d8e
commit 279e543dc707ee19b28cee8a00deafea1f8b8d8e
Author: Konstantin Belousov <kib@FreeBSD.org>
AuthorDate: 2024-07-17 04:05:33 +0000
Commit: Konstantin Belousov <kib@FreeBSD.org>
CommitDate: 2024-08-05 00:32:11 +0000
rtld: add LD_NO_DL_ITERATE_PHDR_AFTER_FORK env var
PR: 280318
(cherry picked from commit 860c4d94ac46cee35a678cf3c9cdbd437dfed75e)
---
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 411fe7956873..e7fcfde8f474 100644
--- a/libexec/rtld-elf/rtld.c
+++ b/libexec/rtld-elf/rtld.c
@@ -376,6 +376,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 96a9da3c4ea3..97187b24ce84 100644
--- a/libexec/rtld-elf/rtld.h
+++ b/libexec/rtld-elf/rtld.h
@@ -383,6 +383,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]);
}