[pkg-opensc-commit] [libp11] 192/239: Use locks to protect forkid checks

Eric Dorland eric at moszumanska.debian.org
Sat Oct 17 06:21:32 UTC 2015


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

eric pushed a commit to branch master
in repository libp11.

commit 730657b5953d5df682675bb23c612d6926de9d47
Author: Nikos Mavrogiannopoulos <nmav at redhat.com>
Date:   Fri Jun 26 15:15:01 2015 +0200

    Use locks to protect forkid checks
---
 configure.ac     | 12 +++++++++++-
 src/Makefile.am  |  4 ++--
 src/libp11-int.h | 39 ++++++++++++++++++++++++++++++++++-----
 src/p11_load.c   |  8 ++++++++
 src/p11_slot.c   |  8 ++++++++
 5 files changed, 63 insertions(+), 8 deletions(-)

diff --git a/configure.ac b/configure.ac
index 35ba66e..e980e71 100644
--- a/configure.ac
+++ b/configure.ac
@@ -141,7 +141,15 @@ if test "${WIN32}" != "yes"; then
 	)
 fi
 
-AC_CHECK_FUNCS([__register_atfork],,)
+if test "${WIN32}" != yes;then
+	AC_CHECK_FUNCS([__register_atfork pthread_mutex_lock],,)
+	if test "$ac_cv_func_pthread_mutex_lock" != "yes";then
+		OLDLIBS=$LIBS
+		AC_CHECK_LIB(pthread, pthread_mutex_lock, [], AC_ERROR([Cannot find pthread_mutex_lock() function]))
+		LIBS=$OLDLIBS
+		PTHREAD_FLAGS="-pthread"
+	fi
+fi
 
 PKG_CHECK_MODULES(
 	[OPENSSL],
@@ -164,6 +172,7 @@ pkgconfigdir="\$(libdir)/pkgconfig"
 
 AC_SUBST([pkgconfigdir])
 AC_SUBST([apidocdir])
+AC_SUBST([PTHREAD_FLAGS])
 AC_SUBST([LIBP11_VERSION_MAJOR])
 AC_SUBST([LIBP11_VERSION_MINOR])
 AC_SUBST([LIBP11_VERSION_FIX])
@@ -212,6 +221,7 @@ Compiler flags:          ${CFLAGS}
 Linker flags:            ${LDFLAGS}
 Libraries:               ${LIBS}
 
+PTHREAD_FLAGS:           ${PTHREAD_FLAGS}
 OPENSSL_CFLAGS:          ${OPENSSL_CFLAGS}
 OPENSSL_LIBS:            ${OPENSSL_LIBS}
 
diff --git a/src/Makefile.am b/src/Makefile.am
index ecc9cf4..b71e958 100644
--- a/src/Makefile.am
+++ b/src/Makefile.am
@@ -16,8 +16,8 @@ libp11_la_SOURCES += versioninfo.rc
 else
 dist_noinst_DATA = versioninfo.rc
 endif
-libp11_la_CFLAGS = $(AM_CFLAGS) $(OPENSSL_CFLAGS)
-libp11_la_LIBADD = $(OPENSSL_LIBS)
+libp11_la_CFLAGS = $(AM_CFLAGS) $(OPENSSL_CFLAGS) $(PTHREAD_FLAGS)
+libp11_la_LIBADD = $(OPENSSL_LIBS) $(PTHREAD_FLAGS)
 libp11_la_LDFLAGS = $(AM_LDFLAGS) \
 	-version-info @LIBP11_LT_CURRENT@:@LIBP11_LT_REVISION@:@LIBP11_LT_AGE@ \
 	-export-symbols "$(srcdir)/libp11.exports" \
diff --git a/src/libp11-int.h b/src/libp11-int.h
index 358fda5..f2af5e3 100644
--- a/src/libp11-int.h
+++ b/src/libp11-int.h
@@ -34,6 +34,17 @@ extern CK_RV C_UnloadModule(void *module);
 
 /* get private implementations of PKCS11 structures */
 
+#ifdef _WIN32
+/* we don't need thread safety here because we don't check for fork */
+# define LOCK(ctx)
+# define UNLOCK(ctx)
+#else
+# include <pthread.h>
+
+# define LOCK(ctx)   {if (pthread_mutex_lock(&ctx->mutex) < 0) abort();}
+# define UNLOCK(ctx) {if (pthread_mutex_unlock(&ctx->mutex) < 0) abort();}
+#endif
+
 /*
  * PKCS11_CTX: context for a PKCS11 implementation
  */
@@ -44,16 +55,24 @@ typedef struct pkcs11_ctx_private {
 
 	char *init_args;
 	unsigned int forkid;
+#ifndef _WIN32
+	pthread_mutex_t mutex; /* mutex for forkid check */
+#endif
 } PKCS11_CTX_private;
 #define PRIVCTX(ctx)		((PKCS11_CTX_private *) (ctx->_private))
 
 #define CHECK_FORK(ctx) { \
 	PKCS11_CTX_private *__priv = PRIVCTX(ctx); \
+	LOCK(__priv); \
 	if (_P11_detect_fork(__priv->forkid)) { \
-		if (PKCS11_CTX_reload(ctx) < 0) \
+		if (PKCS11_CTX_reload(ctx) < 0) { \
+			UNLOCK(__priv); \
 			return -1; \
+		} \
 		__priv->forkid = _P11_get_forkid(); \
-	}}
+	} \
+	UNLOCK(__priv); \
+	}
 
 typedef struct pkcs11_slot_private {
 	PKCS11_CTX *parent;
@@ -66,6 +85,9 @@ typedef struct pkcs11_slot_private {
 	/* options used in last PKCS11_login */
 	char prev_pin[64];
 	int prev_so;
+#ifndef _WIN32
+	pthread_mutex_t mutex; /* mutex for forkid check */
+#endif
 } PKCS11_SLOT_private;
 #define PRIVSLOT(slot)		((PKCS11_SLOT_private *) (slot->_private))
 #define SLOT2CTX(slot)		(PRIVSLOT(slot)->parent)
@@ -75,22 +97,29 @@ typedef struct pkcs11_slot_private {
 	PKCS11_CTX *__ctx = SLOT2CTX(slot_ctx); \
 	PKCS11_CTX_private *__priv = PRIVCTX(__ctx); \
 	CHECK_FORK(SLOT2CTX(slot_ctx)); \
+	LOCK(__spriv); \
 	if (__spriv->forkid != __priv->forkid) { \
 		if (__spriv->loggedIn) { \
 			int __saved = __spriv->haveSession; \
 			__spriv->haveSession = 0; \
 			__spriv->loggedIn = 0; \
-			if (PKCS11_relogin(slot_ctx) < 0) \
+			if (PKCS11_relogin(slot_ctx) < 0) { \
+				UNLOCK(__spriv); \
 				return -1; \
+			} \
 			__spriv->haveSession = __saved; \
 		} \
 		if (__spriv->haveSession) { \
 			__spriv->haveSession = 0; \
-			if (PKCS11_reopen_session(slot_ctx) < 0) \
+			if (PKCS11_reopen_session(slot_ctx) < 0) { \
+				UNLOCK(__spriv); \
 				return -1; \
+			} \
 		} \
 		__spriv->forkid = __priv->forkid; \
-	}}
+	} \
+	UNLOCK(__spriv); \
+	}
 
 typedef struct pkcs11_token_private {
 	PKCS11_SLOT *parent;
diff --git a/src/p11_load.c b/src/p11_load.c
index 32116c2..15cd0c1 100644
--- a/src/p11_load.c
+++ b/src/p11_load.c
@@ -38,6 +38,10 @@ PKCS11_CTX *PKCS11_CTX_new(void)
 	ctx->_private = priv;
 	priv->forkid = _P11_get_forkid();
 
+#ifndef _WIN32
+	pthread_mutex_init(&priv->mutex, NULL);
+#endif
+
 	return ctx;
 }
 
