[Pkg-fedora-ds-maintainers] [libapache2-mod-nss] 118/156: Add a semaphore lock around retrieving token PINs from the nss_pcache pipe. Rarely requests to the pipe were getting overridden causing that child to not enable SSL.

Timo Aaltonen tjaalton-guest at moszumanska.debian.org
Wed Jul 2 13:55:34 UTC 2014


This is an automated email from the git hooks/post-receive script.

tjaalton-guest pushed a commit to branch master
in repository libapache2-mod-nss.

commit f656ffc036af239a4236f1c1fc97e32a809d470d
Author: rcritten <>
Date:   Wed Mar 2 21:12:05 2011 +0000

    Add a semaphore lock around retrieving token PINs from the nss_pcache
    pipe. Rarely requests to the pipe were getting overridden causing
    that child to not enable SSL.
    
    Fedora bug 677701
---
 mod_nss.c            |  2 ++
 mod_nss.h            |  7 +++++++
 nss_engine_config.c  |  9 +++++++++
 nss_engine_init.c    | 45 +++++++++++++++++++++++++++++++++++++++++----
 nss_engine_pphrase.c | 17 +++++++++++++++++
 nss_pcache.c         | 25 ++++++++++++++++++++++---
 6 files changed, 98 insertions(+), 7 deletions(-)

diff --git a/mod_nss.c b/mod_nss.c
index 7dfbc6f..e4fed90 100644
--- a/mod_nss.c
+++ b/mod_nss.c
@@ -152,6 +152,8 @@ static const command_rec nss_config_cmds[] = {
     AP_INIT_RAW_ARGS("NSSLogLevel", ap_set_deprecated, NULL, OR_ALL, 
       "SSLLogLevel directive is no longer supported - use LogLevel."),
 #endif
+    AP_INIT_TAKE1("User", set_user, NULL, RSRC_CONF,
+                  "Apache user. Comes from httpd.conf."),
     
     AP_END_CMD
 };
diff --git a/mod_nss.h b/mod_nss.h
index 086a7cc..dadca59 100644
--- a/mod_nss.h
+++ b/mod_nss.h
@@ -41,6 +41,9 @@
 #include "apr_shm.h"
 #include "apr_global_mutex.h"
 #include "apr_optional.h"
+#include <sys/types.h>
+#include <sys/ipc.h>
+#include <sys/sem.h>
 
 #define MOD_NSS_VERSION AP_SERVER_BASEREVISION
 
@@ -244,6 +247,9 @@ typedef struct {
     struct {
         void *pV1, *pV2, *pV3, *pV4, *pV5, *pV6, *pV7, *pV8, *pV9, *pV10;
     } rCtx;
+
+    int semid;
+    const char *user;
 } SSLModConfigRec;
 
 typedef struct SSLSrvConfigRec SSLSrvConfigRec;
@@ -412,6 +418,7 @@ const char *nss_cmd_NSSProxyProtocol(cmd_parms *, void *, const char *);
 const char *nss_cmd_NSSProxyCipherSuite(cmd_parms *, void *, const char *);
 const char *nss_cmd_NSSProxyNickname(cmd_parms *cmd, void *dcfg, const char *arg);
 const char *nss_cmd_NSSProxyCheckPeerCN(cmd_parms *cmd, void *dcfg, int flag);
+const char *set_user(cmd_parms *cmd, void *dummy, const char *arg);
 
 /*  module initialization  */
 int  nss_init_Module(apr_pool_t *, apr_pool_t *, apr_pool_t *, server_rec *);
diff --git a/nss_engine_config.c b/nss_engine_config.c
index 64ec447..2f1fb5c 100644
--- a/nss_engine_config.c
+++ b/nss_engine_config.c
@@ -830,3 +830,12 @@ const char *nss_cmd_NSSOptions(cmd_parms *cmd,
 
     return NULL;
 }
