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:
parent
7a407fffcd
commit
65715c6162
|
@ -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;
|
||||
}
|
||||
|
|
Loading…
Reference in New Issue