components/openssl/common/patches/029-fork_safe.patch
branchs11u3-sru
changeset 7163 ee09edbd5876
parent 4461 68eb2fdf9b3a
equal deleted inserted replaced
7159:59b406bc4a3a 7163:ee09edbd5876
       
     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 --- a/crypto/cryptlib.c	2016-05-03 06:44:42.000000000 -0700
       
     9 +++ b/crypto/cryptlib.c	2016-09-02 08:47:23.640202700 -0700
       
    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,127 @@
       
    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 +        (void) pthread_mutex_lock(&solaris_openssl_locks[type]);
       
    76 +    } else {
       
    77 +        (void) pthread_mutex_unlock(&solaris_openssl_locks[type]);
       
    78 +    }
       
    79 +}
       
    80 +
       
    81 +/*
       
    82 + * Implement Solaris's own dynamic locking routines.
       
    83 + */
       
    84 +static struct CRYPTO_dynlock_value *
       
    85 +solaris_dynlock_create(const char *file, int line)
       
    86 +{
       
    87 +    int                        ret;
       
    88 +    pthread_mutex_t    *dynlock;
       
    89 +
       
    90 +    dynlock = OPENSSL_malloc(sizeof(pthread_mutex_t));
       
    91 +    if (dynlock == NULL) {
       
    92 +        return (NULL);
       
    93 +    }
       
    94 +
       
    95 +    ret = pthread_mutex_init(dynlock, NULL);
       
    96 +    OPENSSL_assert(ret == 0);
       
    97 +
       
    98 +    return ((struct CRYPTO_dynlock_value *)dynlock);
       
    99 +}
       
   100 +
       
   101 +static void
       
   102 +solaris_dynlock_lock(int mode, struct CRYPTO_dynlock_value *dynlock,
       
   103 +    const char *file, int line)
       
   104 +{
       
   105 +    int        ret;
       
   106 +
       
   107 +    if (mode & CRYPTO_LOCK) {
       
   108 +        ret = pthread_mutex_lock((pthread_mutex_t *)dynlock);
       
   109 +    } else {
       
   110 +        ret = pthread_mutex_unlock((pthread_mutex_t *)dynlock);
       
   111 +    }
       
   112 +
       
   113 +    OPENSSL_assert(ret == 0);
       
   114 +}
       
   115 +
       
   116 +static void
       
   117 +solaris_dynlock_destroy(struct CRYPTO_dynlock_value *dynlock,
       
   118 +    const char *file, int line)
       
   119 +{
       
   120 +    int ret;
       
   121 +    ret = pthread_mutex_destroy((pthread_mutex_t *)dynlock);
       
   122 +    OPENSSL_assert(ret == 0);
       
   123 +}
       
   124 +
       
   125 +
       
   126 +static void solaris_fork_prep(void)
       
   127 +{
       
   128 +    int i;
       
   129 +
       
   130 +    for (i = 0; i < CRYPTO_NUM_LOCKS; i++) {
       
   131 +        (void) pthread_mutex_lock(&solaris_openssl_locks[i]);
       
   132 +    }
       
   133 +}
       
   134 +
       
   135 +static void solaris_fork_post(void)
       
   136 +{
       
   137 +    int i;
       
   138 +
       
   139 +    for (i = CRYPTO_NUM_LOCKS - 1; i >= 0; i--) {
       
   140 +        (void) pthread_mutex_unlock(&solaris_openssl_locks[i]);
       
   141 +    }
       
   142 +
       
   143 +    OPENSSL_assert(dynlock_create_callback == solaris_dynlock_create);
       
   144 +    OPENSSL_assert(dynlock_lock_callback == solaris_dynlock_lock);
       
   145 +    OPENSSL_assert(dynlock_destroy_callback == solaris_dynlock_destroy);
       
   146 +    OPENSSL_assert(locking_callback == solaris_locking_callback);
       
   147 +}
       
   148 +
       
   149 +/*
       
   150 + * This is called by the _init() function to setup locks used by OpenSSL
       
   151 + * and locking callback functions.
       
   152 + */
       
   153 +void
       
   154 +solaris_locking_setup()
       
   155 +{
       
   156 +    int i;
       
   157 +
       
   158 +    /* setup the dynlock callback if not already */
       
   159 +    if (dynlock_create_callback == NULL) {
       
   160 +        dynlock_create_callback = solaris_dynlock_create;
       
   161 +    }
       
   162 +    if (dynlock_lock_callback == NULL) {
       
   163 +        dynlock_lock_callback = solaris_dynlock_lock;
       
   164 +    }
       
   165 +    if (dynlock_destroy_callback == NULL) {
       
   166 +        dynlock_destroy_callback = solaris_dynlock_destroy;
       
   167 +    }
       
   168 +    if (locking_callback == NULL) {
       
   169 +	    locking_callback = solaris_locking_callback;
       
   170 +    }
       
   171 +
       
   172 +    /* allocate and initialize locks needed by OpenSSL  */
       
   173 +    solaris_openssl_locks =
       
   174 +        OPENSSL_malloc(sizeof (pthread_mutex_t) * CRYPTO_NUM_LOCKS);
       
   175 +    if (solaris_openssl_locks == NULL) {
       
   176 +        fprintf(stderr,
       
   177 +            "solaris_locking_setup: memory allocation failure.\n");
       
   178 +        abort();
       
   179 +    }
       
   180 +    for (i = 0; i < CRYPTO_NUM_LOCKS; i++) {
       
   181 +        (void) pthread_mutex_init(&solaris_openssl_locks[i], NULL);
       
   182 +    }
       
   183 +
       
   184 +    (void) pthread_atfork(solaris_fork_prep, solaris_fork_post, solaris_fork_post);
       
   185 +}
       
   186 +
       
   187 +
       
   188  void CRYPTO_set_locking_callback(void (*func) (int mode, int type,
       
   189                                                 const char *file, int line))
       
   190  {
       
   191 @@ -410,7 +541,11 @@
       
   192       * started.
       
   193       */
       
   194      OPENSSL_init();
       
   195 -    locking_callback = func;
       
   196 +
       
   197 +    /*
       
   198 +     * we now setup our own locking callback and mutexes, and disallow
       
   199 +     * setting of another locking callback.
       
   200 +     */
       
   201  }
       
   202  
       
   203  void CRYPTO_set_add_lock_callback(int (*func) (int *num, int mount, int type,
       
   204 @@ -471,9 +606,10 @@
       
   205  
       
   206  int CRYPTO_THREADID_set_callback(void (*func) (CRYPTO_THREADID *))
       
   207  {
       
   208 -    if (threadid_callback)
       
   209 -        return 0;
       
   210 -    threadid_callback = func;
       
   211 +    /*
       
   212 +     * Use the backup method (the address of 'errno') to identify the
       
   213 +     * thread and disallow setting the threadid callback.
       
   214 +     */
       
   215      return 1;
       
   216  }
       
   217  
       
   218 @@ -529,7 +665,10 @@
       
   219  
       
   220  void CRYPTO_set_id_callback(unsigned long (*func) (void))
       
   221  {
       
   222 -    id_callback = func;
       
   223 +    /*
       
   224 +     * Use the backup method to identify the thread/process.
       
   225 +     * Setting the id callback is disallowed.
       
   226 +     */
       
   227  }
       
   228  
       
   229  unsigned long CRYPTO_thread_id(void)
       
   230 --- openssl-1.0.1f/crypto/cryptlib.h.~1~	Fri Feb  7 10:41:42 2014
       
   231 +++ openssl-1.0.1f/crypto/cryptlib.h	Thu Feb  6 16:04:16 2014
       
   232 @@ -104,6 +104,8 @@
       
   233  void *OPENSSL_stderr(void);
       
   234  extern int OPENSSL_NONPIC_relocated;
       
   235  
       
   236 +void solaris_locking_setup();
       
   237 +
       
   238  #ifdef  __cplusplus
       
   239  }
       
   240  #endif
       
   241 --- openssl-1.0.1f/crypto/sparccpuid.S.~1~	Fri Feb  7 10:41:37 2014
       
   242 +++ openssl-1.0.1f/crypto/sparccpuid.S	Thu Feb  6 16:04:14 2014
       
   243 @@ -525,5 +525,7 @@
       
   244  .size	_sparcv9_vis1_instrument_bus2,.-_sparcv9_vis1_instrument_bus2
       
   245 
       
   246  .section	".init",#alloc,#execinstr
       
   247 +	call	solaris_locking_setup
       
   248 +	nop
       
   249  	call	OPENSSL_cpuid_setup
       
   250  	nop
       
   251 --- openssl-1.0.1f/crypto/x86_64cpuid.pl.~1~	Wed Feb 12 13:20:09 2014
       
   252 +++ openssl-1.0.1f/crypto/x86_64cpuid.pl	Wed Feb 12 13:21:20 2014
       
   253 @@ -20,7 +20,10 @@
       
   254  print<<___;
       
   255  .extern		OPENSSL_cpuid_setup
       
   256  .hidden		OPENSSL_cpuid_setup
       
   257 +.extern		solaris_locking_setup
       
   258 +.hidden		solaris_locking_setup
       
   259  .section	.init
       
   260 +	call	solaris_locking_setup
       
   261  	call	OPENSSL_cpuid_setup
       
   262  
       
   263  .hidden	OPENSSL_ia32cap_P
       
   264 --- openssl-1.0.1f/crypto/x86cpuid.pl.~1~	Wed Feb 12 13:38:03 2014
       
   265 +++ openssl-1.0.1f/crypto/x86cpuid.pl	Wed Feb 12 13:38:31 2014
       
   266 @@ -379,8 +379,10 @@
       
   267  	&ret	();
       
   268  &function_end_B("OPENSSL_ia32_rdseed");
       
   269  
       
   270 +&initseg("solaris_locking_setup");
       
   271  &initseg("OPENSSL_cpuid_setup");
       
   272  
       
   273 +&hidden("solaris_locking_setup");
       
   274  &hidden("OPENSSL_cpuid_setup");
       
   275  &hidden("OPENSSL_ia32cap_P");
       
   276