> diff --git a/usr/lib/pkcs11/common/obj_mgr.c b/usr/lib/pkcs11/common/obj_mgr.c
> index 64eda19..f8492dc 100755
> --- a/usr/lib/pkcs11/common/obj_mgr.c
> +++ b/usr/lib/pkcs11/common/obj_mgr.c
> @@ -299,6 +299,8 @@
>  #include <stdio.h>
>  #include <string.h>  // for memcmp() et al
>  #include <strings.h>
> +#include <setjmp.h>
> +#include <signal.h>
>
>  #include "pkcs11types.h"
>  #include "defs.h"
> @@ -310,6 +312,13 @@
>
>  pthread_rwlock_t obj_list_rw_mutex = PTHREAD_RWLOCK_INITIALIZER;
>
> +static jmp_buf objsigbuf;
> +
> +void objsegvhandler(int signum, siginfo_t *info, void *ptr)
> +{
> +   siglongjmp(objsigbuf, 1);

  Same comment here as I had in the last mail, just add some
indication this is the rc from a sigsegv.

> +}
> +
>  CK_RV
>  object_mgr_add( SESSION          * sess,
>                 CK_ATTRIBUTE     * pTemplate,
> @@ -536,7 +545,6 @@ object_mgr_add_to_map( SESSION          * sess,
>       st_err_log(0, __FILE__, __LINE__);
>       return CKR_HOST_MEMORY;
>    }
> -   map_node->handle   = next_object_handle++;
>    map_node->session  = sess;
>    map_node->ptr      = obj;
>
> @@ -551,6 +559,10 @@ object_mgr_add_to_map( SESSION          * sess,
>       return CKR_FUNCTION_FAILED;
>    }
>    object_map = dlist_add_as_first( object_map, map_node );

  While looking into this code I saw a problem not with your patch,
but in the dlist add routines.  If malloc() inside
dlist_add_as_first() fails, the global object_map variable is blown
away by getting set to NULL. Also no error is logged in that case. :-)
 Yikes.  dlist_add_as_last() does the same.  Ping me if you want me to
open a bug for this...

