Skip to content

Commit 9fce506

Browse files
committed
openssl: lazily load libraries when dynamically loading
Defer dlopen until it's needed when dynamically loading OpenSSL libraries.
1 parent aad497c commit 9fce506

File tree

1 file changed

+53
-6
lines changed

1 file changed

+53
-6
lines changed

src/streams/openssl.c

Lines changed: 53 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -102,7 +102,7 @@ static void git_openssl_free(void *mem)
102102
# endif /* !GIT_OPENSSL_LEGACY && !GIT_OPENSSL_DYNAMIC */
103103
#endif /* VALGRIND */
104104

105-
int git_openssl_stream_global_init(void)
105+
static int openssl_init(void)
106106
{
107107
long ssl_opts = SSL_OP_NO_SSLv2 | SSL_OP_NO_SSLv3;
108108
const char *ciphers = git_libgit2__ssl_ciphers();
@@ -115,11 +115,6 @@ int git_openssl_stream_global_init(void)
115115
ssl_opts |= SSL_OP_NO_COMPRESSION;
116116
#endif
117117

118-
#ifdef GIT_OPENSSL_DYNAMIC
119-
if (git_openssl_stream_dynamic_init() < 0)
120-
return -1;
121-
#endif
122-
123118
#ifdef VALGRIND
124119
/*
125120
* Swap in our own allocator functions that initialize
@@ -171,6 +166,49 @@ int git_openssl_stream_global_init(void)
171166
return -1;
172167
}
173168

169+
/*
170+
* When we use dynamic loading, we defer OpenSSL initialization until
171+
* it's first used. `openssl_ensure_initialized` will do the work
172+
* under a mutex.
173+
*/
174+
git_mutex openssl_mutex;
175+
bool openssl_initialized;
176+
177+
int git_openssl_stream_global_init(void)
178+
{
179+
#ifndef GIT_OPENSSL_DYNAMIC
180+
return openssl_init();
181+
#else
182+
if (git_mutex_init(&openssl_mutex) != 0)
183+
return -1;
184+
185+
return 0;
186+
#endif
187+
}
188+
189+
static int openssl_ensure_initialized(void)
190+
{
191+
#ifdef GIT_OPENSSL_DYNAMIC
192+
int error = 0;
193+
194+
if (git_mutex_lock(&openssl_mutex) != 0)
195+
return -1;
196+
197+
if (!openssl_initialized) {
198+
if ((error = git_openssl_stream_dynamic_init()) == 0)
199+
error = openssl_init();
200+
201+
openssl_initialized = true;
202+
}
203+
204+
error |= git_mutex_unlock(&openssl_mutex);
205+
return error;
206+
207+
#else
208+
return 0;
209+
#endif
210+
}
211+
174212
#if !defined(GIT_OPENSSL_LEGACY) && !defined(GIT_OPENSSL_DYNAMIC)
175213
int git_openssl_set_locking(void)
176214
{
@@ -644,6 +682,9 @@ static int openssl_stream_wrap(
644682

645683
int git_openssl_stream_wrap(git_stream **out, git_stream *in, const char *host)
646684
{
685+
if (openssl_ensure_initialized() < 0)
686+
return -1;
687+
647688
return openssl_stream_wrap(out, in, host, 0);
648689
}
649690

@@ -656,6 +697,9 @@ int git_openssl_stream_new(git_stream **out, const char *host, const char *port)
656697
GIT_ASSERT_ARG(host);
657698
GIT_ASSERT_ARG(port);
658699

700+
if (openssl_ensure_initialized() < 0)
701+
return -1;
702+
659703
if ((error = git_socket_stream_new(&stream, host, port)) < 0)
660704
return error;
661705

@@ -669,6 +713,9 @@ int git_openssl_stream_new(git_stream **out, const char *host, const char *port)
669713

670714
int git_openssl__set_cert_location(const char *file, const char *path)
671715
{
716+
if (openssl_ensure_initialized() < 0)
717+
return -1;
718+
672719
if (SSL_CTX_load_verify_locations(git__ssl_ctx, file, path) == 0) {
673720
char errmsg[256];
674721

0 commit comments

Comments
 (0)