]> granicus.if.org Git - p11-kit/commitdiff
Reinitialize modules after fork().
authorStef Walter <stefw@collabora.co.uk>
Tue, 25 Jan 2011 03:41:55 +0000 (21:41 -0600)
committerStef Walter <stefw@collabora.co.uk>
Tue, 25 Jan 2011 03:41:55 +0000 (21:41 -0600)
module/p11-kit-lib.c
module/p11-kit-private.h
module/p11-kit-proxy.c

index 60662d12281b32df6a4ba1384383a9d3c2d5fe5b..1b7a99c279020637d0f1fd4a443824049e4c9476 100644 (file)
@@ -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);
index d5498f889aae4d55e798ad925276189a8eb01827..3760de4414d0b46d3818316194a2d3cba39bff59 100644 (file)
@@ -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__ */
index b02722b5d45964955f4ec890e626548df130cb98..02f8ac3ed7dfc1c88cdcb46a154ab5ef9c363d3e 100644 (file)
@@ -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)
 {