From f08ab2ae5a9ce1ed7d5187f5e93a7e7854faacf3 Mon Sep 17 00:00:00 2001 From: Rich Megginson Date: Jan 07 2011 21:29:43 +0000 Subject: Bug 664671 - Admin server segfault when full SSL access (http+ldap+console) required https://bugzilla.redhat.com/show_bug.cgi?id=664671 Resolves: bug 664671 Bug Description: Admin server segfault when full SSL access (http+ldap+console) required Reviewed by: ??? Branch: master Fix Description: Do not call NSS_Shutdown in mod_admserv. It should always be called in mod_nss, after mod_admserv_unload is called. The only thing we need to do in mod_admserv_unload() is to clear the session cache to release any resources acquired by mod_admserv. mod_nss unload will take care of the rest. Platforms tested: RHEL5 i386 Flag Day: no Doc impact: no --- diff --git a/mod_admserv/mod_admserv.c b/mod_admserv/mod_admserv.c index ec7397c..6f96669 100644 --- a/mod_admserv/mod_admserv.c +++ b/mod_admserv/mod_admserv.c @@ -2223,28 +2223,23 @@ host_ip_init(apr_pool_t *p, apr_pool_t *plog, * NSS caches SSL client session information - this cache must be cleared, otherwise * NSS_Shutdown will give an error. mod_nss also does this (along with the NSS_Shutdown) * It is ok to call SSL_ClearSessionCache multiple times. + * The actual NSS_Shutdown is done in mod_nss. Note that we cannot call NSS_Shutdown + * here - if NSS_Shutdown fails because mod_nss still has server caches referenced, + * NSS will be left in a bad state - it won't really be shutdown because of the outstanding + * references, but NSS_IsInitialized will return false, and NSS_Initialize will fail. + * So we must be careful here to just release any references we have. + * The assumption here is that mod_nss is loaded before mod_admserv (which will usually + * happen since it is listed first in the httpd.conf) - but note that module unload + * happens in _reverse_ order - so mod_admserv_unload will be called _before_ the + * mod_nss unload function. If this ever changes, we will need to figure out some other + * way to ensure that NSS_Shutdown is only ever called once, and only after all caches + * and other resources have been released. */ static apr_status_t mod_admserv_unload(void *data) { if (NSS_IsInitialized()) { - SECStatus status; SSL_ClearSessionCache(); - status = NSS_Shutdown(); - if (status != SECSuccess) { - PRErrorCode prerr = PR_GetError(); - if (prerr == SEC_ERROR_NOT_INITIALIZED) { - ap_log_error(APLOG_MARK, APLOG_NOTICE, 0, NULL, - "Unable to shutdown NSS - not initialized"); - } else if (prerr == SEC_ERROR_BUSY) { - ap_log_error(APLOG_MARK, APLOG_NOTICE, 0, NULL, - "Unable to shutdown NSS - still busy - assume mod_nss is holding references - continuing"); - } else { - ap_log_error(APLOG_MARK, APLOG_WARNING, 0, NULL, - "Unable to shutdown NSS - [%d:%s]", - prerr, SSL_Strerror(prerr)); - } - } } return OK; }