@@ -92,6 +92,12 @@ static void SSLerrfree(char *buf);
92
92
93
93
static bool pq_init_ssl_lib = true;
94
94
static bool pq_init_crypto_lib = true;
95
+
96
+ /*
97
+ * SSL_context is currently shared between threads and therefore we need to be
98
+ * careful to lock around any usage of it when providing thread safety.
99
+ * ssl_config_mutex is the mutex that we use to protect it.
100
+ */
95
101
static SSL_CTX * SSL_context = NULL ;
96
102
97
103
#ifdef ENABLE_THREAD_SAFETY
@@ -253,6 +259,10 @@ pqsecure_open_client(PGconn *conn)
253
259
/* We cannot use MSG_NOSIGNAL to block SIGPIPE when using SSL */
254
260
conn -> sigpipe_flag = false;
255
261
262
+ #ifdef ENABLE_THREAD_SAFETY
263
+ if (pthread_mutex_lock (& ssl_config_mutex ))
264
+ return -1 ;
265
+ #endif
256
266
/* Create a connection-specific SSL object */
257
267
if (!(conn -> ssl = SSL_new (SSL_context )) ||
258
268
!SSL_set_app_data (conn -> ssl , conn ) ||
@@ -265,9 +275,14 @@ pqsecure_open_client(PGconn *conn)
265
275
err );
266
276
SSLerrfree (err );
267
277
close_SSL (conn );
278
+ #ifdef ENABLE_THREAD_SAFETY
279
+ pthread_mutex_unlock (& ssl_config_mutex );
280
+ #endif
268
281
return PGRES_POLLING_FAILED ;
269
282
}
270
-
283
+ #ifdef ENABLE_THREAD_SAFETY
284
+ pthread_mutex_unlock (& ssl_config_mutex );
285
+ #endif
271
286
/*
272
287
* Load client certificate, private key, and trusted CA certs.
273
288
*/
@@ -999,8 +1014,9 @@ destroy_ssl_system(void)
999
1014
CRYPTO_set_id_callback (NULL );
1000
1015
1001
1016
/*
1002
- * We don't free the lock array. If we get another connection in this
1003
- * process, we will just re-use it with the existing mutexes.
1017
+ * We don't free the lock array or the SSL_context. If we get another
1018
+ * connection in this process, we will just re-use them with the
1019
+ * existing mutexes.
1004
1020
*
1005
1021
* This means we leak a little memory on repeated load/unload of the
1006
1022
* library.
@@ -1089,7 +1105,15 @@ initialize_SSL(PGconn *conn)
1089
1105
* understands which subject cert to present, in case different
1090
1106
* sslcert settings are used for different connections in the same
1091
1107
* process.
1108
+ *
1109
+ * NOTE: This function may also modify our SSL_context and therefore
1110
+ * we have to lock around this call and any places where we use the
1111
+ * SSL_context struct.
1092
1112
*/
1113
+ #ifdef ENABLE_THREAD_SAFETY
1114
+ if (pthread_mutex_lock (& ssl_config_mutex ))
1115
+ return -1 ;
1116
+ #endif
1093
1117
if (SSL_CTX_use_certificate_chain_file (SSL_context , fnbuf ) != 1 )
1094
1118
{
1095
1119
char * err = SSLerrmessage ();
@@ -1098,8 +1122,13 @@ initialize_SSL(PGconn *conn)
1098
1122
libpq_gettext ("could not read certificate file \"%s\": %s\n" ),
1099
1123
fnbuf , err );
1100
1124
SSLerrfree (err );
1125
+
1126
+ #ifdef ENABLE_THREAD_SAFETY
1127
+ pthread_mutex_unlock (& ssl_config_mutex );
1128
+ #endif
1101
1129
return -1 ;
1102
1130
}
1131
+
1103
1132
if (SSL_use_certificate_file (conn -> ssl , fnbuf , SSL_FILETYPE_PEM ) != 1 )
1104
1133
{
1105
1134
char * err = SSLerrmessage ();
@@ -1108,10 +1137,18 @@ initialize_SSL(PGconn *conn)
1108
1137
libpq_gettext ("could not read certificate file \"%s\": %s\n" ),
1109
1138
fnbuf , err );
1110
1139
SSLerrfree (err );
1140
+ #ifdef ENABLE_THREAD_SAFETY
1141
+ pthread_mutex_unlock (& ssl_config_mutex );
1142
+ #endif
1111
1143
return -1 ;
1112
1144
}
1145
+
1113
1146
/* need to load the associated private key, too */
1114
1147
have_cert = true;
1148
+
1149
+ #ifdef ENABLE_THREAD_SAFETY
1150
+ pthread_mutex_unlock (& ssl_config_mutex );
1151
+ #endif
1115
1152
}
1116
1153
1117
1154
/*
@@ -1287,6 +1324,10 @@ initialize_SSL(PGconn *conn)
1287
1324
{
1288
1325
X509_STORE * cvstore ;
1289
1326
1327
+ #ifdef ENABLE_THREAD_SAFETY
1328
+ if (pthread_mutex_lock (& ssl_config_mutex ))
1329
+ return -1 ;
1330
+ #endif
1290
1331
if (SSL_CTX_load_verify_locations (SSL_context , fnbuf , NULL ) != 1 )
1291
1332
{
1292
1333
char * err = SSLerrmessage ();
@@ -1295,6 +1336,9 @@ initialize_SSL(PGconn *conn)
1295
1336
libpq_gettext ("could not read root certificate file \"%s\": %s\n" ),
1296
1337
fnbuf , err );
1297
1338
SSLerrfree (err );
1339
+ #ifdef ENABLE_THREAD_SAFETY
1340
+ pthread_mutex_unlock (& ssl_config_mutex );
1341
+ #endif
1298
1342
return -1 ;
1299
1343
}
1300
1344
@@ -1322,11 +1366,17 @@ initialize_SSL(PGconn *conn)
1322
1366
libpq_gettext ("SSL library does not support CRL certificates (file \"%s\")\n" ),
1323
1367
fnbuf );
1324
1368
SSLerrfree (err );
1369
+ #ifdef ENABLE_THREAD_SAFETY
1370
+ pthread_mutex_unlock (& ssl_config_mutex );
1371
+ #endif
1325
1372
return -1 ;
1326
1373
#endif
1327
1374
}
1328
1375
/* if not found, silently ignore; we do not require CRL */
1329
1376
}
1377
+ #ifdef ENABLE_THREAD_SAFETY
1378
+ pthread_mutex_unlock (& ssl_config_mutex );
1379
+ #endif
1330
1380
1331
1381
SSL_set_verify (conn -> ssl , SSL_VERIFY_PEER , verify_cb );
1332
1382
}
0 commit comments