diff options
author | Geoff Thorpe <geoff@openssl.org> | 2008-08-06 15:54:15 +0000 |
---|---|---|
committer | Geoff Thorpe <geoff@openssl.org> | 2008-08-06 15:54:15 +0000 |
commit | 4c3296960de32e5abfbb8f4703a2ce624d82669f (patch) | |
tree | f603740bcbf0e3cde6008cead9586e5b4edbdc5b | |
parent | 96826bfc84c63207b720543443626029946a0fc7 (diff) |
Remove the dual-callback scheme for numeric and pointer thread IDs,
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.
-rw-r--r-- | CHANGES | 48 | ||||
-rw-r--r-- | FAQ | 4 | ||||
-rw-r--r-- | apps/apps.h | 4 | ||||
-rw-r--r-- | crypto/bn/bn.h | 6 | ||||
-rw-r--r-- | crypto/bn/bn_blind.c | 17 | ||||
-rw-r--r-- | crypto/bn/exptest.c | 2 | ||||
-rw-r--r-- | crypto/cryptlib.c | 152 | ||||
-rw-r--r-- | crypto/crypto.h | 21 | ||||
-rw-r--r-- | crypto/dsa/dsatest.c | 2 | ||||
-rw-r--r-- | crypto/ec/ectest.c | 2 | ||||
-rw-r--r-- | crypto/ecdh/ecdhtest.c | 2 | ||||
-rw-r--r-- | crypto/ecdsa/ecdsatest.c | 2 | ||||
-rw-r--r-- | crypto/engine/enginetest.c | 2 | ||||
-rw-r--r-- | crypto/err/err.c | 40 | ||||
-rw-r--r-- | crypto/err/err.h | 6 | ||||
-rw-r--r-- | crypto/err/err_prn.c | 4 | ||||
-rw-r--r-- | crypto/evp/evp_test.c | 2 | ||||
-rw-r--r-- | crypto/mem_dbg.c | 90 | ||||
-rw-r--r-- | crypto/rand/md_rand.c | 17 | ||||
-rw-r--r-- | crypto/rsa/rsa_eay.c | 4 | ||||
-rw-r--r-- | crypto/rsa/rsa_lib.c | 3 | ||||
-rw-r--r-- | crypto/rsa/rsa_test.c | 2 | ||||
-rw-r--r-- | doc/crypto/BN_BLINDING_new.pod | 20 | ||||
-rw-r--r-- | doc/crypto/threads.pod | 101 | ||||
-rw-r--r-- | ssl/ssltest.c | 2 |
25 files changed, 338 insertions, 217 deletions
@@ -4,6 +4,30 @@ 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. @@ -307,30 +331,6 @@ 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 @@ -717,9 +717,7 @@ file. 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? diff --git a/apps/apps.h b/apps/apps.h index 93d874976b..bcf597f3ef 100644 --- a/apps/apps.h +++ b/apps/apps.h @@ -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(); \ - 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() \ @@ -191,7 +191,7 @@ extern BIO *bio_err; # 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 diff --git a/crypto/bn/bn.h b/crypto/bn/bn.h index de2cfcf93c..4749c52341 100644 --- a/crypto/bn/bn.h +++ b/crypto/bn/bn.h @@ -130,6 +130,7 @@ #include <stdio.h> /* FILE */ #endif #include <openssl/ossl_typ.h> +#include <openssl/crypto.h> #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 *); +#ifndef OPENSSL_NO_DEPRECATED 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, diff --git a/crypto/bn/bn_blind.c b/crypto/bn/bn_blind.c index e9b6173e24..e060592fdc 100644 --- a/crypto/bn/bn_blind.c +++ b/crypto/bn/bn_blind.c @@ -121,10 +121,11 @@ struct bn_blinding_st 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 */ - 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; @@ -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; + CRYPTO_THREADID_current(&ret->tid); 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); } +#ifndef OPENSSL_NO_DEPRECATED 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; } +#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) diff --git a/crypto/bn/exptest.c b/crypto/bn/exptest.c index 89ebcc8711..074a8e882a 100644 --- a/crypto/bn/exptest.c +++ b/crypto/bn/exptest.c @@ -187,7 +187,7 @@ int main(int argc, char *argv[]) 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"); diff --git a/crypto/cryptlib.c b/crypto/cryptlib.c index b89bd7a6fa..fe5d3066d7 100644 --- a/crypto/cryptlib.c +++ b/crypto/cryptlib.c @@ -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; +#ifndef OPENSSL_NO_DEPRECATED 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, @@ -414,6 +416,108 @@ void CRYPTO_set_add_lock_callback(int (*func)(int *num,int mount,int type, 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); @@ -446,33 +550,13 @@ unsigned long CRYPTO_thread_id(void) 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 { + CRYPTO_THREADID id; 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"; - 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 @@ -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 - 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); + } #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 - 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); + } #endif *pointer=ret; CRYPTO_lock(CRYPTO_UNLOCK|CRYPTO_WRITE,type,file,line); diff --git a/crypto/crypto.h b/crypto/crypto.h index 8bc927b429..bcc8ca4ad3 100644 --- a/crypto/crypto.h +++ b/crypto/crypto.h @@ -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); + +/* 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_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, diff --git a/crypto/dsa/dsatest.c b/crypto/dsa/dsatest.c index 5a699ca5d3..edffd24e6b 100644 --- a/crypto/dsa/dsatest.c +++ b/crypto/dsa/dsatest.c @@ -222,7 +222,7 @@ end: 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) diff --git a/crypto/ec/ectest.c b/crypto/ec/ectest.c index b74d6435be..7509cb9c7c 100644 --- a/crypto/ec/ectest.c +++ b/crypto/ec/ectest.c @@ -1326,7 +1326,7 @@ int main(int argc, char *argv[]) #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; diff --git a/crypto/ecdh/ecdhtest.c b/crypto/ecdh/ecdhtest.c index 1575006b51..212a87efa4 100644 --- a/crypto/ecdh/ecdhtest.c +++ b/crypto/ecdh/ecdhtest.c @@ -343,7 +343,7 @@ err: 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); diff --git a/crypto/ecdsa/ecdsatest.c b/crypto/ecdsa/ecdsatest.c index b07e31252b..aa4e1481a8 100644 --- a/crypto/ecdsa/ecdsatest.c +++ b/crypto/ecdsa/ecdsatest.c @@ -490,7 +490,7 @@ err: 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) diff --git a/crypto/engine/enginetest.c b/crypto/engine/enginetest.c index cf82f490db..3c1d2b4fbe 100644 --- a/crypto/engine/enginetest.c +++ b/crypto/engine/enginetest.c @@ -276,7 +276,7 @@ end: 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; } diff --git a/crypto/err/err.c b/crypto/err/err.c index f615cb4766..69713a6e2f 100644 --- a/crypto/err/err.c +++ b/crypto/err/err.c @@ -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) { - 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) { - 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) @@ -980,40 +980,37 @@ const char *ERR_reason_error_string(unsigned long e) 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; - void *pidptr; - err_fns_check(); - if (pid != 0) - pidptr = &errno; + if (id) + CRYPTO_THREADID_cpy(&tmp.tid, id); 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); } +#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; - unsigned long pid; - void *pidptr; + CRYPTO_THREADID tid; 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 */ @@ -1021,8 +1018,7 @@ ERR_STATE *ERR_get_state(void) { 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++) diff --git a/crypto/err/err.h b/crypto/err/err.h index 942f820a02..006351d5e3 100644 --- a/crypto/err/err.h +++ b/crypto/err/err.h @@ -147,8 +147,7 @@ extern "C" { #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]; @@ -351,7 +350,10 @@ void ERR_load_ERR_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 */ +#endif ERR_STATE *ERR_get_state(void); #ifndef OPENSSL_NO_LHASH diff --git a/crypto/err/err_prn.c b/crypto/err/err_prn.c index 2224a901e5..de32f332c4 100644 --- a/crypto/err/err_prn.c +++ b/crypto/err/err_prn.c @@ -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; + 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); diff --git a/crypto/evp/evp_test.c b/crypto/evp/evp_test.c index bb6f02c2e9..b8c9235d3e 100644 --- a/crypto/evp/evp_test.c +++ b/crypto/evp/evp_test.c @@ -441,7 +441,7 @@ int main(int argc,char **argv) #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); diff --git a/crypto/mem_dbg.c b/crypto/mem_dbg.c index ad5209b817..131669a23b 100644 --- a/crypto/mem_dbg.c +++ b/crypto/mem_dbg.c @@ -150,8 +150,7 @@ typedef struct app_mem_info_st * 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; @@ -176,8 +175,7 @@ typedef struct mem_st 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; @@ -198,12 +196,10 @@ static unsigned int num_disable = 0; /* num_disable > 0 * 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) { @@ -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) { - 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 @@ -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; - disabling_thread_id=CRYPTO_thread_id(); - disabling_thread_idptr=CRYPTO_thread_idptr(); + CRYPTO_THREADID_cpy(&disabling_threadid, &cur); } num_disable++; } @@ -294,11 +289,12 @@ int CRYPTO_is_mem_check_on(void) 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) - || (disabling_thread_id != CRYPTO_thread_id()) - || (disabling_thread_idptr != CRYPTO_thread_idptr()); + || CRYPTO_THREADID_cmp(&disabling_threadid, &cur); 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) { - 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) { - unsigned long id1, id2; 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); } @@ -370,8 +363,7 @@ static APP_INFO *pop_info(void) 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; @@ -382,10 +374,11 @@ static APP_INFO *pop_info(void) (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 @@ -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; @@ -436,10 +428,11 @@ int CRYPTO |