summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--lib/rpmrc.c3
-rw-r--r--lib/rpmts.c3
-rw-r--r--rpmio/rpmpgp.c27
3 files changed, 29 insertions, 4 deletions
diff --git a/lib/rpmrc.c b/lib/rpmrc.c
index 441ede7c7..8c9399595 100644
--- a/lib/rpmrc.c
+++ b/lib/rpmrc.c
@@ -1605,8 +1605,9 @@ int rpmReadConfigFiles(const char * file, const char * target)
/* Reset umask to its default umask(2) value. */
mode = umask(mode);
- /* Force preloading of name service libraries in case we go chrooting */
+ /* Force preloading of dlopen()'ed libraries in case we go chrooting */
(void) gethostbyname("localhost");
+ (void) rpmInitCrypto();
/* Preset target macros */
/* FIX: target can be NULL */
diff --git a/lib/rpmts.c b/lib/rpmts.c
index 430d51190..b8735db87 100644
--- a/lib/rpmts.c
+++ b/lib/rpmts.c
@@ -1149,9 +1149,6 @@ rpmts rpmtsCreate(void)
ts->nrefs = 0;
- /* make sure crypto gets initialized before we might go chrooting */
- rpmInitCrypto();
-
return rpmtsLink(ts, RPMDBG_M("tsCreate"));
}
diff --git a/rpmio/rpmpgp.c b/rpmio/rpmpgp.c
index 3498e5665..38194497b 100644
--- a/rpmio/rpmpgp.c
+++ b/rpmio/rpmpgp.c
@@ -5,7 +5,10 @@
#include "system.h"
+#include <pthread.h>
+
#include <rpm/rpmstring.h>
+#include <rpm/rpmlog.h>
#include "rpmio/digest.h"
#include "rpmio/rpmio_internal.h" /* XXX rpmioSlurp */
@@ -18,6 +21,7 @@ static int _debug = 0;
static int _print = 0;
static int _crypto_initialized = 0;
+static int _new_process = 1;
static struct pgpValTbl_s const pgpSigTypeTbl[] = {
{ PGPSIGTYPE_BINARY, "Binary document signature" },
@@ -1570,9 +1574,24 @@ char * pgpArmorWrap(int atype, const unsigned char * s, size_t ns)
return val;
}
+/*
+ * Only flag for re-initialization here, in the common case the child
+ * exec()'s something else shutting down NSS here would be waste of time.
+ */
+static void at_forkchild(void)
+{
+ _new_process = 1;
+}
+
int rpmInitCrypto(void) {
int rc = 0;
+ /* Lazy NSS shutdown for re-initialization after fork() */
+ if (_new_process && _crypto_initialized) {
+ rpmFreeCrypto();
+ }
+
+ /* Initialize NSS if not already done */
if (!_crypto_initialized) {
if (NSS_NoDB_Init(NULL) != SECSuccess) {
rc = -1;
@@ -1580,6 +1599,14 @@ int rpmInitCrypto(void) {
_crypto_initialized = 1;
}
}
+
+ /* Register one post-fork handler per process */
+ if (_new_process) {
+ if (pthread_atfork(NULL, NULL, at_forkchild) != 0) {
+ rpmlog(RPMLOG_WARNING, _("Failed to register fork handler: %m\n"));
+ }
+ _new_process = 0;
+ }
return rc;
}