Blob Blame Raw
From 985d17d57cfd5a36bfdecc891e9331210ea38ee4 Mon Sep 17 00:00:00 2001
From: Rob Crittenden <rcritten@redhat.com>
Date: Mon, 8 Aug 2016 10:12:01 -0400
Subject: [PATCH] Fix semaphore leak in nss_pcache

On shutdown Apache was sending a SIGTERM which caused the helper
to be killed rather than shutting down gracefully, resulting in
a leak of the semaphone lock in nss_pcache.

Catch that signal and shut down gracefully instead.

Resolves: #1364560

---
 nss_pcache.c | 43 +++++++++++++++++++++++++++++++++----------
 1 file changed, 33 insertions(+), 10 deletions(-)

diff --git a/nss_pcache.c b/nss_pcache.c
index a8b15f7..5e98adb 100644
--- a/nss_pcache.c
+++ b/nss_pcache.c
@@ -95,6 +95,37 @@ struct Node
 
 /* global variables */
 Node *pinList = NULL;
+int semid = 0;
+PRFileDesc *in = NULL;
+PRFileDesc *out = NULL;
+
+void cleanup() {
+    union semun semarg;
+
+    freeList(pinList);
+    pinList = NULL;
+
+    if (in) {
+        PR_Close(in);
+        in = NULL;
+    }
+
+    if (NSS_IsInitialized()) {
+        NSS_Shutdown();
+    }
+
+    /* Remove the semaphore used for locking here. This is because this
+     * program only goes away when Apache shuts down so we don't have to
+     * worry about reloads.
+     */
+    semctl(semid, 0, IPC_RMID, semarg);
+}
+
+void signalhandler(int signo) {
+    if (signo == SIGTERM) {
+        cleanup();
+    }
+}
 
 /*
  * CreatePk11PinStore
@@ -308,8 +339,6 @@ Pk11StoreGetPin(char **out, Pk11PinStore *store)
 int main(int argc, char ** argv)
 {
     SECStatus rv;
-    PRFileDesc *in;
-    PRFileDesc *out;
     PRPollDesc pd;
     PRIntervalTime timeout = PR_INTERVAL_NO_TIMEOUT;
     char buf[1024];
@@ -318,7 +347,6 @@ int main(int argc, char ** argv)
     char * tokenName;
     char * tokenpw;
     int fipsmode = 0;
-    int semid = 0;
     union semun semarg;
 
     if (argc < 4 || argc > 5) {
@@ -327,6 +355,7 @@ int main(int argc, char ** argv)
     }
 
     signal(SIGHUP, SIG_IGN);
+    signal(SIGTERM, signalhandler);
 
     semid = strtol(argv[1], NULL, 10);
 
@@ -459,13 +488,7 @@ int main(int argc, char ** argv)
             }
         }
     }
-    freeList(pinList);
-    PR_Close(in);
-    /* Remove the semaphore used for locking here. This is because this
-     * program only goes away when Apache shuts down so we don't have to
-     * worry about reloads.
-     */
-    semctl(semid, 0, IPC_RMID, semarg);
+    cleanup();
     return 0;
 }
 
-- 
1.8.3.1