From 13a6ac59ad4825eac4cbe477df936d159b385eef Mon Sep 17 00:00:00 2001 From: "Roland C. Dowdeswell" Date: Tue, 17 Jul 2012 19:38:46 +0100 Subject: [PATCH] Fix memory leak in hx509_context_init(). OpenSSL_add_all_algorithms() should only be run once per application or it will cause data structures to expand. It's not a classic memory leak as all of the memory will be free(3)d when EVP_cleanup() is called but as we are a library we cannot call this. We provide a short term fix here which is using heim_base_once_f() to ensure that we only call it once. But the long term fix should be to stop using OpenSSL_add_all_algorithms() entirely because it both has side effects outside our library and the caller may destroy our OpenSSL global variables by calling EVP_cleanup() on his own. It is suboptimal to have potential interactions between our library and other code in this way. --- lib/hx509/cert.c | 15 ++++++++++++--- 1 file changed, 12 insertions(+), 3 deletions(-) diff --git a/lib/hx509/cert.c b/lib/hx509/cert.c index 5b90da052..a33685c43 100644 --- a/lib/hx509/cert.c +++ b/lib/hx509/cert.c @@ -93,6 +93,14 @@ typedef struct hx509_name_constraints { #define GeneralSubtrees_SET(g,var) \ (g)->len = (var)->len, (g)->val = (var)->val; +static void +init_context_once(void *ignored) +{ + + ENGINE_add_conf_module(); + OpenSSL_add_all_algorithms(); +} + /** * Creates a hx509 context that most functions in the library * uses. The context is only allowed to be used by one thread at each @@ -108,10 +116,14 @@ typedef struct hx509_name_constraints { int hx509_context_init(hx509_context *context) { + static heim_base_once_t init_context = HEIM_BASE_ONCE_INIT; + *context = calloc(1, sizeof(**context)); if (*context == NULL) return ENOMEM; + heim_base_once_f(&init_context, NULL, init_context_once); + _hx509_ks_null_register(*context); _hx509_ks_mem_register(*context); _hx509_ks_file_register(*context); @@ -120,9 +132,6 @@ hx509_context_init(hx509_context *context) _hx509_ks_dir_register(*context); _hx509_ks_keychain_register(*context); - ENGINE_add_conf_module(); - OpenSSL_add_all_algorithms(); - (*context)->ocsp_time_diff = HX509_DEFAULT_OCSP_TIME_DIFF; initialize_hx_error_table_r(&(*context)->et_list);