summaryrefslogtreecommitdiff
path: root/src/lib/libcrypto/err
diff options
context:
space:
mode:
Diffstat (limited to 'src/lib/libcrypto/err')
-rw-r--r--src/lib/libcrypto/err/err.c42
-rw-r--r--src/lib/libcrypto/err/err.h1
2 files changed, 42 insertions, 1 deletions
diff --git a/src/lib/libcrypto/err/err.c b/src/lib/libcrypto/err/err.c
index a4f4a260af..6ab119c1ef 100644
--- a/src/lib/libcrypto/err/err.c
+++ b/src/lib/libcrypto/err/err.c
@@ -225,6 +225,7 @@ struct st_ERR_FNS
225 ERR_STRING_DATA *(*cb_err_del_item)(ERR_STRING_DATA *); 225 ERR_STRING_DATA *(*cb_err_del_item)(ERR_STRING_DATA *);
226 /* Works on the "thread_hash" error-state table */ 226 /* Works on the "thread_hash" error-state table */
227 LHASH *(*cb_thread_get)(int create); 227 LHASH *(*cb_thread_get)(int create);
228 void (*cb_thread_release)(LHASH **hash);
228 ERR_STATE *(*cb_thread_get_item)(const ERR_STATE *); 229 ERR_STATE *(*cb_thread_get_item)(const ERR_STATE *);
229 ERR_STATE *(*cb_thread_set_item)(ERR_STATE *); 230 ERR_STATE *(*cb_thread_set_item)(ERR_STATE *);
230 void (*cb_thread_del_item)(const ERR_STATE *); 231 void (*cb_thread_del_item)(const ERR_STATE *);
@@ -239,6 +240,7 @@ static ERR_STRING_DATA *int_err_get_item(const ERR_STRING_DATA *);
239static ERR_STRING_DATA *int_err_set_item(ERR_STRING_DATA *); 240static ERR_STRING_DATA *int_err_set_item(ERR_STRING_DATA *);
240static ERR_STRING_DATA *int_err_del_item(ERR_STRING_DATA *); 241static ERR_STRING_DATA *int_err_del_item(ERR_STRING_DATA *);
241static LHASH *int_thread_get(int create); 242static LHASH *int_thread_get(int create);
243static void int_thread_release(LHASH **hash);
242static ERR_STATE *int_thread_get_item(const ERR_STATE *); 244static ERR_STATE *int_thread_get_item(const ERR_STATE *);
243static ERR_STATE *int_thread_set_item(ERR_STATE *); 245static ERR_STATE *int_thread_set_item(ERR_STATE *);
244static void int_thread_del_item(const ERR_STATE *); 246static void int_thread_del_item(const ERR_STATE *);
@@ -252,6 +254,7 @@ static const ERR_FNS err_defaults =
252 int_err_set_item, 254 int_err_set_item,
253 int_err_del_item, 255 int_err_del_item,
254 int_thread_get, 256 int_thread_get,
257 int_thread_release,
255 int_thread_get_item, 258 int_thread_get_item,
256 int_thread_set_item, 259 int_thread_set_item,
257 int_thread_del_item, 260 int_thread_del_item,
@@ -271,6 +274,7 @@ static const ERR_FNS *err_fns = NULL;
271 * and state in the loading application. */ 274 * and state in the loading application. */
272static LHASH *int_error_hash = NULL; 275static LHASH *int_error_hash = NULL;
273static LHASH *int_thread_hash = NULL; 276static LHASH *int_thread_hash = NULL;
277static int int_thread_hash_references = 0;
274static int int_err_library_number= ERR_LIB_USER; 278static int int_err_library_number= ERR_LIB_USER;
275 279
276/* Internal function that checks whether "err_fns" is set and if not, sets it to 280/* 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)
417 CRYPTO_pop_info(); 421 CRYPTO_pop_info();
418 } 422 }
419 if (int_thread_hash) 423 if (int_thread_hash)
424 {
425 int_thread_hash_references++;
420 ret = int_thread_hash; 426 ret = int_thread_hash;
427 }
421 CRYPTO_w_unlock(CRYPTO_LOCK_ERR); 428 CRYPTO_w_unlock(CRYPTO_LOCK_ERR);
422 return ret; 429 return ret;
423 } 430 }
424 431
432static void int_thread_release(LHASH **hash)
433 {
434 int i;
435
436 if (hash == NULL || *hash == NULL)
437 return;
438
439 i = CRYPTO_add(&int_thread_hash_references, -1, CRYPTO_LOCK_ERR);
440
441#ifdef REF_PRINT
442 fprintf(stderr,"%4d:%s\n",int_thread_hash_references,"ERR");
443#endif
444 if (i > 0) return;
445#ifdef REF_CHECK
446 if (i < 0)
447 {
448 fprintf(stderr,"int_thread_release, bad reference count\n");
449 abort(); /* ok */
450 }
451#endif
452 *hash = NULL;
453 }
454
425static ERR_STATE *int_thread_get_item(const ERR_STATE *d) 455static ERR_STATE *int_thread_get_item(const ERR_STATE *d)
426 { 456 {
427 ERR_STATE *p; 457 ERR_STATE *p;
@@ -436,6 +466,7 @@ static ERR_STATE *int_thread_get_item(const ERR_STATE *d)
436 p = (ERR_STATE *)lh_retrieve(hash, d); 466 p = (ERR_STATE *)lh_retrieve(hash, d);
437 CRYPTO_r_unlock(CRYPTO_LOCK_ERR); 467 CRYPTO_r_unlock(CRYPTO_LOCK_ERR);
438 468
469 ERRFN(thread_release)(&hash);
439 return p; 470 return p;
440 } 471 }
441 472
@@ -453,6 +484,7 @@ static ERR_STATE *int_thread_set_item(ERR_STATE *d)
453 p = (ERR_STATE *)lh_insert(hash, d); 484 p = (ERR_STATE *)lh_insert(hash, d);
454 CRYPTO_w_unlock(CRYPTO_LOCK_ERR); 485 CRYPTO_w_unlock(CRYPTO_LOCK_ERR);
455 486
487 ERRFN(thread_release)(&hash);
456 return p; 488 return p;
457 } 489 }
458 490
@@ -469,13 +501,15 @@ static void int_thread_del_item(const ERR_STATE *d)
469 CRYPTO_w_lock(CRYPTO_LOCK_ERR); 501 CRYPTO_w_lock(CRYPTO_LOCK_ERR);
470 p = (ERR_STATE *)lh_delete(hash, d); 502 p = (ERR_STATE *)lh_delete(hash, d);
471 /* make sure we don't leak memory */ 503 /* make sure we don't leak memory */
472 if (int_thread_hash && (lh_num_items(int_thread_hash) == 0)) 504 if (int_thread_hash_references == 1
505 && int_thread_hash && (lh_num_items(int_thread_hash) == 0))
473 { 506 {
474 lh_free(int_thread_hash); 507 lh_free(int_thread_hash);
475 int_thread_hash = NULL; 508 int_thread_hash = NULL;
476 } 509 }
477 CRYPTO_w_unlock(CRYPTO_LOCK_ERR); 510 CRYPTO_w_unlock(CRYPTO_LOCK_ERR);
478 511
512 ERRFN(thread_release)(&hash);
479 if (p) 513 if (p)
480 ERR_STATE_free(p); 514 ERR_STATE_free(p);
481 } 515 }
@@ -845,6 +879,12 @@ LHASH *ERR_get_err_state_table(void)
845 return ERRFN(thread_get)(0); 879 return ERRFN(thread_get)(0);
846 } 880 }
847 881
882void ERR_release_err_state_table(LHASH **hash)
883 {
884 err_fns_check();
885 ERRFN(thread_release)(hash);
886 }
887
848const char *ERR_lib_error_string(unsigned long e) 888const char *ERR_lib_error_string(unsigned long e)
849 { 889 {
850 ERR_STRING_DATA d,*p; 890 ERR_STRING_DATA d,*p;
diff --git a/src/lib/libcrypto/err/err.h b/src/lib/libcrypto/err/err.h
index 988ef81aa0..8faa3a7b4f 100644
--- a/src/lib/libcrypto/err/err.h
+++ b/src/lib/libcrypto/err/err.h
@@ -278,6 +278,7 @@ ERR_STATE *ERR_get_state(void);
278#ifndef OPENSSL_NO_LHASH 278#ifndef OPENSSL_NO_LHASH
279LHASH *ERR_get_string_table(void); 279LHASH *ERR_get_string_table(void);
280LHASH *ERR_get_err_state_table(void); 280LHASH *ERR_get_err_state_table(void);
281void ERR_release_err_state_table(LHASH **hash);
281#endif 282#endif
282 283
283int ERR_get_next_error_library(void); 284int ERR_get_next_error_library(void);