diff options
-rw-r--r-- | lib/rpmrc.c | 3 | ||||
-rw-r--r-- | lib/rpmts.c | 3 | ||||
-rw-r--r-- | rpmio/rpmpgp.c | 27 |
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; } |