mirror of https://github.com/openssl/openssl.git
				
				
				
			Locking issues.
This commit is contained in:
		
							parent
							
								
									c08523d862
								
							
						
					
					
						commit
						3ac82faae5
					
				
							
								
								
									
										17
									
								
								CHANGES
								
								
								
								
							
							
						
						
									
										17
									
								
								CHANGES
								
								
								
								
							|  | @ -3,6 +3,23 @@ | |||
| 
 | ||||
|  Changes between 0.9.6 and 0.9.7  [xx XXX 2000] | ||||
| 
 | ||||
|   *) Add functionality to apps/openssl.c for detecting locking | ||||
|      problems: As the program is single-threaded, all we have | ||||
|      to do is register a locking callback using an array for | ||||
|      storing which locks are currently held by the program. | ||||
| 
 | ||||
|      Fix a deadlock in CRYPTO_mem_leaks() that was detected in | ||||
|      apps/openssl.c. | ||||
|      [Bodo Moeller] | ||||
| 
 | ||||
|   *) Use a lock around the call to CRYPTO_get_ex_new_index() in | ||||
|      SSL_get_ex_data_X509_STORE_idx(), which is used in | ||||
|      ssl_verify_cert_chain() and thus can be called at any time | ||||
|      during TLS/SSL handshakes so that thread-safety is essential. | ||||
|      Unfortunately, the ex_data design is not at all suited | ||||
|      for multi-threaded use, so it probably should be abolished. | ||||
|      [Bodo Moeller] | ||||
| 
 | ||||
|   *) Added Broadcom "ubsec" ENGINE to OpenSSL. | ||||
|      [Broadcom, tweaked and integrated by Geoff Thorpe] | ||||
| 
 | ||||
|  |  | |||
							
								
								
									
										126
									
								
								apps/openssl.c
								
								
								
								
							
							
						
						
									
										126
									
								
								apps/openssl.c
								
								
								
								
							|  | @ -55,6 +55,60 @@ | |||
|  * copied and put under another distribution licence | ||||
|  * [including the GNU Public Licence.] | ||||
|  */ | ||||
| /* ====================================================================
 | ||||
|  * Copyright (c) 1998-2000 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 <string.h> | ||||
|  | @ -92,6 +146,71 @@ char *default_config_file=NULL; | |||
| BIO *bio_err=NULL; | ||||
| #endif | ||||
| 
 | ||||
| 
 | ||||
| static void lock_dbg_cb(int mode, int type, const char *file, int line) | ||||
| 	{ | ||||
| 	static int modes[CRYPTO_NUM_LOCKS]; /* = {0, 0, ... } */ | ||||
| 	const char *errstr = NULL; | ||||
| 	int rw; | ||||
| 	 | ||||
| 	rw = mode & (CRYPTO_READ|CRYPTO_WRITE); | ||||
| 	if (!((rw == CRYPTO_READ) || (rw == CRYPTO_WRITE))) | ||||
| 		{ | ||||
| 		errstr = "invalid mode"; | ||||
| 		goto err; | ||||
| 		} | ||||
| 
 | ||||
| 	if (type < 0 || type > CRYPTO_NUM_LOCKS) | ||||
| 		{ | ||||
| 		errstr = "type out of bounds"; | ||||
| 		goto err; | ||||
| 		} | ||||
| 
 | ||||
| 	if (mode & CRYPTO_LOCK) | ||||
| 		{ | ||||
| 		if (modes[type]) | ||||
| 			{ | ||||
| 			errstr = "already locked"; | ||||
| 			/* must not happen in a single-threaded program
 | ||||
| 			 * (would deadlock) */ | ||||
| 			goto err; | ||||
| 			} | ||||
| 
 | ||||
| 		modes[type] = rw; | ||||
| 		} | ||||
| 	else if (mode & CRYPTO_UNLOCK) | ||||
| 		{ | ||||
| 		if (!modes[type]) | ||||
| 			{ | ||||
| 			errstr = "not locked"; | ||||
| 			goto err; | ||||
| 			} | ||||
| 		 | ||||
| 		if (modes[type] != rw) | ||||
| 			{ | ||||
| 			errstr = (rw == CRYPTO_READ) ? | ||||
| 				"CRYPTO_r_unlock on write lock" : | ||||
| 				"CRYPTO_w_unlock on read lock"; | ||||
| 			} | ||||
| 
 | ||||
| 		modes[type] = 0; | ||||
| 		} | ||||
| 	else | ||||
| 		{ | ||||
| 		errstr = "invalid mode"; | ||||
| 		goto err; | ||||
| 		} | ||||
| 
 | ||||
