]> git-server-git.apps.pok.os.sepia.ceph.com Git - ceph.git/commitdiff
crypto: use NSS_InitContext/NSS_ShutdownContex to avoid memory leak
authorJason Dillaman <dillaman@redhat.com>
Tue, 28 Jul 2015 17:14:29 +0000 (13:14 -0400)
committerLoic Dachary <ldachary@redhat.com>
Sun, 6 Sep 2015 14:05:30 +0000 (16:05 +0200)
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 <dillaman@redhat.com>
(cherry picked from commit 9fa0112dd9286178da1d76020158503b2062d252)

src/common/ceph_context.cc
src/common/ceph_crypto.cc
src/rgw/rgw_main.cc
src/test/librbd/fsx.cc
src/test/librbd/test_main.cc

index 79aff8b8cf181a144d54497776ae130a6f6ebac4..6697142b3ebb7a815102fe7e2842ca57701b9618 100644 (file)
@@ -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()
index eb46672b917a82a79145aecdff0daa9ca0278035..041fedad24061c04c17ab2147191aa1089c1dc0b 100644 (file)
@@ -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 <secmod.h>
 
-// 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);
 }
 
index af892c4058c29c78f6b368268c8dc5815d0cd817..0ddd9de272e0506daa063dbec1053de0041194bf 100644 (file)
@@ -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;
index c5ed1e60a8ca9fe491e785b48432d51a7046c4c9..2465417fccdc88ada2d74143bbe532f23aacfdc8 100644 (file)
@@ -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);
index b68d4d28ca9d2a669b48b07bb9b6a2032c28b124..2c6b15b405bf2c275e98c92375ac03560bca591c 100644 (file)
@@ -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;
 }