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
This commit is contained in:
Jan Vcelak 2012-01-25 16:19:45 +01:00 committed by Howard Chu
parent 1107103dd7
commit 4e9926ca97

View File

@ -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;
}