To avoid iterating through the API Session list Anchor->SessListBeg every time we need a session reference, use the session's own pointer as handle.
To avoid segfaults when the caller passes an invalid handle, hook to SIGSEGV and try to recover by using siglongjmp() Signed-off-by: Klaus Heinrich Kiwi <[email protected]> --- usr/include/pkcs11/apictl.h | 3 +- usr/lib/pkcs11/api/api_interface.c | 1 + usr/lib/pkcs11/api/apiutil.c | 55 +++++++++++++++++++++++++++-------- 3 files changed, 45 insertions(+), 14 deletions(-) diff --git a/usr/include/pkcs11/apictl.h b/usr/include/pkcs11/apictl.h index 1e5ab1d..449e021 100755 --- a/usr/include/pkcs11/apictl.h +++ b/usr/include/pkcs11/apictl.h @@ -305,11 +305,12 @@ #define _APILOCAL_H -typedef struct { +typedef struct _Session_struct { void *Previous; void *Next; CK_SLOT_ID SltId; // Slot ID for indexing into the function list pointer CK_SESSION_HANDLE RealHandle; // Handle returned by the STDLL + struct _Session_struct *Handle; // our own handle, cheap check for valid session } Session_Struct_t; #ifdef PK64 diff --git a/usr/lib/pkcs11/api/api_interface.c b/usr/lib/pkcs11/api/api_interface.c index 91dc658..d387cf9 100755 --- a/usr/lib/pkcs11/api/api_interface.c +++ b/usr/lib/pkcs11/api/api_interface.c @@ -3787,6 +3787,7 @@ C_OpenSession ( CK_SLOT_ID slotID, // uniqueness. + apiSessp->Handle = apiSessp; apiSessp->SltId = slotID; // Add to the linked list AddToSessionList(apiSessp); diff --git a/usr/lib/pkcs11/api/apiutil.c b/usr/lib/pkcs11/api/apiutil.c index ab8a3f1..f475ed6 100755 --- a/usr/lib/pkcs11/api/apiutil.c +++ b/usr/lib/pkcs11/api/apiutil.c @@ -311,6 +311,8 @@ #include <sys/syslog.h> #include <sys/ipc.h> +#include <setjmp.h> +#include <signal.h> #include "msg.h" //HACK @@ -350,7 +352,12 @@ set_perm(int file) } - +static jmp_buf apisigbuf; + +void apisegvhandler(int signum, siginfo_t *info, void *ptr) +{ + siglongjmp(apisigbuf, 1); +} @@ -563,27 +570,49 @@ Valid_Session(pSession,rSession) int rv=FALSE; // Assume that it is not on the list Session_Struct_t *cSessionp; - + struct sigaction segvact, oldact; if ( !pSession ) - return FALSE; - - // Walk the Anchor block session linked list - // return TRUE if the pointer is on the list - // False if it is not + return FALSE; + pthread_mutex_lock(&(Anchor->SessListMutex)); - cSessionp = Anchor->SessListBeg; - while (cSessionp) { - if (cSessionp == pSession){ - rv = TRUE; + // Register "recovery point", to which we can return in case + // of a segfault when dereferencing below + if ( sigsetjmp(apisigbuf, 1) == 0 ) { + memset(&segvact, 0, sizeof(segvact)); + segvact.sa_sigaction = apisegvhandler; + segvact.sa_flags = SA_SIGINFO | SA_RESETHAND; + + // Register segfault handler, save original + if ( sigaction( SIGSEGV, &segvact, &oldact ) != 0 ) { + LOGIT(LOG_DEBUG, "Valid_Session() - sigaction() #1 failed!"); + rv = FALSE; + goto out; + } + + // Try dereferencing it, and check for the right handle value + if ( pSession->Handle == pSession ) { rSession->sessionh = pSession->RealHandle; rSession->slotID = pSession->SltId; - break; + rv = TRUE; } - cSessionp = (Session_Struct_t *)cSessionp->Next; + + // restore the original signal handler + if ( sigaction( SIGSEGV, &oldact, NULL ) != 0 ) { + LOGIT(LOG_DEBUG, "Valid_Session() - sigaction() #2 failed!"); + rv = FALSE; + goto out; + } + } + else { + // if we are here it means we recovered from sigsetjmp, which means that + // a segfault was caught when trying to dereference the handle. This + // means that the session handle is invalid. + rv = NULL; } +out: pthread_mutex_unlock(&(Anchor->SessListMutex)); return rv; } -- 1.6.6.1 ------------------------------------------------------------------------------ ThinkGeek and WIRED's GeekDad team up for the Ultimate GeekDad Father's Day Giveaway. ONE MASSIVE PRIZE to the lucky parental unit. See the prize list and enter to win: http://p.sf.net/sfu/thinkgeek-promo _______________________________________________ Opencryptoki-tech mailing list [email protected] https://lists.sourceforge.net/lists/listinfo/opencryptoki-tech
