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