Skip to content

Commit

Permalink
security/gnutls: initialise libpthread
Browse files Browse the repository at this point in the history
To ensure thread-safety libgnutls calls libpthread functions but to
avoid the overhead for single-threaded programs it does not link with
libpthread.  It only calls libpthread if the executable or another
library links to it.

Since 3.8.0 libgnutls calls pthread_key_create from its init function
but because it does not link with libpthread libpthread might not have
been initialised yet.  Patch the libgnutls init function so it
initialises libpthread.

PR:		278076
(cherry picked from commit 9ffc65e)
  • Loading branch information
TijlCoosemans committed Apr 12, 2024
1 parent b4e2679 commit 5842d08
Show file tree
Hide file tree
Showing 2 changed files with 44 additions and 0 deletions.
1 change: 1 addition & 0 deletions security/gnutls/Makefile
Original file line number Diff line number Diff line change
@@ -1,5 +1,6 @@
PORTNAME= gnutls
DISTVERSION= 3.8.5
PORTREVISION= 1
CATEGORIES= security net
MASTER_SITES= GNUPG/${PORTNAME}/v${DISTVERSION:R}

Expand Down
43 changes: 43 additions & 0 deletions security/gnutls/files/patch-lib_global.c
Original file line number Diff line number Diff line change
@@ -0,0 +1,43 @@
--- lib/global.c.orig 2024-04-11 15:36:24 UTC
+++ lib/global.c
@@ -29,6 +29,13 @@
#include "random.h"
#include <gnutls/pkcs11.h>

+#if __FreeBSD__
+#include <sys/param.h>
+#if __FreeBSD_version >= 1400094
+#include <dlfcn.h>
+#endif
+#endif
+
#include "hello_ext.h" /* for _gnutls_hello_ext_init */
#include "supplemental.h" /* for _gnutls_supplemental_deinit */
#include "locks.h"
@@ -520,6 +527,26 @@ static void _CONSTRUCTOR lib_init(void)
if (ret == 1)
return;
}
+
+#if __FreeBSD__
+#if __FreeBSD_version >= 1400094
+ /* This dlopen call initialises libpthread if it is present. Normally
+ this is handled by linking to libpthread but libgnutls does not link
+ with libpthread to avoid the overhead for non-threaded programs. */
+ (void) dlopen("libpthread.so", RTLD_LAZY | RTLD_GLOBAL | RTLD_NOLOAD);
+#else
+ /* The dlopen call above does not work correctly on older versions of
+ FreeBSD. Call pthread_mutex_timedlock instead. It initialises
+ libpthread and there's no libc stub that can preempt it. */
+#pragma weak pthread_mutex_timedlock
+ if (pthread_mutex_timedlock != NULL) {
+ pthread_mutex_t lock = PTHREAD_MUTEX_INITIALIZER;
+ pthread_mutex_timedlock(&lock, NULL);
+ pthread_mutex_unlock(&lock);
+ pthread_mutex_destroy(&lock);
+ }
+#endif
+#endif

ret = _gnutls_global_init(1);
if (ret < 0) {

0 comments on commit 5842d08

Please sign in to comment.