From 48fc582f66a58e3da6f095ba1b4498c17581e05a Mon Sep 17 00:00:00 2001 From: =?utf8?q?Bodo=20M=C3=B6ller?= Date: Fri, 23 Jun 2006 15:21:36 +0000 Subject: [PATCH] New functions CRYPTO_set_idptr_callback(), CRYPTO_get_idptr_callback(), CRYPTO_thread_idptr() for a 'void *' type thread ID, since the 'unsigned long' type of the existing thread ID does not always work well. --- CHANGES | 24 +++++++ FAQ | 7 ++- crypto/bn/bn.h | 55 ++++++++++++++++ crypto/bn/bn_blind.c | 14 ++++- crypto/cryptlib.c | 49 +++++++++++---- crypto/crypto.h | 5 +- crypto/err/err.c | 28 ++++++--- crypto/err/err.h | 54 ++++++++++++++++ crypto/mem_dbg.c | 139 +++++++++++++++++++++++++++++++---------- crypto/rand/md_rand.c | 13 ++-- crypto/rsa/rsa_eay.c | 2 +- crypto/rsa/rsa_lib.c | 1 + doc/crypto/threads.pod | 28 ++++++--- util/libeay.num | 5 ++ 14 files changed, 354 insertions(+), 70 deletions(-) diff --git a/CHANGES b/CHANGES index a2af507a1a..8e7cf614ff 100644 --- a/CHANGES +++ b/CHANGES @@ -4,6 +4,30 @@ Changes between 0.9.8b and 0.9.9 [xx XXX xxxx] + *) 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 . 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 diff --git a/FAQ b/FAQ index f96759b18e..f2a383a297 100644 --- a/FAQ +++ b/FAQ @@ -699,8 +699,11 @@ libraries. If your platform is not one of these, consult the INSTALL file. Multi-threaded applications must provide two callback functions to -OpenSSL. This is described in the threads(3) manpage. - +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) +manpage. * I've compiled a program under Windows and it crashes: why? diff --git a/crypto/bn/bn.h b/crypto/bn/bn.h index a2472b7d28..6eb4d999c2 100644 --- a/crypto/bn/bn.h +++ b/crypto/bn/bn.h @@ -55,6 +55,59 @@ * copied and put under another distribution licence * [including the GNU Public Licence.] */ +/* ==================================================================== + * Copyright (c) 1998-2006 The OpenSSL Project. All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in + * the documentation and/or other materials provided with the + * distribution. + * + * 3. All advertising materials mentioning features or use of this + * software must display the following acknowledgment: + * "This product includes software developed by the OpenSSL Project + * for use in the OpenSSL Toolkit. (http://www.openssl.org/)" + * + * 4. The names "OpenSSL Toolkit" and "OpenSSL Project" must not be used to + * endorse or promote products derived from this software without + * prior written permission. For written permission, please contact + * openssl-core@openssl.org. + * + * 5. Products derived from this software may not be called "OpenSSL" + * nor may "OpenSSL" appear in their names without prior written + * permission of the OpenSSL Project. + * + * 6. Redistributions of any form whatsoever must retain the following + * acknowledgment: + * "This product includes software developed by the OpenSSL Project + * for use in the OpenSSL Toolkit (http://www.openssl.org/)" + * + * THIS SOFTWARE IS PROVIDED BY THE OpenSSL PROJECT ``AS IS'' AND ANY + * EXPRESSED OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE + * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR + * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE OpenSSL PROJECT OR + * ITS CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, + * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT + * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; + * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) + * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, + * STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) + * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED + * OF THE POSSIBILITY OF SUCH DAMAGE. + * ==================================================================== + * + * This product includes cryptographic software written by Eric Young + * (eay@cryptsoft.com). This product includes software written by Tim + * Hudson (tjh@cryptsoft.com). + * + */ /* ==================================================================== * Copyright 2002 Sun Microsystems, Inc. ALL RIGHTS RESERVED. * @@ -502,6 +555,8 @@ 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 *); 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 *); 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 ca22d4f8bd..ccecc63cda 100644 --- a/crypto/bn/bn_blind.c +++ b/crypto/bn/bn_blind.c @@ -1,6 +1,6 @@ /* crypto/bn/bn_blind.c */ /* ==================================================================== - * Copyright (c) 1998-2005 The OpenSSL Project. All rights reserved. + * Copyright (c) 1998-2006 The OpenSSL Project. All rights reserved. * * Redistribution and use in source and binary forms, with or without * modification, are permitted provided that the following conditions @@ -123,6 +123,8 @@ struct bn_blinding_st BIGNUM *mod; /* just a reference */ 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 */ unsigned int counter; unsigned long flags; BN_MONT_CTX *m_ctx; @@ -267,6 +269,16 @@ void BN_BLINDING_set_thread_id(BN_BLINDING *b, unsigned long n) b->thread_id = n; } +void *BN_BLINDING_get_thread_idptr(const BN_BLINDING *b) + { + return b->thread_idptr; + } + +void BN_BLINDING_set_thread_idptr(BN_BLINDING *b, void *p) + { + b->thread_idptr = p; + } + unsigned long BN_BLINDING_get_flags(const BN_BLINDING *b) { return b->flags; diff --git a/crypto/cryptlib.c b/crypto/cryptlib.c index aa19dd7f27..4a814643f4 100644 --- a/crypto/cryptlib.c +++ b/crypto/cryptlib.c @@ -1,6 +1,6 @@ /* crypto/cryptlib.c */ /* ==================================================================== - * Copyright (c) 1998-2003 The OpenSSL Project. All rights reserved. + * Copyright (c) 1998-2006 The OpenSSL Project. All rights reserved. * * Redistribution and use in source and binary forms, with or without * modification, are permitted provided that the following conditions @@ -182,16 +182,17 @@ static STACK_OF(CRYPTO_dynlock) *dyn_locks=NULL; static void (MS_FAR *locking_callback)(int mode,int type, - const char *file,int line)=NULL; + const char *file,int line)=0; static int (MS_FAR *add_lock_callback)(int *pointer,int amount, - int type,const char *file,int line)=NULL; -static unsigned long (MS_FAR *id_callback)(void)=NULL; + int type,const char *file,int line)=0; +static unsigned long (MS_FAR *id_callback)(void)=0; +static void *(MS_FAR *idptr_callback)(void)=0; static struct CRYPTO_dynlock_value *(MS_FAR *dynlock_create_callback) - (const char *file,int line)=NULL; + (const char *file,int line)=0; static void (MS_FAR *dynlock_lock_callback)(int mode, - struct CRYPTO_dynlock_value *l, const char *file,int line)=NULL; + struct CRYPTO_dynlock_value *l, const char *file,int line)=0; static void (MS_FAR *dynlock_destroy_callback)(struct CRYPTO_dynlock_value *l, - const char *file,int line)=NULL; + const char *file,int line)=0; int CRYPTO_get_new_lockid(char *name) { @@ -447,6 +448,28 @@ unsigned long CRYPTO_thread_id(void) 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; + } + void CRYPTO_lock(int mode, int type, const char *file, int line) { #ifdef LOCK_DEBUG @@ -467,8 +490,8 @@ void CRYPTO_lock(int mode, int type, const char *file, int line) else rw_text="ERROR"; - fprintf(stderr,"lock:%08lx:(%s)%s %-18s %s:%d\n", - CRYPTO_thread_id(), rw_text, operation_text, + fprintf(stderr,"lock:%08lx/%08p:(%s)%s %-18s %s:%d\n", + CRYPTO_thread_id(), CRYPTO_thread_idptr(), rw_text, operation_text, CRYPTO_get_lock_name(type), file, line); } #endif @@ -504,8 +527,8 @@ 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:%2d+%2d->%2d %-18s %s:%d\n", - CRYPTO_thread_id(), + fprintf(stderr,"ladd:%08lx/%0xp:%2d+%2d->%2d %-18s %s:%d\n", + CRYPTO_thread_id(), CRYPTO_thread_idptr(), before,amount,ret, CRYPTO_get_lock_name(type), file,line); @@ -517,8 +540,8 @@ int CRYPTO_add_lock(int *pointer, int amount, int type, const char *file, ret= *pointer+amount; #ifdef LOCK_DEBUG - fprintf(stderr,"ladd:%08lx:%2d+%2d->%2d %-18s %s:%d\n", - CRYPTO_thread_id(), + fprintf(stderr,"ladd:%08lx/%0xp:%2d+%2d->%2d %-18s %s:%d\n", + CRYPTO_thread_id(), CRYPTO_thread_idptr(), *pointer,amount,ret, CRYPTO_get_lock_name(type), file,line); diff --git a/crypto/crypto.h b/crypto/crypto.h index d2b5ffe332..ffe92993ec 100644 --- a/crypto/crypto.h +++ b/crypto/crypto.h @@ -1,6 +1,6 @@ /* crypto/crypto.h */ /* ==================================================================== - * Copyright (c) 1998-2003 The OpenSSL Project. All rights reserved. + * Copyright (c) 1998-2006 The OpenSSL Project. All rights reserved. * * Redistribution and use in source and binary forms, with or without * modification, are permitted provided that the following conditions @@ -423,6 +423,9 @@ int (*CRYPTO_get_add_lock_callback(void))(int *num,int mount,int type, 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); const char *CRYPTO_get_lock_name(int type); int CRYPTO_add_lock(int *pointer,int amount,int type, const char *file, int line); diff --git a/crypto/err/err.c b/crypto/err/err.c index 3367a75d99..6812a9afed 100644 --- a/crypto/err/err.c +++ b/crypto/err/err.c @@ -56,7 +56,7 @@ * [including the GNU Public Licence.] */ /* ==================================================================== - * Copyright (c) 1998-2001 The OpenSSL Project. All rights reserved. + * Copyright (c) 1998-2006 The OpenSSL Project. All rights reserved. * * Redistribution and use in source and binary forms, with or without * modification, are permitted provided that the following conditions @@ -973,24 +973,32 @@ static int err_cmp(const void *a_void, const void *b_void) /* static unsigned long pid_hash(ERR_STATE *a) */ static unsigned long pid_hash(const void *a_void) { - return(((const ERR_STATE *)a_void)->pid*13); + return((((const ERR_STATE *)a_void)->pid + (unsigned long)((const ERR_STATE *)a_void)->pidptr)*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)((const ERR_STATE *)a_void)->pid - - (long)((const ERR_STATE *)b_void)->pid)); + return (((const ERR_STATE *)a_void)->pid != ((const ERR_STATE *)b_void)->pid) + || (((const ERR_STATE *)a_void)->pidptr != ((const ERR_STATE *)b_void)->pidptr); } void ERR_remove_state(unsigned long pid) { ERR_STATE tmp; + void *pidptr; err_fns_check(); - if (pid == 0) - pid=(unsigned long)CRYPTO_thread_id(); + if (pid != 0) + pidptr = &errno; + else + { + pid = CRYPTO_thread_id(); + pidptr = CRYPTO_thread_idptr(); + } + tmp.pid=pid; + tmp.pidptr=pidptr; /* thread_del_item automatically destroys the LHASH if the number of * items reaches zero. */ ERRFN(thread_del_item)(&tmp); @@ -1002,10 +1010,13 @@ ERR_STATE *ERR_get_state(void) ERR_STATE *ret,tmp,*tmpp=NULL; int i; unsigned long pid; + void *pidptr; err_fns_check(); - pid=(unsigned long)CRYPTO_thread_id(); - tmp.pid=pid; + pid = CRYPTO_thread_id(); + pidptr = CRYPTO_thread_idptr(); + tmp.pid = pid; + tmp.pidptr = pidptr; ret=ERRFN(thread_get_item)(&tmp); /* ret == the error state, if NULL, make a new one */ @@ -1014,6 +1025,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; ret->top=0; ret->bottom=0; for (i=0; i #include @@ -94,7 +147,8 @@ typedef struct app_mem_info_st * CRYPTO_remove_all_info() to pop all entries. */ { - unsigned long thread; + unsigned long thread_id; + void *thread_idptr; const char *file; int line; const char *info; @@ -116,7 +170,8 @@ typedef struct mem_st int num; const char *file; int line; - unsigned long thread; + unsigned long thread_id; + void *thread_idptr; unsigned long order; time_t time; APP_INFO *app_info; @@ -136,11 +191,13 @@ static unsigned int num_disable = 0; /* num_disable > 0 * iff * mh_mode == CRYPTO_MEM_CHECK_ON (w/o ..._ENABLE) */ -static unsigned long disabling_thread = 0; /* Valid iff num_disable > 0. - * CRYPTO_LOCK_MALLOC2 is locked - * exactly in this case (by the - * thread named in disabling_thread). - */ + +/* 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). + */ +static unsigned long disabling_thread_id = 0; +static void *disabling_thread_idptr = NULL; static void app_info_free(APP_INFO *inf) { @@ -177,7 +234,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 != CRYPTO_thread_id())) /* otherwise we already have the MALLOC2 lock */ + if (!num_disable + || (disabling_thread_id != CRYPTO_thread_id()) + || (disabling_thread_idptr != CRYPTO_thread_idptr())) /* 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 @@ -195,7 +254,8 @@ 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=CRYPTO_thread_id(); + disabling_thread_id=CRYPTO_thread_id(); + disabling_thread_idptr=CRYPTO_thread_idptr(); } num_disable++; } @@ -231,7 +291,8 @@ int CRYPTO_is_mem_check_on(void) CRYPTO_r_lock(CRYPTO_LOCK_MALLOC); ret = (mh_mode & CRYPTO_MEM_CHECK_ENABLE) - || (disabling_thread != CRYPTO_thread_id()); + || (disabling_thread_id != CRYPTO_thread_id()) + || (disabling_thread_idptr != CRYPTO_thread_idptr()); CRYPTO_r_unlock(CRYPTO_LOCK_MALLOC); } @@ -278,16 +339,19 @@ static unsigned long mem_hash(const void *a_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 - != ((const APP_INFO *)b_void)->thread); + 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); } /* static unsigned long app_info_hash(APP_INFO *a) */ static unsigned long app_info_hash(const void *a_void) { + unsigned long id1, id2; unsigned long ret; - ret=(unsigned long)((const APP_INFO *)a_void)->thread; + id1=(unsigned long)((const APP_INFO *)a_void)->thread_id; + id2=(unsigned long)((const APP_INFO *)a_void)->thread_idptr; + ret = id1 + id2; ret=ret*17851+(ret>>14)*7+(ret>>4)*251; return(ret); @@ -300,7 +364,8 @@ static APP_INFO *pop_info(void) if (amih != NULL) { - tmp.thread=CRYPTO_thread_id(); + tmp.thread_id=CRYPTO_thread_id(); + tmp.thread_idptr=CRYPTO_thread_idptr(); if ((ret=(APP_INFO *)lh_delete(amih,&tmp)) != NULL) { APP_INFO *next=ret->next; @@ -311,10 +376,10 @@ static APP_INFO *pop_info(void) lh_insert(amih,(char *)next); } #ifdef LEVITTE_DEBUG_MEM - if (ret->thread != tmp.thread) + if (ret->thread_id != tmp.thread_id || ret->thread_idptr != tmp.thread_idptr) { - fprintf(stderr, "pop_info(): deleted info has other thread ID (%lu) than the current thread (%lu)!!!!\n", - ret->thread, tmp.thread); + 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); abort(); } #endif @@ -354,7 +419,8 @@ int CRYPTO_push_info_(const char *info, const char *file, int line) } } - ami->thread=CRYPTO_thread_id(); + ami->thread_id=CRYPTO_thread_id(); + ami->thread_idptr=CRYPTO_thread_idptr(); ami->file=file; ami->line=line; ami->info=info; @@ -364,10 +430,10 @@ int CRYPTO_push_info_(const char *info, const char *file, int line) if ((amim=(APP_INFO *)lh_insert(amih,(char *)ami)) != NULL) { #ifdef LEVITTE_DEBUG_MEM - if (ami->thread != amim->thread) + if (ami->thread_id != amim->thread_id || ami->thread_idptr != amim->thread_idptr) { - fprintf(stderr, "CRYPTO_push_info(): previous info has other thread ID (%lu) than the current thread (%lu)!!!!\n", - amim->thread, ami->thread); + 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); abort(); } #endif @@ -453,9 +519,15 @@ 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->thread=CRYPTO_thread_id(); + { + m->thread_id=CRYPTO_thread_id(); + m->thread_idptr=CRYPTO_thread_idptr(); + } else - m->thread=0; + { + m->thread_id=0; + m->thread_idptr=NULL; + } if (order == break_order_num) { @@ -464,7 +536,7 @@ void CRYPTO_dbg_malloc(void *addr, int num, const char *file, int line, } m->order=order++; #ifdef LEVITTE_DEBUG_MEM - fprintf(stderr, "LEVITTE_DEBUG_MEM: [%5d] %c 0x%p (%d)\n", + fprintf(stderr, "LEVITTE_DEBUG_MEM: [%5ld] %c 0x%p (%d)\n", m->order, (before_p & 128) ? '*' : '+', m->addr, m->num); @@ -474,7 +546,8 @@ void CRYPTO_dbg_malloc(void *addr, int num, const char *file, int line, else m->time=0; - tmp.thread=CRYPTO_thread_id(); + tmp.thread_id=CRYPTO_thread_id(); + tmp.thread_idptr=CRYPTO_thread_idptr(); m->app_info=NULL; if (amih != NULL && (amim=(APP_INFO *)lh_retrieve(amih,(char *)&tmp)) != NULL) @@ -520,7 +593,7 @@ void CRYPTO_dbg_free(void *addr, int before_p) if (mp != NULL) { #ifdef LEVITTE_DEBUG_MEM - fprintf(stderr, "LEVITTE_DEBUG_MEM: [%5d] - 0x%p (%d)\n", + fprintf(stderr, "LEVITTE_DEBUG_MEM: [%5ld] - 0x%p (%d)\n", mp->order, mp->addr, mp->num); #endif if (mp->app_info != NULL) @@ -570,7 +643,7 @@ void CRYPTO_dbg_realloc(void *addr1, void *addr2, int num, if (mp != NULL) { #ifdef LEVITTE_DEBUG_MEM - fprintf(stderr, "LEVITTE_DEBUG_MEM: [%5d] * 0x%p (%d) -> 0x%p (%d)\n", + fprintf(stderr, "LEVITTE_DEBUG_MEM: [%5ld] * 0x%p (%d) -> 0x%p (%d)\n", mp->order, mp->addr, mp->num, addr2, num); @@ -604,6 +677,7 @@ static void print_leak(const MEM *m, MEM_LEAK *l) int ami_cnt; struct tm *lcl = NULL; unsigned long ti; + void *tip; #define BUF_REMAIN (sizeof buf - (size_t)(bufp - buf)) @@ -625,7 +699,7 @@ static void print_leak(const MEM *m, MEM_LEAK *l) if (options & V_CRYPTO_MDEBUG_THREAD) { - BIO_snprintf(bufp, BUF_REMAIN, "thread=%lu, ", m->thread); + BIO_snprintf(bufp, BUF_REMAIN, "thread=%lu/%p, ", m->thread_id, m->thread_idptr); bufp += strlen(bufp); } @@ -642,7 +716,8 @@ static void print_leak(const MEM *m, MEM_LEAK *l) ami_cnt=0; if (!amip) return; - ti=amip->thread; + ti=amip->thread_id; + tip=amip->thread_idptr; do { @@ -652,8 +727,8 @@ static void print_leak(const MEM *m, MEM_LEAK *l) ami_cnt++; memset(buf,'>',ami_cnt); BIO_snprintf(buf + ami_cnt, sizeof buf - ami_cnt, - " thread=%lu, file=%s, line=%d, info=\"", - amip->thread, amip->file, amip->line); + " thread=%lu/%p, file=%s, line=%d, info=\"", + amip->thread_id, amip->thread_idptr, amip->file, amip->line); buf_len=strlen(buf); info_len=strlen(amip->info); if (128 - buf_len - 3 < info_len) @@ -673,7 +748,7 @@ static void print_leak(const MEM *m, MEM_LEAK *l) amip = amip->next; } - while(amip && amip->thread == ti); + while(amip && amip->thread_id == ti && amip->thread_idptr == tip); #ifdef LEVITTE_DEBUG_MEM if (amip) diff --git a/crypto/rand/md_rand.c b/crypto/rand/md_rand.c index 6e10f6ef67..4aa13f7156 100644 --- a/crypto/rand/md_rand.c +++ b/crypto/rand/md_rand.c @@ -145,7 +145,8 @@ 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 */ -static unsigned long locking_thread = 0; /* valid iff crypto_lock_rand is set */ +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 */ #ifdef PREDICT @@ -214,7 +215,7 @@ static void ssleay_rand_add(const void *buf, int num, double add) if (crypto_lock_rand) { CRYPTO_r_lock(CRYPTO_LOCK_RAND2); - do_not_lock = (locking_thread == CRYPTO_thread_id()); + do_not_lock = (locking_thread_id == CRYPTO_thread_id()) && (locking_thread_idptr == CRYPTO_thread_idptr()); CRYPTO_r_unlock(CRYPTO_LOCK_RAND2); } else @@ -372,7 +373,8 @@ 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); - locking_thread = CRYPTO_thread_id(); + locking_thread_id = CRYPTO_thread_id(); + locking_thread_idptr = CRYPTO_thread_idptr(); CRYPTO_w_unlock(CRYPTO_LOCK_RAND2); crypto_lock_rand = 1; @@ -535,7 +537,7 @@ static int ssleay_rand_status(void) if (crypto_lock_rand) { CRYPTO_r_lock(CRYPTO_LOCK_RAND2); - do_not_lock = (locking_thread == CRYPTO_thread_id()); + do_not_lock = (locking_thread_id == CRYPTO_thread_id()) && (locking_thread_idptr == CRYPTO_thread_idptr()); CRYPTO_r_unlock(CRYPTO_LOCK_RAND2); } else @@ -547,7 +549,8 @@ static int ssleay_rand_status(void) /* prevent ssleay_rand_bytes() from trying to obtain the lock again */ CRYPTO_w_lock(CRYPTO_LOCK_RAND2); - locking_thread = CRYPTO_thread_id(); + locking_thread_id = CRYPTO_thread_id(); + locking_thread_idptr = CRYPTO_thread_idptr(); CRYPTO_w_unlock(CRYPTO_LOCK_RAND2); crypto_lock_rand = 1; } diff --git a/crypto/rsa/rsa_eay.c b/crypto/rsa/rsa_eay.c index 69cabd2716..c6ceaee6e7 100644 --- a/crypto/rsa/rsa_eay.c +++ b/crypto/rsa/rsa_eay.c @@ -259,7 +259,7 @@ static BN_BLINDING *rsa_get_blinding(RSA *rsa, int *local, BN_CTX *ctx) if (ret == NULL) goto err; - if (BN_BLINDING_get_thread_id(ret) == CRYPTO_thread_id()) + if ((BN_BLINDING_get_thread_id(ret) == CRYPTO_thread_id()) && (BN_BLINDING_get_thread_idptr(ret) == CRYPTO_thread_idptr())) { /* rsa->blinding is ours! */ diff --git a/crypto/rsa/rsa_lib.c b/crypto/rsa/rsa_lib.c index 533a711eda..d9feb88caf 100644 --- a/crypto/rsa/rsa_lib.c +++ b/crypto/rsa/rsa_lib.c @@ -408,6 +408,7 @@ BN_BLINDING *RSA_setup_blinding(RSA *rsa, BN_CTX *in_ctx) goto err; } BN_BLINDING_set_thread_id(ret, CRYPTO_thread_id()); + BN_BLINDING_set_thread_idptr(ret, CRYPTO_thread_idptr()); err: BN_CTX_end(ctx); if (in_ctx == NULL) diff --git a/doc/crypto/threads.pod b/doc/crypto/threads.pod index 3df4ecd776..230cbe890b 100644 --- a/doc/crypto/threads.pod +++ b/doc/crypto/threads.pod @@ -2,7 +2,8 @@ =head1 NAME -CRYPTO_set_locking_callback, CRYPTO_set_id_callback, CRYPTO_num_locks, +CRYPTO_set_locking_callback, CRYPTO_set_id_callback, +CRYPTO_set_idptr_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 @@ -16,6 +17,8 @@ CRYPTO_destroy_dynlockid, CRYPTO_lock - OpenSSL thread support void CRYPTO_set_id_callback(unsigned long (*id_function)(void)); + void CRYPTO_set_idptr_callback(void *(*idptr_function)(void)); + int CRYPTO_num_locks(void); @@ -65,10 +68,17 @@ B, and releases it otherwise. B and B 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 thread ID, for example -pthread_self() if it returns an integer (see NOTES below). It isn't -needed on Windows nor on platforms where getpid() returns a different -ID for each thread (see NOTES below). +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). + +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. Additionally, OpenSSL supports dynamic locks, and sometimes, some parts of OpenSSL need it for better performance. To enable this, the following @@ -153,8 +163,10 @@ 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. This is a bit unusual, and this -manual has no cookbook solution for that case. +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 @@ -168,6 +180,8 @@ 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. + =head1 SEE ALSO L diff --git a/util/libeay.num b/util/libeay.num index 6d067e0e41..df3a3f19af 100755 --- a/util/libeay.num +++ b/util/libeay.num @@ -3761,3 +3761,8 @@ TS_TST_INFO_get_ext_by_critical 4153 EXIST::FUNCTION: EVP_PKEY_CTX_new_id 4154 EXIST::FUNCTION: TS_REQ_get_ext_by_OBJ 4155 EXIST::FUNCTION: TS_CONF_set_signer_cert 4156 EXIST::FUNCTION: +BN_BLINDING_set_thread_idptr 4157 EXIST::FUNCTION: +BN_BLINDING_get_thread_idptr 4158 EXIST::FUNCTION: +CRYPTO_set_idptr_callback 4159 EXIST::FUNCTION: +CRYPTO_get_idptr_callback 4160 EXIST::FUNCTION: +CRYPTO_thread_idptr 4161 EXIST::FUNCTION: -- 2.34.1