Skip to content

Commit ba56f78

Browse files
committed
streams: openssl: fix thread-safety for OpenSSL error messages
The function `ERR_error_string` can be invoked without providing a buffer, in which case OpenSSL will simply return a string printed into a static buffer. Obviously and as documented in ERR_error_string(3), this is not thread-safe at all. As libgit2 is a library, though, it is easily possible that other threads may be using OpenSSL at the same time, which might lead to clobbered error strings. Fix the issue by instead using a stack-allocated buffer. According to the documentation, the caller has to provide a buffer of at least 256 bytes of size. While we do so, make sure that the buffer will never get overflown by switching to `ERR_error_string_n` to specify the buffer's size.
1 parent 75e1737 commit ba56f78

File tree

1 file changed

+13
-5
lines changed

1 file changed

+13
-5
lines changed

src/streams/openssl.c

Lines changed: 13 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -282,8 +282,9 @@ static int ssl_set_error(SSL *ssl, int error)
282282
case SSL_ERROR_SYSCALL:
283283
e = ERR_get_error();
284284
if (e > 0) {
285-
giterr_set(GITERR_NET, "SSL error: %s",
286-
ERR_error_string(e, NULL));
285+
char errmsg[256];
286+
ERR_error_string_n(e, errmsg, sizeof(errmsg));
287+
giterr_set(GITERR_NET, "SSL error: %s", errmsg);
287288
break;
288289
} else if (error < 0) {
289290
giterr_set(GITERR_OS, "SSL error: syscall failure");
@@ -293,10 +294,13 @@ static int ssl_set_error(SSL *ssl, int error)
293294
return GIT_EEOF;
294295
break;
295296
case SSL_ERROR_SSL:
297+
{
298+
char errmsg[256];
296299
e = ERR_get_error();
297-
giterr_set(GITERR_NET, "SSL error: %s",
298-
ERR_error_string(e, NULL));
300+
ERR_error_string_n(e, errmsg, sizeof(errmsg));
301+
giterr_set(GITERR_NET, "SSL error: %s", errmsg);
299302
break;
303+
}
300304
case SSL_ERROR_NONE:
301305
case SSL_ERROR_ZERO_RETURN:
302306
default:
@@ -640,8 +644,12 @@ int git_openssl_stream_new(git_stream **out, const char *host, const char *port)
640644
int git_openssl__set_cert_location(const char *file, const char *path)
641645
{
642646
if (SSL_CTX_load_verify_locations(git__ssl_ctx, file, path) == 0) {
647+
char errmsg[256];
648+
649+
ERR_error_string_n(ERR_get_error(), errmsg, sizeof(errmsg));
643650
giterr_set(GITERR_SSL, "OpenSSL error: failed to load certificates: %s",
644-
ERR_error_string(ERR_get_error(), NULL));
651+
errmsg);
652+
645653
return -1;
646654
}
647655
return 0;

0 commit comments

Comments
 (0)