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.
This commit is contained in:
Bodo Möller 2006-06-23 15:21:36 +00:00
parent 81de1028bc
commit 48fc582f66
14 changed files with 354 additions and 70 deletions

24
CHANGES
View File

@ -4,6 +4,30 @@
Changes between 0.9.8b and 0.9.9 [xx XXX xxxx] 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 <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 *) Change the array representation of binary polynomials: the list
of degrees of non-zero coefficients is now terminated with -1. of degrees of non-zero coefficients is now terminated with -1.
Previously it was terminated with 0, which was also part of the Previously it was terminated with 0, which was also part of the

7
FAQ
View File

@ -699,8 +699,11 @@ libraries. If your platform is not one of these, consult the INSTALL
file. file.
Multi-threaded applications must provide two callback functions to 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? * I've compiled a program under Windows and it crashes: why?

View File

@ -55,6 +55,59 @@
* copied and put under another distribution licence * copied and put under another distribution licence
* [including the GNU Public 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. * 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 *); 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 *); unsigned long BN_BLINDING_get_thread_id(const BN_BLINDING *);
void BN_BLINDING_set_thread_id(BN_BLINDING *, unsigned long); 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 *); unsigned long BN_BLINDING_get_flags(const BN_BLINDING *);
void BN_BLINDING_set_flags(BN_BLINDING *, unsigned long); void BN_BLINDING_set_flags(BN_BLINDING *, unsigned long);
BN_BLINDING *BN_BLINDING_create_param(BN_BLINDING *b, BN_BLINDING *BN_BLINDING_create_param(BN_BLINDING *b,

View File

@ -1,6 +1,6 @@
/* crypto/bn/bn_blind.c */ /* 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 * Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions * modification, are permitted provided that the following conditions
@ -123,6 +123,8 @@ struct bn_blinding_st
BIGNUM *mod; /* just a reference */ BIGNUM *mod; /* just a reference */
unsigned long thread_id; /* added in OpenSSL 0.9.6j and 0.9.7b; 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 */ * 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 int counter;
unsigned long flags; unsigned long flags;
BN_MONT_CTX *m_ctx; 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; 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) unsigned long BN_BLINDING_get_flags(const BN_BLINDING *b)
{ {
return b->flags; return b->flags;

View File

@ -1,6 +1,6 @@
/* crypto/cryptlib.c */ /* 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 * Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions * 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, 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, static int (MS_FAR *add_lock_callback)(int *pointer,int amount,
int type,const char *file,int line)=NULL; int type,const char *file,int line)=0;
static unsigned long (MS_FAR *id_callback)(void)=NULL; 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) 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, 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, 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) int CRYPTO_get_new_lockid(char *name)
{ {
@ -447,6 +448,28 @@ unsigned long CRYPTO_thread_id(void)
return(ret); 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) void CRYPTO_lock(int mode, int type, const char *file, int line)
{ {
#ifdef LOCK_DEBUG #ifdef LOCK_DEBUG
@ -467,8 +490,8 @@ void CRYPTO_lock(int mode, int type, const char *file, int line)
else else
rw_text="ERROR"; rw_text="ERROR";
fprintf(stderr,"lock:%08lx:(%s)%s %-18s %s:%d\n", fprintf(stderr,"lock:%08lx/%08p:(%s)%s %-18s %s:%d\n",
CRYPTO_thread_id(), rw_text, operation_text, CRYPTO_thread_id(), CRYPTO_thread_idptr(), rw_text, operation_text,
CRYPTO_get_lock_name(type), file, line); CRYPTO_get_lock_name(type), file, line);
} }
#endif #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); ret=add_lock_callback(pointer,amount,type,file,line);
#ifdef LOCK_DEBUG #ifdef LOCK_DEBUG
fprintf(stderr,"ladd:%08lx:%2d+%2d->%2d %-18s %s:%d\n", fprintf(stderr,"ladd:%08lx/%0xp:%2d+%2d->%2d %-18s %s:%d\n",
CRYPTO_thread_id(), CRYPTO_thread_id(), CRYPTO_thread_idptr(),
before,amount,ret, before,amount,ret,
CRYPTO_get_lock_name(type), CRYPTO_get_lock_name(type),
file,line); file,line);
@ -517,8 +540,8 @@ int CRYPTO_add_lock(int *pointer, int amount, int type, const char *file,
ret= *pointer+amount; ret= *pointer+amount;
#ifdef LOCK_DEBUG #ifdef LOCK_DEBUG
fprintf(stderr,"ladd:%08lx:%2d+%2d->%2d %-18s %s:%d\n", fprintf(stderr,"ladd:%08lx/%0xp:%2d+%2d->%2d %-18s %s:%d\n",
CRYPTO_thread_id(), CRYPTO_thread_id(), CRYPTO_thread_idptr(),
*pointer,amount,ret, *pointer,amount,ret,
CRYPTO_get_lock_name(type), CRYPTO_get_lock_name(type),
file,line); file,line);

View File

@ -1,6 +1,6 @@
/* crypto/crypto.h */ /* 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 * Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions * 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)); void CRYPTO_set_id_callback(unsigned long (*func)(void));
unsigned long (*CRYPTO_get_id_callback(void))(void); unsigned long (*CRYPTO_get_id_callback(void))(void);
unsigned long CRYPTO_thread_id(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); const char *CRYPTO_get_lock_name(int type);
int CRYPTO_add_lock(int *pointer,int amount,int type, const char *file, int CRYPTO_add_lock(int *pointer,int amount,int type, const char *file,
int line); int line);

View File

@ -56,7 +56,7 @@
* [including the GNU Public Licence.] * [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 * Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions * 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(ERR_STATE *a) */
static unsigned long pid_hash(const void *a_void) 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(ERR_STATE *a, ERR_STATE *b) */
static int pid_cmp(const void *a_void, const void *b_void) static int pid_cmp(const void *a_void, const void *b_void)
{ {
return((int)((long)((const ERR_STATE *)a_void)->pid - return (((const ERR_STATE *)a_void)->pid != ((const ERR_STATE *)b_void)->pid)
(long)((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) void ERR_remove_state(unsigned long pid)
{ {
ERR_STATE tmp; ERR_STATE tmp;
void *pidptr;
err_fns_check(); err_fns_check();
if (pid == 0) if (pid != 0)
pid=(unsigned long)CRYPTO_thread_id(); pidptr = &errno;
else
{
pid = CRYPTO_thread_id();
pidptr = CRYPTO_thread_idptr();
}
tmp.pid=pid; tmp.pid=pid;
tmp.pidptr=pidptr;
/* thread_del_item automatically destroys the LHASH if the number of /* thread_del_item automatically destroys the LHASH if the number of
* items reaches zero. */ * items reaches zero. */
ERRFN(thread_del_item)(&tmp); ERRFN(thread_del_item)(&tmp);
@ -1002,10 +1010,13 @@ ERR_STATE *ERR_get_state(void)
ERR_STATE *ret,tmp,*tmpp=NULL; ERR_STATE *ret,tmp,*tmpp=NULL;
int i; int i;
unsigned long pid; unsigned long pid;
void *pidptr;
err_fns_check(); err_fns_check();
pid=(unsigned long)CRYPTO_thread_id(); pid = CRYPTO_thread_id();
tmp.pid=pid; pidptr = CRYPTO_thread_idptr();
tmp.pid = pid;
tmp.pidptr = pidptr;
ret=ERRFN(thread_get_item)(&tmp); ret=ERRFN(thread_get_item)(&tmp);
/* ret == the error state, if NULL, make a new one */ /* 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)); ret=(ERR_STATE *)OPENSSL_malloc(sizeof(ERR_STATE));
if (ret == NULL) return(&fallback); if (ret == NULL) return(&fallback);
ret->pid=pid; ret->pid=pid;
ret->pidptr=pidptr;
ret->top=0; ret->top=0;
ret->bottom=0; ret->bottom=0;
for (i=0; i<ERR_NUM_ERRORS; i++) for (i=0; i<ERR_NUM_ERRORS; i++)

View File

@ -55,6 +55,59 @@
* copied and put under another distribution licence * copied and put under another distribution licence
* [including the GNU Public 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).
*
*/
#ifndef HEADER_ERR_H #ifndef HEADER_ERR_H
#define HEADER_ERR_H #define HEADER_ERR_H
@ -95,6 +148,7 @@ extern "C" {
typedef struct err_state_st typedef struct err_state_st
{ {
unsigned long pid; unsigned long pid;
void *pidptr; /* new in OpenSSL 0.9.9 */
int err_flags[ERR_NUM_ERRORS]; int err_flags[ERR_NUM_ERRORS];
unsigned long err_buffer[ERR_NUM_ERRORS]; unsigned long err_buffer[ERR_NUM_ERRORS];
char *err_data[ERR_NUM_ERRORS]; char *err_data[ERR_NUM_ERRORS];

View File

@ -55,6 +55,59 @@
* copied and put under another distribution licence * copied and put under another distribution licence
* [including the GNU Public 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).
*
*/
#include <stdio.h> #include <stdio.h>
#include <stdlib.h> #include <stdlib.h>
@ -94,7 +147,8 @@ 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; unsigned long thread_id;
void *thread_idptr;
const char *file; const char *file;
int line; int line;
const char *info; const char *info;
@ -116,7 +170,8 @@ typedef struct mem_st
int num; int num;
const char *file; const char *file;
int line; int line;
unsigned long thread; unsigned long thread_id;
void *thread_idptr;
unsigned long order; unsigned long order;
time_t time; time_t time;
APP_INFO *app_info; APP_INFO *app_info;
@ -136,11 +191,13 @@ static unsigned int num_disable = 0; /* num_disable > 0
* iff * iff
* mh_mode == CRYPTO_MEM_CHECK_ON (w/o ..._ENABLE) * 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 /* The following two variables, disabling_thread_id and disabling_thread_idptr,
* exactly in this case (by the * are valid iff num_disable > 0. CRYPTO_LOCK_MALLOC2 is locked exactly in
* thread named in disabling_thread). * 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) 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() */ case CRYPTO_MEM_CHECK_DISABLE: /* aka MemCheck_off() */
if (mh_mode & CRYPTO_MEM_CHECK_ON) 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 /* Long-time lock CRYPTO_LOCK_MALLOC2 must not be claimed while
* we're holding CRYPTO_LOCK_MALLOC, or we'll deadlock if * 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_MALLOC2);
CRYPTO_w_lock(CRYPTO_LOCK_MALLOC); CRYPTO_w_lock(CRYPTO_LOCK_MALLOC);
mh_mode &= ~CRYPTO_MEM_CHECK_ENABLE; 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++; num_disable++;
} }
@ -231,7 +291,8 @@ int CRYPTO_is_mem_check_on(void)
CRYPTO_r_lock(CRYPTO_LOCK_MALLOC); CRYPTO_r_lock(CRYPTO_LOCK_MALLOC);
ret = (mh_mode & CRYPTO_MEM_CHECK_ENABLE) 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); 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(APP_INFO *a, APP_INFO *b) */
static int app_info_cmp(const void *a_void, const void *b_void) static int app_info_cmp(const void *a_void, const void *b_void)
{ {
return(((const APP_INFO *)a_void)->thread return (((const APP_INFO *)a_void)->thread_id != ((const APP_INFO *)b_void)->thread_id)
!= ((const APP_INFO *)b_void)->thread); || (((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(APP_INFO *a) */
static unsigned long app_info_hash(const void *a_void) static unsigned long app_info_hash(const void *a_void)
{ {
unsigned long id1, id2;
unsigned long ret; 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; ret=ret*17851+(ret>>14)*7+(ret>>4)*251;
return(ret); return(ret);
@ -300,7 +364,8 @@ static APP_INFO *pop_info(void)
if (amih != NULL) 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) if ((ret=(APP_INFO *)lh_delete(amih,&tmp)) != NULL)
{ {
APP_INFO *next=ret->next; APP_INFO *next=ret->next;
@ -311,10 +376,10 @@ static APP_INFO *pop_info(void)
lh_insert(amih,(char *)next); lh_insert(amih,(char *)next);
} }
#ifdef LEVITTE_DEBUG_MEM #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", fprintf(stderr, "pop_info(): deleted info has other thread ID (%lu/%p) than the current thread (%lu/%p)!!!!\n",
ret->thread, tmp.thread); ret->thread_id, ret->thread_idptr, tmp.thread_id, tmp.thread_idptr);
abort(); abort();
} }
#endif #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->file=file;
ami->line=line; ami->line=line;
ami->info=info; 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) if ((amim=(APP_INFO *)lh_insert(amih,(char *)ami)) != NULL)
{ {
#ifdef LEVITTE_DEBUG_MEM #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", fprintf(stderr, "CRYPTO_push_info(): previous info has other thread ID (%lu/%p) than the current thread (%lu/%p)!!!!\n",
amim->thread, ami->thread); amim->thread_id, amim->thread_idptr, ami->thread_id, ami->thread_idptr);
abort(); abort();
} }
#endif #endif
@ -453,9 +519,15 @@ void CRYPTO_dbg_malloc(void *addr, int num, const char *file, int line,
m->line=line; m->line=line;
m->num=num; m->num=num;
if (options & V_CRYPTO_MDEBUG_THREAD) if (options & V_CRYPTO_MDEBUG_THREAD)
m->thread=CRYPTO_thread_id(); {
m->thread_id=CRYPTO_thread_id();
m->thread_idptr=CRYPTO_thread_idptr();
}
else else
m->thread=0; {
m->thread_id=0;
m->thread_idptr=NULL;
}
if (order == break_order_num) 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++; m->order=order++;
#ifdef LEVITTE_DEBUG_MEM #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, m->order,
(before_p & 128) ? '*' : '+', (before_p & 128) ? '*' : '+',
m->addr, m->num); m->addr, m->num);
@ -474,7 +546,8 @@ void CRYPTO_dbg_malloc(void *addr, int num, const char *file, int line,
else else
m->time=0; m->time=0;
tmp.thread=CRYPTO_thread_id(); tmp.thread_id=CRYPTO_thread_id();
tmp.thread_idptr=CRYPTO_thread_idptr();
m->app_info=NULL; m->app_info=NULL;
if (amih != NULL if (amih != NULL
&& (amim=(APP_INFO *)lh_retrieve(amih,(char *)&tmp)) != 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) if (mp != NULL)
{ {
#ifdef LEVITTE_DEBUG_MEM #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); mp->order, mp->addr, mp->num);
#endif #endif
if (mp->app_info != NULL) if (mp->app_info != NULL)
@ -570,7 +643,7 @@ void CRYPTO_dbg_realloc(void *addr1, void *addr2, int num,
if (mp != NULL) if (mp != NULL)
{ {
#ifdef LEVITTE_DEBUG_MEM #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->order,
mp->addr, mp->num, mp->addr, mp->num,
addr2, num); addr2, num);
@ -604,6 +677,7 @@ static void print_leak(const MEM *m, MEM_LEAK *l)
int ami_cnt; int ami_cnt;
struct tm *lcl = NULL; struct tm *lcl = NULL;
unsigned long ti; unsigned long ti;
void *tip;
#define BUF_REMAIN (sizeof buf - (size_t)(bufp - buf)) #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) 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); bufp += strlen(bufp);
} }
@ -642,7 +716,8 @@ static void print_leak(const MEM *m, MEM_LEAK *l)
ami_cnt=0; ami_cnt=0;
if (!amip) if (!amip)
return; return;
ti=amip->thread; ti=amip->thread_id;
tip=amip->thread_idptr;
do do
{ {
@ -652,8 +727,8 @@ static void print_leak(const MEM *m, MEM_LEAK *l)
ami_cnt++; ami_cnt++;
memset(buf,'>',ami_cnt); memset(buf,'>',ami_cnt);
BIO_snprintf(buf + ami_cnt, sizeof buf - ami_cnt, BIO_snprintf(buf + ami_cnt, sizeof buf - ami_cnt,
" thread=%lu, file=%s, line=%d, info=\"", " thread=%lu/%p, file=%s, line=%d, info=\"",
amip->thread, amip->file, amip->line); amip->thread_id, amip->thread_idptr, amip->file, amip->line);
buf_len=strlen(buf); buf_len=strlen(buf);
info_len=strlen(amip->info); info_len=strlen(amip->info);
if (128 - buf_len - 3 < info_len) if (128 - buf_len - 3 < info_len)
@ -673,7 +748,7 @@ static void print_leak(const MEM *m, MEM_LEAK *l)
amip = amip->next; amip = amip->next;
} }
while(amip && amip->thread == ti); while(amip && amip->thread_id == ti && amip->thread_idptr == tip);
#ifdef LEVITTE_DEBUG_MEM #ifdef LEVITTE_DEBUG_MEM
if (amip) if (amip)

View File

@ -145,7 +145,8 @@ static unsigned int crypto_lock_rand = 0; /* may be set only when a thread
* holds CRYPTO_LOCK_RAND * holds CRYPTO_LOCK_RAND
* (to prevent double locking) */ * (to prevent double locking) */
/* access to lockin_thread is synchronized by CRYPTO_LOCK_RAND2 */ /* 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 #ifdef PREDICT
@ -214,7 +215,7 @@ static void ssleay_rand_add(const void *buf, int num, double add)
if (crypto_lock_rand) if (crypto_lock_rand)
{ {
CRYPTO_r_lock(CRYPTO_LOCK_RAND2); 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); CRYPTO_r_unlock(CRYPTO_LOCK_RAND2);
} }
else 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 */ /* prevent ssleay_rand_bytes() from trying to obtain the lock again */
CRYPTO_w_lock(CRYPTO_LOCK_RAND2); 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_w_unlock(CRYPTO_LOCK_RAND2);
crypto_lock_rand = 1; crypto_lock_rand = 1;
@ -535,7 +537,7 @@ static int ssleay_rand_status(void)
if (crypto_lock_rand) if (crypto_lock_rand)
{ {
CRYPTO_r_lock(CRYPTO_LOCK_RAND2); 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); CRYPTO_r_unlock(CRYPTO_LOCK_RAND2);
} }
else else
@ -547,7 +549,8 @@ static int ssleay_rand_status(void)
/* prevent ssleay_rand_bytes() from trying to obtain the lock again */ /* prevent ssleay_rand_bytes() from trying to obtain the lock again */
CRYPTO_w_lock(CRYPTO_LOCK_RAND2); 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_w_unlock(CRYPTO_LOCK_RAND2);
crypto_lock_rand = 1; crypto_lock_rand = 1;
} }

View File

@ -259,7 +259,7 @@ static BN_BLINDING *rsa_get_blinding(RSA *rsa, int *local, BN_CTX *ctx)
if (ret == NULL) if (ret == NULL)
goto err; 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! */ /* rsa->blinding is ours! */

View File

@ -408,6 +408,7 @@ BN_BLINDING *RSA_setup_blinding(RSA *rsa, BN_CTX *in_ctx)
goto err; goto err;
} }
BN_BLINDING_set_thread_id(ret, CRYPTO_thread_id()); BN_BLINDING_set_thread_id(ret, CRYPTO_thread_id());
BN_BLINDING_set_thread_idptr(ret, CRYPTO_thread_idptr());
err: err:
BN_CTX_end(ctx); BN_CTX_end(ctx);
if (in_ctx == NULL) if (in_ctx == NULL)

View File

@ -2,7 +2,8 @@
=head1 NAME =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_create_callback, CRYPTO_set_dynlock_lock_callback,
CRYPTO_set_dynlock_destroy_callback, CRYPTO_get_new_dynlockid, CRYPTO_set_dynlock_destroy_callback, CRYPTO_get_new_dynlockid,
CRYPTO_destroy_dynlockid, CRYPTO_lock - OpenSSL thread support 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_id_callback(unsigned long (*id_function)(void));
void CRYPTO_set_idptr_callback(void *(*idptr_function)(void));
int CRYPTO_num_locks(void); int CRYPTO_num_locks(void);
@ -65,10 +68,17 @@ B<CRYPTO_LOCK>, and releases it otherwise.
B<file> and B<line> are the file number of the function setting the B<file> and B<line> are the file number of the function setting the
lock. They can be useful for debugging. lock. They can be useful for debugging.
id_function(void) is a function that returns a thread ID, for example id_function(void) is a function that returns a numerical thread ID,
pthread_self() if it returns an integer (see NOTES below). It isn't for example pthread_self() if it returns an integer (see NOTES below).
needed on Windows nor on platforms where getpid() returns a different By OpenSSL's defaults, this is not needed on Windows nor on platforms
ID for each thread (see NOTES below). 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 Additionally, OpenSSL supports dynamic locks, and sometimes, some parts
of OpenSSL need it for better performance. To enable this, the following 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. all threads.
There is still the issue of platforms where pthread_self() returns There is still the issue of platforms where pthread_self() returns
something other than an integer. This is a bit unusual, and this something other than an integer. It is for cases like this that
manual has no cookbook solution for that case. 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 =head1 EXAMPLES
@ -168,6 +180,8 @@ available in all versions of SSLeay and OpenSSL.
CRYPTO_num_locks() was added in OpenSSL 0.9.4. CRYPTO_num_locks() was added in OpenSSL 0.9.4.
All functions dealing with dynamic locks were added in OpenSSL 0.9.5b-dev. 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 =head1 SEE ALSO
L<crypto(3)|crypto(3)> L<crypto(3)|crypto(3)>

View File

@ -3761,3 +3761,8 @@ TS_TST_INFO_get_ext_by_critical 4153 EXIST::FUNCTION:
EVP_PKEY_CTX_new_id 4154 EXIST::FUNCTION: EVP_PKEY_CTX_new_id 4154 EXIST::FUNCTION:
TS_REQ_get_ext_by_OBJ 4155 EXIST::FUNCTION: TS_REQ_get_ext_by_OBJ 4155 EXIST::FUNCTION:
TS_CONF_set_signer_cert 4156 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: