diff --git a/lib/includes/gnutls/crypto.h b/lib/includes/gnutls/crypto.h old mode 100644 new mode 100755 index 4d4926c..fa6b004 --- a/lib/includes/gnutls/crypto.h +++ b/lib/includes/gnutls/crypto.h @@ -162,6 +162,7 @@ int gnutls_rnd(gnutls_rnd_level_t level, void *data, size_t len); void gnutls_rnd_refresh(void); +void gnutls_rnd_ctx_free(void); /* API to override ciphers and MAC algorithms */ diff --git a/lib/libgnutls.map b/lib/libgnutls.map old mode 100644 new mode 100755 index 6e1da85..cb4a18f --- a/lib/libgnutls.map +++ b/lib/libgnutls.map @@ -861,6 +861,7 @@ GNUTLS_3_4 gnutls_pkcs11_token_get_flags; gnutls_pubkey_import_ecc_x962; gnutls_rnd_refresh; + gnutls_rnd_ctx_free; gnutls_mac_get_nonce_size; gnutls_x509_crl_get_raw_issuer_dn; gnutls_certificate_get_crt_raw; diff --git a/lib/random.c b/lib/random.c old mode 100644 new mode 100755 index 6462738..db85868 --- a/lib/random.c +++ b/lib/random.c @@ -191,3 +191,40 @@ void gnutls_rnd_refresh(void) if (rnd_initialized && _gnutls_rnd_ops.rnd_refresh) _gnutls_rnd_ops.rnd_refresh(gnutls_rnd_ctx); } + +/** + * gnutls_rnd_ctx_free: + * + * Modification to prevent heap exhaustion by + * freeing this threads random generator context. + * Only necessary to call in long running processes that + * don't routinely free the global list of contexts. + */ +void gnutls_rnd_ctx_free(void) +{ + GNUTLS_STATIC_MUTEX_LOCK(gnutls_rnd_ctx_list_mutex); + if (_gnutls_rnd_ops.deinit != NULL) { + struct rnd_ctx_list_st *e = head, *prev = head, *next; + + while (e != NULL) { + next = e->next; + if (e->ctx == gnutls_rnd_ctx) { + if (e == head) { + head = next; + } else { + prev->next = next; + } + _gnutls_rnd_ops.deinit(e->ctx); + gnutls_free(e); + break; + } + prev = e; + e = next; + } + } + + rnd_initialized = 0; + GNUTLS_STATIC_MUTEX_UNLOCK(gnutls_rnd_ctx_list_mutex); +}