|  err: | ||||
| 	if (errstr) | ||||
| 		{ | ||||
| 		/* we cannot use bio_err here */ | ||||
| 		fprintf(stderr, "openssl (lock_dbg_cb): %s (mode=%d, type=%d) at %s:%d\n", | ||||
| 			errstr, mode, type, file, line); | ||||
| 		} | ||||
| 	} | ||||
| 
 | ||||
| 
 | ||||
| int main(int Argc, char *Argv[]) | ||||
| 	{ | ||||
| 	ARGS arg; | ||||
|  | @ -112,6 +231,13 @@ int main(int Argc, char *Argv[]) | |||
| 		CRYPTO_malloc_debug_init(); | ||||
| 	CRYPTO_mem_ctrl(CRYPTO_MEM_CHECK_ON); | ||||
| 
 | ||||
| #if 0 | ||||
| 	if (getenv("OPENSSL_DEBUG_LOCKING") != NULL) | ||||
| #endif | ||||
| 		{ | ||||
| 		CRYPTO_set_locking_callback(lock_dbg_cb); | ||||
| 		} | ||||
| 
 | ||||
| 	apps_startup(); | ||||
| 
 | ||||
| 	if (bio_err == NULL) | ||||
|  |  | |||
|  | @ -133,11 +133,11 @@ int CRYPTO_get_new_lockid(char *name) | |||
| 	char *str; | ||||
| 	int i; | ||||
| 
 | ||||
| #if defined(WIN32) || defined(WIN16) | ||||
| 	/* A hack to make Visual C++ 5.0 work correctly when linking as
 | ||||
| 	 * a DLL using /MT. Without this, the application cannot use | ||||
| 	 * and floating point printf's. | ||||
| 	 * It also seems to be needed for Visual C 1.5 (win16) */ | ||||
| #if defined(WIN32) || defined(WIN16) | ||||
| 	SSLeay_MSVC5_hack=(double)name[0]*(double)name[1]; | ||||
| #endif | ||||
| 
 | ||||
|  |  | |||
|  | @ -1,4 +1,17 @@ | |||
| /* crypto/ex_data.c */ | ||||
| 
 | ||||
| /*
 | ||||
|  * This is not thread-safe, nor can it be changed to become thread-safe | ||||
|  * without changing various function prototypes and using a lot of locking. | ||||
|  * Luckily, it's not really used anywhere except in ssl_verify_cert_chain | ||||
|  * via SSL_get_ex_data_X509_STORE_CTX_idx (ssl/ssl_cert.c), where | ||||
|  * new_func, dup_func, and free_func all are 0. | ||||
|  * | ||||
|  * Any multi-threaded application crazy enough to use ex_data for its own | ||||
|  * purposes had better make sure that SSL_get_ex_data_X509_STORE_CTX_idx | ||||
|  * is called once before multiple threads are created. | ||||
|  */ | ||||
| 
 | ||||
| /* Copyright (C) 1995-1998 Eric Young (eay@cryptsoft.com)
 | ||||
|  * All rights reserved. | ||||
|  * | ||||
|  |  | |||
|  | @ -678,7 +678,15 @@ void CRYPTO_mem_leaks(BIO *b) | |||
| 		 * void_fn_to_char kludge in CRYPTO_mem_leaks_cb. | ||||
| 		 * Otherwise the code police will come and get us.) | ||||
| 		 */ | ||||
| 		int old_mh_mode; | ||||
| 
 | ||||
| 		CRYPTO_w_lock(CRYPTO_LOCK_MALLOC); | ||||
| 
 | ||||
| 		/* avoid deadlock when lh_free() uses CRYPTO_dbg_free(),
 | ||||
| 		 * which uses CRYPTO_is_mem_check_on */ | ||||
| 		old_mh_mode = mh_mode; | ||||
| 		mh_mode = CRYPTO_MEM_CHECK_OFF; | ||||
| 
 | ||||
| 		if (mh != NULL) | ||||
| 			{ | ||||
| 			lh_free(mh); | ||||
|  | @ -692,6 +700,8 @@ void CRYPTO_mem_leaks(BIO *b) | |||
| 				amih = NULL; | ||||
| 				} | ||||
| 			} | ||||
| 
 | ||||
