diff options
author | Panu Matilainen <pmatilai@redhat.com> | 2009-04-23 15:54:09 +0300 |
---|---|---|
committer | Panu Matilainen <pmatilai@redhat.com> | 2009-04-23 15:54:09 +0300 |
commit | 2ce7b56e621b097b76a2e5059def7d0e5a64d53b (patch) | |
tree | 3169750264194baaec554fab32f9725ce3939ba5 /rpmio | |
parent | 4b523ac1b85b9d4f71cd024306f01c3fb2418c8f (diff) | |
download | rpm-2ce7b56e621b097b76a2e5059def7d0e5a64d53b.tar.gz rpm-2ce7b56e621b097b76a2e5059def7d0e5a64d53b.tar.bz2 rpm-2ce7b56e621b097b76a2e5059def7d0e5a64d53b.zip |
Hide NSS peculiarities from API
- PKCS#11 standard requires modules to be re-initialized after fork(),
arrange this to occur automatically.
- Most of the time child processes will exec() something else so dont
bother shutting down NSS for every child, only lazily re-initialize
as needed.
- This lets us initialize NSS early to force preloading of its dlopen()'ed
libraries to avoid issues on chroot(), without causing problems to API
users which fork() after initializing rpm (such as func, urpmi etc).
Diffstat (limited to 'rpmio')
-rw-r--r-- | rpmio/rpmpgp.c | 27 |
1 files changed, 27 insertions, 0 deletions
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; } |