@@ -131,6 +135,10 @@ void PKCS11_CTX_unload(PKCS11_CTX * ctx)
 	if (priv->forkid == _P11_get_forkid())
 		priv->method->C_Finalize(NULL);
 
+#ifndef _WIN32
+	pthread_mutex_destroy(&priv->mutex);
+#endif
+
 	/* Unload the module */
 	C_UnloadModule(handle);
 }
diff --git a/src/p11_slot.c b/src/p11_slot.c
index 1cbe5e7..8adc107 100644
--- a/src/p11_slot.c
+++ b/src/p11_slot.c
@@ -380,6 +380,10 @@ static int pkcs11_init_slot(PKCS11_CTX * ctx, PKCS11_SLOT * slot, CK_SLOT_ID id)
 	priv->id = id;
 	priv->forkid = PRIVCTX(ctx)->forkid;
 
+#ifndef _WIN32
+	pthread_mutex_init(&priv->mutex, NULL);
+#endif
+
 	slot->description = PKCS11_DUP(info.slotDescription);
 	slot->manufacturer = PKCS11_DUP(info.manufacturerID);
 	slot->removable = (info.flags & CKF_REMOVABLE_DEVICE) ? 1 : 0;
@@ -415,6 +419,10 @@ void pkcs11_release_slot(PKCS11_CTX * ctx, PKCS11_SLOT * slot)
 		pkcs11_destroy_token(slot->token);
 		OPENSSL_free(slot->token);
 	}
+
+#ifndef _WIN32
+	pthread_mutex_destroy(&priv->mutex);
+#endif
 	memset(slot, 0, sizeof(*slot));
 }
 

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



More information about the pkg-opensc-commit mailing list