summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorStef Walter <stefw@collabora.co.uk>2011-01-24 21:41:55 -0600
committerStef Walter <stefw@collabora.co.uk>2011-01-24 21:41:55 -0600
commitf8009b4d504de0ed752b867893acd263108409e0 (patch)
tree106d3f60a7a6cb45f6e3ed21a4f11ec3c40034d2
parentb2b0acbc5789823a33de9eabec10e2b8656f3632 (diff)
downloadp11-kit-f8009b4d504de0ed752b867893acd263108409e0.tar.gz
Reinitialize modules after fork().
-rw-r--r--module/p11-kit-lib.c51
-rw-r--r--module/p11-kit-private.h1
-rw-r--r--module/p11-kit-proxy.c18
3 files changed, 66 insertions, 4 deletions
diff --git a/module/p11-kit-lib.c b/module/p11-kit-lib.c
index 60662d1..1b7a99c 100644
--- a/module/p11-kit-lib.c
+++ b/module/p11-kit-lib.c
@@ -458,14 +458,56 @@ initialize_module_unlocked_reentrant (Module *module, CK_C_INITIALIZE_ARGS_PTR a
return rv;
}
+static void
+reinitialize_after_fork (void)
+{
+ CK_C_INITIALIZE_ARGS args;
+ hash_iter_t it;
+ Module *module;
+
+ /* WARNING: This function must be reentrant */
+
+ memset (&args, 0, sizeof (args));
+ args.CreateMutex = create_mutex;
+ args.DestroyMutex = destroy_mutex;
+ args.LockMutex = lock_mutex;
+ args.UnlockMutex = unlock_mutex;
+ args.flags = CKF_OS_LOCKING_OK;
+
+ _p11_lock ();
+
+ if (gl.modules) {
+ hash_iterate (gl.modules, &it);
+ while (hash_next (&it, NULL, (void**)&module)) {
+ module->initialize_count = 0;
+
+ /* WARNING: Reentrancy can occur here */
+ initialize_module_unlocked_reentrant (module, &args);
+ }
+ }
+
+ _p11_unlock ();
+
+ _p11_kit_proxy_after_fork ();
+}
+
static CK_RV
-init_modules_unlocked (void)
+init_globals_unlocked (void)
{
+ static int once = 0;
+
if (!gl.modules)
gl.modules = hash_create (hash_direct_hash, hash_direct_equal,
NULL, free_module_unlocked);
if (!gl.modules)
return CKR_HOST_MEMORY;
+
+ if (once)
+ return CKR_OK;
+
+ pthread_atfork (NULL, NULL, reinitialize_after_fork);
+ once = 1;
+
return CKR_OK;
}
@@ -552,7 +594,9 @@ _p11_kit_initialize_registered_unlocked_reentrant (CK_C_INITIALIZE_ARGS_PTR args
hash_iter_t it;
CK_RV rv;
- rv = load_registered_modules_unlocked ();
+ rv = init_globals_unlocked ();
+ if (rv == CKR_OK)
+ rv = load_registered_modules_unlocked ();
if (rv == CKR_OK) {
hash_iterate (gl.modules, &it);
while (hash_next (&it, NULL, (void**)&module)) {
@@ -627,7 +671,6 @@ _p11_kit_finalize_registered_unlocked_reentrant (CK_VOID_PTR args)
}
for (i = 0; i < count; ++i) {
-
/* WARNING: Reentrant calls can occur here */
finalize_module_unlocked_reentrant (to_finalize[i], args);
}
@@ -760,7 +803,7 @@ p11_kit_initialize_module (CK_FUNCTION_LIST_PTR funcs, CK_C_INITIALIZE_ARGS_PTR
_p11_lock ();
- rv = init_modules_unlocked ();
+ rv = init_globals_unlocked ();
if (rv == CKR_OK) {
module = hash_get (gl.modules, funcs);
diff --git a/module/p11-kit-private.h b/module/p11-kit-private.h
index d5498f8..3760de4 100644
--- a/module/p11-kit-private.h
+++ b/module/p11-kit-private.h
@@ -47,5 +47,6 @@ CK_RV _p11_kit_initialize_registered_unlocked_reentrant (CK_C_INITIALIZE
CK_RV _p11_kit_finalize_registered_unlocked_reentrant (CK_VOID_PTR args);
+void _p11_kit_proxy_after_fork (void);
#endif /* __P11_KIT_PRIVATE_H__ */
diff --git a/module/p11-kit-proxy.c b/module/p11-kit-proxy.c
index b02722b..02f8ac3 100644
--- a/module/p11-kit-proxy.c
+++ b/module/p11-kit-proxy.c
@@ -191,6 +191,24 @@ finalize_mappings_unlocked (void)
gl.sessions = NULL;
}
+void
+_p11_kit_proxy_after_fork (void)
+{
+ /*
+ * After a fork the callers are supposed to call C_Initialize and all.
+ * In addition the underlying libraries may change their state so free
+ * up any mappings and all
+ */
+
+ _p11_lock ();
+
+ gl.mappings_refs = 1;
+ finalize_mappings_unlocked ();
+ assert (!gl.mappings);
+
+ _p11_unlock ();
+}
+
static CK_RV
proxy_C_Finalize (CK_VOID_PTR reserved)
{