Skip to content

Commit

Permalink
apr_crypto: fix potential memory leaks of cprng_stream_ctx_t.
Browse files Browse the repository at this point in the history
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



git-svn-id: https://svn.apache.org/repos/asf/apr/apr/trunk@1893201 13f79535-47bb-0310-9956-ffa450edef68
  • Loading branch information
ylavic committed Sep 10, 2021
1 parent 90a2a77 commit 398fc32
Showing 1 changed file with 18 additions and 6 deletions.
24 changes: 18 additions & 6 deletions crypto/apr_crypto_openssl.c
Original file line number Diff line number Diff line change
Expand Up @@ -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[] =
Expand Down Expand Up @@ -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)
{
Expand All @@ -1554,8 +1565,10 @@ static apr_status_t cprng_stream_ctx_make(cprng_stream_ctx_t **psctx,
return APR_ENOMEM;
}

sctx->malloced = !pool;
sctx->ctx = ctx = EVP_CIPHER_CTX_new();
if (!ctx) {
cprng_stream_ctx_free(sctx);
return APR_ENOMEM;
}

Expand All @@ -1573,6 +1586,7 @@ static apr_status_t cprng_stream_ctx_make(cprng_stream_ctx_t **psctx,
#elif defined(NID_aes_256_ctr)
ecipher = EVP_aes_256_ctr();
#else
cprng_stream_ctx_free(sctx);
return APR_ENOCIPHER;
#endif
}
Expand All @@ -1581,6 +1595,7 @@ static apr_status_t cprng_stream_ctx_make(cprng_stream_ctx_t **psctx,
ecipher = EVP_aes_256_ctr();
break;
#else
cprng_stream_ctx_free(sctx);
return APR_ENOCIPHER;
#endif
}
Expand All @@ -1589,27 +1604,24 @@ static apr_status_t cprng_stream_ctx_make(cprng_stream_ctx_t **psctx,
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,
Expand Down

0 comments on commit 398fc32

Please sign in to comment.