fix SSL related crashes (#14076)
prevent concurrent initialization of SSL from multiple threads; prevent re-initialization of SSL
Costa Tsaousis committed
Dec 1, 2022 at 15:56 UTC
54d461b179b1a3b825acde60911fb50515c4bea8
2 files changed
+33
-16
libnetdata/socket/security.c
+25
-13
@@ -204,31 +204,43 @@ static SSL_CTX * security_initialize_openssl_server() {
204
* NETDATA_SSL_CONTEXT_EXPORTING - Starts the OpenTSDB context
205
*/
206
void security_start_ssl(int selector) {
207
+ static SPINLOCK sp = NETDATA_SPINLOCK_INITIALIZER;
208
+ netdata_spinlock_lock(&sp);
209
+
210
switch (selector) {
211
case NETDATA_SSL_CONTEXT_SERVER: {
209
- struct stat statbuf;
210
- if (stat(netdata_ssl_security_key, &statbuf) || stat(netdata_ssl_security_cert, &statbuf)) {
211
- info("To use encryption it is necessary to set \"ssl certificate\" and \"ssl key\" in [web] !\n");
212
- return;
212
+ if(!netdata_ssl_srv_ctx) {
213
+ struct stat statbuf;
214
+ if (stat(netdata_ssl_security_key, &statbuf) || stat(netdata_ssl_security_cert, &statbuf))
215
+ info("To use encryption it is necessary to set \"ssl certificate\" and \"ssl key\" in [web] !\n");
216
+ else {
217
+ netdata_ssl_srv_ctx = security_initialize_openssl_server();
218
+ SSL_CTX_set_mode(netdata_ssl_srv_ctx, SSL_MODE_ENABLE_PARTIAL_WRITE);
219
+ }
220
}
214
-
215
- netdata_ssl_srv_ctx = security_initialize_openssl_server();
216
- SSL_CTX_set_mode(netdata_ssl_srv_ctx, SSL_MODE_ENABLE_PARTIAL_WRITE);
221
break;
222
}
223
+
224
case NETDATA_SSL_CONTEXT_STREAMING: {
220
- netdata_ssl_client_ctx = security_initialize_openssl_client();
221
- //This is necessary for the stream, because it is working sometimes with nonblock socket.
222
- //It returns the bitmask after to change, there is not any description of errors in the documentation
223
- SSL_CTX_set_mode(
224
- netdata_ssl_client_ctx, SSL_MODE_ENABLE_PARTIAL_WRITE |SSL_MODE_ACCEPT_MOVING_WRITE_BUFFER |SSL_MODE_AUTO_RETRY);
225
+ if(!netdata_ssl_client_ctx) {
226
+ netdata_ssl_client_ctx = security_initialize_openssl_client();
227
+ //This is necessary for the stream, because it is working sometimes with nonblock socket.
228
+ //It returns the bitmask after to change, there is not any description of errors in the documentation
229
+ SSL_CTX_set_mode(netdata_ssl_client_ctx,
230
+ SSL_MODE_ENABLE_PARTIAL_WRITE | SSL_MODE_ACCEPT_MOVING_WRITE_BUFFER |
231
+ SSL_MODE_AUTO_RETRY);
232
+ }
233
break;
234
}
235
+
236
case NETDATA_SSL_CONTEXT_EXPORTING: {
228
- netdata_ssl_exporting_ctx = security_initialize_openssl_client();
237
+ if(!netdata_ssl_exporting_ctx)
238
+ netdata_ssl_exporting_ctx = security_initialize_openssl_client();
239
break;
240
}
241
}
242
+
243
+ netdata_spinlock_unlock(&sp);
244
}
245
246
/**
streaming/sender.c
+8
-3
@@ -1114,9 +1114,14 @@ void *rrdpush_sender_thread(void *ptr) {
1114
}
1115
1116
#ifdef ENABLE_HTTPS
1117
- if (netdata_use_ssl_on_stream & NETDATA_SSL_FORCE ){
1118
- security_start_ssl(NETDATA_SSL_CONTEXT_STREAMING);
1119
- ssl_security_location_for_context(netdata_ssl_client_ctx, netdata_ssl_ca_file, netdata_ssl_ca_path);
1117
+ if (netdata_use_ssl_on_stream & NETDATA_SSL_FORCE ) {
1118
+ static SPINLOCK sp = NETDATA_SPINLOCK_INITIALIZER;
1119
+ netdata_spinlock_lock(&sp);
1120
+ if(!netdata_ssl_client_ctx) {
1121
+ security_start_ssl(NETDATA_SSL_CONTEXT_STREAMING);
1122
+ ssl_security_location_for_context(netdata_ssl_client_ctx, netdata_ssl_ca_file, netdata_ssl_ca_path);
1123
+ }
1124
+ netdata_spinlock_unlock(&sp);
1125
}
1126
#endif
1127