Index: aclocal/Makefile ================================================================== --- aclocal/Makefile +++ aclocal/Makefile @@ -1,2 +1,2 @@ -../aclocal.m4: acx_pthread.m4 dc_shobjs.m4 dc_pcsc.m4 dc_versionscript.m4 +../aclocal.m4: acx_pthread.m4 dc_shobjs.m4 dc_pcsc.m4 dc_versionscript.m4 dc_dlfuncs.m4 cat $^ > "$@" ADDED aclocal/dc_dlfuncs.m4 Index: aclocal/dc_dlfuncs.m4 ================================================================== --- /dev/null +++ aclocal/dc_dlfuncs.m4 @@ -0,0 +1,21 @@ +AC_DEFUN([DC_DLFUNCS], [ + dnl Check for dl headers and functions + AC_CHECK_HEADERS(dlfcn.h) + if test -n "${ac_cv_func_dlsym}"; then + AC_CHECK_FUNC(dlsym, [ + AC_DEFINE([HAVE_DLSYM], [1], [Have dlsym()]) + ]) + else + SAVE_LIBS="${LIBS}" + for addlibs in '' '-ldl'; do + LIBS="${SAVE_LIBS} ${addlibs}" + unset ac_cv_func_dlsym + AC_CHECK_FUNC(dlsym, [ + AC_DEFINE([HAVE_DLSYM], [1], [Have dlsym()]) + SAVE_LIBS="${LIBS}" + break + ]) + done + LIBS="${SAVE_LIBS}" + fi +]) Index: cackey.c ================================================================== --- cackey.c +++ cackey.c @@ -45,10 +45,18 @@ # endif #else # ifdef HAVE_LIBZ # undef HAVE_LIBZ # endif +#endif +#ifndef _THREAD_EMULATION +# ifdef HAVE_DLFCN_H +# ifdef HAVE_DLSYM +# include +# define HAVE_CACKEY_MUTEX_PTHREAD_FUNCS 1 +# endif +# endif #endif #ifdef CACKEY_DEBUG_SEARCH_SPEEDTEST # include #endif @@ -3736,10 +3744,44 @@ # endif #endif return(x509_read_ret); } + +/* Dynamically load pthreads from the running application */ +#ifdef HAVE_CACKEY_MUTEX_PTHREAD_FUNCS +#warning building with pthreads opened via dlsym +struct cackey_mutex_pthread_funcs_st { + int (*pthread_mutex_init)(pthread_mutex_t *restrict mutex, const pthread_mutexattr_t *restrict attr); + int (*pthread_mutex_lock)(pthread_mutex_t *mutex); + int (*pthread_mutex_unlock)(pthread_mutex_t *mutex); +}; + +static struct cackey_mutex_pthread_funcs_st *cackey_mutex_pthread_funcs(void) { + static struct cackey_mutex_pthread_funcs_st funcs = {0}; + static int init = 0; + + if (init != 0) { + return(&funcs); + } + + funcs.pthread_mutex_init = dlsym(RTLD_DEFAULT, "pthread_mutex_init"); + funcs.pthread_mutex_lock = dlsym(RTLD_DEFAULT, "pthread_mutex_lock"); + funcs.pthread_mutex_unlock = dlsym(RTLD_DEFAULT, "pthread_mutex_unlock"); + + init = 1; + + return(&funcs); +} +#define cackey_pthread_mutex_init cackey_mutex_pthread_funcs()->pthread_mutex_init +#define cackey_pthread_mutex_lock cackey_mutex_pthread_funcs()->pthread_mutex_lock +#define cackey_pthread_mutex_unlock cackey_mutex_pthread_funcs()->pthread_mutex_unlock +#else +#define cackey_pthread_mutex_init pthread_mutex_init +#define cackey_pthread_mutex_lock pthread_mutex_lock +#define cackey_pthread_mutex_unlock pthread_mutex_unlock +#endif /* Returns 0 on success */ static int cackey_mutex_create(void **mutex) { pthread_mutex_t *pthread_mutex; int pthread_retval; @@ -3753,11 +3795,11 @@ CACKEY_DEBUG_PRINTF("Failed to allocate memory."); return(-1); } - pthread_retval = pthread_mutex_init(pthread_mutex, NULL); + pthread_retval = cackey_pthread_mutex_init(pthread_mutex, NULL); if (pthread_retval != 0) { CACKEY_DEBUG_PRINTF("pthread_mutex_init() returned error (%i).", pthread_retval); return(-1); } @@ -3789,11 +3831,11 @@ CACKEY_DEBUG_PRINTF("Called."); if ((cackey_args.flags & CKF_OS_LOCKING_OK) == CKF_OS_LOCKING_OK) { pthread_mutex = mutex; - pthread_retval = pthread_mutex_lock(pthread_mutex); + pthread_retval = cackey_pthread_mutex_lock(pthread_mutex); if (pthread_retval != 0) { CACKEY_DEBUG_PRINTF("pthread_mutex_lock() returned error (%i).", pthread_retval); return(-1); } @@ -3823,11 +3865,11 @@ CACKEY_DEBUG_PRINTF("Called."); if ((cackey_args.flags & CKF_OS_LOCKING_OK) == CKF_OS_LOCKING_OK) { pthread_mutex = mutex; - pthread_retval = pthread_mutex_unlock(pthread_mutex); + pthread_retval = cackey_pthread_mutex_unlock(pthread_mutex); if (pthread_retval != 0) { CACKEY_DEBUG_PRINTF("pthread_mutex_unlock() returned error (%i).", pthread_retval); return(-1); } @@ -4616,10 +4658,18 @@ if (args->CreateMutex != NULL || args->DestroyMutex != NULL || args->LockMutex != NULL || args->UnlockMutex != NULL) { CACKEY_DEBUG_PRINTF("Error. Some, but not All threading primitives provided."); return(CKR_ARGUMENTS_BAD); } + } else { +#ifdef HAVE_CACKEY_MUTEX_PTHREAD_FUNCS + if (cackey_mutex_pthread_funcs()->pthread_mutex_init == NULL || cackey_mutex_pthread_funcs()->pthread_mutex_lock == NULL || cackey_mutex_pthread_funcs()->pthread_mutex_unlock == NULL) { + CACKEY_DEBUG_PRINTF("Error. Library is not linked to pthreads and we are unable to find them at runtime."); + + return(CKR_GENERAL_ERROR); + } +#endif } } else { cackey_args.CreateMutex = NULL; cackey_args.DestroyMutex = NULL; cackey_args.LockMutex = NULL; Index: configure.ac ================================================================== --- configure.ac +++ configure.ac @@ -79,10 +79,13 @@ dnl Check for PC/SC headers and libraries DC_PCSC dnl Check for ZLIB libraries AC_CHECK_LIB(z, uncompress) + +dnl Check for dl headers and functions +DC_DLFUNCS dnl Verify that a basic program will compile AC_CACHE_CHECK([if basic PC/SC program works], cackey_cv_pcsc_works, [ AC_LINK_IFELSE( AC_LANG_PROGRAM([[