Commit 732d1bf4 authored by Richard Levitte's avatar Richard Levitte
Browse files

Add reference counting around the thread state hash table.

Unfortunately, this means that the dynamic ENGINE version just went up, and
isn't backward compatible.
PR: 678
parent 88fd7424
Loading
Loading
Loading
Loading
+2 −2
Original line number Diff line number Diff line
@@ -538,10 +538,10 @@ void ENGINE_add_conf_module(void);
/**************************/

/* Binary/behaviour compatibility levels */
#define OSSL_DYNAMIC_VERSION		(unsigned long)0x00010100
#define OSSL_DYNAMIC_VERSION		(unsigned long)0x00010200
/* Binary versions older than this are too old for us (whether we're a loader or
 * a loadee) */
#define OSSL_DYNAMIC_OLDEST		(unsigned long)0x00010100
#define OSSL_DYNAMIC_OLDEST		(unsigned long)0x00010200

/* When compiling an ENGINE entirely as an external shared library, loadable by
 * the "dynamic" ENGINE, these types are needed. The 'dynamic_fns' structure
+41 −1
Original line number Diff line number Diff line
@@ -225,6 +225,7 @@ struct st_ERR_FNS
	ERR_STRING_DATA *(*cb_err_del_item)(ERR_STRING_DATA *);
	/* Works on the "thread_hash" error-state table */
	LHASH *(*cb_thread_get)(int create);
	void (*cb_thread_release)(LHASH **hash);
	ERR_STATE *(*cb_thread_get_item)(const ERR_STATE *);
	ERR_STATE *(*cb_thread_set_item)(ERR_STATE *);
	void (*cb_thread_del_item)(const ERR_STATE *);
@@ -239,6 +240,7 @@ static ERR_STRING_DATA *int_err_get_item(const ERR_STRING_DATA *);
static ERR_STRING_DATA *int_err_set_item(ERR_STRING_DATA *);
static ERR_STRING_DATA *int_err_del_item(ERR_STRING_DATA *);
static LHASH *int_thread_get(int create);
static void int_thread_release(LHASH **hash);
static ERR_STATE *int_thread_get_item(const ERR_STATE *);
static ERR_STATE *int_thread_set_item(ERR_STATE *);
static void int_thread_del_item(const ERR_STATE *);
@@ -252,6 +254,7 @@ static const ERR_FNS err_defaults =
	int_err_set_item,
	int_err_del_item,
	int_thread_get,
	int_thread_release,
	int_thread_get_item,
	int_thread_set_item,
	int_thread_del_item,
@@ -271,6 +274,7 @@ static const ERR_FNS *err_fns = NULL;
 * and state in the loading application. */
static LHASH *int_error_hash = NULL;
static LHASH *int_thread_hash = NULL;
static int int_thread_hash_references = 0;
static int int_err_library_number= ERR_LIB_USER;

/* Internal function that checks whether "err_fns" is set and if not, sets it to
@@ -417,11 +421,37 @@ static LHASH *int_thread_get(int create)
		CRYPTO_pop_info();
		}
	if (int_thread_hash)
		{
		int_thread_hash_references++;
		ret = int_thread_hash;
		}
	CRYPTO_w_unlock(CRYPTO_LOCK_ERR);
	return ret;
	}

static void int_thread_release(LHASH **hash)
	{
	int i;

	if (hash == NULL || *hash == NULL)
		return;

	i = CRYPTO_add(&int_thread_hash_references, -1, CRYPTO_LOCK_ERR);

#ifdef REF_PRINT
	fprintf(stderr,"%4d:%s\n",int_thread_hash_references,"ERR");
#endif
	if (i > 0) return;
#ifdef REF_CHECK
	if (i < 0)
		{
		fprintf(stderr,"int_thread_release, bad reference count\n");
		abort(); /* ok */
		}
#endif
	*hash = NULL;
	}

static ERR_STATE *int_thread_get_item(const ERR_STATE *d)
	{
	ERR_STATE *p;
@@ -436,6 +466,7 @@ static ERR_STATE *int_thread_get_item(const ERR_STATE *d)
	p = (ERR_STATE *)lh_retrieve(hash, d);
	CRYPTO_r_unlock(CRYPTO_LOCK_ERR);

	ERRFN(thread_release)(&hash);
	return p;
	}

@@ -453,6 +484,7 @@ static ERR_STATE *int_thread_set_item(ERR_STATE *d)
	p = (ERR_STATE *)lh_insert(hash, d);
	CRYPTO_w_unlock(CRYPTO_LOCK_ERR);

	ERRFN(thread_release)(&hash);
	return p;
	}

@@ -469,13 +501,15 @@ static void int_thread_del_item(const ERR_STATE *d)
	CRYPTO_w_lock(CRYPTO_LOCK_ERR);
	p = (ERR_STATE *)lh_delete(hash, d);
	/* make sure we don't leak memory */
	if (int_thread_hash && (lh_num_items(int_thread_hash) == 0))
	if (int_thread_hash_references == 1
		&& int_thread_hash && (lh_num_items(int_thread_hash) == 0))
		{
		lh_free(int_thread_hash);
		int_thread_hash = NULL;
		}
	CRYPTO_w_unlock(CRYPTO_LOCK_ERR);

	ERRFN(thread_release)(&hash);
	if (p)
		ERR_STATE_free(p);
	}
@@ -845,6 +879,12 @@ LHASH *ERR_get_err_state_table(void)
	return ERRFN(thread_get)(0);
	}

void ERR_release_err_state_table(LHASH **hash)
	{
	err_fns_check();
	ERRFN(thread_release)(hash);
	}

const char *ERR_lib_error_string(unsigned long e)
	{
	ERR_STRING_DATA d,*p;
+1 −0
Original line number Diff line number Diff line
@@ -278,6 +278,7 @@ ERR_STATE *ERR_get_state(void);
#ifndef OPENSSL_NO_LHASH
LHASH *ERR_get_string_table(void);
LHASH *ERR_get_err_state_table(void);
void ERR_release_err_state_table(LHASH **hash);
#endif

int ERR_get_next_error_library(void);