> +   map_node->handle   = (CK_SESSION_HANDLE) object_map;  // handle is the 
> DL_NODE pointer and
> +                                                         // 
> dlist_add_as_first() will return
> +                                                         // this newly added 
> DL_NODE as it is the
> +                                                         // new head of the 
> list
>    pthread_rwlock_unlock(&obj_list_rw_mutex);
>
>    *handle = map_node->handle;
> @@ -1176,13 +1188,23 @@ CK_RV
>  object_mgr_find_in_map_nocache( CK_OBJECT_HANDLE    handle,
>                          OBJECT           ** ptr )
>  {
> -   DL_NODE   * node = NULL;
> -   OBJECT    * obj  = NULL;
> +   DL_NODE    * node = NULL;
> +   OBJECT_MAP * map  = NULL;
> +   OBJECT     * obj  = NULL;
> +   CK_RV      result = CKR_OK;
> +
> +   struct sigaction segvact, oldact;
>
>    if (!ptr){
>       st_err_log(4, __FILE__, __LINE__, __FUNCTION__);
>       return CKR_FUNCTION_FAILED;
>    }
> +
> +   if (!handle) {
> +      st_err_log(30, __FILE__, __LINE__);
> +      return CKR_OBJECT_HANDLE_INVALID;
> +   }
> +
>    //
>    // no mutex here.  the calling function should have locked the mutex
>    //
> @@ -1191,20 +1213,52 @@ object_mgr_find_in_map_nocache( CK_OBJECT_HANDLE    
> handle,
>      st_err_log(4, __FILE__, __LINE__, __FUNCTION__);
>      return CKR_FUNCTION_FAILED;
>    }
> -   node = object_map;
> -   while (node) {
> -      OBJECT_MAP *map = (OBJECT_MAP *)node->data;
> +   node = (DL_NODE *) handle;
> +
> +   if (sigsetjmp(objsigbuf, 1) == 0) {
> +      memset(&segvact, 0, sizeof(segvact));
> +      segvact.sa_sigaction = objsegvhandler;
> +      segvact.sa_flags = SA_SIGINFO | SA_RESETHAND;
>
> -      if (map->handle == handle) {
> +      // Register Segfault signal handler, so we can derefence 'node'
> +      // safely (or sort of)
> +      if (sigaction(SIGSEGV, &segvact, &oldact) != 0) {
> +         st_err_log(4, __FILE__, __LINE__, __FUNCTION__);
> +         result = CKR_FUNCTION_FAILED;
> +         goto out;
> +      }
> +
> +      // Try dereferencing it, and check if we have the right handle
> +      map = (OBJECT_MAP *) node->data;
> +      if ( map->handle == handle ){
>          obj = map->ptr;
> -         break;
>       }
>
> -      node = node->next;
> +      // restore the old signal handler
> +      if (sigaction(SIGSEGV, &oldact, NULL) != 0) {
> +         // Even if we *have* the right handle & could recover, failing to
> +         // restore the handler might indicate problems.
> +         st_err_log(4, __FILE__, __LINE__, __FUNCTION__);
> +         result = CKR_FUNCTION_FAILED;
> +         goto out;
> +      }
> +   }
> +   else {

  In this path, doesn't oldact stay registered as we exit?  Shouldn't
the if block above be moved down to be common to both the segfault
case and the non-segfault case?  I am new at reading the flow of these
signal catchers. :-)

> +      // If we are here, means that a segfault was caught and we somehow 
> recovered
> +      // result: the object handle was invalid
> +      result = CKR_OK;
> +      obj = NULL;
>    }
> +
> +
> +out:
>    pthread_rwlock_unlock(&obj_list_rw_mutex);
> +
> +   if (result != CKR_OK) {
> +      return result;
> +   }
>
> -   if (obj == NULL || node == NULL) {
> +   if (obj == NULL) {
>       st_err_log(30, __FILE__, __LINE__);
>       return CKR_OBJECT_HANDLE_INVALID;
>    }
> @@ -1232,13 +1286,22 @@ CK_RV
>  object_mgr_find_in_map1( CK_OBJECT_HANDLE    handle,
>                          OBJECT           ** ptr )
>  {
> -   DL_NODE   * node = NULL;
> -   OBJECT    * obj  = NULL;
> +   DL_NODE    * node = NULL;
> +   OBJECT_MAP * map  = NULL;
> +   OBJECT     * obj  = NULL;
> +   CK_RV      result = CKR_OK;
> +
> +   struct sigaction segvact, oldact;
>
>    if (!ptr){
>       st_err_log(4, __FILE__, __LINE__, __FUNCTION__);
>       return CKR_FUNCTION_FAILED;
>    }
> +
> +   if (!handle){
> +      st_err_log(30, __FILE__, __LINE__);
> +      return CKR_OBJECT_HANDLE_INVALID;
> +   }
>    //
>    // no mutex here.  the calling function should have locked the mutex
>    //
> @@ -1247,20 +1310,54 @@ object_mgr_find_in_map1( CK_OBJECT_HANDLE    handle,
>      st_err_log(4, __FILE__, __LINE__, __FUNCTION__);
>      return CKR_FUNCTION_FAILED;
>    }
> -   node = object_map;
> -   while (node) {
> -      OBJECT_MAP *map = (OBJECT_MAP *)node->data;
> -
> -      if (map->handle == handle) {
> +   node = (DL_NODE *) handle;
> +
> +   // FIXME:  the below will segfault when the app gives us an invalid
> +   // handle
> +    if (sigsetjmp(objsigbuf, 1) == 0) {
> +      memset(&segvact, 0, sizeof(segvact));
> +      segvact.sa_sigaction = objsegvhandler;
> +      segvact.sa_flags = SA_SIGINFO | SA_RESETHAND;
> +
> +      // Register Segfault signal handler, so we can derefence 'node'
> +      // safely (or sort of)
> +      if (sigaction(SIGSEGV, &segvact, &oldact) != 0) {
> +         st_err_log(4, __FILE__, __LINE__, __FUNCTION__);
> +         result = CKR_FUNCTION_FAILED;
> +         goto out;
> +      }
> +
> +      // Try dereferencing it, and check if we have the right handle
> +      map = (OBJECT_MAP *) node->data;
> +      if ( handle == map->handle ){
>          obj = map->ptr;
> -         break;
>       }
>
> -      node = node->next;
> +      // restore the old signal handler
> +      if (sigaction(SIGSEGV, &oldact, NULL) != 0) {
> +         // Even if we *have* the right handle & could recover, failing to
> +         // restore the handler might indicate problems.
> +         st_err_log(4, __FILE__, __LINE__, __FUNCTION__);
> +         result = CKR_FUNCTION_FAILED;
> +         goto out;
> +      }
> +   }
> +   else {

  Same question here as above.

Kent

> +      // If we are here, means that a segfault was caught and we somehow 
> recovered
> +      // result: the object handle was invalid
> +      result = CKR_OK;
> +      obj = NULL;
>    }
> +
> +out:
>    pthread_rwlock_unlock(&obj_list_rw_mutex);
>
> -   if (obj == NULL || node == NULL) {
> +   if (result != CKR_OK) {
> +      return result;
> +   }
> +
> +
> +   if (obj == NULL) {
>       st_err_log(30, __FILE__, __LINE__);
>       return CKR_OBJECT_HANDLE_INVALID;
>    }
> @@ -1646,34 +1743,39 @@ done:
>  CK_BBOOL
>  object_mgr_invalidate_handle1( CK_OBJECT_HANDLE handle )
>  {
> -   DL_NODE *node = NULL;
> +   DL_NODE     *node = NULL;
> +   OBJECT_MAP  *map  = NULL;
> +   CK_BBOOL    result;
>
>    //
>    // no mutex stuff here.  the calling routine should have locked the mutex
>    //
>
> +   if (!handle){
> +     return FALSE;
> +   }
> +
>    if (pthread_rwlock_wrlock(&obj_list_rw_mutex)) {
>      st_err_log(4, __FILE__, __LINE__, __FUNCTION__);
> -     return CKR_FUNCTION_FAILED;
> +     return FALSE; // FIXME: Proper error messages
>    }
> -   node = object_map;
> -
> -   while (node) {
> -      OBJECT_MAP *map = (OBJECT_MAP *)node->data;
>
> -      // I think we can do this because even token objects exist in RAM
> -      //
> -      if (map->handle == handle) {
> -         object_map = dlist_remove_node( object_map, node );
> -         free( map );
> -        pthread_rwlock_unlock(&obj_list_rw_mutex);
> -         return TRUE;
> -      }
> +   node = (DL_NODE *)handle;
> +   // FIXME: The below will segfault whenever the caller uses an invalid
> +   // handle
> +   map = (OBJECT_MAP *)node->data;
>
> -      node = node->next;
> +   if ( handle == map->handle ) {
> +      object_map = dlist_remove_node( object_map, node );
> +      free( map );
> +      result = TRUE;
>    }
> +   else {
> +     result = FALSE;
> +   }
> +
>    pthread_rwlock_unlock(&obj_list_rw_mutex);
> -   return FALSE;
> +   return result;
>
>  }
>
> --
> 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