Module Name: src Committed By: martin Date: Wed May 13 18:08:38 UTC 2020
Modified Files: src/lib/libc/gen [netbsd-9]: pthread_atfork.c src/libexec/ld.elf_so [netbsd-9]: rtld.c rtld.h symbols.map Log Message: Pull up following revision(s) (requested by chs in ticket #907): libexec/ld.elf_so/rtld.c: revision 1.205 libexec/ld.elf_so/rtld.h: revision 1.140 libexec/ld.elf_so/symbols.map: revision 1.3 libexec/ld.elf_so/symbols.map: revision 1.4 lib/libc/gen/pthread_atfork.c: revision 1.13 lib/libc/gen/pthread_atfork.c: revision 1.14 libexec/ld.elf_so/rtld.h: revision 1.139 libexec/ld.elf_so/rtld.c: revision 1.204 Introduce intermediate locking for fork, so that the dynamic linker is in a consistent state. This most importantly avoids races between dlopen and friends and fork, potentially resulting in dead locks in the child when it itself tries to acquire locks. Rename __atomic_fork to __locked_fork and give it &errno as argument. rtld and libc use different storage, so the initial version would incorrectly report the failure reason for fork(). There is still a small race condition inside ld.elf_so as it doesn't use thread-safe errno internally, but that's a more contained internal issue. To generate a diff of this commit: cvs rdiff -u -r1.10 -r1.10.18.1 src/lib/libc/gen/pthread_atfork.c cvs rdiff -u -r1.197.2.3 -r1.197.2.4 src/libexec/ld.elf_so/rtld.c cvs rdiff -u -r1.136 -r1.136.2.1 src/libexec/ld.elf_so/rtld.h cvs rdiff -u -r1.2 -r1.2.8.1 src/libexec/ld.elf_so/symbols.map Please note that diffs are not public domain; they are subject to the copyright notices on the relevant files.
Modified files: Index: src/lib/libc/gen/pthread_atfork.c diff -u src/lib/libc/gen/pthread_atfork.c:1.10 src/lib/libc/gen/pthread_atfork.c:1.10.18.1 --- src/lib/libc/gen/pthread_atfork.c:1.10 Tue Jan 20 18:31:25 2015 +++ src/lib/libc/gen/pthread_atfork.c Wed May 13 18:08:38 2020 @@ -1,4 +1,4 @@ -/* $NetBSD: pthread_atfork.c,v 1.10 2015/01/20 18:31:25 christos Exp $ */ +/* $NetBSD: pthread_atfork.c,v 1.10.18.1 2020/05/13 18:08:38 martin Exp $ */ /*- * Copyright (c) 2002 The NetBSD Foundation, Inc. @@ -31,7 +31,7 @@ #include <sys/cdefs.h> #if defined(LIBC_SCCS) && !defined(lint) -__RCSID("$NetBSD: pthread_atfork.c,v 1.10 2015/01/20 18:31:25 christos Exp $"); +__RCSID("$NetBSD: pthread_atfork.c,v 1.10.18.1 2020/05/13 18:08:38 martin Exp $"); #endif /* LIBC_SCCS and not lint */ #include "namespace.h" @@ -48,6 +48,13 @@ __weak_alias(fork, _fork) #endif /* __weak_alias */ pid_t __fork(void); /* XXX */ +pid_t __locked_fork(int *) __weak; /* XXX */ + +pid_t +__locked_fork(int *my_errno) +{ + return __fork(); +} struct atfork_callback { SIMPLEQ_ENTRY(atfork_callback) next; @@ -157,7 +164,7 @@ fork(void) SIMPLEQ_FOREACH(iter, &prepareq, next) (*iter->fn)(); - ret = __fork(); + ret = __locked_fork(&errno); if (ret != 0) { /* Index: src/libexec/ld.elf_so/rtld.c diff -u src/libexec/ld.elf_so/rtld.c:1.197.2.3 src/libexec/ld.elf_so/rtld.c:1.197.2.4 --- src/libexec/ld.elf_so/rtld.c:1.197.2.3 Sun Mar 8 10:22:29 2020 +++ src/libexec/ld.elf_so/rtld.c Wed May 13 18:08:38 2020 @@ -1,4 +1,4 @@ -/* $NetBSD: rtld.c,v 1.197.2.3 2020/03/08 10:22:29 martin Exp $ */ +/* $NetBSD: rtld.c,v 1.197.2.4 2020/05/13 18:08:38 martin Exp $ */ /* * Copyright 1996 John D. Polstra. @@ -40,7 +40,7 @@ #include <sys/cdefs.h> #ifndef lint -__RCSID("$NetBSD: rtld.c,v 1.197.2.3 2020/03/08 10:22:29 martin Exp $"); +__RCSID("$NetBSD: rtld.c,v 1.197.2.4 2020/05/13 18:08:38 martin Exp $"); #endif /* not lint */ #include <sys/param.h> @@ -1530,6 +1530,23 @@ __dl_cxa_refcount(void *addr, ssize_t de _rtld_exclusive_exit(&mask); } +pid_t __fork(void); + +__dso_public pid_t +__locked_fork(int *my_errno) +{ + sigset_t mask; + pid_t result; + + _rtld_exclusive_enter(&mask); + result = __fork(); + if (result == -1) + *my_errno = errno; + _rtld_exclusive_exit(&mask); + + return result; +} + /* * Error reporting function. Use it like printf. If formats the message * into a buffer, and sets things up so that the next call to dlerror() Index: src/libexec/ld.elf_so/rtld.h diff -u src/libexec/ld.elf_so/rtld.h:1.136 src/libexec/ld.elf_so/rtld.h:1.136.2.1 --- src/libexec/ld.elf_so/rtld.h:1.136 Sun Dec 30 01:48:37 2018 +++ src/libexec/ld.elf_so/rtld.h Wed May 13 18:08:38 2020 @@ -1,4 +1,4 @@ -/* $NetBSD: rtld.h,v 1.136 2018/12/30 01:48:37 christos Exp $ */ +/* $NetBSD: rtld.h,v 1.136.2.1 2020/05/13 18:08:38 martin Exp $ */ /* * Copyright 1996 John D. Polstra. @@ -347,6 +347,8 @@ __dso_public int dl_iterate_phdr(int (*) __dso_public void *_dlauxinfo(void) __pure; __dso_public void __dl_cxa_refcount(void *addr, ssize_t delta); +__dso_public pid_t __locked_fork(int *); + #if defined(__ARM_EABI__) && !defined(__ARM_DWARF_EH__) /* * This is used by libgcc to find the start and length of the exception table Index: src/libexec/ld.elf_so/symbols.map diff -u src/libexec/ld.elf_so/symbols.map:1.2 src/libexec/ld.elf_so/symbols.map:1.2.8.1 --- src/libexec/ld.elf_so/symbols.map:1.2 Tue Jul 11 15:21:35 2017 +++ src/libexec/ld.elf_so/symbols.map Wed May 13 18:08:38 2020 @@ -23,5 +23,6 @@ ___tls_get_addr; __gnu_Unwind_Find_exidx; __dl_cxa_refcount; + __locked_fork; local: *; };