Thread-safety fixes
[openssl.git] / crypto / err / err.c
index f2c322c1cb322228b7186dfe7f3fcf9c65ac8b3b..3367a75d99abed655f8ffaed336aad0aa0c8edd4 100644 (file)
 #include <stdio.h>
 #include <stdarg.h>
 #include <string.h>
+#include "cryptlib.h"
 #include <openssl/lhash.h>
 #include <openssl/crypto.h>
-#include "cryptlib.h"
 #include <openssl/buffer.h>
 #include <openssl/bio.h>
 #include <openssl/err.h>
@@ -147,6 +147,7 @@ static ERR_STRING_DATA ERR_str_libraries[]=
 {ERR_PACK(ERR_LIB_PKCS12,0,0)          ,"PKCS12 routines"},
 {ERR_PACK(ERR_LIB_RAND,0,0)            ,"random number generator"},
 {ERR_PACK(ERR_LIB_DSO,0,0)             ,"DSO support routines"},
+{ERR_PACK(ERR_LIB_TS,0,0)              ,"time stamp routines"},
 {ERR_PACK(ERR_LIB_ENGINE,0,0)          ,"engine routines"},
 {ERR_PACK(ERR_LIB_OCSP,0,0)            ,"OCSP routines"},
 {0,NULL},
@@ -195,6 +196,7 @@ static ERR_STRING_DATA ERR_str_reasons[]=
 {ERR_R_DSO_LIB                         ,"DSO lib"},
 {ERR_R_ENGINE_LIB                      ,"ENGINE lib"},
 {ERR_R_OCSP_LIB                                ,"OCSP lib"},
+{ERR_R_TS_LIB                          ,"TS lib"},
 
 {ERR_R_NESTED_ASN1_ERROR               ,"nested asn1 error"},
 {ERR_R_BAD_ASN1_OBJECT_HEADER          ,"bad asn1 object header"},
@@ -541,16 +543,27 @@ static ERR_STRING_DATA SYS_str_reasons[NUM_SYS_STR_REASONS + 1];
  * will be returned for SYSerr(), which always gets an errno
  * value and never one of those 'standard' reason codes. */
 
-static void build_SYS_str_reasons()
+static void build_SYS_str_reasons(void)
        {
        /* OPENSSL_malloc cannot be used here, use static storage instead */
        static char strerror_tab[NUM_SYS_STR_REASONS][LEN_SYS_STR_REASON];
        int i;
        static int init = 1;
 
-       if (!init) return;
-
+       CRYPTO_r_lock(CRYPTO_LOCK_ERR);
+       if (!init)
+               {
+               CRYPTO_r_unlock(CRYPTO_LOCK_ERR);
+               return;
+               }
+       
+       CRYPTO_r_unlock(CRYPTO_LOCK_ERR);
        CRYPTO_w_lock(CRYPTO_LOCK_ERR);
+       if (!init)
+               {
+               CRYPTO_w_unlock(CRYPTO_LOCK_ERR);
+               return;
+               }
 
        for (i = 1; i <= NUM_SYS_STR_REASONS; i++)
                {
@@ -594,11 +607,11 @@ static void build_SYS_str_reasons()
 
 #define err_clear(p,i) \
        do { \
-       es->err_flags[i]=0; \
-       es->err_buffer[i]=0; \
+       (p)->err_flags[i]=0; \
+       (p)->err_buffer[i]=0; \
        err_clear_data(p,i); \
-       es->err_file[i]=NULL; \
-       es->err_line[i]= -1; \
+       (p)->err_file[i]=NULL; \
+       (p)->err_line[i]= -1; \
        } while(0)
 
 static void ERR_STATE_free(ERR_STATE *s)
@@ -631,7 +644,8 @@ static void err_load_strings(int lib, ERR_STRING_DATA *str)
        {
        while (str->error)
                {
-               str->error|=ERR_PACK(lib,0,0);
+               if (lib)
+                       str->error|=ERR_PACK(lib,0,0);
                ERRFN(err_set_item)(str);
                str++;
                }
@@ -647,7 +661,8 @@ void ERR_unload_strings(int lib, ERR_STRING_DATA *str)
        {
        while (str->error)
                {
-               str->error|=ERR_PACK(lib,0,0);
+               if (lib)
+                       str->error|=ERR_PACK(lib,0,0);
                ERRFN(err_del_item)(str);
                str++;
                }
@@ -943,7 +958,7 @@ static unsigned long err_hash(const void *a_void)
        {
        unsigned long ret,l;
 
-       l=((ERR_STRING_DATA *)a_void)->error;
+       l=((const ERR_STRING_DATA *)a_void)->error;
        ret=l^ERR_GET_LIB(l)^ERR_GET_FUNC(l);
        return(ret^ret%19*13);
        }
@@ -951,21 +966,21 @@ static unsigned long err_hash(const void *a_void)
 /* static int err_cmp(ERR_STRING_DATA *a, ERR_STRING_DATA *b) */
 static int err_cmp(const void *a_void, const void *b_void)
        {
-       return((int)(((ERR_STRING_DATA *)a_void)->error -
-                       ((ERR_STRING_DATA *)b_void)->error));
+       return((int)(((const ERR_STRING_DATA *)a_void)->error -
+                       ((const ERR_STRING_DATA *)b_void)->error));
        }
 
 /* static unsigned long pid_hash(ERR_STATE *a) */
 static unsigned long pid_hash(const void *a_void)
        {
-       return(((ERR_STATE *)a_void)->pid*13);
+       return(((const ERR_STATE *)a_void)->pid*13);
        }
 
 /* static int pid_cmp(ERR_STATE *a, ERR_STATE *b) */
 static int pid_cmp(const void *a_void, const void *b_void)
        {
-       return((int)((long)((ERR_STATE *)a_void)->pid -
-                       (long)((ERR_STATE *)b_void)->pid));
+       return((int)((long)((const ERR_STATE *)a_void)->pid -
+                       (long)((const ERR_STATE *)b_void)->pid));
        }
 
 void ERR_remove_state(unsigned long pid)
@@ -1075,7 +1090,7 @@ void ERR_add_error_data(int num, ...)
                                else
                                        str=p;
                                }
-                       strcat(str,a);
+                       BUF_strlcat(str,a,(size_t)s+1);
                        }
                }
        ERR_set_error_data(str,ERR_TXT_MALLOCED|ERR_TXT_STRING);
@@ -1106,7 +1121,7 @@ int ERR_pop_to_mark(void)
                {
                err_clear(es,es->top);
                es->top-=1;
-               if (es->top == -1) es->top=ERR_NUM_ERRORS;
+               if (es->top == -1) es->top=ERR_NUM_ERRORS-1;
                }
                
        if (es->bottom == es->top) return 0;