ld.elf_so(8): Make fork take a shared, not exclusive, lock.

We only need to ensure that there are no concurrent modifications to
the rtld data structures in flight, since the threads that began
those modifications will not exist in the child and will therefore be
unable to complete them in the child.

A shared lock suffices to ensure there are no such concurrent
modifications in flight; an exclusive lock is not necessary, and can
cause deadlock if fork is executed from a signal handler, which is
explicitly allowed by POSIX (and our own sigaction(2) man page) which
marks fork as async-signal-safe.

PR lib/56979
This commit is contained in:
riastradh 2022-09-13 10:18:58 +00:00
parent 7a407fffcd
commit 65715c6162
1 changed files with 4 additions and 5 deletions

View File

@ -1,4 +1,4 @@
/* $NetBSD: rtld.c,v 1.211 2022/04/09 23:39:07 riastradh Exp $ */
/* $NetBSD: rtld.c,v 1.212 2022/09/13 10:18:58 riastradh Exp $ */
/*
* Copyright 1996 John D. Polstra.
@ -40,7 +40,7 @@
#include <sys/cdefs.h>
#ifndef lint
__RCSID("$NetBSD: rtld.c,v 1.211 2022/04/09 23:39:07 riastradh Exp $");
__RCSID("$NetBSD: rtld.c,v 1.212 2022/09/13 10:18:58 riastradh Exp $");
#endif /* not lint */
#include <sys/param.h>
@ -1539,14 +1539,13 @@ pid_t __fork(void);
__dso_public pid_t
__locked_fork(int *my_errno)
{
sigset_t mask;
pid_t result;
_rtld_exclusive_enter(&mask);
_rtld_shared_enter();
result = __fork();
if (result == -1)
*my_errno = errno;
_rtld_exclusive_exit(&mask);
_rtld_shared_exit();
return result;
}