Thanks to visit codestin.com
Credit goes to github.com

Skip to content

Commit cf15ac8

Browse files
committed
ssl: cargo-cult thread safety
OpenSSL's tests init everything in the main thread, so let's do that.
1 parent 5fa0494 commit cf15ac8

File tree

4 files changed

+46
-23
lines changed

4 files changed

+46
-23
lines changed

src/global.c

Lines changed: 20 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -16,6 +16,11 @@ git_mutex git__mwindow_mutex;
1616

1717
#define MAX_SHUTDOWN_CB 8
1818

19+
#ifdef GIT_SSL
20+
# include <openssl/ssl.h>
21+
SSL_CTX *git__ssl_ctx;
22+
#endif
23+
1924
git_mutex git__ssl_mutex;
2025
git_atomic git__ssl_init;
2126

@@ -160,6 +165,15 @@ static pthread_key_t _tls_key;
160165
static pthread_once_t _once_init = PTHREAD_ONCE_INIT;
161166
int init_error = 0;
162167

168+
static void init_ssl(void)
169+
{
170+
#ifdef GIT_SSL
171+
SSL_load_error_strings();
172+
OpenSSL_add_ssl_algorithms();
173+
git__ssl_ctx = SSL_CTX_new(SSLv23_method());
174+
#endif
175+
}
176+
163177
static void cb__free_status(void *st)
164178
{
165179
git__free(st);
@@ -169,12 +183,18 @@ static void init_once(void)
169183
{
170184
if ((init_error = git_mutex_init(&git__mwindow_mutex)) != 0)
171185
return;
186+
if ((init_error = git_mutex_init(&git__ssl_mutex)) != 0)
187+
return;
172188
pthread_key_create(&_tls_key, &cb__free_status);
173189

190+
174191
/* Initialize any other subsystems that have global state */
175192
if ((init_error = git_hash_global_init()) >= 0)
176193
init_error = git_sysdir_global_init();
177194

195+
/* OpenSSL needs to be initialized from the main thread */
196+
init_ssl();
197+
178198
GIT_MEMORY_BARRIER;
179199
}
180200

src/global.h

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -15,6 +15,11 @@ typedef struct {
1515
git_error error_t;
1616
} git_global_st;
1717

18+
#ifdef GIT_SSL
19+
# include <openssl/ssl.h>
20+
extern SSL_CTX *git__ssl_ctx;
21+
#endif
22+
1823
git_global_st *git__global_state(void);
1924

2025
extern git_mutex git__mwindow_mutex;

src/netops.c

Lines changed: 21 additions & 22 deletions
Original file line numberDiff line numberDiff line change
@@ -163,7 +163,7 @@ void gitno_buffer_setup_callback(
163163
void gitno_buffer_setup(gitno_socket *socket, gitno_buffer *buf, char *data, size_t len)
164164
{
165165
#ifdef GIT_SSL
166-
if (socket->ssl.ctx) {
166+
if (socket->ssl.ssl) {
167167
gitno_buffer_setup_callback(socket, buf, data, len, gitno__recv_ssl, NULL);
168168
return;
169169
}
@@ -208,7 +208,6 @@ static int gitno_ssl_teardown(gitno_ssl *ssl)
208208
ret = 0;
209209

210210
SSL_free(ssl->ssl);
211-
SSL_CTX_free(ssl->ctx);
212211
return ret;
213212
}
214213

@@ -428,30 +427,39 @@ static int init_ssl(void)
428427
if (git__ssl_init.val)
429428
return 0;
430429

431-
432-
SSL_library_init();
433-
SSL_load_error_strings();
430+
SSL_CTX_set_mode(git__ssl_ctx, SSL_MODE_AUTO_RETRY);
431+
SSL_CTX_set_verify(git__ssl_ctx, SSL_VERIFY_NONE, NULL);
432+
if (!SSL_CTX_set_default_verify_paths(git__ssl_ctx)) {
433+
unsigned long err = ERR_get_error();
434+
giterr_set(GITERR_SSL, "failed to set verify paths: %s\n", ERR_error_string(err, NULL));
435+
return -1;
436+
}
434437

435438
#ifdef GIT_THREADS
436439
{
437440
int num_locks, i;
438441

439-
440-
CRYPTO_set_locking_callback(openssl_locking_function);
441-
442442
num_locks = CRYPTO_num_locks();
443443
openssl_locks = git__calloc(num_locks, sizeof(git_mutex));
444+
if (openssl_locks == NULL) {
445+
git_mutex_unlock(&git__ssl_mutex);
446+
return -1;
447+
}
448+
GITERR_CHECK_ALLOC(openssl_locks);
449+
444450
for (i = 0; i < num_locks; i++) {
445-
if (git_mutex_init(&openssl_locks[i]) < 0) {
451+
if (git_mutex_init(&openssl_locks[i]) != 0) {
446452
git_mutex_unlock(&git__ssl_mutex);
447453
giterr_set(GITERR_SSL, "failed to init lock %d", i);
448454
return -1;
449455
}
450456
}
451457
}
458+
459+
CRYPTO_set_locking_callback(openssl_locking_function);
452460
#endif
453461

454-
git_atomic_set(&git__ssl_init, 1);
462+
git_atomic_inc(&git__ssl_init);
455463
git_mutex_unlock(&git__ssl_mutex);
456464

457465
return 0;
@@ -464,16 +472,7 @@ static int ssl_setup(gitno_socket *socket, const char *host, int flags)
464472
if (init_ssl() < 0)
465473
return -1;
466474

467-
socket->ssl.ctx = SSL_CTX_new(SSLv23_method());
468-
if (socket->ssl.ctx == NULL)
469-
return ssl_set_error(&socket->ssl, 0);
470-
471-
SSL_CTX_set_mode(socket->ssl.ctx, SSL_MODE_AUTO_RETRY);
472-
SSL_CTX_set_verify(socket->ssl.ctx, SSL_VERIFY_NONE, NULL);
473-
if (!SSL_CTX_set_default_verify_paths(socket->ssl.ctx))
474-
return ssl_set_error(&socket->ssl, 0);
475-
476-
socket->ssl.ssl = SSL_new(socket->ssl.ctx);
475+
socket->ssl.ssl = SSL_new(git__ssl_ctx);
477476
if (socket->ssl.ssl == NULL)
478477
return ssl_set_error(&socket->ssl, 0);
479478

@@ -610,7 +609,7 @@ int gitno_send(gitno_socket *socket, const char *msg, size_t len, int flags)
610609
size_t off = 0;
611610

612611
#ifdef GIT_SSL
613-
if (socket->ssl.ctx)
612+
if (socket->ssl.ssl)
614613
return gitno_send_ssl(&socket->ssl, msg, len, flags);
615614
#endif
616615

@@ -631,7 +630,7 @@ int gitno_send(gitno_socket *socket, const char *msg, size_t len, int flags)
631630
int gitno_close(gitno_socket *s)
632631
{
633632
#ifdef GIT_SSL
634-
if (s->ssl.ctx &&
633+
if (s->ssl.ssl &&
635634
gitno_ssl_teardown(&s->ssl) < 0)
636635
return -1;
637636
#endif

src/netops.h

Lines changed: 0 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -16,7 +16,6 @@
1616

1717
struct gitno_ssl {
1818
#ifdef GIT_SSL
19-
SSL_CTX *ctx;
2019
SSL *ssl;
2120
#else
2221
size_t dummy;

0 commit comments

Comments
 (0)