| 		mh_mode = old_mh_mode; | ||||
| 		CRYPTO_w_unlock(CRYPTO_LOCK_MALLOC); | ||||
| 		} | ||||
| 	MemCheck_on(); /* releases CRYPTO_LOCK_MALLOC2 */ | ||||
|  |  | |||
|  | @ -80,10 +80,7 @@ const char *X509_version="X.509" OPENSSL_VERSION_PTEXT; | |||
| 
 | ||||
| static STACK_OF(CRYPTO_EX_DATA_FUNCS) *x509_store_ctx_method=NULL; | ||||
| static int x509_store_ctx_num=0; | ||||
| #if 0 | ||||
| static int x509_store_num=1; | ||||
| static STACK *x509_store_method=NULL; | ||||
| #endif | ||||
| 
 | ||||
| 
 | ||||
| static int null_callback(int ok, X509_STORE_CTX *e) | ||||
| 	{ | ||||
|  | @ -703,6 +700,11 @@ int X509_get_pubkey_parameters(EVP_PKEY *pkey, STACK_OF(X509) *chain) | |||
| int X509_STORE_CTX_get_ex_new_index(long argl, void *argp, CRYPTO_EX_new *new_func, | ||||
| 	     CRYPTO_EX_dup *dup_func, CRYPTO_EX_free *free_func) | ||||
| 	{ | ||||
| 	/* This function is (usually) called only once, by
 | ||||
| 	 * SSL_get_ex_data_X509_STORE_CTX_idx (ssl/ssl_cert.c). | ||||
| 	 * That function uses locking, so we don't (usually) | ||||
| 	 * have to worry about locking here. For the whole cruel | ||||
| 	 * truth, see crypto/ex_data.c */ | ||||
| 	x509_store_ctx_num++; | ||||
| 	return CRYPTO_get_ex_new_index(x509_store_ctx_num-1, | ||||
| 		&x509_store_ctx_method, | ||||
|  |  | |||
|  | @ -129,15 +129,23 @@ | |||
| 
 | ||||
| int SSL_get_ex_data_X509_STORE_CTX_idx(void) | ||||
| 	{ | ||||
| 	static int ssl_x509_store_ctx_idx= -1; | ||||
| 	static volatile int ssl_x509_store_ctx_idx= -1; | ||||
| 
 | ||||
| 	if (ssl_x509_store_ctx_idx < 0) | ||||
| 		{ | ||||
| 		/* any write lock will do; usually this branch
 | ||||
| 		 * will only be taken once anyway */ | ||||
| 		CRYPTO_w_lock(CRYPTO_LOCK_SSL_CTX); | ||||
| 		 | ||||
| 	/* FIXME: should do locking */ | ||||
| 		if (ssl_x509_store_ctx_idx < 0) | ||||
| 			{ | ||||
| 			ssl_x509_store_ctx_idx=X509_STORE_CTX_get_ex_new_index( | ||||
| 				0,"SSL for verify callback",NULL,NULL,NULL); | ||||
| 			} | ||||
| 	return(ssl_x509_store_ctx_idx); | ||||
| 		 | ||||
| 		CRYPTO_w_unlock(CRYPTO_LOCK_SSL_CTX); | ||||
| 		} | ||||
| 	return ssl_x509_store_ctx_idx; | ||||
| 	} | ||||
| 
 | ||||
| CERT *ssl_cert_new(void) | ||||
|  | @ -452,13 +460,15 @@ int ssl_verify_cert_chain(SSL *s,STACK_OF(X509) *sk) | |||
| 	if (SSL_get_verify_depth(s) >= 0) | ||||
| 		X509_STORE_CTX_set_depth(&ctx, SSL_get_verify_depth(s)); | ||||
| 	X509_STORE_CTX_set_ex_data(&ctx,SSL_get_ex_data_X509_STORE_CTX_idx(),s); | ||||
| 
 | ||||
| 	/* We need to set the verify purpose. The purpose can be determined by
 | ||||
| 	 * the context: if its a server it will verify SSL client certificates | ||||
| 	 * or vice versa. | ||||
| 	 */ | ||||
| 
 | ||||
| 	if(s->server) i = X509_PURPOSE_SSL_CLIENT; | ||||
| 	else i = X509_PURPOSE_SSL_SERVER; | ||||
| 	if (s->server) | ||||
| 		i = X509_PURPOSE_SSL_CLIENT; | ||||
| 	else | ||||
| 		i = X509_PURPOSE_SSL_SERVER; | ||||
| 
 | ||||
| 	X509_STORE_CTX_purpose_inherit(&ctx, i, s->purpose, s->trust); | ||||
| 
 | ||||
|  |  | |||
							
								
								
									
										118
									
								
								ssl/ssltest.c
								
								
								
								
							
							
						
						
									
										118
									
								
								ssl/ssltest.c
								
								
								
								
							|  | @ -55,6 +55,59 @@ | |||
|  * copied and put under another distribution licence | ||||
|  * [including the GNU Public Licence.] | ||||
|  */ | ||||
| /* ====================================================================
 | ||||
|  * Copyright (c) 1998-2000 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 <assert.h> | ||||
| #include <errno.h> | ||||
|  | @ -202,6 +255,69 @@ static void print_details(SSL *c_ssl, const char *prefix) | |||
| 	BIO_printf(bio_stdout,"\n"); | ||||
| 	} | ||||
| 
 | ||||
| static void lock_dbg_cb(int mode, int type, const char *file, int line) | ||||
| 	{ | ||||
| 	static int modes[CRYPTO_NUM_LOCKS]; /* = {0, 0, ... } */ | ||||
| 	const char *errstr = NULL; | ||||
| 	int rw; | ||||
| 	 | ||||
| 	rw = mode & (CRYPTO_READ|CRYPTO_WRITE); | ||||
| 	if (!((rw == CRYPTO_READ) || (rw == CRYPTO_WRITE))) | ||||
| 		{ | ||||
| 		errstr = "invalid mode"; | ||||
| 		goto err; | ||||
| 		} | ||||
| 
 | ||||
| 	if (type < 0 || type > CRYPTO_NUM_LOCKS) | ||||
| 		{ | ||||
| 		errstr = "type out of bounds"; | ||||
| 		goto err; | ||||
| 		} | ||||
| 
 | ||||
| 	if (mode & CRYPTO_LOCK) | ||||
| 		{ | ||||
| 		if (modes[type]) | ||||
| 			{ | ||||
| 			errstr = "already locked"; | ||||
| 			/* must not happen in a single-threaded program
 | ||||
| 			 * (would deadlock) */ | ||||
| 			goto err; | ||||
| 			} | ||||
| 
 | ||||
| 		modes[type] = rw; | ||||
| 		} | ||||
| 	else if (mode & CRYPTO_UNLOCK) | ||||
| 		{ | ||||
| 		if (!modes[type]) | ||||
| 			{ | ||||
| 			errstr = "not locked"; | ||||
| 			goto err; | ||||
| 			} | ||||
| 		 | ||||
| 		if (modes[type] != rw) | ||||
| 			{ | ||||
| 			errstr = (rw == CRYPTO_READ) ? | ||||
| 				"CRYPTO_r_unlock on write lock" : | ||||
| 				"CRYPTO_w_unlock on read lock"; | ||||
| 			} | ||||
| 
 | ||||
| 		modes[type] = 0; | ||||
| 		} | ||||
| 	else | ||||
| 		{ | ||||
| 		errstr = "invalid mode"; | ||||
| 		goto err; | ||||
| 		} | ||||
| 
 | ||||
|  err: | ||||
| 	if (errstr) | ||||
| 		{ | ||||
| 		/* we cannot use bio_err here */ | ||||
| 		fprintf(stderr, "openssl (lock_dbg_cb): %s (mode=%d, type=%d) at %s:%d\n", | ||||
| 			errstr, mode, type, file, line); | ||||
| 		} | ||||
| 	} | ||||
| 
 | ||||
| int main(int argc, char *argv[]) | ||||
| 	{ | ||||
| 	char *CApath=NULL,*CAfile=NULL; | ||||
|  | @ -235,6 +351,8 @@ int main(int argc, char *argv[]) | |||
| 	debug = 0; | ||||
| 	cipher = 0; | ||||
| 	 | ||||
| 	CRYPTO_set_locking_callback(lock_dbg_cb); | ||||
| 
 | ||||
| 	CRYPTO_mem_ctrl(CRYPTO_MEM_CHECK_ON); | ||||
| 
 | ||||
| 	RAND_seed(rnd_seed, sizeof rnd_seed); | ||||
|  |  | |||
		Loading…
	
		Reference in New Issue