summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorPatrick Steinhardt <ps@pks.im>2018-01-03 12:54:42 +0000
committerPatrick Steinhardt <ps@pks.im>2018-01-03 12:54:42 +0000
commitba56f781a91487ad657e1a72888c914b1cec5de9 (patch)
tree18f7b495e1ccf15feb1e13413677e0d23e81adaf
parent75e1737a5173709b14b669bf08dae78232c6389d (diff)
downloadlibgit2-ba56f781a91487ad657e1a72888c914b1cec5de9.tar.gz
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.
-rw-r--r--src/streams/openssl.c18
1 files changed, 13 insertions, 5 deletions
diff --git a/src/streams/openssl.c b/src/streams/openssl.c
index 2b246002f..133d1416d 100644
--- a/src/streams/openssl.c
+++ b/src/streams/openssl.c
@@ -282,8 +282,9 @@ static int ssl_set_error(SSL *ssl, int error)
case SSL_ERROR_SYSCALL:
e = ERR_get_error();
if (e > 0) {
- giterr_set(GITERR_NET, "SSL error: %s",
- ERR_error_string(e, NULL));
+ char errmsg[256];
+ ERR_error_string_n(e, errmsg, sizeof(errmsg));
+ giterr_set(GITERR_NET, "SSL error: %s", errmsg);
break;
} else if (error < 0) {
giterr_set(GITERR_OS, "SSL error: syscall failure");
@@ -293,10 +294,13 @@ static int ssl_set_error(SSL *ssl, int error)
return GIT_EEOF;
break;
case SSL_ERROR_SSL:
+ {
+ char errmsg[256];
e = ERR_get_error();
- giterr_set(GITERR_NET, "SSL error: %s",
- ERR_error_string(e, NULL));
+ ERR_error_string_n(e, errmsg, sizeof(errmsg));
+ giterr_set(GITERR_NET, "SSL error: %s", errmsg);
break;
+ }
case SSL_ERROR_NONE:
case SSL_ERROR_ZERO_RETURN:
default:
@@ -640,8 +644,12 @@ out_err:
int git_openssl__set_cert_location(const char *file, const char *path)
{
if (SSL_CTX_load_verify_locations(git__ssl_ctx, file, path) == 0) {
+ char errmsg[256];
+
+ ERR_error_string_n(ERR_get_error(), errmsg, sizeof(errmsg));
giterr_set(GITERR_SSL, "OpenSSL error: failed to load certificates: %s",
- ERR_error_string(ERR_get_error(), NULL));
+ errmsg);
+
return -1;
}
return 0;