v2-0001-Fix-race-condition-in-initialization-of-my_bio_me.patch
text/x-diff
Filename: v2-0001-Fix-race-condition-in-initialization-of-my_bio_me.patch
Type: text/x-diff
Part: 0
Patch
Format: format-patch
Series: patch v2-0001
Subject: Fix race condition in initialization of my_bio_methods static variable
| File | + | − |
|---|---|---|
| src/interfaces/libpq/fe-secure-openssl.c | 40 | 21 |
From dc1bc40271311868ec4840be2c246efa705dc7a5 Mon Sep 17 00:00:00 2001
From: Michael Paquier <michael@paquier.xyz>
Date: Fri, 24 Nov 2023 16:47:03 +0900
Subject: [PATCH v2] Fix race condition in initialization of my_bio_methods
static variable
---
src/interfaces/libpq/fe-secure-openssl.c | 61 ++++++++++++++++--------
1 file changed, 40 insertions(+), 21 deletions(-)
diff --git a/src/interfaces/libpq/fe-secure-openssl.c b/src/interfaces/libpq/fe-secure-openssl.c
index f1192d28f2..30a83fbd01 100644
--- a/src/interfaces/libpq/fe-secure-openssl.c
+++ b/src/interfaces/libpq/fe-secure-openssl.c
@@ -1885,6 +1885,13 @@ my_sock_write(BIO *h, const char *buf, int size)
static BIO_METHOD *
my_BIO_s_socket(void)
{
+ BIO_METHOD *res;
+
+ if (pthread_mutex_lock(&ssl_config_mutex))
+ return NULL;
+
+ res = my_bio_methods;
+
if (!my_bio_methods)
{
BIO_METHOD *biom = (BIO_METHOD *) BIO_s_socket();
@@ -1893,39 +1900,51 @@ my_BIO_s_socket(void)
my_bio_index = BIO_get_new_index();
if (my_bio_index == -1)
- return NULL;
+ goto err;
my_bio_index |= (BIO_TYPE_DESCRIPTOR | BIO_TYPE_SOURCE_SINK);
- my_bio_methods = BIO_meth_new(my_bio_index, "libpq socket");
- if (!my_bio_methods)
- return NULL;
+ res = BIO_meth_new(my_bio_index, "libpq socket");
+ if (!res)
+ goto err;
/*
* As of this writing, these functions never fail. But check anyway,
* like OpenSSL's own examples do.
*/
- if (!BIO_meth_set_write(my_bio_methods, my_sock_write) ||
- !BIO_meth_set_read(my_bio_methods, my_sock_read) ||
- !BIO_meth_set_gets(my_bio_methods, BIO_meth_get_gets(biom)) ||
- !BIO_meth_set_puts(my_bio_methods, BIO_meth_get_puts(biom)) ||
- !BIO_meth_set_ctrl(my_bio_methods, BIO_meth_get_ctrl(biom)) ||
- !BIO_meth_set_create(my_bio_methods, BIO_meth_get_create(biom)) ||
- !BIO_meth_set_destroy(my_bio_methods, BIO_meth_get_destroy(biom)) ||
- !BIO_meth_set_callback_ctrl(my_bio_methods, BIO_meth_get_callback_ctrl(biom)))
+ if (!BIO_meth_set_write(res, my_sock_write) ||
+ !BIO_meth_set_read(res, my_sock_read) ||
+ !BIO_meth_set_gets(res, BIO_meth_get_gets(biom)) ||
+ !BIO_meth_set_puts(res, BIO_meth_get_puts(biom)) ||
+ !BIO_meth_set_ctrl(res, BIO_meth_get_ctrl(biom)) ||
+ !BIO_meth_set_create(res, BIO_meth_get_create(biom)) ||
+ !BIO_meth_set_destroy(res, BIO_meth_get_destroy(biom)) ||
+ !BIO_meth_set_callback_ctrl(res, BIO_meth_get_callback_ctrl(biom)))
{
- BIO_meth_free(my_bio_methods);
- my_bio_methods = NULL;
- return NULL;
+ goto err;
}
#else
- my_bio_methods = malloc(sizeof(BIO_METHOD));
- if (!my_bio_methods)
- return NULL;
- memcpy(my_bio_methods, biom, sizeof(BIO_METHOD));
- my_bio_methods->bread = my_sock_read;
- my_bio_methods->bwrite = my_sock_write;
+ res = malloc(sizeof(BIO_METHOD));
+ if (!res)
+ goto err;
+ memcpy(res, res, sizeof(BIO_METHOD));
+ res->bread = my_sock_read;
+ res->bwrite = my_sock_write;
#endif
}
+
+ my_bio_methods = res;
+ pthread_mutex_unlock(&ssl_config_mutex);
return my_bio_methods;
+
+err:
+#ifdef HAVE_BIO_METH_NEW
+ if (res)
+ BIO_meth_free(res);
+#else
+ if (res)
+ free(res);
+#endif
+ pthread_mutex_unlock(&ssl_config_mutex);
+ return NULL;
}
/* This should exactly match OpenSSL's SSL_set_fd except for using my BIO */
--
2.42.0