rtld: add LD_NO_DL_ITERATE_PHDR_AFTER_FORK env var

PR:	280318

(cherry picked from commit 860c4d94ac46cee35a678cf3c9cdbd437dfed75e)
This commit is contained in:
Konstantin Belousov 2024-07-17 07:05:33 +03:00
parent da32a0616b
commit 279e543dc7
4 changed files with 16 additions and 3 deletions

View file

@ -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

View file

@ -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 *

View file

@ -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;

View file

@ -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]);
}