Commit ba56f781 by Patrick Steinhardt

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.
parent 75e1737a
...@@ -282,8 +282,9 @@ static int ssl_set_error(SSL *ssl, int error) ...@@ -282,8 +282,9 @@ static int ssl_set_error(SSL *ssl, int error)
case SSL_ERROR_SYSCALL: case SSL_ERROR_SYSCALL:
e = ERR_get_error(); e = ERR_get_error();
if (e > 0) { if (e > 0) {
giterr_set(GITERR_NET, "SSL error: %s", char errmsg[256];
ERR_error_string(e, NULL)); ERR_error_string_n(e, errmsg, sizeof(errmsg));
giterr_set(GITERR_NET, "SSL error: %s", errmsg);
break; break;
} else if (error < 0) { } else if (error < 0) {
giterr_set(GITERR_OS, "SSL error: syscall failure"); giterr_set(GITERR_OS, "SSL error: syscall failure");
...@@ -293,10 +294,13 @@ static int ssl_set_error(SSL *ssl, int error) ...@@ -293,10 +294,13 @@ static int ssl_set_error(SSL *ssl, int error)
return GIT_EEOF; return GIT_EEOF;
break; break;
case SSL_ERROR_SSL: case SSL_ERROR_SSL:
{
char errmsg[256];
e = ERR_get_error(); e = ERR_get_error();
giterr_set(GITERR_NET, "SSL error: %s", ERR_error_string_n(e, errmsg, sizeof(errmsg));
ERR_error_string(e, NULL)); giterr_set(GITERR_NET, "SSL error: %s", errmsg);
break; break;
}
case SSL_ERROR_NONE: case SSL_ERROR_NONE:
case SSL_ERROR_ZERO_RETURN: case SSL_ERROR_ZERO_RETURN:
default: default:
...@@ -640,8 +644,12 @@ out_err: ...@@ -640,8 +644,12 @@ out_err:
int git_openssl__set_cert_location(const char *file, const char *path) int git_openssl__set_cert_location(const char *file, const char *path)
{ {
if (SSL_CTX_load_verify_locations(git__ssl_ctx, file, path) == 0) { 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", giterr_set(GITERR_SSL, "OpenSSL error: failed to load certificates: %s",
ERR_error_string(ERR_get_error(), NULL)); errmsg);
return -1; return -1;
} }
return 0; return 0;
......
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment