Hi Klaus,
On Mon, Jun 14, 2010 at 7:46 PM, Klaus Heinrich Kiwi
<[email protected]> wrote:
> 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);
1 here is a magic number -- something that indicates it as the
sigsegv error return code would help.
> +}
>
>
>
> @@ -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;
Should this be rv = FALSE for consistency?
Kent
> }
>
> +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
>
------------------------------------------------------------------------------
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