[pkg-opensc-commit] [pkcs11-helper] 13/60: Fixed fork() while in hook

Eric Dorland eric at moszumanska.debian.org
Fri Jan 6 23:39:42 UTC 2017


This is an automated email from the git hooks/post-receive script.

eric pushed a commit to tag pkcs11-helper-1.02
in repository pkcs11-helper.

commit bf3d4d2f31d53e015de2f816c709e3b334bfaefc
Author: alonbl <alonbl at 485eb718-1723-0410-b8a9-88cf21a28c35>
Date:   Mon Nov 27 20:14:59 2006 +0000

    Fixed fork() while in hook
---
 include/pkcs11-helper-1.0/pkcs11h-core.h | 24 ++++++++++++-
 lib/_pkcs11h-core.h                      |  3 ++
 lib/_pkcs11h-slotevent.h                 |  3 ++
 lib/core.exports                         |  1 +
 lib/pkcs11h-core.c                       | 58 +++++++++++++++++++++++++++-----
 lib/pkcs11h-slotevent.c                  | 11 ++++--
 6 files changed, 88 insertions(+), 12 deletions(-)

diff --git a/include/pkcs11-helper-1.0/pkcs11h-core.h b/include/pkcs11-helper-1.0/pkcs11h-core.h
index 519bfd8..41a60a1 100644
--- a/include/pkcs11-helper-1.0/pkcs11h-core.h
+++ b/include/pkcs11-helper-1.0/pkcs11h-core.h
@@ -388,6 +388,23 @@ unsigned
 pkcs11h_getLogLevel (void);
 
 /**
+ * @brief How does the foked process bahaves after POSIX fork()
+ * @param safe		Safe mode, default is false.
+ * @return CK_RV.
+ * @attention
+ * This function should be called after @ref pkcs11h_initialize()
+ * @note 
+ * This funciton is releavant if @ref PKCS11H_FEATURE_MASK_THREADING is set.
+ * If safe mode is on, the child process can use the loaded PKCS#11 providers
+ * but it cannot use fork(), while it is in one of the hooks functions, since
+ * locked mutexes cannot be released.
+ */
+CK_RV
+pkcs11h_setForkMode (
+	IN const PKCS11H_BOOL safe
+);
+
+/**
  * @brief Set a log callback.
  * @param hook		Callback.
  * @param global_data	Data to send to callback.
@@ -421,6 +438,8 @@ pkcs11h_setSlotEventHook (
  * @param hook		Callback.
  * @param global_data	Data to send to callback.
  * @return CK_RV.
+ * @attention
+ * If @ref pkcs11h_setForkMode() is true, you cannot fork while in hook.
  */
 CK_RV
 pkcs11h_setTokenPromptHook (
@@ -433,6 +452,8 @@ pkcs11h_setTokenPromptHook (
  * @param hook	Callback.
  * @param global_data	Data to send to callback.
  * @return CK_RV.
+ * @attention
+ * If @ref pkcs11h_setForkMode() is true, you cannot fork while in hook.
  */
 CK_RV
 pkcs11h_setPINPromptHook (
@@ -516,7 +537,8 @@ pkcs11h_removeProvider (
  * This function should be called after fork is called. This is required
  * due to a limitation of the PKCS#11 standard.
  * @note The helper library handles fork automatically if @ref PKCS11H_FEATURE_MASK_THREADING
- * is set on configuration file, by use of pthread_atfork.
+ * is set by use of pthread_atfork.
+ * When @ref PKCS11H_FEATURE_MASK_THREADING is enabled this function does nothing.
  */
 CK_RV
 pkcs11h_forkFixup (void);
diff --git a/lib/_pkcs11h-core.h b/lib/_pkcs11h-core.h
index a020729..15f37d6 100644
--- a/lib/_pkcs11h-core.h
+++ b/lib/_pkcs11h-core.h
@@ -207,6 +207,9 @@ struct pkcs11h_data_s {
 		pkcs11h_mutex_t session;
 		pkcs11h_mutex_t cache;
 	} mutexes;
+#if !defined(_WIN32)
+	PKCS11H_BOOL safefork;
+#endif
 #endif
 
 #if defined(ENABLE_PKCS11H_SLOTEVENT)
diff --git a/lib/_pkcs11h-slotevent.h b/lib/_pkcs11h-slotevent.h
index d33031b..b937249 100644
--- a/lib/_pkcs11h-slotevent.h
+++ b/lib/_pkcs11h-slotevent.h
@@ -65,6 +65,9 @@ CK_RV
 _pkcs11h_slotevent_notify (void);
 
 CK_RV
+_pkcs11h_slotevent_terminate_force (void);
+
+CK_RV
 _pkcs11h_slotevent_terminate (void);
 
 #endif				/* ENABLE_PKCS11H_SLOTEVENT */
diff --git a/lib/core.exports b/lib/core.exports
index 6851107..4b37fe6 100644
--- a/lib/core.exports
+++ b/lib/core.exports
@@ -12,6 +12,7 @@ pkcs11h_plugAndPlay
 pkcs11h_removeProvider
 pkcs11h_setLogHook
 pkcs11h_setLogLevel
+pkcs11h_setForkMode
 pkcs11h_setMaxLoginRetries
 pkcs11h_setPINCachePeriod
 pkcs11h_setPINPromptHook
diff --git a/lib/pkcs11h-core.c b/lib/pkcs11h-core.c
index 21e2f10..257f6b6 100644
--- a/lib/pkcs11h-core.c
+++ b/lib/pkcs11h-core.c
@@ -113,7 +113,9 @@ __pkcs11h_threading_atfork_child (void);
 #endif
 static
 CK_RV
-__pkcs11h_forkFixup (void);
+__pkcs11h_forkFixup (
+	IN const PKCS11H_BOOL activate_slotevent
+);
 #endif
 
 
@@ -482,6 +484,19 @@ pkcs11h_setLogLevel (
 	g_pkcs11h_loglevel = flags;
 }
 
+CK_RV
+pkcs11h_setForkMode (
+	IN const PKCS11H_BOOL safe
+) {
+#if defined(ENABLE_PKCS11H_THREADING) && !defined(_WIN32)
+	PKCS11H_ASSERT (g_pkcs11h_data!=NULL);
+	PKCS11H_ASSERT (g_pkcs11h_data->initialized);
+
+	g_pkcs11h_data->safefork = safe;
+#endif
+	return CKR_OK;
+}
+
 unsigned
 pkcs11h_getLogLevel (void) {
 	PKCS11H_ASSERT (g_pkcs11h_data!=NULL);
@@ -903,7 +918,7 @@ pkcs11h_forkFixup (void) {
 #if defined(ENABLE_PKCS11H_THREADING)
 	return CKR_OK;
 #else
-	return __pkcs11h_forkFixup ();
+	return __pkcs11h_forkFixup (TRUE);
 #endif
 #endif
 }
@@ -1098,25 +1113,43 @@ __pkcs11h_hooks_default_pin_prompt (
 static
 void
 __pkcs11h_threading_atfork_prepare  (void) {
-	_pkcs1h_threading_mutexLockAll ();
+	if (g_pkcs11h_data != NULL && g_pkcs11h_data->initialized) {
+		if (g_pkcs11h_data->safefork) {
+			_pkcs1h_threading_mutexLockAll ();
+		}
+	}
 }
 static
 void
 __pkcs11h_threading_atfork_parent (void) {
-	_pkcs1h_threading_mutexReleaseAll ();
+	if (g_pkcs11h_data != NULL && g_pkcs11h_data->initialized) {
+		if (g_pkcs11h_data->safefork) {
+			_pkcs1h_threading_mutexReleaseAll ();
+		}
+	}
 }
 static
 void
 __pkcs11h_threading_atfork_child (void) {
-	_pkcs1h_threading_mutexReleaseAll ();
-	__pkcs11h_forkFixup ();
+	if (g_pkcs11h_data != NULL && g_pkcs11h_data->initialized) {
+		_pkcs1h_threading_mutexReleaseAll ();
+		if (g_pkcs11h_data->safefork) {
+			__pkcs11h_forkFixup (TRUE);
+		}
+		else {
+			__pkcs11h_forkFixup (FALSE);
+			pkcs11h_terminate ();
+		}
+	}
 }
 
 #endif				/* ENABLE_PKCS11H_THREADING */
 
 static
 CK_RV
-__pkcs11h_forkFixup (void) {
+__pkcs11h_forkFixup (
+	IN const PKCS11H_BOOL activate_slotevent
+) {
 #if defined(ENABLE_PKCS11H_THREADING)
 	PKCS11H_BOOL mutex_locked = FALSE;
 #endif
@@ -1128,6 +1161,10 @@ __pkcs11h_forkFixup (void) {
 		mypid
 	);
 
+#if !defined(ENABLE_PKCS11H_SLOTEVENT)
+	(void)activate_slotevent;
+#endif
+
 	if (g_pkcs11h_data != NULL && g_pkcs11h_data->initialized) {
 		pkcs11h_provider_t current;
 
@@ -1152,8 +1189,11 @@ __pkcs11h_forkFixup (void) {
 			 * So just initialized.
 			 */
 			if (g_pkcs11h_data->slotevent.initialized) {
-				g_pkcs11h_data->slotevent.initialized = FALSE;
-				_pkcs11h_slotevent_init ();
+				_pkcs11h_slotevent_terminate_force ();
+
+				if (activate_slotevent) {
+					_pkcs11h_slotevent_init ();
+				}
 			}
 #endif
 		}
diff --git a/lib/pkcs11h-slotevent.c b/lib/pkcs11h-slotevent.c
index 1720448..804c84a 100644
--- a/lib/pkcs11h-slotevent.c
+++ b/lib/pkcs11h-slotevent.c
@@ -453,6 +453,14 @@ _pkcs11h_slotevent_notify (void) {
 }
 
 CK_RV
+_pkcs11h_slotevent_terminate_force (void) {
+	if (g_pkcs11h_data->slotevent.initialized) {
+		_pkcs11h_threading_condFree (&g_pkcs11h_data->slotevent.cond_event);
+		g_pkcs11h_data->slotevent.initialized = FALSE;
+	}
+}
+
+CK_RV
 _pkcs11h_slotevent_terminate (void) {
 	
 	PKCS11H_DEBUG (
@@ -469,8 +477,7 @@ _pkcs11h_slotevent_terminate (void) {
 			_pkcs11h_threading_threadJoin (&g_pkcs11h_data->slotevent.thread);
 		}
 
-		_pkcs11h_threading_condFree (&g_pkcs11h_data->slotevent.cond_event);
-		g_pkcs11h_data->slotevent.initialized = FALSE;
+		_pkcs11h_slotevent_terminate_force ();
 	}
 
 	PKCS11H_DEBUG (

-- 
Alioth's /usr/local/bin/git-commit-notice on /srv/git.debian.org/git/pkg-opensc/pkcs11-helper.git



More information about the pkg-opensc-commit mailing list