mirror of
https://git.proxmox.com/git/libgit2
synced 2025-08-06 16:39:23 +00:00
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.
This commit is contained in:
parent
716e20b47e
commit
1d3364ac9d
@ -16,6 +16,9 @@ git_mutex git__mwindow_mutex;
|
|||||||
|
|
||||||
#define MAX_SHUTDOWN_CB 8
|
#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_global_shutdown_fn git__shutdown_callbacks[MAX_SHUTDOWN_CB];
|
||||||
static git_atomic git__n_shutdown_callbacks;
|
static git_atomic git__n_shutdown_callbacks;
|
||||||
static git_atomic git__n_inits;
|
static git_atomic git__n_inits;
|
||||||
|
@ -18,6 +18,8 @@ typedef struct {
|
|||||||
git_global_st *git__global_state(void);
|
git_global_st *git__global_state(void);
|
||||||
|
|
||||||
extern git_mutex git__mwindow_mutex;
|
extern git_mutex git__mwindow_mutex;
|
||||||
|
extern git_mutex git__ssl_mutex;
|
||||||
|
extern git_atomic git__ssl_init;
|
||||||
|
|
||||||
#define GIT_GLOBAL (git__global_state())
|
#define GIT_GLOBAL (git__global_state())
|
||||||
|
|
||||||
|
34
src/netops.c
34
src/netops.c
@ -33,6 +33,7 @@
|
|||||||
#include "posix.h"
|
#include "posix.h"
|
||||||
#include "buffer.h"
|
#include "buffer.h"
|
||||||
#include "http_parser.h"
|
#include "http_parser.h"
|
||||||
|
#include "global.h"
|
||||||
|
|
||||||
#ifdef GIT_WIN32
|
#ifdef GIT_WIN32
|
||||||
static void net_set_error(const char *str)
|
static void net_set_error(const char *str)
|
||||||
@ -386,12 +387,41 @@ cert_fail_name:
|
|||||||
return -1;
|
return -1;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* The OpenSSL init functions are not reentrant so we need to init
|
||||||
|
* them under lock.
|
||||||
|
*/
|
||||||
|
static int init_ssl(void)
|
||||||
|
{
|
||||||
|
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)
|
static int ssl_setup(gitno_socket *socket, const char *host, int flags)
|
||||||
{
|
{
|
||||||
int ret;
|
int ret;
|
||||||
|
|
||||||
SSL_library_init();
|
if (init_ssl() < 0)
|
||||||
SSL_load_error_strings();
|
return -1;
|
||||||
|
|
||||||
socket->ssl.ctx = SSL_CTX_new(SSLv23_method());
|
socket->ssl.ctx = SSL_CTX_new(SSLv23_method());
|
||||||
if (socket->ssl.ctx == NULL)
|
if (socket->ssl.ctx == NULL)
|
||||||
return ssl_set_error(&socket->ssl, 0);
|
return ssl_set_error(&socket->ssl, 0);
|
||||||
|
Loading…
Reference in New Issue
Block a user