From 124072cef0c06581ae5bb8581be095c92b65e802 Mon Sep 17 00:00:00 2001
From: jsing <>
Date: Mon, 1 Apr 2019 15:58:02 +0000
Subject: Add a mutex to guard reference counting for tls_config.

This makes libtls more friendly for multithreaded use - otherwise we can
end up with incorrect refcounts and end up freeing when we should not be
(or not freeing when we should be).

ok beck@
---
 src/lib/libtls/tls.c          |  4 +++-
 src/lib/libtls/tls_config.c   | 11 +++++++++--
 src/lib/libtls/tls_internal.h |  5 ++++-
 3 files changed, 16 insertions(+), 4 deletions(-)

diff --git a/src/lib/libtls/tls.c b/src/lib/libtls/tls.c
index bf1d9da81e..46ed8180d1 100644
--- a/src/lib/libtls/tls.c
+++ b/src/lib/libtls/tls.c
@@ -1,4 +1,4 @@
-/* $OpenBSD: tls.c,v 1.82 2018/11/29 14:24:23 tedu Exp $ */
+/* $OpenBSD: tls.c,v 1.83 2019/04/01 15:58:02 jsing Exp $ */
 /*
  * Copyright (c) 2014 Joel Sing <jsing@openbsd.org>
  *
@@ -256,7 +256,9 @@ tls_configure(struct tls *ctx, struct tls_config *config)
 	if (config == NULL)
 		config = tls_config_default;
 
+	pthread_mutex_lock(&config->mutex);
 	config->refcount++;
+	pthread_mutex_unlock(&config->mutex);
 
 	tls_config_free(ctx->config);
 
diff --git a/src/lib/libtls/tls_config.c b/src/lib/libtls/tls_config.c
index 19dcc8b0d0..62361e6122 100644
--- a/src/lib/libtls/tls_config.c
+++ b/src/lib/libtls/tls_config.c
@@ -1,4 +1,4 @@
-/* $OpenBSD: tls_config.c,v 1.54 2019/03/27 11:12:10 tedu Exp $ */
+/* $OpenBSD: tls_config.c,v 1.55 2019/04/01 15:58:02 jsing Exp $ */
 /*
  * Copyright (c) 2014 Joel Sing <jsing@openbsd.org>
  *
@@ -20,6 +20,7 @@
 #include <ctype.h>
 #include <errno.h>
 #include <fcntl.h>
+#include <pthread.h>
 #include <stdlib.h>
 #include <unistd.h>
 
@@ -96,6 +97,7 @@ tls_config_new_internal(void)
 	if ((config->keypair = tls_keypair_new()) == NULL)
 		goto err;
 
+	config->mutex = PTHREAD_MUTEX_INITIALIZER;
 	config->refcount = 1;
 	config->session_fd = -1;
 
@@ -149,11 +151,16 @@ void
 tls_config_free(struct tls_config *config)
 {
 	struct tls_keypair *kp, *nkp;
+	int refcount;
 
 	if (config == NULL)
 		return;
 
-	if (--config->refcount > 0)
+	pthread_mutex_lock(&config->mutex);
+	refcount = --config->refcount;
+	pthread_mutex_unlock(&config->mutex);
+
+	if (refcount > 0)
 		return;
 
 	for (kp = config->keypair; kp != NULL; kp = nkp) {
diff --git a/src/lib/libtls/tls_internal.h b/src/lib/libtls/tls_internal.h
index e1a858d4de..3842439d58 100644
--- a/src/lib/libtls/tls_internal.h
+++ b/src/lib/libtls/tls_internal.h
@@ -1,4 +1,4 @@
-/* $OpenBSD: tls_internal.h,v 1.73 2018/11/06 20:34:54 jsing Exp $ */
+/* $OpenBSD: tls_internal.h,v 1.74 2019/04/01 15:58:02 jsing Exp $ */
 /*
  * Copyright (c) 2014 Jeremie Courreges-Anglas <jca@openbsd.org>
  * Copyright (c) 2014 Joel Sing <jsing@openbsd.org>
@@ -19,6 +19,8 @@
 #ifndef HEADER_TLS_INTERNAL_H
 #define HEADER_TLS_INTERNAL_H
 
+#include <pthread.h>
+
 #include <arpa/inet.h>
 #include <netinet/in.h>
 
@@ -75,6 +77,7 @@ struct tls_ticket_key {
 struct tls_config {
 	struct tls_error error;
 
+	pthread_mutex_t mutex;
 	int refcount;
 
 	char *alpn;
-- 
cgit v1.2.3-55-g6feb