diff options
author | Stef Walter <stefw@collabora.co.uk> | 2011-01-24 21:41:55 -0600 |
---|---|---|
committer | Stef Walter <stefw@collabora.co.uk> | 2011-01-24 21:41:55 -0600 |
commit | f8009b4d504de0ed752b867893acd263108409e0 (patch) | |
tree | 106d3f60a7a6cb45f6e3ed21a4f11ec3c40034d2 /module | |
parent | b2b0acbc5789823a33de9eabec10e2b8656f3632 (diff) |
Reinitialize modules after fork().
Diffstat (limited to 'module')
-rw-r--r-- | module/p11-kit-lib.c | 51 | ||||
-rw-r--r-- | module/p11-kit-private.h | 1 | ||||
-rw-r--r-- | module/p11-kit-proxy.c | 18 |
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) { |