openssl: RAND_DRBG does not free related pointers
RAND_DRBG is not freeing pointers created before and linked into RAND_DRBG* like EVP_CIPHERs.
void RAND_DRBG_free(RAND_DRBG *drbg)
{
if (drbg == NULL)
return;
if (drbg->meth != NULL)
drbg->meth->uninstantiate(drbg);
rand_pool_free(drbg->adin_pool);
CRYPTO_THREAD_lock_free(drbg->lock);
CRYPTO_free_ex_data(CRYPTO_EX_INDEX_DRBG, drbg, &drbg->ex_data);
if (drbg->secure)
OPENSSL_secure_clear_free(drbg, sizeof(*drbg));
else
OPENSSL_clear_free(drbg, sizeof(*drbg));
}
[16:13:30] 798 file=crypto/rand/rand_lib.c, line=444, thread=15072, number=12288, address=0x2610a830 [16:13:30] 787 file=crypto/rand/drbg_lib.c, line=191, thread=15072, number=360, address=0x261005d0 [16:13:30] 803 file=crypto/evp/evp_enc.c, line=42, thread=15072, number=160, address=0x2610d9b0 [16:13:30] 788 file=crypto/evp/evp_enc.c, line=42, thread=15072, number=160, address=0x26100740 [16:13:30] 813 file=crypto/rand/rand_lib.c, line=444, thread=15072, number=12288, address=0x2610fb20 [16:13:30] 804 file=crypto/evp/evp_enc.c, line=42, thread=15072, number=160, address=0x2610da60 [16:13:30] 790 file=crypto/evp/evp_enc.c, line=128, thread=15072, number=264, address=0x111d2f0 [16:13:30] 812 file=crypto/rand/rand_lib.c, line=433, thread=15072, number=56, address=0x2610de30 [16:13:30] 789 file=crypto/evp/evp_enc.c, line=42, thread=15072, number=160, address=0x2610a780 [16:13:30] 801 file=crypto/evp/evp_enc.c, line=128, thread=15072, number=264, address=0x111cfc0 [16:13:30] 797 file=crypto/rand/rand_lib.c, line=433, thread=15072, number=56, address=0x26108b50 [16:13:30] 805 file=crypto/evp/evp_enc.c, line=128, thread=15072, number=264, address=0x111cc90 [16:13:30] 822 file=crypto/evp/evp_enc.c, line=128, thread=15072, number=264, address=0x111c630 [16:13:30] 802 file=crypto/rand/drbg_lib.c, line=191, thread=15072, number=360, address=0x2610d840 27104 bytes leaked in 14 chunks
About this issue
- Original URL
- State: open
- Created 5 years ago
- Comments: 25 (9 by maintainers)
Not quite.
It looks like all the cleanup keys off of this
handfnparameter toossl_init_thread_start. https://github.com/openssl/openssl/blob/master/crypto/rand/rand_lib.c#L725 https://github.com/openssl/openssl/blob/master/crypto/initthread.c#L346 Which is called ininit_thread_stop. https://github.com/openssl/openssl/blob/master/crypto/initthread.c#L303That’s called in a bunch of places, but I gather this is the important one: https://github.com/openssl/openssl/blob/master/crypto/initthread.c#L195C13-L209
On pthreads, the
cleanupparameter toCRYPTO_THREAD_init_localis registered as a cleanup handler. https://github.com/openssl/openssl/blob/master/crypto/threads_pthread.c#L160But the parameter is silently ignored on Windows. So, on Windows, OpenSSL will leak this state if nothing calls
OPENSSL_thread_stop. https://github.com/openssl/openssl/blob/master/crypto/threads_win.c#L154There’s a
DLL_THREAD_DETACHhandler here, which calls it: https://github.com/openssl/openssl/blob/master/crypto/dllmain.c#L38But per the docs, it doesn’t work when OpenSSL is linked statically on Windows. In that case, OpenSSL currently makes it the application’s responsibility to call
OPENSSL_thread_stopon exit of every thread where OpenSSL is used. This is sufficiently non-obvious that it’s probably worth calling out more prominently. https://www.openssl.org/docs/man3.0/man3/OPENSSL_thread_stop.html#NOTESCRYPTO_THREAD_init_localis also public API, but I don’t see any documentation that its cleanup function doesn’t work.(It is possible to register a destructor with the thread-locals on Windows that works with static linking. We do it in BoringSSL and Chromium. But it’s pretty gnarly. I believe the C++11
thread_localkeyword ultimately keys off of that mechanism on Windows.)I can confirm the same leak with openSSL 1.1.1f is still there: mem.c:198 CRYPTO_malloc() mem.c:230 CRYPTO_zalloc() evp_enc.c:128 EVP_CipherInit_ex() drbg_ctr.c:274 ctr_update() drbg_ctr.c:349 drbg_ctr_generate() drbg_lib.c:641 RAND_DRBG_generate() drbg_lib.c:682 RAND_DRBG_bytes() drbg_lib.c:971 drbg_bytes() rand_lib.c:939 RAND_bytes()