From 4e9926ca9719a0dab8c780d3d2f4cf4bfc03bfdc Mon Sep 17 00:00:00 2001 From: Jan Vcelak Date: Wed, 25 Jan 2012 16:19:45 +0100 Subject: [PATCH] ITS#7136 MozNSS: store TLS params until the deferred initialization is finished Deferred TLS initialization is used with Mozilla NSS. The real initialization takes place when the TLS context is needed for the first time. If the initialization parameters were freed immediately after tlsm_ctx_init was called, they were not available at the time of deferred initialization which caused segmentation fault. With this patch, initialization parameters are copied and stored until the deferred initialization is finished. The parameters are freed afterwards. Red Hat Bugzilla: #783431 --- libraries/libldap/tls_m.c | 72 +++++++++++++++++++++++++++++++++++++-- 1 file changed, 70 insertions(+), 2 deletions(-) diff --git a/libraries/libldap/tls_m.c b/libraries/libldap/tls_m.c index da230c58d5..092b59f925 100644 --- a/libraries/libldap/tls_m.c +++ b/libraries/libldap/tls_m.c @@ -1960,6 +1960,66 @@ tlsm_destroy( void ) #endif } +static struct ldaptls * +tlsm_copy_config ( const struct ldaptls *config ) +{ + struct ldaptls *copy; + + assert(config); + + copy = LDAP_MALLOC(sizeof(*copy)); + if (!copy) + return NULL; + + memset(copy, 0, sizeof(*copy)); + + if (config->lt_certfile) + copy->lt_certfile = LDAP_STRDUP(config->lt_certfile); + if (config->lt_keyfile) + copy->lt_keyfile = LDAP_STRDUP(config->lt_keyfile); + if (config->lt_dhfile) + copy->lt_dhfile = LDAP_STRDUP(config->lt_dhfile); + if (config->lt_cacertfile) + copy->lt_cacertfile = LDAP_STRDUP(config->lt_cacertfile); + if (config->lt_cacertdir) + copy->lt_cacertdir = LDAP_STRDUP(config->lt_cacertdir); + if (config->lt_ciphersuite) + copy->lt_ciphersuite = LDAP_STRDUP(config->lt_ciphersuite); + if (config->lt_crlfile) + copy->lt_crlfile = LDAP_STRDUP(config->lt_crlfile); + if (config->lt_randfile) + copy->lt_randfile = LDAP_STRDUP(config->lt_randfile); + + copy->lt_protocol_min = config->lt_protocol_min; + + return copy; +} + +static void +tlsm_free_config ( struct ldaptls *config ) +{ + assert(config); + + if (config->lt_certfile) + LDAP_FREE(config->lt_certfile); + if (config->lt_keyfile) + LDAP_FREE(config->lt_keyfile); + if (config->lt_dhfile) + LDAP_FREE(config->lt_dhfile); + if (config->lt_cacertfile) + LDAP_FREE(config->lt_cacertfile); + if (config->lt_cacertdir) + LDAP_FREE(config->lt_cacertdir); + if (config->lt_ciphersuite) + LDAP_FREE(config->lt_ciphersuite); + if (config->lt_crlfile) + LDAP_FREE(config->lt_crlfile); + if (config->lt_randfile) + LDAP_FREE(config->lt_randfile); + + LDAP_FREE(config); +} + static tls_ctx * tlsm_ctx_new ( struct ldapoptions *lo ) { @@ -1971,7 +2031,7 @@ tlsm_ctx_new ( struct ldapoptions *lo ) #ifdef LDAP_R_COMPILE ldap_pvt_thread_mutex_init( &ctx->tc_refmutex ); #endif - ctx->tc_config = &lo->ldo_tls_info; /* pointer into lo structure - must have global scope and must not go away before we can do real init */ + ctx->tc_config = NULL; /* populated later by tlsm_ctx_init */ ctx->tc_certdb = NULL; ctx->tc_certname = NULL; ctx->tc_pin_file = NULL; @@ -2038,6 +2098,10 @@ tlsm_ctx_free ( tls_ctx *ctx ) #ifdef LDAP_R_COMPILE ldap_pvt_thread_mutex_destroy( &c->tc_refmutex ); #endif + + if ( c->tc_config ) + tlsm_free_config( c->tc_config ); + LDAP_FREE( c ); } @@ -2048,6 +2112,7 @@ static int tlsm_ctx_init( struct ldapoptions *lo, struct ldaptls *lt, int is_server ) { tlsm_ctx *ctx = (tlsm_ctx *)lo->ldo_tls_ctx; + ctx->tc_config = tlsm_copy_config(lt); ctx->tc_is_server = is_server; return 0; @@ -2067,7 +2132,7 @@ tlsm_deferred_ctx_init( void *arg ) if ( tlsm_deferred_init( ctx ) ) { Debug( LDAP_DEBUG_ANY, - "TLS: could perform TLS system initialization.\n", + "TLS: could not perform TLS system initialization.\n", 0, 0, 0 ); return -1; } @@ -2333,6 +2398,9 @@ tlsm_deferred_ctx_init( void *arg ) return -1; } + tlsm_free_config( ctx->tc_config ); + ctx->tc_config = NULL; + return 0; } -- 2.39.5