Print this page
4912 soft_giant_mutex in pkcs11_softtoken stays held after fork

Split Close
Expand all
Collapse all
          --- old/usr/src/lib/pkcs11/pkcs11_softtoken/common/softGeneral.c
          +++ new/usr/src/lib/pkcs11/pkcs11_softtoken/common/softGeneral.c
↓ open down ↓ 13 lines elided ↑ open up ↑
  14   14   * file and include the License file at usr/src/OPENSOLARIS.LICENSE.
  15   15   * If applicable, add the following below this CDDL HEADER, with the
  16   16   * fields enclosed by brackets "[]" replaced with your own identifying
  17   17   * information: Portions Copyright [yyyy] [name of copyright owner]
  18   18   *
  19   19   * CDDL HEADER END
  20   20   */
  21   21  /*
  22   22   * Copyright 2009 Sun Microsystems, Inc.  All rights reserved.
  23   23   * Use is subject to license terms.
       24 + *
       25 + * Copyright 2014, OmniTI Computer Consulting, Inc. All rights reserved.
  24   26   */
  25   27  
  26   28  #include <strings.h>
  27   29  #include <errno.h>
  28   30  #include <cryptoutil.h>
  29   31  #include <unistd.h> /* for pid_t */
  30   32  #include <pthread.h>
  31   33  #include <security/cryptoki.h>
  32   34  #include "softGlobal.h"
  33   35  #include "softSession.h"
