components/openssl/openssl-1.0.1-fips-140/patches/29_fork_safe.patch
branchs11u3-sru
changeset 7163 ee09edbd5876
parent 7159 59b406bc4a3a
child 7164 b2abbab8e6d5
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 --- 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,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 +		pthread_mutex_lock(&solaris_openssl_locks[type]);
       
    76 +	} else {
       
    77 +		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);
       
    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);
       
   123 +}
       
   124 +
       
   125 +/*
       
   126 + * This function is called when a child process is forked to setup its own
       
   127 + * global locking callback function ptr and mutexes.
       
   128 + */
       
   129 +static void solaris_fork_child(void)
       
   130 +{
       
   131 +	/*
       
   132 +	 * clear locking_callback to indicate that locks should
       
   133 +	 * be reinitialized.
       
   134 +	 */
       
   135 +	locking_callback = NULL;
       
   136 +	solaris_locking_setup();
       
   137 +}
       
   138 +
       
   139 +/*
       
   140 + * This function allocates and initializes the global mutex array, and
       
   141 + * sets the locking callback.
       
   142 + */
       
   143 +void solaris_locking_setup()
       
   144 +{
       
   145 +	int i;
       
   146 +	int num_locks;
       
   147 +
       
   148 +	/* setup the dynlock callback if not already */
       
   149 +	if (dynlock_create_callback == NULL) {
       
   150 +		dynlock_create_callback = solaris_dynlock_create;
       
   151 +	}
       
   152 +	if (dynlock_lock_callback == NULL) {
       
   153 +		dynlock_lock_callback = solaris_dynlock_lock;
       
   154 +	}
       
   155 +	if (dynlock_destroy_callback == NULL) {
       
   156 +		dynlock_destroy_callback = solaris_dynlock_destroy;
       
   157 +	}
       
   158 +
       
   159 +	/* locking callback is already setup. Nothing to do */
       
   160 +	if (locking_callback != NULL) {
       
   161 +		return;
       
   162 +	}
       
   163 +
       
   164 +	/*
       
   165 +	 * Set atfork handler so that child can setup its own mutexes and
       
   166 +	 * locking callbacks when it is forked
       
   167 +	 */
       
   168 +	(void) pthread_atfork(NULL, NULL, solaris_fork_child);
       
   169 +
       
   170 +	/* allocate locks needed by OpenSSL  */
       
   171 +	num_locks = CRYPTO_num_locks();
       
   172 +	solaris_openssl_locks =
       
   173 +	    OPENSSL_malloc(sizeof (pthread_mutex_t) * num_locks);
       
   174 +	if (solaris_openssl_locks == NULL) {
       
   175 +		fprintf(stderr,
       
   176 +			"solaris_locking_setup: memory allocation failure.\n");
       
   177 +		abort();
       
   178 +	}
       
   179 +
       
   180 +	/* initialize openssl mutexes */
       
   181 +	for (i = 0; i < num_locks; i++) {
       
   182 +		pthread_mutex_init(&solaris_openssl_locks[i], NULL);
       
   183 +	}
       
   184 +	locking_callback = solaris_locking_callback;
       
   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 +543,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 +608,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 +667,10 @@
       
   219  
       
   220  void CRYPTO_set_id_callback(unsigned long (*func) (void))
       
   221  {
       
   222 -    id_callback = func;
       
   223 +    /*
       
   224 +     * Use the backup method (the address of 'errno') to identify the
       
   225 +     * thread and disallow setting the threadid callback.
       
   226 +     */
       
   227  }
       
   228  
       
   229  unsigned long CRYPTO_thread_id(void)
       
   230 
       
   231 --- openssl-1.0.1f/crypto/cryptlib.h.~1~	Fri Feb  7 10:41:42 2014
       
   232 +++ openssl-1.0.1f/crypto/cryptlib.h    Thu Feb  6 16:04:16 2014
       
   233 @@ -104,6 +104,8 @@
       
   234  void *OPENSSL_stderr(void);
       
   235  extern int OPENSSL_NONPIC_relocated;
       
   236 
       
   237 +void solaris_locking_setup();
       
   238 +
       
   239  #ifdef  __cplusplus
       
   240  }
       
   241  #endif
       
   242 --- openssl-1.0.1f/crypto/sparccpuid.S.~1~      Fri Feb  7 10:41:37 2014
       
   243 +++ openssl-1.0.1f/crypto/sparccpuid.S  Thu Feb  6 16:04:14 2014
       
   244 @@ -398,5 +398,7 @@
       
   245  .size	OPENSSL_cleanse,.-OPENSSL_cleanse
       
   246  
       
   247  .section	".init",#alloc,#execinstr
       
   248 +	call	solaris_locking_setup
       
   249 +	nop
       
   250 	call	OPENSSL_cpuid_setup
       
   251 	nop
       
   252 --- openssl-1.0.1f/crypto/x86_64cpuid.pl.~1~    Wed Feb 12 13:20:09 2014
       
   253 +++ openssl-1.0.1f/crypto/x86_64cpuid.pl	Wed Feb 12 13:21:20 2014
       
   254 @@ -20,7 +20,10 @@
       
   255  print<<___;
       
   256  .extern		OPENSSL_cpuid_setup
       
   257  .hidden		OPENSSL_cpuid_setup
       
   258 +.extern		solaris_locking_setup
       
   259 +.hidden		solaris_locking_setup
       
   260  .section	.init
       
   261 +	call	solaris_locking_setup
       
   262 	call	OPENSSL_cpuid_setup
       
   263  
       
   264  .hidden	OPENSSL_ia32cap_P
       
   265 --- openssl-1.0.1f/crypto/x86cpuid.pl.~1~       Wed Feb 12 13:38:03 2014
       
   266 +++ openssl-1.0.1f/crypto/x86cpuid.pl   Wed Feb 12 13:38:31 2014
       
   267 @@ -353,6 +353,7 @@
       
   268  	&ret	();
       
   269  &function_end_B("OPENSSL_ia32_rdrand");
       
   270  
       
   271 +&initseg("solaris_locking_setup");
       
   272  &initseg("OPENSSL_cpuid_setup");
       
   273  
       
   274  &asm_finish();