]> git.proxmox.com Git - libgit2.git/blobdiff - src/streams/openssl.c
New upstream version 1.1.0+dfsg.1
[libgit2.git] / src / streams / openssl.c
index fe5f79cce84d34be68466a498ee521ed7d9ca744..6a490d17d2e787bf200081dda865283fe77dffa6 100644 (file)
@@ -156,7 +156,7 @@ static void openssl_locking_function(
        lock = mode & CRYPTO_LOCK;
 
        if (lock) {
-               git_mutex_lock(&openssl_locks[n]);
+               (void)git_mutex_lock(&openssl_locks[n]);
        } else {
                git_mutex_unlock(&openssl_locks[n]);
        }
@@ -196,16 +196,69 @@ static void shutdown_ssl(void)
        }
 }
 
+#ifdef VALGRIND
+#ifdef OPENSSL_LEGACY_API
+static void *git_openssl_malloc(size_t bytes)
+{
+       return git__calloc(1, bytes);
+}
+
+static void *git_openssl_realloc(void *mem, size_t size)
+{
+       return git__realloc(mem, size);
+}
+
+static void git_openssl_free(void *mem)
+{
+       return git__free(mem);
+}
+#else
+static void *git_openssl_malloc(size_t bytes, const char *file, int line)
+{
+       GIT_UNUSED(file);
+       GIT_UNUSED(line);
+       return git__calloc(1, bytes);
+}
+
+static void *git_openssl_realloc(void *mem, size_t size, const char *file, int line)
+{
+       GIT_UNUSED(file);
+       GIT_UNUSED(line);
+       return git__realloc(mem, size);
+}
+
+static void git_openssl_free(void *mem, const char *file, int line)
+{
+       GIT_UNUSED(file);
+       GIT_UNUSED(line);
+       return git__free(mem);
+}
+#endif
+#endif
+
 int git_openssl_stream_global_init(void)
 {
        long ssl_opts = SSL_OP_NO_SSLv2 | SSL_OP_NO_SSLv3;
        const char *ciphers = git_libgit2__ssl_ciphers();
+#ifdef VALGRIND
+       static bool allocators_initialized = false;
+#endif
 
        /* Older OpenSSL and MacOS OpenSSL doesn't have this */
 #ifdef SSL_OP_NO_COMPRESSION
        ssl_opts |= SSL_OP_NO_COMPRESSION;
 #endif
 
+#ifdef VALGRIND
+       /* Swap in our own allocator functions that initialize allocated memory */
+       if (!allocators_initialized &&
+           CRYPTO_set_mem_functions(git_openssl_malloc,
+                                    git_openssl_realloc,
+                                    git_openssl_free) != 1)
+               goto error;
+       allocators_initialized = true;
+#endif
+
        OPENSSL_init_ssl(0, NULL);
 
        /*
@@ -310,7 +363,6 @@ static int bio_read(BIO *b, char *buf, int len)
 static int bio_write(BIO *b, const char *buf, int len)
 {
        git_stream *io = (git_stream *) BIO_get_data(b);
-
        return (int) git_stream_write(io, buf, len, 0);
 }
 
@@ -603,15 +655,16 @@ static int openssl_connect(git_stream *stream)
 static int openssl_certificate(git_cert **out, git_stream *stream)
 {
        openssl_stream *st = (openssl_stream *) stream;
-       int len;
        X509 *cert = SSL_get_peer_certificate(st->ssl);
-       unsigned char *guard, *encoded_cert;
+       unsigned char *guard, *encoded_cert = NULL;
+       int error, len;
 
        /* Retrieve the length of the certificate first */
        len = i2d_X509(cert, NULL);
        if (len < 0) {
                git_error_set(GIT_ERROR_NET, "failed to retrieve certificate information");
-               return -1;
+               error = -1;
+               goto out;
        }
 
        encoded_cert = git__malloc(len);
@@ -621,18 +674,23 @@ static int openssl_certificate(git_cert **out, git_stream *stream)
 
        len = i2d_X509(cert, &guard);
        if (len < 0) {
-               git__free(encoded_cert);
                git_error_set(GIT_ERROR_NET, "failed to retrieve certificate information");
-               return -1;
+               error = -1;
+               goto out;
        }
 
        st->cert_info.parent.cert_type = GIT_CERT_X509;
        st->cert_info.data = encoded_cert;
        st->cert_info.len = len;
+       encoded_cert = NULL;
 
        *out = &st->cert_info.parent;
+       error = 0;
 
-       return 0;
+out:
+       git__free(encoded_cert);
+       X509_free(cert);
+       return error;
 }
 
 static int openssl_set_proxy(git_stream *stream, const git_proxy_options *proxy_opts)