diff options
| author | riastradh <riastradh@NetBSD.org> | 2022-09-13 10:18:58 +0000 |
|---|---|---|
| committer | riastradh <riastradh@NetBSD.org> | 2022-09-13 10:18:58 +0000 |
| commit | aca97603f45f74ac45ea605ff8ad2fae8a3291b4 (patch) | |
| tree | 12fecabd49311360f6e2439d5df8850d9eb0b089 /libexec | |
| parent | 79072e604909e578fd9c77ace56ce0c51e523503 (diff) | |
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
Diffstat (limited to 'libexec')
| -rw-r--r-- | libexec/ld.elf_so/rtld.c | 9 |
1 files changed, 4 insertions, 5 deletions
diff --git a/libexec/ld.elf_so/rtld.c b/libexec/ld.elf_so/rtld.c index a9171d626aa..8e152d59586 100644 --- a/libexec/ld.elf_so/rtld.c +++ b/libexec/ld.elf_so/rtld.c @@ -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; } |
