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

Reply via email to