From 0c4f91495248f1b1b6150fb6917c3753759985f9 Mon Sep 17 00:00:00 2001 From: Stef Walter Date: Thu, 2 Oct 2014 12:20:34 +0200 Subject: [PATCH] p11-kit: Use getpid() to detect when process has forked pthread_atfork() is notoriously hard to use cleanly. In particular since we don't have portable atomics, it becomes nearly impossible. https://bugs.freedesktop.org/show_bug.cgi?id=84567 --- p11-kit/modules.c | 45 ++++++++++----------------------------------- 1 file changed, 10 insertions(+), 35 deletions(-) diff --git a/p11-kit/modules.c b/p11-kit/modules.c index 8aaa769..eab854a 100644 --- a/p11-kit/modules.c +++ b/p11-kit/modules.c @@ -158,7 +158,7 @@ typedef struct _Module { /* Initialization, mutex must be held */ p11_mutex_t initialize_mutex; - bool initialize_called; + pid_t initialize_called; p11_thread_id_t initialize_thread; } Module; @@ -247,7 +247,6 @@ free_module_unlocked (void *data) p11_debug_precond ("module unloaded without C_Finalize having been " "called for each C_Initialize"); } else { - assert (!mod->initialize_called); assert (mod->initialize_thread == 0); } @@ -612,6 +611,7 @@ initialize_module_inlock_reentrant (Module *mod) { CK_RV rv = CKR_OK; p11_thread_id_t self; + pid_t pid; assert (mod); @@ -633,7 +633,8 @@ initialize_module_inlock_reentrant (Module *mod) p11_unlock (); p11_mutex_lock (&mod->initialize_mutex); - if (!mod->initialize_called) { + pid = getpid (); + if (mod->initialize_called != pid) { p11_debug ("C_Initialize: calling"); rv = mod->virt.funcs.C_Initialize (&mod->virt.funcs, @@ -643,10 +644,12 @@ initialize_module_inlock_reentrant (Module *mod) /* Module was initialized and C_Finalize should be called */ if (rv == CKR_OK) - mod->initialize_called = true; + mod->initialize_called = pid; + else + mod->initialize_called = 0; /* Module was already initialized, we don't call C_Finalize */ - else if (rv == CKR_CRYPTOKI_ALREADY_INITIALIZED) + if (rv == CKR_CRYPTOKI_ALREADY_INITIALIZED) rv = CKR_OK; } @@ -665,31 +668,6 @@ initialize_module_inlock_reentrant (Module *mod) return rv; } -#ifdef OS_UNIX - -static void -reinitialize_after_fork (void) -{ - p11_dictiter iter; - Module *mod; - - p11_debug ("forked"); - - p11_lock (); - - if (gl.modules) { - p11_dict_iterate (gl.modules, &iter); - while (p11_dict_next (&iter, (void **)&mod, NULL)) - mod->initialize_called = false; - } - - p11_unlock (); - - p11_proxy_after_fork (); -} - -#endif /* OS_UNIX */ - static CK_RV init_globals_unlocked (void) { @@ -719,9 +697,6 @@ init_globals_unlocked (void) if (once) return CKR_OK; -#ifdef OS_UNIX - pthread_atfork (NULL, NULL, reinitialize_after_fork); -#endif once = true; return CKR_OK; @@ -777,9 +752,9 @@ finalize_module_inlock_reentrant (Module *mod) p11_unlock (); p11_mutex_lock (&mod->initialize_mutex); - if (mod->initialize_called) { + if (mod->initialize_called == getpid ()) { mod->virt.funcs.C_Finalize (&mod->virt.funcs, NULL); - mod->initialize_called = false; + mod->initialize_called = 0; } p11_mutex_unlock (&mod->initialize_mutex); -- 1.9.3