Commit 1d3364ac by Carlos Martín Nieto

netops: init OpenSSL once under lock

The OpenSSL init functions are not reentrant, which means that running
multiple fetches in parallel can cause us to crash.

Use a mutex to init OpenSSL, and since we're adding this extra checks,
init it only once.
parent 716e20b4
......@@ -16,6 +16,9 @@ git_mutex git__mwindow_mutex;
#define MAX_SHUTDOWN_CB 8
git_mutex git__ssl_mutex;
git_atomic git__ssl_init;
static git_global_shutdown_fn git__shutdown_callbacks[MAX_SHUTDOWN_CB];
static git_atomic git__n_shutdown_callbacks;
static git_atomic git__n_inits;
......
......@@ -18,6 +18,8 @@ typedef struct {
git_global_st *git__global_state(void);
extern git_mutex git__mwindow_mutex;
extern git_mutex git__ssl_mutex;
extern git_atomic git__ssl_init;
#define GIT_GLOBAL (git__global_state())
......
......@@ -33,6 +33,7 @@
#include "posix.h"
#include "buffer.h"
#include "http_parser.h"
#include "global.h"
#ifdef GIT_WIN32
static void net_set_error(const char *str)
......@@ -386,12 +387,41 @@ cert_fail_name:
return -1;
}
static int ssl_setup(gitno_socket *socket, const char *host, int flags)
/**
* The OpenSSL init functions are not reentrant so we need to init
* them under lock.
*/
static int init_ssl(void)
{
int ret;
if (git__ssl_init.val)
return 0;
if (git_mutex_lock(&git__ssl_mutex) < 0) {
giterr_set(GITERR_OS, "failed to acquire ssl init lock");
return -1;
}
/* if we had to wait for the lock, someone else did it, we can return */
if (git__ssl_init.val)
return 0;
SSL_library_init();
SSL_load_error_strings();
git_atomic_set(&git__ssl_init, 1);
git_mutex_unlock(&git__ssl_mutex);
return 0;
}
static int ssl_setup(gitno_socket *socket, const char *host, int flags)
{
int ret;
if (init_ssl() < 0)
return -1;
socket->ssl.ctx = SSL_CTX_new(SSLv23_method());
if (socket->ssl.ctx == NULL)
return ssl_set_error(&socket->ssl, 0);
......
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment