summaryrefslogtreecommitdiff
path: root/libexec/ld.elf_so
diff options
context:
space:
mode:
authorjoerg <joerg@NetBSD.org>2020-04-16 14:39:58 +0000
committerjoerg <joerg@NetBSD.org>2020-04-16 14:39:58 +0000
commit8e524776bfc153bf8ae68a82c2ea7bd5c0a3aa1e (patch)
tree2aff7af6b9904a3b6a78b332163c5301b0311d95 /libexec/ld.elf_so
parent755ad72ebd962ec254959d19a20af63425120c38 (diff)
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.
Diffstat (limited to 'libexec/ld.elf_so')
-rw-r--r--libexec/ld.elf_so/rtld.c19
-rw-r--r--libexec/ld.elf_so/rtld.h4
-rw-r--r--libexec/ld.elf_so/symbols.map1
3 files changed, 21 insertions, 3 deletions
diff --git a/libexec/ld.elf_so/rtld.c b/libexec/ld.elf_so/rtld.c
index 888977a3907..64d5452c970 100644
--- a/libexec/ld.elf_so/rtld.c
+++ b/libexec/ld.elf_so/rtld.c
@@ -1,4 +1,4 @@
-/* $NetBSD: rtld.c,v 1.203 2020/03/04 01:21:17 thorpej Exp $ */
+/* $NetBSD: rtld.c,v 1.204 2020/04/16 14:39:58 joerg Exp $ */
/*
* Copyright 1996 John D. Polstra.
@@ -40,7 +40,7 @@
#include <sys/cdefs.h>
#ifndef lint
-__RCSID("$NetBSD: rtld.c,v 1.203 2020/03/04 01:21:17 thorpej Exp $");
+__RCSID("$NetBSD: rtld.c,v 1.204 2020/04/16 14:39:58 joerg Exp $");
#endif /* not lint */
#include <sys/param.h>
@@ -1532,6 +1532,21 @@ __dl_cxa_refcount(void *addr, ssize_t delta)
_rtld_exclusive_exit(&mask);
}
+pid_t __fork(void);
+
+__dso_public pid_t
+__atomic_fork(void)
+{
+ sigset_t mask;
+ pid_t result;
+
+ _rtld_exclusive_enter(&mask);
+ result = __fork();
+ _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()
diff --git a/libexec/ld.elf_so/rtld.h b/libexec/ld.elf_so/rtld.h
index f4e5f9d1b19..61794003ff3 100644
--- a/libexec/ld.elf_so/rtld.h
+++ b/libexec/ld.elf_so/rtld.h
@@ -1,4 +1,4 @@
-/* $NetBSD: rtld.h,v 1.138 2020/02/29 04:24:33 kamil Exp $ */
+/* $NetBSD: rtld.h,v 1.139 2020/04/16 14:39:58 joerg Exp $ */
/*
* Copyright 1996 John D. Polstra.
@@ -370,6 +370,8 @@ __dso_public int dl_iterate_phdr(int (*)(struct dl_phdr_info *, size_t, void *),
__dso_public void *_dlauxinfo(void) __pure;
__dso_public void __dl_cxa_refcount(void *addr, ssize_t delta);
+__dso_public pid_t __atomic_fork(void);
+
#if defined(__ARM_EABI__) && !defined(__ARM_DWARF_EH__)
/*
* This is used by libgcc to find the start and length of the exception table
diff --git a/libexec/ld.elf_so/symbols.map b/libexec/ld.elf_so/symbols.map
index 41f1bb53f38..b13f098889f 100644
--- a/libexec/ld.elf_so/symbols.map
+++ b/libexec/ld.elf_so/symbols.map
@@ -23,5 +23,6 @@
___tls_get_addr;
__gnu_Unwind_Find_exidx;
__dl_cxa_refcount;
+ __atomic_fork;
local: *;
};