components/openssl/openssl-1.0.1-fips-140/patches/29_fork_safe.patch
changeset 4370 7043c27399f1
parent 4367 2f56a3dac19a
child 4371 29fdb14099eb
equal deleted inserted replaced
4367:2f56a3dac19a 4370:7043c27399f1
     1 #
       
     2 # This file adds the code to setup internal mutexes and callback function.
       
     3 #	PSARC/2014/077
       
     4 #	PSARC/2015/043
       
     5 # This change was implemented in-house.  The issue was brought up to
       
     6 # the upstream engineers, but there was no commitment.
       
     7 #
       
     8 --- openssl-1.0.1f/crypto/cryptlib.c.~1~	Fri Feb  7 10:41:36 2014
       
     9 +++ openssl-1.0.1f/crypto/cryptlib.c	Thu Feb  6 16:03:58 2014
       
    10 @@ -116,6 +116,7 @@
       
    11  
       
    12  #include "cryptlib.h"
       
    13  #include <openssl/safestack.h>
       
    14 +#include <pthread.h>
       
    15  
       
    16  #if defined(OPENSSL_SYS_WIN32) || defined(OPENSSL_SYS_WIN16)
       
    17  static double SSLeay_MSVC5_hack = 0.0; /* and for VC1.5 */
       
    18 @@ -184,6 +185,8 @@
       
    19   */
       
    20  static STACK_OF(CRYPTO_dynlock) *dyn_locks = NULL;
       
    21  
       
    22 +static pthread_mutex_t *solaris_openssl_locks;
       
    23 +
       
    24  static void (MS_FAR *locking_callback) (int mode, int type,
       
    25                                          const char *file, int line) = 0;
       
    26  static int (MS_FAR *add_lock_callback) (int *pointer, int amount,
       
    27 @@ -373,7 +376,10 @@
       
    28  void CRYPTO_set_dynlock_create_callback(struct CRYPTO_dynlock_value *(*func)
       
    29                                           (const char *file, int line))
       
    30  {
       
    31 -    dynlock_create_callback = func;
       
    32 +    /*
       
    33 +     * we now setup our own dynamic locking callback, and disallow
       
    34 +     * setting of another locking callback.
       
    35 +     */
       
    36  }
       
    37 
       
    38  void CRYPTO_set_dynlock_lock_callback(void (*func) (int mode,
       
    39 @@ -382,7 +388,10 @@
       
    40                                                      const char *file,
       
    41                                                      int line))
       
    42  {
       
    43 -    dynlock_lock_callback = func;
       
    44 +    /*
       
    45 +     * we now setup our own dynamic locking callback, and disallow
       
    46 +     * setting of another locking callback.
       
    47 +     */
       
    48  }
       
    49 
       
    50  void CRYPTO_set_dynlock_destroy_callback(void (*func)
       
    51 @@ -389,7 +398,10 @@
       
    52                                            (struct CRYPTO_dynlock_value *l,
       
    53                                             const char *file, int line))
       
    54  {
       
    55 -    dynlock_destroy_callback = func;
       
    56 +    /*
       
    57 +     * we now setup our own dynamic locking callback, and disallow
       
    58 +     * setting of another locking callback.
       
    59 +     */
       
    60  }
       
    61 
       
    62  void (*CRYPTO_get_locking_callback(void)) (int mode, int type,
       
    63 @@ -402,6 +414,129@@
       
    64      return (add_lock_callback);
       
    65  }
       
    66 
       
    67 +/*
       
    68 + * This is the locking callback function which all applications will be
       
    69 + * using when CRYPTO_lock() is called.
       
    70 + */ 
       
    71 +static void solaris_locking_callback(int mode, int type, const char *file,
       
    72 +    int line)
       
    73 +{
       
    74 +    if (mode & CRYPTO_LOCK) {
       
    75 +        pthread_mutex_lock(&solaris_openssl_locks[type]);
       
    76 +    } else {
       
    77 +        pthread_mutex_unlock(&solaris_openssl_locks[type]);
       
    78 +    }
       
    79 +}
       
    80 +
       
    81 +
       
    82 +/*
       
    83 + * Implement Solaris's own dynamic locking routines.
       
    84 + */
       
    85 +static struct CRYPTO_dynlock_value *
       
    86 +solaris_dynlock_create(const char *file, int line)
       
    87 +{
       
    88 +    int                        ret;
       
    89 +    pthread_mutex_t    *dynlock;
       
    90 +
       
    91 +    dynlock = OPENSSL_malloc(sizeof(pthread_mutex_t));
       
    92 +    if (dynlock == NULL) {
       
    93 +        return (NULL);
       
    94 +    }
       
    95 +
       
    96 +    ret = pthread_mutex_init(dynlock, NULL);
       
    97 +    OPENSSL_assert(ret);
       
    98 +
       
    99 +    return ((struct CRYPTO_dynlock_value *)dynlock);
       
   100 +}
       
   101 +
       
   102 +static void
       
   103 +solaris_dynlock_lock(int mode, struct CRYPTO_dynlock_valud *dynlock,
       
   104 +    const char *file, int line)
       
   105 +{
       
   106 +    int        ret;
       
   107 +
       
   108 +    if (mode & CRYPTO_LOCK) {
       
   109 +        ret = pthread_mutex_lock((pthread_mutex_t *)dynlock);
       
   110 +    } else {
       
   111 +        ret = pthread_mutex_unlock((pthread_mutex_t *)dynlock);
       
   112 +    }
       
   113 +
       
   114 +    OPENSSL_assert(ret == 0);
       
   115 +}
       
   116 +
       
   117 +static void
       
   118 +solaris_dynlock_destroy(struct CRYPTO_dynlock_value *dynlock,
       
   119 +    const char *file, int line)
       
   120 +{
       
   121 +    int ret;
       
   122 +    ret = pthread_mutex_destroy((pthread_mutex_t *)dynlock);
       
   123 +    OPENSSL_assert(ret);
       
   124 +}
       
   125 +
       
   126 +
       
   127 +/*
       
   128 + * This function is called when a child process is forked to setup its own
       
   129 + * global locking callback function ptr and mutexes.
       
   130 + */
       
   131 +static void solaris_fork_child(void)
       
   132 +{
       
   133 +    /*
       
   134 +     * clear locking_callback to indicate that locks should
       
   135 +     * be reinitialized.
       
   136 +     */
       
   137 +    locking_callback = NULL;
       
   138 +    solaris_locking_setup();
       
   139 +}
       
   140 +
       
   141 +/*
       
   142 + * This function allocates and initializes the global mutex array, and
       
   143 + * sets the locking callback.
       
   144 + */
       
   145 +void solaris_locking_setup()
       
   146 +{
       
   147 +    int i;
       
   148 +    int num_locks;
       
   149 +
       
   150 +    /* setup the dynlock callback if not already */
       
   151 +    if (dynlock_create_callback == NULL) {
       
   152 +        dynlock_create_callback = solaris_dynlock_create;
       
   153 +    }
       
   154 +    if (dynlock_lock_callback == NULL) {
       
   155 +        dynlock_lock_callback = solaris_dynlock_lock;
       
   156 +    }
       
   157 +    if (dynlock_destroy_callback == NULL) {
       
   158 +        dynlock_destroy_callback = solaris_dynlock_destroy;
       
   159 +    }
       
   160 +
       
   161 +    /* locking callback is already setup. Nothing to do */
       
   162 +    if (locking_callback != NULL) {
       
   163 +        return;
       
   164 +    }
       
   165 +
       
   166 +    /*
       
   167 +     * Set atfork handler so that child can setup its own mutexes and
       
   168 +     * locking callbacks when it is forked
       
   169 +     */
       
   170 +    (void) pthread_atfork(NULL, NULL, solaris_fork_child);
       
   171 +
       
   172 +    /* allocate locks needed by OpenSSL  */
       
   173 +    num_locks = CRYPTO_num_locks();
       
   174 +    solaris_openssl_locks =
       
   175 +        OPENSSL_malloc(sizeof (pthread_mutex_t) * num_locks);
       
   176 +    if (solaris_openssl_locks == NULL) {
       
   177 +        fprintf(stderr,
       
   178 +            "solaris_locking_setup: memory allocation failure.\n");
       
   179 +        abort();
       
   180 +    }
       
   181 +
       
   182 +    /* initialize openssl mutexes */
       
   183 +    for (i = 0; i < num_locks; i++) {
       
   184 +        pthread_mutex_init(&solaris_openssl_locks[i], NULL);
       
   185 +    }
       
   186 +    locking_callback = solaris_locking_callback;
       
   187 +
       
   188 +}
       
   189 +
       
   190  void CRYPTO_set_locking_callback(void (*func) (int mode, int type,
       
   191                                                 const char *file, int line))
       
   192  {
       
   193 @@ -410,7 +486,11 @@
       
   194       * started.
       
   195       */
       
   196      OPENSSL_init();
       
   197 -    locking_callback = func;
       
   198 +
       
   199 +    /*
       
   200 +     * we now setup our own locking callback and mutexes, and disallow
       
   201 +     * setting of another locking callback.
       
   202 +     */
       
   203  }
       
   204  
       
   205  void CRYPTO_set_add_lock_callback(int (*func) (int *num, int mount, int type,
       
   206 @@ -471,9 +551,10 @@
       
   207  
       
   208  int CRYPTO_THREADID_set_callback(void (*func) (CRYPTO_THREADID *))
       
   209  {
       
   210 -    if (threadid_callback)
       
   211 -        return 0;
       
   212 -    threadid_callback = func;
       
   213 +    /*
       
   214 +     * Use the backup method (the address of 'errno') to identify the
       
   215 +     * thread and disallow setting the threadid callback.
       
   216 +     */
       
   217      return 1;
       
   218  }
       
   219  
       
   220 @@ -531,7 +611,10 @@
       
   221  
       
   222  void CRYPTO_set_id_callback(unsigned long (*func) (void))
       
   223  {
       
   224 -    id_callback = func;
       
   225 +    /*
       
   226 +     * Use the backup method to identify the thread/process.
       
   227 +     * Setting the id callback is disallowed.
       
   228 +     */
       
   229  }
       
   230  
       
   231  unsigned long CRYPTO_thread_id(void)
       
   232 --- openssl-1.0.1f/crypto/cryptlib.h.~1~	Fri Feb  7 10:41:42 2014
       
   233 +++ openssl-1.0.1f/crypto/cryptlib.h	Thu Feb  6 16:04:16 2014
       
   234 @@ -104,6 +104,8 @@
       
   235  void *OPENSSL_stderr(void);
       
   236  extern int OPENSSL_NONPIC_relocated;
       
   237  
       
   238 +void solaris_locking_setup();
       
   239 +
       
   240  #ifdef  __cplusplus
       
   241  }
       
   242  #endif
       
   243 --- openssl-1.0.1f/crypto/sparccpuid.S.~1~	Fri Feb  7 10:41:37 2014
       
   244 +++ openssl-1.0.1f/crypto/sparccpuid.S	Thu Feb  6 16:04:14 2014
       
   245 @@ -398,5 +398,7 @@
       
   246  .size	OPENSSL_cleanse,.-OPENSSL_cleanse
       
   247 
       
   248  .section	".init",#alloc,#execinstr
       
   249 +	call	solaris_locking_setup
       
   250 +	nop
       
   251  	call	OPENSSL_cpuid_setup
       
   252  	nop
       
   253 --- openssl-1.0.1f/crypto/x86_64cpuid.pl.~1~	Wed Feb 12 13:20:09 2014
       
   254 +++ openssl-1.0.1f/crypto/x86_64cpuid.pl	Wed Feb 12 13:21:20 2014
       
   255 @@ -20,7 +20,10 @@
       
   256  print<<___;
       
   257  .extern		OPENSSL_cpuid_setup
       
   258  .hidden		OPENSSL_cpuid_setup
       
   259 +.extern		solaris_locking_setup
       
   260 +.hidden		solaris_locking_setup
       
   261  .section	.init
       
   262 +	call	solaris_locking_setup
       
   263  	call	OPENSSL_cpuid_setup
       
   264  
       
   265  .hidden	OPENSSL_ia32cap_P
       
   266 --- openssl-1.0.1f/crypto/x86cpuid.pl.~1~	Wed Feb 12 13:38:03 2014
       
   267 +++ openssl-1.0.1f/crypto/x86cpuid.pl	Wed Feb 12 13:38:31 2014
       
   268 @@ -353,6 +353,7 @@
       
   269  	&ret	();
       
   270  &function_end_B("OPENSSL_ia32_rdrand");
       
   271  
       
   272 +&initseg("solaris_locking_setup");
       
   273  &initseg("OPENSSL_cpuid_setup");
       
   274  
       
   275  &asm_finish();