[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