Commit b0ebb0d4c26b281facbab7a774510b541637b13b

Guillem Jover 2019-08-06T23:16:42

build: Use __register_atfork() only if really available This is a glibc-specific symbol that has no public declaration. But is being used by the OpenBSD and this implementation as a hack to avoid having to link against the pthread library. This interface is at least included in LSB 5.0 [L], and using pthread_atfork() is otherwise problematic anyway [P]. [L] <https://refspecs.linuxfoundation.org/LSB_5.0.0/LSB-Core-generic/LSB-Core-generic/baselib---register-atfork.html> [P] <http://austingroupbugs.net/view.php?id=851> One problem is that we were using it whenever __GLIBC__ is defined, which is supposed to be defined only on an actual glibc, but uClibc defines that macro, but it does not provide the symbol on its noMMU variant. We add a new configure check that will try to link a program that uses that symbol to make sure it is present. Closes: !2 Reported-by: Fabrice Fontaine <fontaine.fabrice@gmail.com>

diff --git a/configure.ac b/configure.ac
index 1654072..3beb08e 100644
--- a/configure.ac
+++ b/configure.ac
@@ -145,6 +145,23 @@ AC_LINK_IFELSE(
 	 AC_MSG_RESULT([yes])],
 	[AC_MSG_RESULT([no])])
 
+AC_MSG_CHECKING([for __register_atfork])
+AC_LINK_IFELSE(
+	[AC_LANG_PROGRAM([[
+		#include <stddef.h>
+		extern void *__dso_handle;
+		extern int __register_atfork(void (*)(void), void(*)(void), void (*)(void), void *);
+	]], [[
+		__register_atfork(NULL, NULL, NULL, __dso_handle);
+	]])],
+	[AC_DEFINE([HAVE___REGISTER_ATFORK], [1],
+	           [Define to 1 if you have __register_atfork])
+	 AC_MSG_RESULT([yes])],
+	[ARC4RANDOM_ATFORK_LIBS="-pthread"
+	 AC_SUBST([ARC4RANDOM_ATFORK_LIBS])
+	 AC_MSG_RESULT([no])
+	])
+
 AC_CHECK_FUNCS([clearenv dirfd fopencookie __fpurge \
                 getauxval getentropy getexecname getline \
                 pstat_getproc sysconf])
diff --git a/src/Makefile.am b/src/Makefile.am
index f3cc0fa..76222a3 100644
--- a/src/Makefile.am
+++ b/src/Makefile.am
@@ -54,7 +54,9 @@ libbsd_la_DEPENDENCIES = \
 	$(libbsd_la_included_sources) \
 	libbsd.map
 libbsd_la_LIBADD = \
-	$(CLOCK_GETTIME_LIBS)
+	$(CLOCK_GETTIME_LIBS) \
+	$(ARC4RANDOM_ATFORK_LIBS) \
+	$(nil)
 libbsd_la_LDFLAGS = \
 	-Wl,--version-script=$(srcdir)/libbsd.map \
 	-version-number $(LIBBSD_ABI)
diff --git a/src/arc4random_linux.h b/src/arc4random_linux.h
index 7a2ca1e..bc57cd1 100644
--- a/src/arc4random_linux.h
+++ b/src/arc4random_linux.h
@@ -32,7 +32,7 @@ static pthread_mutex_t arc4random_mtx = PTHREAD_MUTEX_INITIALIZER;
 #define _ARC4_LOCK()   pthread_mutex_lock(&arc4random_mtx)
 #define _ARC4_UNLOCK() pthread_mutex_unlock(&arc4random_mtx)
 
-#ifdef __GLIBC__
+#ifdef HAVE___REGISTER_ATFORK
 extern void *__dso_handle;
 extern int __register_atfork(void (*)(void), void(*)(void), void (*)(void), void *);
 #define _ARC4_ATFORK(f) __register_atfork(NULL, NULL, (f), __dso_handle)
diff --git a/src/arc4random_unix.h b/src/arc4random_unix.h
index 0e37683..2e6c6ea 100644
--- a/src/arc4random_unix.h
+++ b/src/arc4random_unix.h
@@ -32,7 +32,7 @@ static pthread_mutex_t arc4random_mtx = PTHREAD_MUTEX_INITIALIZER;
 #define _ARC4_LOCK()   pthread_mutex_lock(&arc4random_mtx)
 #define _ARC4_UNLOCK() pthread_mutex_unlock(&arc4random_mtx)
 
-#ifdef __GLIBC__
+#ifdef HAVE___REGISTER_ATFORK
 extern void *__dso_handle;
 extern int __register_atfork(void (*)(void), void(*)(void), void (*)(void), void *);
 #define _ARC4_ATFORK(f) __register_atfork(NULL, NULL, (f), __dso_handle)