↓ open down ↓ 87 lines elided ↑ open up ↑
 121  123  soft_session_t *soft_session_list = NULL;
 122  124  
 123  125  int all_sessions_closing = 0;
 124  126  
 125  127  slot_t soft_slot;
 126  128  obj_to_be_freed_list_t obj_delay_freed;
 127  129  ses_to_be_freed_list_t ses_delay_freed;
 128  130  
 129  131  /* protects softtoken_initialized and access to C_Initialize/C_Finalize */
 130  132  pthread_mutex_t soft_giant_mutex = PTHREAD_MUTEX_INITIALIZER;
      133 +/*
      134 + * ONLY SET TO TRUE BY softtoken_fork_prepare().
      135 + * ONLY SET TO FALSE BY softtoken_fork_after().
      136 + */
      137 +boolean_t fork_prepared = B_FALSE;
 131  138  
 132  139  static CK_RV finalize_common(boolean_t force, CK_VOID_PTR pReserved);
 133  140  static void softtoken_init();
 134  141  static void softtoken_fini();
 135  142  static void softtoken_fork_prepare();
 136  143  static void softtoken_fork_after();
      144 +static void softtoken_fork_after_droplocks(void);
 137  145  
 138  146  CK_RV
 139  147  C_Initialize(CK_VOID_PTR pInitArgs)
 140  148  {
 141  149  
 142  150          int initialize_pid;
 143  151          boolean_t supplied_ok;
 144  152          CK_RV rv;
 145  153  
 146  154          /*
↓ open down ↓ 257 lines elided ↑ open up ↑
 404  412              softtoken_fork_after, softtoken_fork_after);
 405  413  }
 406  414  
 407  415  /*
 408  416   * softtoken_fini() function required to make sure complete cleanup
 409  417   * is done if softtoken is ever unloaded without a C_Finalize() call.
 410  418   */
 411  419  static void
 412  420  softtoken_fini()
 413  421  {
 414      -        (void) pthread_mutex_lock(&soft_giant_mutex);
      422 +        int rc;
 415  423  
 416      -        /* if we're not initilized, do not attempt to finalize */
 417      -        if (!softtoken_initialized) {
 418      -                (void) pthread_mutex_unlock(&soft_giant_mutex);
 419      -                return;
 420      -        }
      424 +        rc = pthread_mutex_trylock(&soft_giant_mutex);
      425 +        /*
      426 +         * Check to see if it was acquired by softtoken_fork_prepare().
      427 +         */
      428 +        if (rc == EBUSY && fork_prepared)
      429 +                rc = 0;
 421  430  
 422      -        (void) finalize_common(B_TRUE, NULL_PTR);
      431 +        if (rc != 0) {
      432 +                /*
      433 +                 * I don't know WHAT just happened, but it's pretty bad.  Grab
      434 +                 * the lock for real, even if it means deadlocking here.
      435 +                 */
      436 +                (void) pthread_mutex_lock(&soft_giant_mutex);
      437 +        } /* Else we acquired the lock and life is good. */
 423  438  
 424      -        (void) pthread_mutex_unlock(&soft_giant_mutex);
      439 +        /* Only finalize if we're initialized. */
      440 +        if (softtoken_initialized) {
      441 +                /*
      442 +                 * We also have to DROP all of the other locks that
      443 +                 * softtoken_fork_prepare did IF it was prepared, because
      444 +                 * finalize_common() is going to pick them right back up.
      445 +                 */
      446 +                if (fork_prepared)
      447 +                        softtoken_fork_after_droplocks();
      448 +                (void) finalize_common(B_TRUE, NULL_PTR);
      449 +                /* ASSERT(!softtoken_initialized); */
      450 +        }
      451 +
      452 +        /*
      453 +         * If we don't want to drop the lock, we assume softtoken_fork_after()
      454 +         * will get called.
      455 +         */
      456 +        if (!fork_prepared)
      457 +                (void) pthread_mutex_unlock(&soft_giant_mutex);
 425  458  }
 426  459  
 427  460  CK_RV
 428  461  C_GetInfo(CK_INFO_PTR pInfo)
 429  462  {
 430  463          if (!softtoken_initialized)
 431  464                  return (CKR_CRYPTOKI_NOT_INITIALIZED);
 432  465  
 433  466          if (pInfo == NULL) {
 434  467                  return (CKR_ARGUMENTS_BAD);
↓ open down ↓ 54 lines elided ↑ open up ↑
 489  522   * 1. soft_giant_mutex
 490  523   * 2. soft_sessionlist_mutex
 491  524   * 3. soft_slot.slot_mutex
 492  525   * 4. soft_slot.keystore_mutex
 493  526   * 5. token_session mutexes via soft_acquire_all_session_mutexes()
 494  527   * 6. all soft_session_list mutexes via soft_acquire_all_session_mutexes()
 495  528   * 7. obj_delay_freed.obj_to_be_free_mutex;
 496  529   * 8. ses_delay_freed.ses_to_be_free_mutex
 497  530   */
 498  531  void
 499      -softtoken_fork_prepare()
      532 +softtoken_fork_prepare(void)
 500  533  {
 501  534          (void) pthread_mutex_lock(&soft_giant_mutex);
 502  535          if (softtoken_initialized) {
 503  536                  (void) pthread_mutex_lock(&soft_sessionlist_mutex);
 504  537                  (void) pthread_mutex_lock(&soft_slot.slot_mutex);
 505  538                  (void) pthread_mutex_lock(&soft_slot.keystore_mutex);
 506  539                  soft_acquire_all_session_mutexes(&token_session);
 507  540                  soft_acquire_all_session_mutexes(soft_session_list);
 508  541                  (void) pthread_mutex_lock(
 509  542                      &obj_delay_freed.obj_to_be_free_mutex);
 510  543                  (void) pthread_mutex_lock(
 511  544                      &ses_delay_freed.ses_to_be_free_mutex);
 512  545          }
      546 +        fork_prepared = B_TRUE;
 513  547  }
 514  548  
      549 +static void
      550 +softtoken_fork_after_droplocks(void)
      551 +{
      552 +        /* ASSERT(softtoken_initialized); */
      553 +        (void) pthread_mutex_unlock(&ses_delay_freed.ses_to_be_free_mutex);
      554 +        (void) pthread_mutex_unlock(&obj_delay_freed.obj_to_be_free_mutex);
      555 +        soft_release_all_session_mutexes(soft_session_list);
      556 +        soft_release_all_session_mutexes(&token_session);
      557 +        (void) pthread_mutex_unlock(&soft_slot.keystore_mutex);
      558 +        (void) pthread_mutex_unlock(&soft_slot.slot_mutex);
      559 +        (void) pthread_mutex_unlock(&soft_sessionlist_mutex);
      560 +}
      561 +
 515  562  /*
 516  563   * Release in opposite order to softtoken_fork_prepare().
 517  564   * Function is used for parent and child.
 518  565   */
 519  566  void
 520      -softtoken_fork_after()
      567 +softtoken_fork_after(void)
 521  568  {
 522      -        if (softtoken_initialized) {
 523      -                (void) pthread_mutex_unlock(
 524      -                    &ses_delay_freed.ses_to_be_free_mutex);
 525      -                (void) pthread_mutex_unlock(
 526      -                    &obj_delay_freed.obj_to_be_free_mutex);
 527      -                soft_release_all_session_mutexes(soft_session_list);
 528      -                soft_release_all_session_mutexes(&token_session);
 529      -                (void) pthread_mutex_unlock(&soft_slot.keystore_mutex);
 530      -                (void) pthread_mutex_unlock(&soft_slot.slot_mutex);
 531      -                (void) pthread_mutex_unlock(&soft_sessionlist_mutex);
 532      -        }
      569 +        if (softtoken_initialized)
      570 +                softtoken_fork_after_droplocks();
      571 +        fork_prepared = B_FALSE;
 533  572          (void) pthread_mutex_unlock(&soft_giant_mutex);
 534  573  }
    
XXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX