Remove the dual-callback scheme for numeric and pointer thread IDs,
authorGeoff Thorpe <geoff@openssl.org>
Wed, 6 Aug 2008 15:54:15 +0000 (15:54 +0000)
committerGeoff Thorpe <geoff@openssl.org>
Wed, 6 Aug 2008 15:54:15 +0000 (15:54 +0000)
deprecate the original (numeric-only) scheme, and replace with the
CRYPTO_THREADID object. This hides the platform-specifics and should reduce
the possibility for programming errors (where failing to explicitly check
both thread ID forms could create subtle, platform-specific bugs).

Thanks to Bodo, for invaluable review and feedback.

25 files changed:
CHANGES
FAQ
apps/apps.h
crypto/bn/bn.h
crypto/bn/bn_blind.c
crypto/bn/exptest.c
crypto/cryptlib.c
crypto/crypto.h
crypto/dsa/dsatest.c
crypto/ec/ectest.c
crypto/ecdh/ecdhtest.c
crypto/ecdsa/ecdsatest.c
crypto/engine/enginetest.c
crypto/err/err.c
crypto/err/err.h
crypto/err/err_prn.c
crypto/evp/evp_test.c
crypto/mem_dbg.c
crypto/rand/md_rand.c
crypto/rsa/rsa_eay.c
crypto/rsa/rsa_lib.c
crypto/rsa/rsa_test.c
doc/crypto/BN_BLINDING_new.pod
doc/crypto/threads.pod
ssl/ssltest.c

diff --git a/CHANGES b/CHANGES
index 35bd37f..9b524dd 100644 (file)
--- a/CHANGES
+++ b/CHANGES
@@ -4,6 +4,30 @@
 
  Changes between 0.9.8i and 0.9.9  [xx XXX xxxx]
 
 
  Changes between 0.9.8i and 0.9.9  [xx XXX xxxx]
 
+  *) To cater for systems that provide a pointer-based thread ID rather
+     than numeric, deprecate the current numeric thread ID mechanism and
+     replace it with a structure and associated callback type. This
+     mechanism allows a numeric "hash" to be extracted from a thread ID in
+     either case, and on platforms where pointers are larger than 'long',
+     mixing is done to help ensure the numeric 'hash' is usable even if it
+     can't be guaranteed unique. The default mechanism is to use "&errno"
+     as a pointer-based thread ID to distinguish between threads.
+
+     Applications that want to provide their own thread IDs should now use
+     CRYPTO_THREADID_set_callback() to register a callback that will call
+     either CRYPTO_THREADID_set_numeric() or CRYPTO_THREADID_set_pointer().
+
+     (This new approach replaces the functions CRYPTO_set_idptr_callback(),
+     CRYPTO_get_idptr_callback(), and CRYPTO_thread_idptr() that existed in
+     OpenSSL 0.9.9-dev between June 2006 and August 2008. Also, if an
+     application was previously providing a numeric thread callback that
+     was inappropriate for distinguishing threads, then uniqueness might
+     have been obtained with &errno that happened immediately in the
+     intermediate development versions of OpenSSL; this is no longer the
+     case, the numeric thread callback will now override the automatic use
+     of &errno.)
+     [Geoff Thorpe, with help from Bodo Moeller]
+
   *) Initial support for different CRL issuing certificates. This covers a
      simple case where the self issued certificates in the chain exist and
      the real CRL issuer is higher in the existing chain.
   *) Initial support for different CRL issuing certificates. This covers a
      simple case where the self issued certificates in the chain exist and
      the real CRL issuer is higher in the existing chain.
      list-message-digest-algorithms and list-cipher-algorithms.
      [Steve Henson]
 
      list-message-digest-algorithms and list-cipher-algorithms.
      [Steve Henson]
 
-  *) In addition to the numerical (unsigned long) thread ID, provide
-     for a pointer (void *) thread ID.  This helps accomodate systems
-     that do not provide an unsigned long thread ID.  OpenSSL assumes
-     it is in the same thread iff both the numerical and the pointer
-     thread ID agree; so applications are just required to define one
-     of them appropriately (e.g., by using a pointer to a per-thread
-     memory object malloc()ed by the application for the pointer-type
-     thread ID).  Exactly analoguous to the existing functions
-
-        void CRYPTO_set_id_callback(unsigned long (*func)(void));
-        unsigned long (*CRYPTO_get_id_callback(void))(void);
-        unsigned long CRYPTO_thread_id(void);
-
-     we now have additional functions
-
-        void CRYPTO_set_idptr_callback(void *(*func)(void));
-        void *(*CRYPTO_get_idptr_callback(void))(void);
-        void *CRYPTO_thread_idptr(void);
-
-     also in <openssl/crypto.h>.  The default value for
-     CRYPTO_thread_idptr() if the application has not provided its own
-     callback is &errno.
-     [Bodo Moeller]
-
   *) Change the array representation of binary polynomials: the list
      of degrees of non-zero coefficients is now terminated with -1.
      Previously it was terminated with 0, which was also part of the
   *) Change the array representation of binary polynomials: the list
      of degrees of non-zero coefficients is now terminated with -1.
      Previously it was terminated with 0, which was also part of the
diff --git a/FAQ b/FAQ
index 60a527f..fb997b6 100644 (file)
--- a/FAQ
+++ b/FAQ
@@ -717,9 +717,7 @@ file.
 
 Multi-threaded applications must provide two callback functions to
 OpenSSL by calling CRYPTO_set_locking_callback() and
 
 Multi-threaded applications must provide two callback functions to
 OpenSSL by calling CRYPTO_set_locking_callback() and
-CRYPTO_set_id_callback().  (For OpenSSL 0.9.9 or later, the new
-function CRYPTO_set_idptr_callback() may be used in place of
-CRYPTO_set_id_callback().)  This is described in the threads(3)
+CRYPTO_set_id_callback().  This is described in the threads(3)
 manpage.
 
 * I've compiled a program under Windows and it crashes: why?
 manpage.
 
 * I've compiled a program under Windows and it crashes: why?
index 93d8749..bcf597f 100644 (file)
@@ -181,7 +181,7 @@ extern BIO *bio_err;
 #    define apps_shutdown() \
                        do { CONF_modules_unload(1); destroy_ui_method(); \
                        OBJ_cleanup(); EVP_cleanup(); ENGINE_cleanup(); \
 #    define apps_shutdown() \
                        do { CONF_modules_unload(1); destroy_ui_method(); \
                        OBJ_cleanup(); EVP_cleanup(); ENGINE_cleanup(); \
-                       CRYPTO_cleanup_all_ex_data(); ERR_remove_state(0); \
+                       CRYPTO_cleanup_all_ex_data(); ERR_remove_thread_state(NULL); \
                        ERR_free_strings(); COMP_zlib_cleanup();} while(0)
 #  else
 #    define apps_startup() \
                        ERR_free_strings(); COMP_zlib_cleanup();} while(0)
 #  else
 #    define apps_startup() \
@@ -191,7 +191,7 @@ extern BIO *bio_err;
 #    define apps_shutdown() \
                        do { CONF_modules_unload(1); destroy_ui_method(); \
                        OBJ_cleanup(); EVP_cleanup(); \
 #    define apps_shutdown() \
                        do { CONF_modules_unload(1); destroy_ui_method(); \
                        OBJ_cleanup(); EVP_cleanup(); \
-                       CRYPTO_cleanup_all_ex_data(); ERR_remove_state(0); \
+                       CRYPTO_cleanup_all_ex_data(); ERR_remove_thread_state(NULL); \
                        ERR_free_strings(); } while(0)
 #  endif
 #endif
                        ERR_free_strings(); } while(0)
 #  endif
 #endif
index de2cfcf..4749c52 100644 (file)
 #include <stdio.h> /* FILE */
 #endif
 #include <openssl/ossl_typ.h>
 #include <stdio.h> /* FILE */
 #endif
 #include <openssl/ossl_typ.h>
+#include <openssl/crypto.h>
 
 #ifdef  __cplusplus
 extern "C" {
 
 #ifdef  __cplusplus
 extern "C" {
@@ -564,10 +565,11 @@ int BN_BLINDING_convert(BIGNUM *n, BN_BLINDING *b, BN_CTX *ctx);
 int BN_BLINDING_invert(BIGNUM *n, BN_BLINDING *b, BN_CTX *ctx);
 int BN_BLINDING_convert_ex(BIGNUM *n, BIGNUM *r, BN_BLINDING *b, BN_CTX *);
 int BN_BLINDING_invert_ex(BIGNUM *n, const BIGNUM *r, BN_BLINDING *b, BN_CTX *);
 int BN_BLINDING_invert(BIGNUM *n, BN_BLINDING *b, BN_CTX *ctx);
 int BN_BLINDING_convert_ex(BIGNUM *n, BIGNUM *r, BN_BLINDING *b, BN_CTX *);
 int BN_BLINDING_invert_ex(BIGNUM *n, const BIGNUM *r, BN_BLINDING *b, BN_CTX *);
+#ifndef OPENSSL_NO_DEPRECATED
 unsigned long BN_BLINDING_get_thread_id(const BN_BLINDING *);
 void BN_BLINDING_set_thread_id(BN_BLINDING *, unsigned long);
 unsigned long BN_BLINDING_get_thread_id(const BN_BLINDING *);
 void BN_BLINDING_set_thread_id(BN_BLINDING *, unsigned long);
-void *BN_BLINDING_get_thread_idptr(const BN_BLINDING *);
-void BN_BLINDING_set_thread_idptr(BN_BLINDING *, void *);
+#endif
+CRYPTO_THREADID *BN_BLINDING_thread_id(BN_BLINDING *);
 unsigned long BN_BLINDING_get_flags(const BN_BLINDING *);
 void BN_BLINDING_set_flags(BN_BLINDING *, unsigned long);
 BN_BLINDING *BN_BLINDING_create_param(BN_BLINDING *b,
 unsigned long BN_BLINDING_get_flags(const BN_BLINDING *);
 void BN_BLINDING_set_flags(BN_BLINDING *, unsigned long);
 BN_BLINDING *BN_BLINDING_create_param(BN_BLINDING *b,
index e9b6173..e060592 100644 (file)
@@ -121,10 +121,11 @@ struct bn_blinding_st
        BIGNUM *Ai;
        BIGNUM *e;
        BIGNUM *mod; /* just a reference */
        BIGNUM *Ai;
        BIGNUM *e;
        BIGNUM *mod; /* just a reference */
+#ifndef OPENSSL_NO_DEPRECATED
        unsigned long thread_id; /* added in OpenSSL 0.9.6j and 0.9.7b;
                                  * used only by crypto/rsa/rsa_eay.c, rsa_lib.c */
        unsigned long thread_id; /* added in OpenSSL 0.9.6j and 0.9.7b;
                                  * used only by crypto/rsa/rsa_eay.c, rsa_lib.c */
-       void *thread_idptr; /* added in OpenSSL 0.9.9;
-                            * used only by crypto/rsa/rsa_eay.c, rsa_lib.c */
+#endif
+       CRYPTO_THREADID tid;
        unsigned int  counter;
        unsigned long flags;
        BN_MONT_CTX *m_ctx;
        unsigned int  counter;
        unsigned long flags;
        BN_MONT_CTX *m_ctx;
@@ -160,6 +161,7 @@ BN_BLINDING *BN_BLINDING_new(const BIGNUM *A, const BIGNUM *Ai, BIGNUM *mod)
                BN_set_flags(ret->mod, BN_FLG_CONSTTIME);
 
        ret->counter = BN_BLINDING_COUNTER;
                BN_set_flags(ret->mod, BN_FLG_CONSTTIME);
 
        ret->counter = BN_BLINDING_COUNTER;
+       CRYPTO_THREADID_current(&ret->tid);
        return(ret);
 err:
        if (ret != NULL) BN_BLINDING_free(ret);
        return(ret);
 err:
        if (ret != NULL) BN_BLINDING_free(ret);
@@ -265,6 +267,7 @@ int BN_BLINDING_invert_ex(BIGNUM *n, const BIGNUM *r, BN_BLINDING *b, BN_CTX *ct
        return(ret);
        }
 
        return(ret);
        }
 
+#ifndef OPENSSL_NO_DEPRECATED
 unsigned long BN_BLINDING_get_thread_id(const BN_BLINDING *b)
        {
        return b->thread_id;
 unsigned long BN_BLINDING_get_thread_id(const BN_BLINDING *b)
        {
        return b->thread_id;
@@ -274,15 +277,11 @@ void BN_BLINDING_set_thread_id(BN_BLINDING *b, unsigned long n)
        {
        b->thread_id = n;
        }
        {
        b->thread_id = n;
        }
+#endif
 
 
-void *BN_BLINDING_get_thread_idptr(const BN_BLINDING *b)
+CRYPTO_THREADID *BN_BLINDING_thread_id(BN_BLINDING *b)
        {
        {
-       return b->thread_idptr;
-       }
-
-void BN_BLINDING_set_thread_idptr(BN_BLINDING *b, void *p)
-       {
-       b->thread_idptr = p;
+       return &b->tid;
        }
 
 unsigned long BN_BLINDING_get_flags(const BN_BLINDING *b)
        }
 
 unsigned long BN_BLINDING_get_flags(const BN_BLINDING *b)
index 89ebcc8..074a8e8 100644 (file)
@@ -187,7 +187,7 @@ int main(int argc, char *argv[])
        BN_free(b);
        BN_free(m);
        BN_CTX_free(ctx);
        BN_free(b);
        BN_free(m);
        BN_CTX_free(ctx);
-       ERR_remove_state(0);
+       ERR_remove_thread_state(NULL);
        CRYPTO_mem_leaks(out);
        BIO_free(out);
        printf(" done\n");
        CRYPTO_mem_leaks(out);
        BIO_free(out);
        printf(" done\n");
index b89bd7a..fe5d306 100644 (file)
@@ -184,8 +184,10 @@ static void (MS_FAR *locking_callback)(int mode,int type,
        const char *file,int line)=0;
 static int (MS_FAR *add_lock_callback)(int *pointer,int amount,
        int type,const char *file,int line)=0;
        const char *file,int line)=0;
 static int (MS_FAR *add_lock_callback)(int *pointer,int amount,
        int type,const char *file,int line)=0;
+#ifndef OPENSSL_NO_DEPRECATED
 static unsigned long (MS_FAR *id_callback)(void)=0;
 static unsigned long (MS_FAR *id_callback)(void)=0;
-static void *(MS_FAR *idptr_callback)(void)=0;
+#endif
+static void (MS_FAR *threadid_callback)(CRYPTO_THREADID *)=0;
 static struct CRYPTO_dynlock_value *(MS_FAR *dynlock_create_callback)
        (const char *file,int line)=0;
 static void (MS_FAR *dynlock_lock_callback)(int mode,
 static struct CRYPTO_dynlock_value *(MS_FAR *dynlock_create_callback)
        (const char *file,int line)=0;
 static void (MS_FAR *dynlock_lock_callback)(int mode,
@@ -414,6 +416,108 @@ void CRYPTO_set_add_lock_callback(int (*func)(int *num,int mount,int type,
        add_lock_callback=func;
        }
 
        add_lock_callback=func;
        }
 
+/* the memset() here and in set_pointer() seem overkill, but for the sake of
+ * CRYPTO_THREADID_cmp() this avoids any platform silliness that might cause two
+ * "equal" THREADID structs to not be memcmp()-identical. */
+void CRYPTO_THREADID_set_numeric(CRYPTO_THREADID *id, unsigned long val)
+       {
+       memset(id, 0, sizeof(*id));
+       id->val = val;
+       }
+
+static const unsigned char hash_coeffs[] = { 3, 5, 7, 11, 13, 17, 19, 23 };
+void CRYPTO_THREADID_set_pointer(CRYPTO_THREADID *id, void *ptr)
+       {
+       unsigned char *dest = (void *)&id->val;
+       unsigned int accum = 0;
+       unsigned char dnum = sizeof(id->val);
+
+       memset(id, 0, sizeof(*id));
+       id->ptr = ptr;
+       if (sizeof(id->val) >= sizeof(id->ptr))
+               {
+               /* 'ptr' can be embedded in 'val' without loss of uniqueness */
+               id->val = (unsigned long)id->ptr;
+               return;
+               }
+       /* hash ptr ==> val. Each byte of 'val' gets the mod-256 total of a
+        * linear function over the bytes in 'ptr', the co-efficients of which
+        * are a sequence of low-primes (hash_coeffs is an 8-element cycle) -
+        * the starting prime for the sequence varies for each byte of 'val'
+        * (unique polynomials unless pointers are >64-bit). For added spice,
+        * the totals accumulate rather than restarting from zero, and the index
+        * of the 'val' byte is added each time (position dependence). If I was
+        * a black-belt, I'd scan big-endian pointers in reverse to give
+        * low-order bits more play, but this isn't crypto and I'd prefer nobody
+        * mistake it as such. Plus I'm lazy. */
+       while (dnum--)
+               {
+               const unsigned char *src = (void *)&id->ptr;
+               unsigned char snum = sizeof(id->ptr);
+               while (snum--)
+                       accum += *(src++) * hash_coeffs[(snum + dnum) & 7];
+               accum += dnum;
+               *(dest++) = accum & 255;
+               }
+       }
+
+int CRYPTO_THREADID_set_callback(void (*func)(CRYPTO_THREADID *))
+       {
+       if (threadid_callback)
+               return 0;
+       threadid_callback = func;
+       return 1;
+       }
+
+void (*CRYPTO_THREADID_get_callback(void))(CRYPTO_THREADID *)
+       {
+       return threadid_callback;
+       }
+
+void CRYPTO_THREADID_current(CRYPTO_THREADID *id)
+       {
+       if (threadid_callback)
+               {
+               threadid_callback(id);
+               return;
+               }
+#ifndef OPENSSL_NO_DEPRECATED
+       /* If the deprecated callback was set, fall back to that */
+       if (id_callback)
+               {
+               CRYPTO_THREADID_set_numeric(id, id_callback());
+               return;
+               }
+#endif
+       /* Else pick a backup */
+#ifdef OPENSSL_SYS_WIN16
+       CRYPTO_THREADID_set_numeric(id, (unsigned long)GetCurrentTask());
+#elif defined(OPENSSL_SYS_WIN32)
+       CRYPTO_THREADID_set_numeric(id, (unsigned long)GetCurrentThreadId());
+#elif defined(OPENSSL_SYS_BEOS)
+       CRYPTO_THREADID_set_numeric(id, (unsigned long)find_thread(NULL));
+#else
+       /* For everything else, default to using the address of 'errno' */
+       CRYPTO_THREADID_set_pointer(id, &errno);
+#endif
+       }
+
+int CRYPTO_THREADID_cmp(const CRYPTO_THREADID *a, const CRYPTO_THREADID *b)
+       {
+       return memcmp(a, b, sizeof(*a));
+       }
+
+void CRYPTO_THREADID_cpy(CRYPTO_THREADID *dest, const CRYPTO_THREADID *src)
+       {
+       memcpy(dest, src, sizeof(*src));
+       }
+
+unsigned long CRYPTO_THREADID_hash(const CRYPTO_THREADID *id)
+       {
+       return id->val;
+       }
+
+#ifndef OPENSSL_NO_DEPRECATED
 unsigned long (*CRYPTO_get_id_callback(void))(void)
        {
        return(id_callback);
 unsigned long (*CRYPTO_get_id_callback(void))(void)
        {
        return(id_callback);
@@ -446,33 +550,13 @@ unsigned long CRYPTO_thread_id(void)
                ret=id_callback();
        return(ret);
        }
                ret=id_callback();
        return(ret);
        }
-
-void *(*CRYPTO_get_idptr_callback(void))(void)
-       {
-       return(idptr_callback);
-       }
-
-void CRYPTO_set_idptr_callback(void *(*func)(void))
-       {
-       idptr_callback=func;
-       }
-
-void *CRYPTO_thread_idptr(void)
-       {
-       void *ret=NULL;
-
-       if (idptr_callback == NULL)
-               ret = &errno;
-       else
-               ret = idptr_callback();
-
-       return ret;
-       }
+#endif
 
 void CRYPTO_lock(int mode, int type, const char *file, int line)
        {
 #ifdef LOCK_DEBUG
                {
 
 void CRYPTO_lock(int mode, int type, const char *file, int line)
        {
 #ifdef LOCK_DEBUG
                {
+               CRYPTO_THREADID id;
                char *rw_text,*operation_text;
 
                if (mode & CRYPTO_LOCK)
                char *rw_text,*operation_text;
 
                if (mode & CRYPTO_LOCK)
@@ -489,8 +573,9 @@ void CRYPTO_lock(int mode, int type, const char *file, int line)
                else
                        rw_text="ERROR";
 
                else
                        rw_text="ERROR";
 
-               fprintf(stderr,"lock:%08lx/%08p:(%s)%s %-18s %s:%d\n",
-                       CRYPTO_thread_id(), CRYPTO_thread_idptr(), rw_text, operation_text,
+               CRYPTO_THREADID_current(&id);
+               fprintf(stderr,"lock:%08lx:(%s)%s %-18s %s:%d\n",
+                       CRYPTO_THREADID_hash(&id), rw_text, operation_text,
                        CRYPTO_get_lock_name(type), file, line);
                }
 #endif
                        CRYPTO_get_lock_name(type), file, line);
                }
 #endif
@@ -526,11 +611,14 @@ int CRYPTO_add_lock(int *pointer, int amount, int type, const char *file,
 
                ret=add_lock_callback(pointer,amount,type,file,line);
 #ifdef LOCK_DEBUG
 
                ret=add_lock_callback(pointer,amount,type,file,line);
 #ifdef LOCK_DEBUG
-               fprintf(stderr,"ladd:%08lx/%0xp:%2d+%2d->%2d %-18s %s:%d\n",
-                       CRYPTO_thread_id(), CRYPTO_thread_idptr(),
-                       before,amount,ret,
+               {
+               CRYPTO_THREADID id;
+               CRYPTO_THREADID_current(&id);
+               fprintf(stderr,"ladd:%08lx:%2d+%2d->%2d %-18s %s:%d\n",
+                       CRYPTO_THREADID_hash(&id), before,amount,ret,
                        CRYPTO_get_lock_name(type),
                        file,line);
                        CRYPTO_get_lock_name(type),
                        file,line);
+               }
 #endif
                }
        else
 #endif
                }
        else
@@ -539,11 +627,15 @@ int CRYPTO_add_lock(int *pointer, int amount, int type, const char *file,
 
                ret= *pointer+amount;
 #ifdef LOCK_DEBUG
 
                ret= *pointer+amount;
 #ifdef LOCK_DEBUG
-               fprintf(stderr,"ladd:%08lx/%0xp:%2d+%2d->%2d %-18s %s:%d\n",
-                       CRYPTO_thread_id(), CRYPTO_thread_idptr(),
+               {
+               CRYPTO_THREADID id;
+               CRYPTO_THREADID_current(&id);
+               fprintf(stderr,"ladd:%08lx:%2d+%2d->%2d %-18s %s:%d\n",
+                       CRYPTO_THREADID_hash(&id),
                        *pointer,amount,ret,
                        CRYPTO_get_lock_name(type),
                        file,line);
                        *pointer,amount,ret,
                        CRYPTO_get_lock_name(type),
                        file,line);
+               }
 #endif
                *pointer=ret;
                CRYPTO_lock(CRYPTO_UNLOCK|CRYPTO_WRITE,type,file,line);
 #endif
                *pointer=ret;
                CRYPTO_lock(CRYPTO_UNLOCK|CRYPTO_WRITE,type,file,line);
index 8bc927b..bcc8ca4 100644 (file)
@@ -421,12 +421,27 @@ void CRYPTO_set_add_lock_callback(int (*func)(int *num,int mount,int type,
                                              const char *file, int line));
 int (*CRYPTO_get_add_lock_callback(void))(int *num,int mount,int type,
                                          const char *file,int line);
                                              const char *file, int line));
 int (*CRYPTO_get_add_lock_callback(void))(int *num,int mount,int type,
                                          const char *file,int line);
+
+/* Don't use this structure directly. */
+typedef struct crypto_threadid_st
+       {
+       void *ptr;
+       unsigned long val;
+       } CRYPTO_THREADID;
+/* Only use CRYPTO_THREADID_set_[numeric|pointer]() within callbacks */
+void CRYPTO_THREADID_set_numeric(CRYPTO_THREADID *id, unsigned long val);
+void CRYPTO_THREADID_set_pointer(CRYPTO_THREADID *id, void *ptr);
+int CRYPTO_THREADID_set_callback(void (*threadid_func)(CRYPTO_THREADID *));
+void (*CRYPTO_THREADID_get_callback(void))(CRYPTO_THREADID *);
+void CRYPTO_THREADID_current(CRYPTO_THREADID *id);
+int CRYPTO_THREADID_cmp(const CRYPTO_THREADID *a, const CRYPTO_THREADID *b);
+void CRYPTO_THREADID_cpy(CRYPTO_THREADID *dest, const CRYPTO_THREADID *src);
+unsigned long CRYPTO_THREADID_hash(const CRYPTO_THREADID *id);
+#ifndef OPENSSL_NO_DEPRECATED
 void CRYPTO_set_id_callback(unsigned long (*func)(void));
 unsigned long (*CRYPTO_get_id_callback(void))(void);
 unsigned long CRYPTO_thread_id(void);
 void CRYPTO_set_id_callback(unsigned long (*func)(void));
 unsigned long (*CRYPTO_get_id_callback(void))(void);
 unsigned long CRYPTO_thread_id(void);
-void CRYPTO_set_idptr_callback(void *(*func)(void));
-void *(*CRYPTO_get_idptr_callback(void))(void);
-void *CRYPTO_thread_idptr(void);
+#endif
 
 const char *CRYPTO_get_lock_name(int type);
 int CRYPTO_add_lock(int *pointer,int amount,int type, const char *file,
 
 const char *CRYPTO_get_lock_name(int type);
 int CRYPTO_add_lock(int *pointer,int amount,int type, const char *file,
index 5a699ca..edffd24 100644 (file)
@@ -222,7 +222,7 @@ end:
                ERR_print_errors(bio_err);
        if (dsa != NULL) DSA_free(dsa);
        CRYPTO_cleanup_all_ex_data();
                ERR_print_errors(bio_err);
        if (dsa != NULL) DSA_free(dsa);
        CRYPTO_cleanup_all_ex_data();
-       ERR_remove_state(0);
+       ERR_remove_thread_state(NULL);
        ERR_free_strings();
        CRYPTO_mem_leaks(bio_err);
        if (bio_err != NULL)
        ERR_free_strings();
        CRYPTO_mem_leaks(bio_err);
        if (bio_err != NULL)
index b74d643..7509cb9 100644 (file)
@@ -1326,7 +1326,7 @@ int main(int argc, char *argv[])
 #endif
        CRYPTO_cleanup_all_ex_data();
        ERR_free_strings();
 #endif
        CRYPTO_cleanup_all_ex_data();
        ERR_free_strings();
-       ERR_remove_state(0);
+       ERR_remove_thread_state(NULL);
        CRYPTO_mem_leaks_fp(stderr);
        
        return 0;
        CRYPTO_mem_leaks_fp(stderr);
        
        return 0;
index 1575006..212a87e 100644 (file)
@@ -343,7 +343,7 @@ err:
        if (ctx) BN_CTX_free(ctx);
        BIO_free(out);
        CRYPTO_cleanup_all_ex_data();
        if (ctx) BN_CTX_free(ctx);
        BIO_free(out);
        CRYPTO_cleanup_all_ex_data();
-       ERR_remove_state(0);
+       ERR_remove_thread_state(NULL);
        CRYPTO_mem_leaks_fp(stderr);
        EXIT(ret);
        return(ret);
        CRYPTO_mem_leaks_fp(stderr);
        EXIT(ret);
        return(ret);
index b07e312..aa4e148 100644 (file)
@@ -490,7 +490,7 @@ err:
        if (ret)
                ERR_print_errors(out);
        CRYPTO_cleanup_all_ex_data();
        if (ret)
                ERR_print_errors(out);
        CRYPTO_cleanup_all_ex_data();
-       ERR_remove_state(0);
+       ERR_remove_thread_state(NULL);
        ERR_free_strings();
        CRYPTO_mem_leaks(out);
        if (out != NULL)
        ERR_free_strings();
        CRYPTO_mem_leaks(out);
        if (out != NULL)
index cf82f49..3c1d2b4 100644 (file)
@@ -276,7 +276,7 @@ end:
        ENGINE_cleanup();
        CRYPTO_cleanup_all_ex_data();
        ERR_free_strings();
        ENGINE_cleanup();
        CRYPTO_cleanup_all_ex_data();
        ERR_free_strings();
-       ERR_remove_state(0);
+       ERR_remove_thread_state(NULL);
        CRYPTO_mem_leaks_fp(stderr);
        return to_return;
        }
        CRYPTO_mem_leaks_fp(stderr);
        return to_return;
        }
index f615cb4..69713a6 100644 (file)
@@ -429,13 +429,13 @@ static ERR_STRING_DATA *int_err_del_item(ERR_STRING_DATA *d)
 
 static unsigned long err_state_hash(const ERR_STATE *a)
        {
 
 static unsigned long err_state_hash(const ERR_STATE *a)
        {
-       return (a->pid + (unsigned long)a->pidptr) * 13;
+       return CRYPTO_THREADID_hash(&a->tid) * 13;
        }
 static IMPLEMENT_LHASH_HASH_FN(err_state, ERR_STATE)
 
 static int err_state_cmp(const ERR_STATE *a, const ERR_STATE *b)
        {
        }
 static IMPLEMENT_LHASH_HASH_FN(err_state, ERR_STATE)
 
 static int err_state_cmp(const ERR_STATE *a, const ERR_STATE *b)
        {
-       return (a->pid != b->pid) || (a->pidptr != b->pidptr);
+       return CRYPTO_THREADID_cmp(&a->tid, &b->tid);
        }
 static IMPLEMENT_LHASH_COMP_FN(err_state, ERR_STATE)
 
        }
 static IMPLEMENT_LHASH_COMP_FN(err_state, ERR_STATE)
 
@@ -980,40 +980,37 @@ const char *ERR_reason_error_string(unsigned long e)
        return((p == NULL)?NULL:p->string);
        }
 
        return((p == NULL)?NULL:p->string);
        }
 
-void ERR_remove_state(unsigned long pid)
+void ERR_remove_thread_state(const CRYPTO_THREADID *id)
        {
        ERR_STATE tmp;
        {
        ERR_STATE tmp;
-       void *pidptr;
 
 
-       err_fns_check();
-       if (pid != 0)
-               pidptr = &errno;
+       if (id)
+               CRYPTO_THREADID_cpy(&tmp.tid, id);
        else
        else
-               {
-               pid = CRYPTO_thread_id();
-               pidptr = CRYPTO_thread_idptr();
-               }
-       
-       tmp.pid=pid;
-       tmp.pidptr=pidptr;
+               CRYPTO_THREADID_current(&tmp.tid);
+       err_fns_check();
        /* thread_del_item automatically destroys the LHASH if the number of
         * items reaches zero. */
        ERRFN(thread_del_item)(&tmp);
        }
 
        /* thread_del_item automatically destroys the LHASH if the number of
         * items reaches zero. */
        ERRFN(thread_del_item)(&tmp);
        }
 
+#ifndef OPENSSL_NO_DEPRECATED
+void ERR_remove_state(unsigned long pid)
+       {
+       ERR_remove_thread_state(NULL);
+       }
+#endif
+
 ERR_STATE *ERR_get_state(void)
        {
        static ERR_STATE fallback;
        ERR_STATE *ret,tmp,*tmpp=NULL;
        int i;
 ERR_STATE *ERR_get_state(void)
        {
        static ERR_STATE fallback;
        ERR_STATE *ret,tmp,*tmpp=NULL;
        int i;
-       unsigned long pid;
-       void *pidptr;
+       CRYPTO_THREADID tid;
 
        err_fns_check();
 
        err_fns_check();
-       pid = CRYPTO_thread_id();
-       pidptr = CRYPTO_thread_idptr();
-       tmp.pid = pid;
-       tmp.pidptr = pidptr;
+       CRYPTO_THREADID_current(&tid);
+       CRYPTO_THREADID_cpy(&tmp.tid, &tid);
        ret=ERRFN(thread_get_item)(&tmp);
 
        /* ret == the error state, if NULL, make a new one */
        ret=ERRFN(thread_get_item)(&tmp);
 
        /* ret == the error state, if NULL, make a new one */
@@ -1021,8 +1018,7 @@ ERR_STATE *ERR_get_state(void)
                {
                ret=(ERR_STATE *)OPENSSL_malloc(sizeof(ERR_STATE));
                if (ret == NULL) return(&fallback);
                {
                ret=(ERR_STATE *)OPENSSL_malloc(sizeof(ERR_STATE));
                if (ret == NULL) return(&fallback);
-               ret->pid=pid;
-               ret->pidptr=pidptr;
+               CRYPTO_THREADID_cpy(&ret->tid, &tid);
                ret->top=0;
                ret->bottom=0;
                for (i=0; i<ERR_NUM_ERRORS; i++)
                ret->top=0;
                ret->bottom=0;
                for (i=0; i<ERR_NUM_ERRORS; i++)
index 942f820..006351d 100644 (file)
@@ -147,8 +147,7 @@ extern "C" {
 #define ERR_NUM_ERRORS 16
 typedef struct err_state_st
        {
 #define ERR_NUM_ERRORS 16
 typedef struct err_state_st
        {
-       unsigned long pid;
-       void *pidptr; /* new in OpenSSL 0.9.9 */
+       CRYPTO_THREADID tid;
        int err_flags[ERR_NUM_ERRORS];
        unsigned long err_buffer[ERR_NUM_ERRORS];
        char *err_data[ERR_NUM_ERRORS];
        int err_flags[ERR_NUM_ERRORS];
        unsigned long err_buffer[ERR_NUM_ERRORS];
        char *err_data[ERR_NUM_ERRORS];
@@ -351,7 +350,10 @@ void ERR_load_ERR_strings(void);
 void ERR_load_crypto_strings(void);
 void ERR_free_strings(void);
 
 void ERR_load_crypto_strings(void);
 void ERR_free_strings(void);
 
+void ERR_remove_thread_state(const CRYPTO_THREADID *tid);
+#ifndef OPENSSL_NO_DEPRECATED
 void ERR_remove_state(unsigned long pid); /* if zero we look it up */
 void ERR_remove_state(unsigned long pid); /* if zero we look it up */
+#endif
 ERR_STATE *ERR_get_state(void);
 
 #ifndef OPENSSL_NO_LHASH
 ERR_STATE *ERR_get_state(void);
 
 #ifndef OPENSSL_NO_LHASH
index 2224a90..de32f33 100644 (file)
@@ -72,8 +72,10 @@ void ERR_print_errors_cb(int (*cb)(const char *str, size_t len, void *u),
        const char *file,*data;
        int line,flags;
        unsigned long es;
        const char *file,*data;
        int line,flags;
        unsigned long es;
+       CRYPTO_THREADID cur;
 
 
-       es=CRYPTO_thread_id();
+       CRYPTO_THREADID_current(&cur);
+       es=CRYPTO_THREADID_hash(&cur);
        while ((l=ERR_get_error_line_data(&file,&line,&data,&flags)) != 0)
                {
                ERR_error_string_n(l, buf, sizeof buf);
        while ((l=ERR_get_error_line_data(&file,&line,&data,&flags)) != 0)
                {
                ERR_error_string_n(l, buf, sizeof buf);
index bb6f02c..b8c9235 100644 (file)
@@ -441,7 +441,7 @@ int main(int argc,char **argv)
 #endif
     EVP_cleanup();
     CRYPTO_cleanup_all_ex_data();
 #endif
     EVP_cleanup();
     CRYPTO_cleanup_all_ex_data();
-    ERR_remove_state(0);
+    ERR_remove_thread_state(NULL);
     ERR_free_strings();
     CRYPTO_mem_leaks_fp(stderr);
 
     ERR_free_strings();
     CRYPTO_mem_leaks_fp(stderr);
 
index ad5209b..131669a 100644 (file)
@@ -150,8 +150,7 @@ typedef struct app_mem_info_st
  *   CRYPTO_remove_all_info()    to pop all entries.
  */
        {
  *   CRYPTO_remove_all_info()    to pop all entries.
  */
        {
-       unsigned long thread_id;
-       void *thread_idptr;
+       CRYPTO_THREADID threadid;
        const char *file;
        int line;
        const char *info;
        const char *file;
        int line;
        const char *info;
@@ -176,8 +175,7 @@ typedef struct mem_st
        int num;
        const char *file;
        int line;
        int num;
        const char *file;
        int line;
-       unsigned long thread_id;
-       void *thread_idptr;
+       CRYPTO_THREADID threadid;
        unsigned long order;
        time_t time;
        APP_INFO *app_info;
        unsigned long order;
        time_t time;
        APP_INFO *app_info;
@@ -198,12 +196,10 @@ static unsigned int num_disable = 0; /* num_disable > 0
                                       * mh_mode == CRYPTO_MEM_CHECK_ON (w/o ..._ENABLE)
                                       */
 
                                       * mh_mode == CRYPTO_MEM_CHECK_ON (w/o ..._ENABLE)
                                       */
 
-/* The following two variables, disabling_thread_id and disabling_thread_idptr,
- * are valid iff num_disable > 0.  CRYPTO_LOCK_MALLOC2 is locked exactly in
- * this case (by the thread named in disabling_thread_id / disabling_thread_idptr).
+/* Valid iff num_disable > 0.  CRYPTO_LOCK_MALLOC2 is locked exactly in this
+ * case (by the thread named in disabling_thread).
  */
  */
-static unsigned long disabling_thread_id = 0;
-static void *disabling_thread_idptr = NULL;
+static CRYPTO_THREADID disabling_threadid;
 
 static void app_info_free(APP_INFO *inf)
        {
 
 static void app_info_free(APP_INFO *inf)
        {
@@ -240,9 +236,9 @@ int CRYPTO_mem_ctrl(int mode)
        case CRYPTO_MEM_CHECK_DISABLE: /* aka MemCheck_off() */
                if (mh_mode & CRYPTO_MEM_CHECK_ON)
                        {
        case CRYPTO_MEM_CHECK_DISABLE: /* aka MemCheck_off() */
                if (mh_mode & CRYPTO_MEM_CHECK_ON)
                        {
-                       if (!num_disable
-                           || (disabling_thread_id != CRYPTO_thread_id())
-                           || (disabling_thread_idptr != CRYPTO_thread_idptr())) /* otherwise we already have the MALLOC2 lock */
+                       CRYPTO_THREADID cur;
+                       CRYPTO_THREADID_current(&cur);
+                       if (!num_disable || CRYPTO_THREADID_cmp(&disabling_threadid, &cur)) /* otherwise we already have the MALLOC2 lock */
                                {
                                /* Long-time lock CRYPTO_LOCK_MALLOC2 must not be claimed while
                                 * we're holding CRYPTO_LOCK_MALLOC, or we'll deadlock if
                                {
                                /* Long-time lock CRYPTO_LOCK_MALLOC2 must not be claimed while
                                 * we're holding CRYPTO_LOCK_MALLOC, or we'll deadlock if
@@ -260,8 +256,7 @@ int CRYPTO_mem_ctrl(int mode)
                                CRYPTO_w_lock(CRYPTO_LOCK_MALLOC2);
                                CRYPTO_w_lock(CRYPTO_LOCK_MALLOC);
                                mh_mode &= ~CRYPTO_MEM_CHECK_ENABLE;
                                CRYPTO_w_lock(CRYPTO_LOCK_MALLOC2);
                                CRYPTO_w_lock(CRYPTO_LOCK_MALLOC);
                                mh_mode &= ~CRYPTO_MEM_CHECK_ENABLE;
-                               disabling_thread_id=CRYPTO_thread_id();
-                               disabling_thread_idptr=CRYPTO_thread_idptr();
+                               CRYPTO_THREADID_cpy(&disabling_threadid, &cur);
                                }
                        num_disable++;
                        }
                                }
                        num_disable++;
                        }
@@ -294,11 +289,12 @@ int CRYPTO_is_mem_check_on(void)
 
        if (mh_mode & CRYPTO_MEM_CHECK_ON)
                {
 
        if (mh_mode & CRYPTO_MEM_CHECK_ON)
                {
+               CRYPTO_THREADID cur;
+               CRYPTO_THREADID_current(&cur);
                CRYPTO_r_lock(CRYPTO_LOCK_MALLOC);
 
                ret = (mh_mode & CRYPTO_MEM_CHECK_ENABLE)
                CRYPTO_r_lock(CRYPTO_LOCK_MALLOC);
 
                ret = (mh_mode & CRYPTO_MEM_CHECK_ENABLE)
-                       || (disabling_thread_id != CRYPTO_thread_id())
-                       || (disabling_thread_idptr != CRYPTO_thread_idptr());
+                       || CRYPTO_THREADID_cmp(&disabling_threadid, &cur);
 
                CRYPTO_r_unlock(CRYPTO_LOCK_MALLOC);
                }
 
                CRYPTO_r_unlock(CRYPTO_LOCK_MALLOC);
                }
@@ -344,20 +340,17 @@ static IMPLEMENT_LHASH_HASH_FN(mem, MEM)
 /* static int app_info_cmp(APP_INFO *a, APP_INFO *b) */
 static int app_info_cmp(const void *a_void, const void *b_void)
        {
 /* static int app_info_cmp(APP_INFO *a, APP_INFO *b) */
 static int app_info_cmp(const void *a_void, const void *b_void)
        {
-       return (((const APP_INFO *)a_void)->thread_id != ((const APP_INFO *)b_void)->thread_id)
-              || (((const APP_INFO *)a_void)->thread_idptr != ((const APP_INFO *)b_void)->thread_idptr);
+       return CRYPTO_THREADID_cmp(&((const APP_INFO *)a_void)->threadid,
+                               &((const APP_INFO *)b_void)->threadid);
        }
 static IMPLEMENT_LHASH_COMP_FN(app_info, APP_INFO)
 
 static unsigned long app_info_hash(const APP_INFO *a)
        {
        }
 static IMPLEMENT_LHASH_COMP_FN(app_info, APP_INFO)
 
 static unsigned long app_info_hash(const APP_INFO *a)
        {
-       unsigned long id1, id2;
        unsigned long ret;
 
        unsigned long ret;
 
-       id1=(unsigned long)a->thread_id;
-       id2=(unsigned long)a->thread_idptr;
-       ret = id1 + id2;
-
+       ret = CRYPTO_THREADID_hash(&a->threadid);
+       /* This is left in as a "who am I to question legacy?" measure */
        ret=ret*17851+(ret>>14)*7+(ret>>4)*251;
        return(ret);
        }
        ret=ret*17851+(ret>>14)*7+(ret>>4)*251;
        return(ret);
        }
@@ -370,8 +363,7 @@ static APP_INFO *pop_info(void)
 
        if (amih != NULL)
                {
 
        if (amih != NULL)
                {
-               tmp.thread_id=CRYPTO_thread_id();
-               tmp.thread_idptr=CRYPTO_thread_idptr();
+               CRYPTO_THREADID_current(&tmp.threadid);
                if ((ret=lh_APP_INFO_delete(amih,&tmp)) != NULL)
                        {
                        APP_INFO *next=ret->next;
                if ((ret=lh_APP_INFO_delete(amih,&tmp)) != NULL)
                        {
                        APP_INFO *next=ret->next;
@@ -382,10 +374,11 @@ static APP_INFO *pop_info(void)
                                (void)lh_APP_INFO_insert(amih,next);
                                }
 #ifdef LEVITTE_DEBUG_MEM
                                (void)lh_APP_INFO_insert(amih,next);
                                }
 #ifdef LEVITTE_DEBUG_MEM
-                       if (ret->thread_id != tmp.thread_id || ret->thread_idptr != tmp.thread_idptr)
+                       if (CRYPTO_THREADID_cmp(&ret->threadid, &tmp.threadid))
                                {
                                {
-                               fprintf(stderr, "pop_info(): deleted info has other thread ID (%lu/%p) than the current thread (%lu/%p)!!!!\n",
-                                       ret->thread_id, ret->thread_idptr, tmp.thread_id, tmp.thread_idptr);
+                               fprintf(stderr, "pop_info(): deleted info has other thread ID (%lu) than the current thread (%lu)!!!!\n",
+                                       CRYPTO_THREADID_hash(&ret->threadid),
+                                       CRYPTO_THREADID_hash(&tmp.threadid));
                                abort();
                                }
 #endif
                                abort();
                                }
 #endif
@@ -425,8 +418,7 @@ int CRYPTO_push_info_(const char *info, const char *file, int line)
                                }
                        }
 
                                }
                        }
 
-               ami->thread_id=CRYPTO_thread_id();
-               ami->thread_idptr=CRYPTO_thread_idptr();
+               CRYPTO_THREADID_current(&ami->threadid);
                ami->file=file;
                ami->line=line;
                ami->info=info;
                ami->file=file;
                ami->line=line;
                ami->info=info;
@@ -436,10 +428,11 @@ int CRYPTO_push_info_(const char *info, const char *file, int line)
                if ((amim=lh_APP_INFO_insert(amih,ami)) != NULL)
                        {
 #ifdef LEVITTE_DEBUG_MEM
                if ((amim=lh_APP_INFO_insert(amih,ami)) != NULL)
                        {
 #ifdef LEVITTE_DEBUG_MEM
-                       if (ami->thread_id != amim->thread_id || ami->thread_idptr != amim->thread_idptr)
+                       if (CRYPTO_THREADID_cmp(&ami->threadid, &amim->threadid))
                                {
                                {
-                               fprintf(stderr, "CRYPTO_push_info(): previous info has other thread ID (%lu/%p) than the current thread (%lu/%p)!!!!\n",
-                                       amim->thread_id, amim->thread_idptr, ami->thread_id, ami->thread_idptr);
+                               fprintf(stderr, "CRYPTO_push_info(): previous info has other thread ID (%lu) than the current thread (%lu)!!!!\n",
+                                       CRYPTO_THREADID_hash(&amim->threadid),
+                                       CRYPTO_THREADID_hash(&ami->threadid));
                                abort();
                                }
 #endif
                                abort();
                                }
 #endif
@@ -525,15 +518,9 @@ void CRYPTO_dbg_malloc(void *addr, int num, const char *file, int line,
                        m->line=line;
                        m->num=num;
                        if (options & V_CRYPTO_MDEBUG_THREAD)
                        m->line=line;
                        m->num=num;
                        if (options & V_CRYPTO_MDEBUG_THREAD)
-                               {
-                               m->thread_id=CRYPTO_thread_id();
-                               m->thread_idptr=CRYPTO_thread_idptr();
-                               }
+                               CRYPTO_THREADID_current(&m->threadid);
                        else
                        else
-                               {
-                               m->thread_id=0;
-                               m->thread_idptr=NULL;
-                               }
+                               memset(&m->threadid, 0, sizeof(m->threadid));
 
                        if (order == break_order_num)
                                {
 
                        if (order == break_order_num)
                                {
@@ -552,8 +539,7 @@ void CRYPTO_dbg_malloc(void *addr, int num, const char *file, int line,
                        else
                                m->time=0;
 
                        else
                                m->time=0;
 
-                       tmp.thread_id=CRYPTO_thread_id();
-                       tmp.thread_idptr=CRYPTO_thread_idptr();
+                       CRYPTO_THREADID_current(&tmp.threadid);
                        m->app_info=NULL;
                        if (amih != NULL
                            && (amim=lh_APP_INFO_retrieve(amih,&tmp)) != NULL)
                        m->app_info=NULL;
                        if (amih != NULL
                            && (amim=lh_APP_INFO_retrieve(amih,&tmp)) != NULL)
@@ -682,8 +668,7 @@ static void print_leak_doall_arg(const MEM *m, MEM_LEAK *l)
        APP_INFO *amip;
        int ami_cnt;
        struct tm *lcl = NULL;
        APP_INFO *amip;
        int ami_cnt;
        struct tm *lcl = NULL;
-       unsigned long ti;
-       void *tip;
+       CRYPTO_THREADID ti;
 
 #define BUF_REMAIN (sizeof buf - (size_t)(bufp - buf))
 
 
 #define BUF_REMAIN (sizeof buf - (size_t)(bufp - buf))
 
@@ -705,7 +690,8 @@ static void print_leak_doall_arg(const MEM *m, MEM_LEAK *l)
 
        if (options & V_CRYPTO_MDEBUG_THREAD)
                {
 
        if (options & V_CRYPTO_MDEBUG_THREAD)
                {
-               BIO_snprintf(bufp, BUF_REMAIN, "thread=%lu/%p, ", m->thread_id, m->thread_idptr);
+               BIO_snprintf(bufp, BUF_REMAIN, "thread=%lu, ",
+                       CRYPTO_THREADID_hash(&m->threadid));
                bufp += strlen(bufp);
                }
 
                bufp += strlen(bufp);
                }
 
@@ -722,9 +708,8 @@ static void print_leak_doall_arg(const MEM *m, MEM_LEAK *l)
        ami_cnt=0;
        if (!amip)
                return;
        ami_cnt=0;
        if (!amip)
                return;
-       ti=amip->thread_id;
-       tip=amip->thread_idptr;
-       
+       CRYPTO_THREADID_cpy(&ti, &amip->threadid);
+
        do
                {
                int buf_len;
        do
                {
                int buf_len;
@@ -733,8 +718,9 @@ static void print_leak_doall_arg(const MEM *m, MEM_LEAK *l)
                ami_cnt++;
                memset(buf,'>',ami_cnt);
                BIO_snprintf(buf + ami_cnt, sizeof buf - ami_cnt,
                ami_cnt++;
                memset(buf,'>',ami_cnt);
                BIO_snprintf(buf + ami_cnt, sizeof buf - ami_cnt,
-                       " thread=%lu/%p, file=%s, line=%d, info=\"",
-                       amip->thread_id, amip->thread_idptr, amip->file, amip->line);
+                       " thread=%lu, file=%s, line=%d, info=\"",
+                       CRYPTO_THREADID_hash(&amip->threadid), amip->file,
+                       amip->line);
                buf_len=strlen(buf);
                info_len=strlen(amip->info);
                if (128 - buf_len - 3 < info_len)
                buf_len=strlen(buf);
                info_len=strlen(amip->info);
                if (128 - buf_len - 3 < info_len)
@@ -754,7 +740,7 @@ static void print_leak_doall_arg(const MEM *m, MEM_LEAK *l)
 
                amip = amip->next;
                }
 
                amip = amip->next;
                }
-       while(amip && amip->thread_id == ti && amip->thread_idptr == tip);
+       while(amip && !CRYPTO_THREADID_cmp(&amip->threadid, &ti));
 
 #ifdef LEVITTE_DEBUG_MEM
        if (amip)
 
 #ifdef LEVITTE_DEBUG_MEM
        if (amip)
index cfc7877..810b4c2 100644 (file)
@@ -145,8 +145,7 @@ static unsigned int crypto_lock_rand = 0; /* may be set only when a thread
                                            * holds CRYPTO_LOCK_RAND
                                            * (to prevent double locking) */
 /* access to lockin_thread is synchronized by CRYPTO_LOCK_RAND2 */
                                            * holds CRYPTO_LOCK_RAND
                                            * (to prevent double locking) */
 /* access to lockin_thread is synchronized by CRYPTO_LOCK_RAND2 */
-static unsigned long locking_thread_id = 0; /* valid iff crypto_lock_rand is set */
-static void *locking_thread_idptr = NULL; /* valid iff crypto_lock_rand is set */
+static CRYPTO_THREADID locking_threadid; /* valid iff crypto_lock_rand is set */
 
 
 #ifdef PREDICT
 
 
 #ifdef PREDICT
@@ -214,8 +213,10 @@ static void ssleay_rand_add(const void *buf, int num, double add)
        /* check if we already have the lock */
        if (crypto_lock_rand)
                {
        /* check if we already have the lock */
        if (crypto_lock_rand)
                {
+               CRYPTO_THREADID cur;
+               CRYPTO_THREADID_current(&cur);
                CRYPTO_r_lock(CRYPTO_LOCK_RAND2);
                CRYPTO_r_lock(CRYPTO_LOCK_RAND2);
-               do_not_lock = (locking_thread_id == CRYPTO_thread_id()) && (locking_thread_idptr == CRYPTO_thread_idptr());
+               do_not_lock = !CRYPTO_THREADID_cmp(&locking_threadid, &cur);
                CRYPTO_r_unlock(CRYPTO_LOCK_RAND2);
                }
        else
                CRYPTO_r_unlock(CRYPTO_LOCK_RAND2);
                }
        else
@@ -373,8 +374,7 @@ static int ssleay_rand_bytes(unsigned char *buf, int num)
 
        /* prevent ssleay_rand_bytes() from trying to obtain the lock again */
        CRYPTO_w_lock(CRYPTO_LOCK_RAND2);
 
        /* prevent ssleay_rand_bytes() from trying to obtain the lock again */
        CRYPTO_w_lock(CRYPTO_LOCK_RAND2);
-       locking_thread_id = CRYPTO_thread_id();
-       locking_thread_idptr = CRYPTO_thread_idptr();
+       CRYPTO_THREADID_current(&locking_threadid);
        CRYPTO_w_unlock(CRYPTO_LOCK_RAND2);
        crypto_lock_rand = 1;
 
        CRYPTO_w_unlock(CRYPTO_LOCK_RAND2);
        crypto_lock_rand = 1;
 
@@ -529,15 +529,17 @@ static int ssleay_rand_pseudo_bytes(unsigned char *buf, int num)
 
 static int ssleay_rand_status(void)
        {
 
 static int ssleay_rand_status(void)
        {
+       CRYPTO_THREADID cur;
        int ret;
        int do_not_lock;
 
        int ret;
        int do_not_lock;
 
+       CRYPTO_THREADID_current(&cur);
        /* check if we already have the lock
         * (could happen if a RAND_poll() implementation calls RAND_status()) */
        if (crypto_lock_rand)
                {
                CRYPTO_r_lock(CRYPTO_LOCK_RAND2);
        /* check if we already have the lock
         * (could happen if a RAND_poll() implementation calls RAND_status()) */
        if (crypto_lock_rand)
                {
                CRYPTO_r_lock(CRYPTO_LOCK_RAND2);
-               do_not_lock = (locking_thread_id == CRYPTO_thread_id()) && (locking_thread_idptr == CRYPTO_thread_idptr());
+               do_not_lock = !CRYPTO_THREADID_cmp(&locking_threadid, &cur);
                CRYPTO_r_unlock(CRYPTO_LOCK_RAND2);
                }
        else
                CRYPTO_r_unlock(CRYPTO_LOCK_RAND2);
                }
        else
@@ -549,8 +551,7 @@ static int ssleay_rand_status(void)
                
                /* prevent ssleay_rand_bytes() from trying to obtain the lock again */
                CRYPTO_w_lock(CRYPTO_LOCK_RAND2);
                
                /* prevent ssleay_rand_bytes() from trying to obtain the lock again */
                CRYPTO_w_lock(CRYPTO_LOCK_RAND2);
-               locking_thread_id = CRYPTO_thread_id();
-               locking_thread_idptr = CRYPTO_thread_idptr();
+               CRYPTO_THREADID_cpy(&locking_threadid, &cur);
                CRYPTO_w_unlock(CRYPTO_LOCK_RAND2);
                crypto_lock_rand = 1;
                }
                CRYPTO_w_unlock(CRYPTO_LOCK_RAND2);
                crypto_lock_rand = 1;
                }
index a1ecd6d..7321349 100644 (file)
@@ -264,6 +264,7 @@ static BN_BLINDING *rsa_get_blinding(RSA *rsa, int *local, BN_CTX *ctx)
 {
        BN_BLINDING *ret;
        int got_write_lock = 0;
 {
        BN_BLINDING *ret;
        int got_write_lock = 0;
+       CRYPTO_THREADID cur;
 
        CRYPTO_r_lock(CRYPTO_LOCK_RSA);
 
 
        CRYPTO_r_lock(CRYPTO_LOCK_RSA);
 
@@ -281,7 +282,8 @@ static BN_BLINDING *rsa_get_blinding(RSA *rsa, int *local, BN_CTX *ctx)
        if (ret == NULL)
                goto err;
 
        if (ret == NULL)
                goto err;
 
-       if ((BN_BLINDING_get_thread_id(ret) == CRYPTO_thread_id()) && (BN_BLINDING_get_thread_idptr(ret) == CRYPTO_thread_idptr()))
+       CRYPTO_THREADID_current(&cur);
+       if (!CRYPTO_THREADID_cmp(&cur, BN_BLINDING_thread_id(ret)))
                {
                /* rsa->blinding is ours! */
 
                {
                /* rsa->blinding is ours! */
 
index dd09609..6b1b029 100644 (file)
@@ -417,8 +417,7 @@ BN_BLINDING *RSA_setup_blinding(RSA *rsa, BN_CTX *in_ctx)
                RSAerr(RSA_F_RSA_SETUP_BLINDING, ERR_R_BN_LIB);
                goto err;
                }
                RSAerr(RSA_F_RSA_SETUP_BLINDING, ERR_R_BN_LIB);
                goto err;
                }
-       BN_BLINDING_set_thread_id(ret, CRYPTO_thread_id());
-       BN_BLINDING_set_thread_idptr(ret, CRYPTO_thread_idptr());
+       CRYPTO_THREADID_current(BN_BLINDING_thread_id(ret));
 err:
        BN_CTX_end(ctx);
        if (in_ctx == NULL)
 err:
        BN_CTX_end(ctx);
        if (in_ctx == NULL)
index 4080de8..c8705a0 100644 (file)
@@ -328,7 +328,7 @@ int main(int argc, char *argv[])
        }
 
     CRYPTO_cleanup_all_ex_data();
        }
 
     CRYPTO_cleanup_all_ex_data();
-    ERR_remove_state(0);
+    ERR_remove_thread_state(NULL);
 
     CRYPTO_mem_leaks_fp(stderr);
 
 
     CRYPTO_mem_leaks_fp(stderr);
 
index 7b087f7..5e3fe1d 100644 (file)
@@ -22,8 +22,11 @@ functions.
        BN_CTX *ctx);
  int BN_BLINDING_invert_ex(BIGNUM *n, const BIGNUM *r, BN_BLINDING *b,
        BN_CTX *ctx);
        BN_CTX *ctx);
  int BN_BLINDING_invert_ex(BIGNUM *n, const BIGNUM *r, BN_BLINDING *b,
        BN_CTX *ctx);
+ #ifndef OPENSSL_NO_DEPRECATED
  unsigned long BN_BLINDING_get_thread_id(const BN_BLINDING *);
  void BN_BLINDING_set_thread_id(BN_BLINDING *, unsigned long);
  unsigned long BN_BLINDING_get_thread_id(const BN_BLINDING *);
  void BN_BLINDING_set_thread_id(BN_BLINDING *, unsigned long);
+ #endif
+ CRYPTO_THREADID *BN_BLINDING_thread_id(BN_BLINDING *);
  unsigned long BN_BLINDING_get_flags(const BN_BLINDING *);
  void BN_BLINDING_set_flags(BN_BLINDING *, unsigned long);
  BN_BLINDING *BN_BLINDING_create_param(BN_BLINDING *b,
  unsigned long BN_BLINDING_get_flags(const BN_BLINDING *);
  void BN_BLINDING_set_flags(BN_BLINDING *, unsigned long);
  BN_BLINDING *BN_BLINDING_create_param(BN_BLINDING *b,
@@ -54,11 +57,11 @@ BN_BLINDING_convert() and BN_BLINDING_invert() are wrapper
 functions for BN_BLINDING_convert_ex() and BN_BLINDING_invert_ex()
 with B<r> set to NULL.
 
 functions for BN_BLINDING_convert_ex() and BN_BLINDING_invert_ex()
 with B<r> set to NULL.
 
-BN_BLINDING_set_thread_id() and BN_BLINDING_get_thread_id()
-set and get the "thread id" value of the B<BN_BLINDING> structure,
-a field provided to users of B<BN_BLINDING> structure to help them
-provide proper locking if needed for multi-threaded use. The 
-"thread id" of a newly allocated B<BN_BLINDING> structure is zero.
+BN_BLINDING_thread_id() provides access to the B<CRYPTO_THREADID>
+object within the B<BN_BLINDING> structure. This is to help users
+provide proper locking if needed for multi-threaded use. The "thread
+id" object of a newly allocated B<BN_BLINDING> structure is
+initialised to the thread id in which BN_BLINDING_new() was called.
 
 BN_BLINDING_get_flags() returns the BN_BLINDING flags. Currently
 there are two supported flags: B<BN_BLINDING_NO_UPDATE> and
 
 BN_BLINDING_get_flags() returns the BN_BLINDING flags. Currently
 there are two supported flags: B<BN_BLINDING_NO_UPDATE> and
@@ -83,8 +86,8 @@ BN_BLINDING_update(), BN_BLINDING_convert(), BN_BLINDING_invert(),
 BN_BLINDING_convert_ex() and BN_BLINDING_invert_ex() return 1 on
 success and 0 if an error occured.
 
 BN_BLINDING_convert_ex() and BN_BLINDING_invert_ex() return 1 on
 success and 0 if an error occured.
 
-BN_BLINDING_get_thread_id() returns the thread id (a B<unsigned long>
-value) or 0 if not set.
+BN_BLINDING_thread_id() returns a pointer to the thread id object
+within a B<BN_BLINDING> object.
 
 BN_BLINDING_get_flags() returns the currently set B<BN_BLINDING> flags
 (a B<unsigned long> value).
 
 BN_BLINDING_get_flags() returns the currently set B<BN_BLINDING> flags
 (a B<unsigned long> value).
@@ -98,6 +101,9 @@ L<bn(3)|bn(3)>
 
 =head1 HISTORY
 
 
 =head1 HISTORY
 
+BN_BLINDING_thread_id was first introduced in OpenSSL 0.9.9, and it
+deprecates BN_BLINDING_set_thread_id and BN_BLINDING_get_thread_id.
+
 BN_BLINDING_convert_ex, BN_BLINDIND_invert_ex, BN_BLINDING_get_thread_id,
 BN_BLINDING_set_thread_id, BN_BLINDING_set_flags, BN_BLINDING_get_flags
 and BN_BLINDING_create_param were first introduced in OpenSSL 0.9.8
 BN_BLINDING_convert_ex, BN_BLINDIND_invert_ex, BN_BLINDING_get_thread_id,
 BN_BLINDING_set_thread_id, BN_BLINDING_set_flags, BN_BLINDING_get_flags
 and BN_BLINDING_create_param were first introduced in OpenSSL 0.9.8
index 230cbe8..e6266a1 100644 (file)
@@ -2,8 +2,9 @@
 
 =head1 NAME
 
 
 =head1 NAME
 
-CRYPTO_set_locking_callback, CRYPTO_set_id_callback,
-CRYPTO_set_idptr_callback, CRYPTO_num_locks,
+CRYPTO_THREADID_set_callback, CRYPTO_THREADID_get_callback,
+CRYPTO_THREADID_current, CRYPTO_THREADID_cmp, CRYPTO_THREADID_cpy,
+CRYPTO_THREADID_hash, CRYPTO_set_locking_callback, CRYPTO_num_locks,
 CRYPTO_set_dynlock_create_callback, CRYPTO_set_dynlock_lock_callback,
 CRYPTO_set_dynlock_destroy_callback, CRYPTO_get_new_dynlockid,
 CRYPTO_destroy_dynlockid, CRYPTO_lock - OpenSSL thread support
 CRYPTO_set_dynlock_create_callback, CRYPTO_set_dynlock_lock_callback,
 CRYPTO_set_dynlock_destroy_callback, CRYPTO_get_new_dynlockid,
 CRYPTO_destroy_dynlockid, CRYPTO_lock - OpenSSL thread support
@@ -12,16 +13,26 @@ CRYPTO_destroy_dynlockid, CRYPTO_lock - OpenSSL thread support
 
  #include <openssl/crypto.h>
 
 
  #include <openssl/crypto.h>
 
- void CRYPTO_set_locking_callback(void (*locking_function)(int mode,
-        int n, const char *file, int line));
-
- void CRYPTO_set_id_callback(unsigned long (*id_function)(void));
-
- void CRYPTO_set_idptr_callback(void *(*idptr_function)(void));
+ /* Don't use this structure directly. */
+ typedef struct crypto_threadid_st
+         {
+         void *ptr;
+         unsigned long val;
+         } CRYPTO_THREADID;
+ /* Only use CRYPTO_THREADID_set_[numeric|pointer]() within callbacks */
+ void CRYPTO_THREADID_set_numeric(CRYPTO_THREADID *id, unsigned long val);
+ void CRYPTO_THREADID_set_pointer(CRYPTO_THREADID *id, void *ptr);
+ int CRYPTO_THREADID_set_callback(void (*threadid_func)(CRYPTO_THREADID *));
+ void (*CRYPTO_THREADID_get_callback(void))(CRYPTO_THREADID *);
+ void CRYPTO_THREADID_current(CRYPTO_THREADID *id);
+ int CRYPTO_THREADID_cmp(const CRYPTO_THREADID *a,
+                         const CRYPTO_THREADID *b);
+ void CRYPTO_THREADID_cpy(CRYPTO_THREADID *dest,
+                          const CRYPTO_THREADID *src);
+ unsigned long CRYPTO_THREADID_hash(const CRYPTO_THREADID *id);
 
  int CRYPTO_num_locks(void);
 
 
  int CRYPTO_num_locks(void);
 
-
  /* struct CRYPTO_dynlock_value needs to be defined by the user */
  struct CRYPTO_dynlock_value;
 
  /* struct CRYPTO_dynlock_value needs to be defined by the user */
  struct CRYPTO_dynlock_value;
 
@@ -53,7 +64,8 @@ CRYPTO_destroy_dynlockid, CRYPTO_lock - OpenSSL thread support
 =head1 DESCRIPTION
 
 OpenSSL can safely be used in multi-threaded applications provided
 =head1 DESCRIPTION
 
 OpenSSL can safely be used in multi-threaded applications provided
-that at least two callback functions are set.
+that at least two callback functions are set, locking_function and
+threadid_func.
 
 locking_function(int mode, int n, const char *file, int line) is
 needed to perform locking on shared data structures. 
 
 locking_function(int mode, int n, const char *file, int line) is
 needed to perform locking on shared data structures. 
@@ -68,17 +80,42 @@ B<CRYPTO_LOCK>, and releases it otherwise.
 B<file> and B<line> are the file number of the function setting the
 lock. They can be useful for debugging.
 
 B<file> and B<line> are the file number of the function setting the
 lock. They can be useful for debugging.
 
-id_function(void) is a function that returns a numerical thread ID,
-for example pthread_self() if it returns an integer (see NOTES below).
-By OpenSSL's defaults, this is not needed on Windows nor on platforms
-where getpid() returns a different ID for each thread (see NOTES
-below).
+threadid_func(CRYPTO_THREADID *id) is needed to record the currently-executing
+thread's identifier into B<id>. The implementation of this callback should not
+fill in B<id> directly, but should use CRYPTO_THREADID_set_numeric() if thread
+IDs are numeric, or CRYPTO_THREADID_set_pointer() if they are pointer-based.
+If the application does not register such a callback using
+CRYPTO_THREADID_set_callback(), then a default implementation is used - on
+Windows and BeOS this uses the system's default thread identifying APIs, and on
+all other platforms it uses the address of B<errno>. The latter is satisfactory
+for thread-safety if and only if the platform has a thread-local error number
+facility.
 
 
-idptr_function(void) is a function that similarly returns a thread ID,
-but of type void *.  This is not needed on platforms where &errno is
-different for each thread.  OpenSSL assumes that it is in the same
-thread iff both the numerical and the pointer thread ID agree, so it
-suffices to define one of these two callback functions appropriately.
+Once threadid_func() is registered, or if the built-in default implementation is
+to be used;
+
+=over 4
+
+=item *
+CRYPTO_THREADID_current() records the currently-executing thread ID into the
+given B<id> object.
+
+=item *
+CRYPTO_THREADID_cmp() compares two thread IDs (returning zero for equality, ie.
+the same semantics as memcmp()).
+
+=item *
+CRYPTO_THREADID_cpy() duplicates a thread ID value,
+
+=item *
+CRYPTO_THREADID_hash() returns a numeric value usable as a hash-table key. This
+is usually the exact numeric or pointer-based thread ID used internally, however
+this also handles the unusual case where pointers are larger than 'long'
+variables and the platform's thread IDs are pointer-based - in this case, mixing
+is done to attempt to produce a unique numeric value even though it is not as
+wide as the platform's true thread IDs.
+
+=back
 
 Additionally, OpenSSL supports dynamic locks, and sometimes, some parts
 of OpenSSL need it for better performance.  To enable this, the following
 
 Additionally, OpenSSL supports dynamic locks, and sometimes, some parts
 of OpenSSL need it for better performance.  To enable this, the following
@@ -150,24 +187,6 @@ You can find out if OpenSSL was configured with thread support:
 Also, dynamic locks are currently not used internally by OpenSSL, but
 may do so in the future.
 
 Also, dynamic locks are currently not used internally by OpenSSL, but
 may do so in the future.
 
-Defining id_function(void) has it's own issues.  Generally speaking,
-pthread_self() should be used, even on platforms where getpid() gives
-different answers in each thread, since that may depend on the machine
-the program is run on, not the machine where the program is being
-compiled.  For instance, Red Hat 8 Linux and earlier used
-LinuxThreads, whose getpid() returns a different value for each
-thread.  Red Hat 9 Linux and later use NPTL, which is
-Posix-conformant, and has a getpid() that returns the same value for
-all threads in a process.  A program compiled on Red Hat 8 and run on
-Red Hat 9 will therefore see getpid() returning the same value for
-all threads.
-
-There is still the issue of platforms where pthread_self() returns
-something other than an integer.  It is for cases like this that
-CRYPTO_set_idptr_callback() comes in handy.  (E.g., call malloc(1)
-once in each thread, and have idptr_function() return a pointer to
-this object.)
-
 =head1 EXAMPLES
 
 B<crypto/threads/mttest.c> shows examples of the callback functions on
 =head1 EXAMPLES
 
 B<crypto/threads/mttest.c> shows examples of the callback functions on
@@ -179,8 +198,10 @@ CRYPTO_set_locking_callback() and CRYPTO_set_id_callback() are
 available in all versions of SSLeay and OpenSSL.
 CRYPTO_num_locks() was added in OpenSSL 0.9.4.
 All functions dealing with dynamic locks were added in OpenSSL 0.9.5b-dev.
 available in all versions of SSLeay and OpenSSL.
 CRYPTO_num_locks() was added in OpenSSL 0.9.4.
 All functions dealing with dynamic locks were added in OpenSSL 0.9.5b-dev.
-
-CRYPTO_set_idptr_callback() was added in OpenSSL 0.9.9.
+B<CRYPTO_THREADID> and associated functions were introduced in OpenSSL 0.9.9
+to replace (actually, deprecate) the previous CRYPTO_set_id_callback(),
+CRYPTO_get_id_callback(), and CRYPTO_thread_id() functions which assumed
+thread IDs to always be represented by 'unsigned long'.
 
 =head1 SEE ALSO
 
 
 =head1 SEE ALSO
 
index 83a571d..b20ab0f 100644 (file)
@@ -1014,7 +1014,7 @@ end:
 #endif
        CRYPTO_cleanup_all_ex_data();
        ERR_free_strings();
 #endif
        CRYPTO_cleanup_all_ex_data();
        ERR_free_strings();
-       ERR_remove_state(0);
+       ERR_remove_thread_state(NULL);
        EVP_cleanup();
        CRYPTO_mem_leaks(bio_err);
        if (bio_err != NULL) BIO_free(bio_err);
        EVP_cleanup();
        CRYPTO_mem_leaks(bio_err);
        if (bio_err != NULL) BIO_free(bio_err);