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

Reply via email to