+
+const char *set_user(cmd_parms *cmd, void *dummy, const char *arg)
+{
+    SSLModConfigRec *mc = myModConfig(cmd->server);
+
+    mc->user = arg;
+
+    return NULL;
+}
diff --git a/nss_engine_init.c b/nss_engine_init.c
index 0392205..6b0770c 100644
--- a/nss_engine_init.c
+++ b/nss_engine_init.c
@@ -312,6 +312,7 @@ int nss_init_Module(apr_pool_t *p, apr_pool_t *plog,
     int sslenabled = FALSE;
     int fipsenabled = FALSE;
     int threaded = 0;
+    struct semid_ds status;
 
     mc->nInitCount++;
 
@@ -412,10 +413,26 @@ int nss_init_Module(apr_pool_t *p, apr_pool_t *plog,
     ap_log_error(APLOG_MARK, APLOG_INFO, 0, s,
                  "Init: %snitializing NSS library", mc->nInitCount == 1 ? "I" : "Re-i");
 
+    /* The first pass through this function will create the semaphore that
+     * will be used to lock the pipe. The user is still root at that point
+     * so for any later calls the semaphore ops will fail with permission
+     * errors. So switch the user to the Apache user.
+     */
+    if (mc->semid) {
+        uid_t user_id;
+
+        user_id = ap_uname2id(mc->user);
+        semctl(mc->semid, 0, IPC_STAT, &status);
+        status.sem_perm.uid = user_id;
+        semctl(mc->semid,0,IPC_SET,&status);
+    }
+
     /* Do we need to fire up our password helper? */
     if (mc->nInitCount == 1) {
         const char * child_argv[5];
         apr_status_t rv;
+        struct sembuf sb;
+        char sembuf[32];
 
         if (mc->pphrase_dialog_helper == NULL) {
             ap_log_error(APLOG_MARK, APLOG_ERR, 0, s,
@@ -423,11 +440,31 @@ int nss_init_Module(apr_pool_t *p, apr_pool_t *plog,
             nss_die();
         }
 
+        mc->semid = semget(IPC_PRIVATE, 1, IPC_CREAT | IPC_EXCL | 0600);
+        if (mc->semid == -1) {
+            ap_log_error(APLOG_MARK, APLOG_ERR, 0, s,
+                "Unable to obtain semaphore.");
+            nss_die();
+        }
+
+        /* Initialize the semaphore */
+        sb.sem_num = 0;
+        sb.sem_op = 1;
+        sb.sem_flg = 0;
+        if ((semop(mc->semid, &sb, 1)) == -1) {
+            ap_log_error(APLOG_MARK, APLOG_ERR, 0, s,
+                "Unable to initialize semaphore.");
+            nss_die();
+        }
+
+        PR_snprintf(sembuf, 32, "%d", mc->semid);
+
         child_argv[0] = mc->pphrase_dialog_helper;
-        child_argv[1] = fipsenabled ? "on" : "off";
-        child_argv[2] = mc->pCertificateDatabase;
-        child_argv[3] = mc->pDBPrefix;
-        child_argv[4] = NULL;
+        child_argv[1] = sembuf;
+        child_argv[2] = fipsenabled ? "on" : "off";
+        child_argv[3] = mc->pCertificateDatabase;
+        child_argv[4] = mc->pDBPrefix;
+        child_argv[5] = NULL;
 
         rv = apr_procattr_create(&mc->procattr, mc->pPool);
 
diff --git a/nss_engine_pphrase.c b/nss_engine_pphrase.c
index eb66029..a27de6f 100644
--- a/nss_engine_pphrase.c
+++ b/nss_engine_pphrase.c
@@ -279,6 +279,16 @@ static char *nss_get_password(FILE *input, FILE *output,
         char buf[1024];
         apr_status_t rv;
         apr_size_t nBytes = 1024;
+        struct sembuf sb;
+
+        /* lock the pipe */
+        sb.sem_num = 0;
+        sb.sem_op = -1;
+        sb.sem_flg = SEM_UNDO;
+        if (semop(parg->mc->semid, &sb, 1) == -1) {
+            ap_log_error(APLOG_MARK, APLOG_ERR, 0, NULL,
+                "Unable to reserve semaphore resource");
+        }
 
         snprintf(buf, 1024, "RETR\t%s", token_name);
         rv = apr_file_write_full(parg->mc->proc.in, buf, strlen(buf), NULL);
@@ -293,6 +303,13 @@ static char *nss_get_password(FILE *input, FILE *output,
          */
         memset(buf, 0, sizeof(buf));
         rv = apr_file_read(parg->mc->proc.out, buf, &nBytes);
+        sb.sem_op = 1;
+        if (semop(parg->mc->semid, &sb, 1) == -1) {
+            ap_log_error(APLOG_MARK, APLOG_ERR, 0, NULL,
+                "Unable to free semaphore resource");
+            /* perror("semop free resource id"); */
+        }
+
         if (rv != APR_SUCCESS) {
             ap_log_error(APLOG_MARK, APLOG_ERR, 0, NULL,
                 "Unable to read from pin store for slot: %s APR err: %d",  PK11_GetTokenName(slot), rv);
diff --git a/nss_pcache.c b/nss_pcache.c
index 3ba252e..800c0b6 100644
--- a/nss_pcache.c
+++ b/nss_pcache.c
@@ -21,6 +21,9 @@
 #include <pk11func.h>
 #include <secmod.h>
 #include <signal.h>
+#include <sys/types.h>
+#include <sys/ipc.h>
+#include <sys/sem.h>
 #include "nss_pcache.h"
 
 static char * getstr(const char * cmd, int el);
@@ -70,6 +73,13 @@ struct Pk11PinStore
     unsigned char *crypt;
 };
 
+union semun {
+    int val;
+    struct semid_ds *buf;
+    unsigned short *array;
+    struct seminfo *__buf;
+};
+
 /*
  * Node - for maintaining link list of tokens with cached PINs
  */
@@ -304,15 +314,19 @@ int main(int argc, char ** argv)
     char * tokenName;
     char * tokenpw;
     int fipsmode = 0;
+    int semid = 0;
+    union semun semarg;
 
-    if (argc < 3 || argc > 4) {
+    if (argc < 4 || argc > 5) {
         fprintf(stderr, "Usage: nss_pcache <fips on/off> <directory> <prefix>\n");
         exit(1);
     }
 
     signal(SIGHUP, SIG_IGN);
 
-    if (!strcasecmp(argv[1], "on"))
+    semid = strtol(argv[1], NULL, 10);
+
+    if (!strcasecmp(argv[2], "on"))
         fipsmode = 1;
 
     /* Initialize NSPR */
@@ -322,7 +336,7 @@ int main(int argc, char ** argv)
     PK11_ConfigurePKCS11(NULL,NULL,NULL, INTERNAL_TOKEN_NAME, NULL, NULL,NULL,NULL,8,1);
  
     /* Initialize NSS and open the certificate database read-only. */
-    rv = NSS_Initialize(argv[2], argc == 4 ? argv[3] : NULL, argc == 4 ? argv[3] : NULL, "secmod.db", NSS_INIT_READONLY);
+    rv = NSS_Initialize(argv[3], argc == 4 ? argv[4] : NULL, argc == 5 ? argv[4] : NULL, "secmod.db", NSS_INIT_READONLY);
 
     if (rv != SECSuccess) {
         fprintf(stderr, "Unable to initialize NSS database: %d\n", rv);
@@ -437,6 +451,11 @@ 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);
     return 0;
 }
 

-- 
Alioth's /usr/local/bin/git-commit-notice on /srv/git.debian.org/git/pkg-fedora-ds/libapache2-mod-nss.git



More information about the Pkg-fedora-ds-maintainers mailing list