Skip to content

Commit 398fc32

Browse files
committed
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 git-svn-id: https://svn.apache.org/repos/asf/apr/apr/trunk@1893201 13f79535-47bb-0310-9956-ffa450edef68
1 parent 90a2a77 commit 398fc32

File tree

1 file changed

+18
-6
lines changed

1 file changed

+18
-6
lines changed

crypto/apr_crypto_openssl.c

Lines changed: 18 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -112,6 +112,7 @@ struct apr_crypto_digest_t {
112112

113113
struct cprng_stream_ctx_t {
114114
EVP_CIPHER_CTX *ctx;
115+
int malloced;
115116
};
116117

117118
static struct apr_crypto_block_key_digest_t key_digests[] =
@@ -1537,6 +1538,16 @@ static apr_status_t crypto_digest(
15371538
return status;
15381539
}
15391540

1541+
static void cprng_stream_ctx_free(cprng_stream_ctx_t *sctx)
1542+
{
1543+
if (sctx->ctx) {
1544+
EVP_CIPHER_CTX_free(sctx->ctx);
1545+
}
1546+
if (sctx->malloced) {
1547+
free(sctx);
1548+
}
1549+
}
1550+
15401551
static apr_status_t cprng_stream_ctx_make(cprng_stream_ctx_t **psctx,
15411552
apr_crypto_t *f, apr_crypto_cipher_e cipher, apr_pool_t *pool)
15421553
{
@@ -1554,8 +1565,10 @@ static apr_status_t cprng_stream_ctx_make(cprng_stream_ctx_t **psctx,
15541565
return APR_ENOMEM;
15551566
}
15561567

1568+
sctx->malloced = !pool;
15571569
sctx->ctx = ctx = EVP_CIPHER_CTX_new();
15581570
if (!ctx) {
1571+
cprng_stream_ctx_free(sctx);
15591572
return APR_ENOMEM;
15601573
}
15611574

@@ -1573,6 +1586,7 @@ static apr_status_t cprng_stream_ctx_make(cprng_stream_ctx_t **psctx,
15731586
#elif defined(NID_aes_256_ctr)
15741587
ecipher = EVP_aes_256_ctr();
15751588
#else
1589+
cprng_stream_ctx_free(sctx);
15761590
return APR_ENOCIPHER;
15771591
#endif
15781592
}
@@ -1581,6 +1595,7 @@ static apr_status_t cprng_stream_ctx_make(cprng_stream_ctx_t **psctx,
15811595
ecipher = EVP_aes_256_ctr();
15821596
break;
15831597
#else
1598+
cprng_stream_ctx_free(sctx);
15841599
return APR_ENOCIPHER;
15851600
#endif
15861601
}
@@ -1589,27 +1604,24 @@ static apr_status_t cprng_stream_ctx_make(cprng_stream_ctx_t **psctx,
15891604
ecipher = EVP_chacha20();
15901605
break;
15911606
#else
1607+
cprng_stream_ctx_free(sctx);
15921608
return APR_ENOCIPHER;
15931609
#endif
15941610
}
15951611
default: {
1612+
cprng_stream_ctx_free(sctx);
15961613
return APR_ENOCIPHER;
15971614
}
15981615
}
15991616

16001617
if (EVP_EncryptInit_ex(ctx, ecipher, f->config->engine, NULL, NULL) <= 0) {
1601-
EVP_CIPHER_CTX_free(ctx);
1618+
cprng_stream_ctx_free(sctx);
16021619
return APR_ENOMEM;
16031620
}
16041621

16051622
return APR_SUCCESS;
16061623
}
16071624

1608-
static void cprng_stream_ctx_free(cprng_stream_ctx_t *sctx)
1609-
{
1610-
EVP_CIPHER_CTX_free(sctx->ctx);
1611-
}
1612-
16131625
static APR_INLINE
16141626
void cprng_stream_setkey(cprng_stream_ctx_t *sctx,
16151627
const unsigned char *key,

0 commit comments

Comments
 (0)