From: Jason Dillaman Date: Tue, 28 Jul 2015 17:14:29 +0000 (-0400) Subject: crypto: use NSS_InitContext/NSS_ShutdownContex to avoid memory leak X-Git-Tag: v0.94.4~29^2~4 X-Git-Url: http://git-server-git.apps.pok.os.sepia.ceph.com/?a=commitdiff_plain;h=f0fa637e4a91a93a326ba303bc22101fadcc787d;p=ceph.git crypto: use NSS_InitContext/NSS_ShutdownContex to avoid memory leak Switched to context-aware NSS init/shutdown functions to avoid conflicts with parent application. Use a reference counter to properly shutdown the NSS crypto library when the last CephContext is destroyed. This avoids memory leaks with the NSS library from users of librados. Signed-off-by: Jason Dillaman (cherry picked from commit 9fa0112dd9286178da1d76020158503b2062d252) --- diff --git a/src/common/ceph_context.cc b/src/common/ceph_context.cc index 79aff8b8cf18..6697142b3ebb 100644 --- a/src/common/ceph_context.cc +++ b/src/common/ceph_context.cc @@ -20,6 +20,7 @@ #include "common/perf_counters.h" #include "common/Thread.h" #include "common/ceph_context.h" +#include "common/ceph_crypto.h" #include "common/config.h" #include "common/debug.h" #include "common/HeartbeatMap.h" @@ -467,6 +468,7 @@ CephContext::~CephContext() delete _crypto_none; delete _crypto_aes; + ceph::crypto::shutdown(); } void CephContext::start_service_thread() diff --git a/src/common/ceph_crypto.cc b/src/common/ceph_crypto.cc index eb46672b917a..041fedad2406 100644 --- a/src/common/ceph_crypto.cc +++ b/src/common/ceph_crypto.cc @@ -12,6 +12,7 @@ * */ +#include "include/int_types.h" #include "common/config.h" #include "common/ceph_context.h" #include "ceph_crypto.h" @@ -40,37 +41,46 @@ ceph::crypto::HMACSHA1::~HMACSHA1() // for SECMOD_RestartModules() #include -// Initialization of NSS requires a mutex due to a race condition in -// NSS_NoDB_Init. static pthread_mutex_t crypto_init_mutex = PTHREAD_MUTEX_INITIALIZER; +static uint32_t crypto_refs = 0; +static NSSInitContext *crypto_context = NULL; static pid_t crypto_init_pid = 0; void ceph::crypto::init(CephContext *cct) { pid_t pid = getpid(); - SECStatus s; pthread_mutex_lock(&crypto_init_mutex); if (crypto_init_pid != pid) { - if (crypto_init_pid > 0) + if (crypto_init_pid > 0) { SECMOD_RestartModules(PR_FALSE); + } crypto_init_pid = pid; } - if (cct->_conf->nss_db_path.empty()) { - s = NSS_NoDB_Init(NULL); - } else { - s = NSS_Init(cct->_conf->nss_db_path.c_str()); + + if (++crypto_refs == 1) { + NSSInitParameters init_params; + memset(&init_params, 0, sizeof(init_params)); + init_params.length = sizeof(init_params); + + uint32_t flags = NSS_INIT_READONLY; + if (cct->_conf->nss_db_path.empty()) { + flags |= (NSS_INIT_NOCERTDB | NSS_INIT_NOMODDB); + } + crypto_context = NSS_InitContext(cct->_conf->nss_db_path.c_str(), "", "", + SECMOD_DB, &init_params, flags); } pthread_mutex_unlock(&crypto_init_mutex); - assert(s == SECSuccess); + assert(crypto_context != NULL); } void ceph::crypto::shutdown() { - SECStatus s; pthread_mutex_lock(&crypto_init_mutex); - s = NSS_Shutdown(); - assert(s == SECSuccess); - crypto_init_pid = 0; + if (--crypto_refs == 0) { + NSS_ShutdownContext(crypto_context); + crypto_context = NULL; + crypto_init_pid = 0; + } pthread_mutex_unlock(&crypto_init_mutex); } diff --git a/src/rgw/rgw_main.cc b/src/rgw/rgw_main.cc index af892c4058c2..0ddd9de272e0 100644 --- a/src/rgw/rgw_main.cc +++ b/src/rgw/rgw_main.cc @@ -1262,8 +1262,6 @@ int main(int argc, const char **argv) dout(1) << "final shutdown" << dendl; g_ceph_context->put(); - ceph::crypto::shutdown(); - signal_fd_finalize(); return 0; diff --git a/src/test/librbd/fsx.cc b/src/test/librbd/fsx.cc index c5ed1e60a8ca..2465417fccdc 100644 --- a/src/test/librbd/fsx.cc +++ b/src/test/librbd/fsx.cc @@ -42,7 +42,6 @@ #include "include/krbd.h" #include "include/rados/librados.h" #include "include/rbd/librbd.h" -#include "common/ceph_crypto.h" #define NUMPRINTCOLUMNS 32 /* # columns of data to print on each line */ @@ -2312,7 +2311,6 @@ main(int argc, char **argv) krbd_destroy(krbd); rados_shutdown(cluster); - ceph::crypto::shutdown(); free(original_buf); free(good_buf); free(temp_buf); diff --git a/src/test/librbd/test_main.cc b/src/test/librbd/test_main.cc index b68d4d28ca9d..2c6b15b405bf 100644 --- a/src/test/librbd/test_main.cc +++ b/src/test/librbd/test_main.cc @@ -3,7 +3,6 @@ #include "gtest/gtest.h" #include "common/ceph_argparse.h" -#include "common/ceph_crypto.h" #include "common/config.h" #include "global/global_context.h" #include "global/global_init.h" @@ -36,6 +35,5 @@ int main(int argc, char **argv) int r = RUN_ALL_TESTS(); g_ceph_context->put(); - ceph::crypto::shutdown(); return r; }