C_Initialize may be called by multiple threads
While trying to setup an OpenSC context, the global_locking and detect cards, it is possible that multiple threads may call C_Initialize. The current code tries to prevent this using "if (context == NULL)" but this is not a mutex, and multiple threads may endup overwrite contexts and global locking and cause additional problems, with pcsc and segfault. FireFox appears to do this see #2032 The PR adds a mutex or Critical section to make sure only one thread creates the context sets the global_locking and does the initial detect cards, etc. This allows the global_lock (if requested) to be setup which is then used for other calls. All but the first call to C_Initialize will return with CKR_OK, others will return CKR_CRYPTOKI_ALREADY_INITIALIZED. Date: Mon Jan 11 12:47:12 2021 -0600 Changes to be committed: modified: src/pkcs11/pkcs11-global.c
This commit is contained in:
parent
d369965a7f
commit
1b4e9f1d4a
|
@ -61,6 +61,11 @@ extern CK_FUNCTION_LIST_3_0 pkcs11_function_list_3_0;
|
|||
|
||||
#if defined(HAVE_PTHREAD)
|
||||
|
||||
/* mutex used to control C_Initilize creation of mutexes */
|
||||
static pthread_mutex_t c_initialize_m = PTHREAD_MUTEX_INITIALIZER;
|
||||
#define C_INITIALIZE_M_LOCK pthread_mutex_lock(&c_initialize_m);
|
||||
#define C_INITIALIZE_M_UNLOCK pthread_mutex_unlock(&c_initialize_m);
|
||||
|
||||
CK_RV mutex_create(void **mutex)
|
||||
{
|
||||
pthread_mutex_t *m;
|
||||
|
@ -101,6 +106,9 @@ static CK_C_INITIALIZE_ARGS _def_locks = {
|
|||
#define HAVE_OS_LOCKING
|
||||
|
||||
#elif defined(_WIN32)
|
||||
CRITICAL_SECTION c_initialize_cs = {0};
|
||||
#define C_INITIALIZE_M_LOCK EnterCriticalSection(&c_initialize_cs);
|
||||
#define C_INITIALIZE_M_UNLOCK LeaveCriticalSection(&c_initialize_cs);
|
||||
|
||||
CK_RV mutex_create(void **mutex)
|
||||
{
|
||||
|
@ -141,6 +149,10 @@ static CK_C_INITIALIZE_ARGS _def_locks = {
|
|||
|
||||
#endif
|
||||
|
||||
#else /* PKCS11_THREAD_LOCKING */
|
||||
#define C_INITIALIZE_M_LOCK
|
||||
#define C_INITIALIZE_M_UNLOCK
|
||||
|
||||
#endif /* PKCS11_THREAD_LOCKING */
|
||||
|
||||
static CK_C_INITIALIZE_ARGS_PTR global_locking;
|
||||
|
@ -221,6 +233,9 @@ __attribute__((constructor))
|
|||
#endif
|
||||
int module_init()
|
||||
{
|
||||
#ifdef _WIN32
|
||||
InitializeCriticalSection(&c_initialize_cs);
|
||||
#endif
|
||||
sc_notify_init();
|
||||
return 1;
|
||||
}
|
||||
|
@ -236,6 +251,9 @@ int module_close()
|
|||
#endif
|
||||
#ifdef ENABLE_OPENPACE
|
||||
EAC_cleanup();
|
||||
#endif
|
||||
#ifdef _WIN32
|
||||
DeleteCriticalSection(&c_initialize_cs);
|
||||
#endif
|
||||
return 1;
|
||||
}
|
||||
|
@ -283,8 +301,12 @@ CK_RV C_Initialize(CK_VOID_PTR pInitArgs)
|
|||
in_finalize = 0;
|
||||
#endif
|
||||
|
||||
/* protect from multiple threads tryng to setup locking */
|
||||
C_INITIALIZE_M_LOCK
|
||||
|
||||
if (context != NULL) {
|
||||
sc_log(context, "C_Initialize(): Cryptoki already initialized\n");
|
||||
C_INITIALIZE_M_UNLOCK
|
||||
return CKR_CRYPTOKI_ALREADY_INITIALIZED;
|
||||
}
|
||||
|
||||
|
@ -336,6 +358,9 @@ out:
|
|||
sc_pkcs11_free_lock();
|
||||
}
|
||||
|
||||
/* protect from multiple threads tryng to setup locking */
|
||||
C_INITIALIZE_M_UNLOCK
|
||||
|
||||
return rv;
|
||||
}
|
||||
|
||||
|
|
Loading…
Reference in New Issue