You are viewing a plain text version of this content. The canonical link for it is here.
Posted to commits@apr.apache.org by yl...@apache.org on 2021/09/10 00:16:15 UTC

svn commit: r1893201 - /apr/apr/trunk/crypto/apr_crypto_openssl.c

Author: ylavic
Date: Fri Sep 10 00:16:15 2021
New Revision: 1893201

URL: http://svn.apache.org/viewvc?rev=1893201&view=rev
Log:
apr_crypto: fix potential memory leaks of cprng_stream_ctx_t.

This can happen in cprng_stream_ctx_make() on error paths, or at thread exit
with APR_CRYPTO_PRNG_PER_THREAD like the below.

Direct leak of 64 byte(s) in 8 object(s) allocated from:
    #0 0x7efd954c7628 in malloc (/usr/lib/x86_64-linux-gnu/libasan.so.5+0x107628)
    #1 0x7efd921db6ca  (<unknown module>)
    #2 0x7efd952937a2 in apr_crypto_prng_create crypto/apr_crypto_prng.c:367
    #3 0x7efd95292c1e in apr_crypto_random_thread_bytes crypto/apr_crypto_prng.c:218
    #4 0x5611dbbb9440 in thread_func /home/yle/src/apache/apr/trunk.ro/test/testcrypto.c:2597
    #5 0x7efd9537dd86 in dummy_worker threadproc/unix/thread.c:148
    #6 0x7efd951efea6 in start_thread nptl/pthread_create.c:477


Modified:
    apr/apr/trunk/crypto/apr_crypto_openssl.c

Modified: apr/apr/trunk/crypto/apr_crypto_openssl.c
URL: http://svn.apache.org/viewvc/apr/apr/trunk/crypto/apr_crypto_openssl.c?rev=1893201&r1=1893200&r2=1893201&view=diff
==============================================================================
--- apr/apr/trunk/crypto/apr_crypto_openssl.c (original)
+++ apr/apr/trunk/crypto/apr_crypto_openssl.c Fri Sep 10 00:16:15 2021
@@ -112,6 +112,7 @@ struct apr_crypto_digest_t {
 
 struct cprng_stream_ctx_t {
     EVP_CIPHER_CTX *ctx;
+    int malloced;
 };
 
 static struct apr_crypto_block_key_digest_t key_digests[] =
@@ -1537,6 +1538,16 @@ static apr_status_t crypto_digest(
     return status;
 }
 
+static void cprng_stream_ctx_free(cprng_stream_ctx_t *sctx)
+{
+    if (sctx->ctx) {
+        EVP_CIPHER_CTX_free(sctx->ctx);
+    }
+    if (sctx->malloced) {
+        free(sctx);
+    }
+}
+
 static apr_status_t cprng_stream_ctx_make(cprng_stream_ctx_t **psctx,
         apr_crypto_t *f, apr_crypto_cipher_e cipher, apr_pool_t *pool)
 {
@@ -1554,8 +1565,10 @@ static apr_status_t cprng_stream_ctx_mak
         return APR_ENOMEM;
     }
 
+    sctx->malloced = !pool;
     sctx->ctx = ctx = EVP_CIPHER_CTX_new();
     if (!ctx) {
+        cprng_stream_ctx_free(sctx);
         return APR_ENOMEM;
     }
 
@@ -1573,6 +1586,7 @@ static apr_status_t cprng_stream_ctx_mak
 #elif defined(NID_aes_256_ctr)
         ecipher = EVP_aes_256_ctr();
 #else
+        cprng_stream_ctx_free(sctx);
         return APR_ENOCIPHER;
 #endif
     }
@@ -1581,6 +1595,7 @@ static apr_status_t cprng_stream_ctx_mak
         ecipher = EVP_aes_256_ctr();
         break;
 #else
+        cprng_stream_ctx_free(sctx);
         return APR_ENOCIPHER;
 #endif
     }
@@ -1589,27 +1604,24 @@ static apr_status_t cprng_stream_ctx_mak
         ecipher = EVP_chacha20();
         break;
 #else
+        cprng_stream_ctx_free(sctx);
         return APR_ENOCIPHER;
 #endif
     }
     default: {
+        cprng_stream_ctx_free(sctx);
         return APR_ENOCIPHER;
     }
     }
 
     if (EVP_EncryptInit_ex(ctx, ecipher, f->config->engine, NULL, NULL) <= 0) {
-        EVP_CIPHER_CTX_free(ctx);
+        cprng_stream_ctx_free(sctx);
         return APR_ENOMEM;
     }
 
     return APR_SUCCESS;
 }
 
-static void cprng_stream_ctx_free(cprng_stream_ctx_t *sctx)
-{
-    EVP_CIPHER_CTX_free(sctx->ctx);
-}
-
 static APR_INLINE
 void cprng_stream_setkey(cprng_stream_ctx_t *sctx,
                          const unsigned char *key,