Loading crypto/err/err.c +32 −166 Original line number Diff line number Diff line Loading @@ -112,13 +112,13 @@ #include <stdarg.h> #include <string.h> #include <internal/cryptlib_int.h> #include <internal/threads.h> #include <openssl/lhash.h> #include <openssl/crypto.h> #include <openssl/buffer.h> #include <openssl/bio.h> #include <openssl/err.h> #include <openssl/opensslconf.h> #include "err_lcl.h" static void err_load_strings(int lib, ERR_STRING_DATA *str); Loading Loading @@ -231,25 +231,18 @@ static ERR_STRING_DATA ERR_str_reasons[] = { }; #endif static CRYPTO_ONCE err_init = CRYPTO_ONCE_STATIC_INIT; static CRYPTO_THREAD_LOCAL err_thread_local; /* Predeclarations of the "err_defaults" functions */ static LHASH_OF(ERR_STRING_DATA) *get_hash(int create, int lockit); static ERR_STRING_DATA *int_err_get_item(const ERR_STRING_DATA *); static LHASH_OF(ERR_STATE) *int_thread_get(int create, int lockit); static void int_thread_release(LHASH_OF(ERR_STATE) **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 *); /* * The internal state */ /* This is a struct so that REF_PRINT_COUNT works. */ static struct refcount { int references; } refcount = { 0 }; static LHASH_OF(ERR_STRING_DATA) *int_error_hash = NULL; static LHASH_OF(ERR_STATE) *int_thread_hash = NULL; static int int_err_library_number = ERR_LIB_USER; static unsigned long get_error_values(int inc, int top, const char **file, Loading Loading @@ -303,106 +296,6 @@ static ERR_STRING_DATA *int_err_get_item(const ERR_STRING_DATA *d) return p; } static unsigned long err_state_hash(const ERR_STATE *a) { return CRYPTO_THREADID_hash(&a->tid) * 13; } static int err_state_cmp(const ERR_STATE *a, const ERR_STATE *b) { return CRYPTO_THREADID_cmp(&a->tid, &b->tid); } static LHASH_OF(ERR_STATE) *int_thread_get(int create, int lockit) { LHASH_OF(ERR_STATE) *ret = NULL; if (lockit) CRYPTO_w_lock(CRYPTO_LOCK_ERR); if (!int_thread_hash && create) { int_thread_hash = lh_ERR_STATE_new(err_state_hash, err_state_cmp); } if (int_thread_hash != NULL) { refcount.references++; ret = int_thread_hash; } if (lockit) CRYPTO_w_unlock(CRYPTO_LOCK_ERR); return ret; } static void int_thread_release(LHASH_OF(ERR_STATE) **hash) { int i; if (hash == NULL || *hash == NULL) return; i = CRYPTO_add(&refcount.references, -1, CRYPTO_LOCK_ERR); REF_PRINT_COUNT(&refcount, "ERR"); if (i > 0) return; REF_ASSERT_ISNT(i < 0); *hash = NULL; } static ERR_STATE *int_thread_get_item(const ERR_STATE *d) { ERR_STATE *p = NULL; LHASH_OF(ERR_STATE) *hash; CRYPTO_r_lock(CRYPTO_LOCK_ERR); hash = int_thread_get(0, 0); if (hash) p = lh_ERR_STATE_retrieve(hash, d); CRYPTO_r_unlock(CRYPTO_LOCK_ERR); int_thread_release(&hash); return p; } static ERR_STATE *int_thread_set_item(ERR_STATE *d) { ERR_STATE *p = NULL; LHASH_OF(ERR_STATE) *hash; CRYPTO_w_lock(CRYPTO_LOCK_ERR); hash = int_thread_get(1, 0); if (hash) p = lh_ERR_STATE_insert(hash, d); CRYPTO_w_unlock(CRYPTO_LOCK_ERR); int_thread_release(&hash); return p; } static void int_thread_del_item(const ERR_STATE *d) { ERR_STATE *p = NULL; LHASH_OF(ERR_STATE) *hash; CRYPTO_w_lock(CRYPTO_LOCK_ERR); hash = int_thread_get(0, 0); if (hash) { p = lh_ERR_STATE_delete(hash, d); /* If there are no other references, and we just removed the * last item, delete the int_thread_hash */ if (refcount.references == 1 && int_thread_hash && lh_ERR_STATE_num_items(int_thread_hash) == 0) { refcount.references = 0; lh_ERR_STATE_free(int_thread_hash); int_thread_hash = NULL; hash = NULL; } } CRYPTO_w_unlock(CRYPTO_LOCK_ERR); int_thread_release(&hash); ERR_STATE_free(p); } #ifndef OPENSSL_NO_ERR # define NUM_SYS_STR_REASONS 127 # define LEN_SYS_STR_REASON 32 Loading Loading @@ -768,7 +661,6 @@ void ERR_error_string_n(unsigned long e, char *buf, size_t len) } } /* BAD for multi-threading: uses a local buffer if ret == NULL */ /* * ERR_error_string_n should be used instead for ret != NULL as * ERR_error_string cannot know how large the buffer is Loading @@ -789,16 +681,6 @@ LHASH_OF(ERR_STRING_DATA) *ERR_get_string_table(void) return get_hash(0, 1); } LHASH_OF(ERR_STATE) *ERR_get_err_state_table(void) { return int_thread_get(0, 1); } void ERR_release_err_state_table(LHASH_OF(ERR_STATE) **hash) { int_thread_release(hash); } const char *ERR_lib_error_string(unsigned long e) { ERR_STRING_DATA d, *p; Loading Loading @@ -838,68 +720,52 @@ const char *ERR_reason_error_string(unsigned long e) return ((p == NULL) ? NULL : p->string); } void ERR_remove_thread_state(const CRYPTO_THREADID *id) void ERR_remove_thread_state(void) { ERR_STATE tmp; ERR_STATE *state = ERR_get_state(); if (state == NULL) return; if (id) CRYPTO_THREADID_cpy(&tmp.tid, id); else CRYPTO_THREADID_current(&tmp.tid); /* * thread_del_item automatically destroys the LHASH if the number of * items reaches zero. */ int_thread_del_item(&tmp); CRYPTO_THREAD_set_local(&err_thread_local, NULL); ERR_STATE_free(state); } #if OPENSSL_API_COMPAT < 0x10000000L void ERR_remove_state(unsigned long pid) { ERR_remove_thread_state(NULL); ERR_remove_thread_state(); } #endif static void err_do_init(void) { CRYPTO_THREAD_init_local(&err_thread_local, NULL); } ERR_STATE *ERR_get_state(void) { static ERR_STATE fallback; ERR_STATE *ret, tmp, *tmpp = NULL; int i; CRYPTO_THREADID tid; ERR_STATE *state = NULL; CRYPTO_THREADID_current(&tid); CRYPTO_THREADID_cpy(&tmp.tid, &tid); ret = int_thread_get_item(&tmp); CRYPTO_THREAD_run_once(&err_init, err_do_init); /* ret == the error state, if NULL, make a new one */ if (ret == NULL) { ret = OPENSSL_malloc(sizeof(*ret)); if (ret == NULL) return (&fallback); CRYPTO_THREADID_cpy(&ret->tid, &tid); ret->top = 0; ret->bottom = 0; for (i = 0; i < ERR_NUM_ERRORS; i++) { ret->err_data[i] = NULL; ret->err_data_flags[i] = 0; } tmpp = int_thread_set_item(ret); /* To check if insertion failed, do a get. */ if (int_thread_get_item(ret) != ret) { ERR_STATE_free(ret); /* could not insert it */ return (&fallback); state = CRYPTO_THREAD_get_local(&err_thread_local); if (state == NULL) { state = OPENSSL_zalloc(sizeof(*state)); if (state == NULL) return NULL; if (!CRYPTO_THREAD_set_local(&err_thread_local, state)) { ERR_STATE_free(state); return NULL; } /* * If a race occurred in this function and we came second, tmpp is * the first one that we just replaced. */ ERR_STATE_free(tmpp); /* Ignore failures from these */ OPENSSL_init_crypto(OPENSSL_INIT_LOAD_CRYPTO_STRINGS, NULL); ossl_init_thread_start(OPENSSL_INIT_THREAD_ERR_STATE); } return ret; return state; } int ERR_get_next_error_library(void) Loading crypto/err/err_lcl.hdeleted 100644 → 0 +0 −2 Original line number Diff line number Diff line DEFINE_LHASH_OF(ERR_STATE); crypto/init.c +2 −2 Original line number Diff line number Diff line Loading @@ -360,9 +360,9 @@ static void ossl_init_thread_stop(struct thread_local_inits_st *locals) if (locals->err_state) { #ifdef OPENSSL_INIT_DEBUG fprintf(stderr, "OPENSSL_INIT: ossl_init_thread_stop: " "ERR_remove_thread_state(NULL)\n"); "ERR_remove_thread_state()\n"); #endif ERR_remove_thread_state(NULL); ERR_remove_thread_state(); } OPENSSL_free(locals); Loading doc/crypto/ERR_remove_state.pod +6 −8 Original line number Diff line number Diff line Loading @@ -8,7 +8,7 @@ ERR_remove_thread_state, ERR_remove_state - free a thread's error queue #include <openssl/err.h> void ERR_remove_thread_state(const CRYPTO_THREADID *tid); void ERR_remove_thread_state(void); Deprecated: Loading @@ -18,17 +18,16 @@ Deprecated: =head1 DESCRIPTION ERR_remove_thread_state() frees the error queue associated with thread B<tid>. If B<tid> == B<NULL>, the current thread will have its error queue removed. ERR_remove_thread_state() frees the error queue associated with the current thread. Since error queue data structures are allocated automatically for new threads, they must be freed when threads are terminated in order to avoid memory leaks. ERR_remove_state is deprecated and has been replaced by ERR_remove_thread_state. Since threads in OpenSSL are no longer identified by unsigned long values any argument to this function is ignored. Calling ERR_remove_state is equivalent to B<ERR_remove_thread_state(NULL)>. ERR_remove_thread_state. Any argument to this function is ignored and calling ERR_remove_state is equivalent to B<ERR_remove_thread_state()>. =head1 RETURN VALUE Loading @@ -41,7 +40,6 @@ L<err(3)> =head1 HISTORY ERR_remove_state() was deprecated in OpenSSL 1.0.0 when ERR_remove_thread_state() was introduced and thread IDs were introduced to identify threads instead of 'unsigned long'. was deprecated in OpenSSL 1.0.0 when ERR_remove_thread_state() was introduced. =cut doc/crypto/err.pod +5 −6 Original line number Diff line number Diff line Loading @@ -22,7 +22,7 @@ err - error codes int ERR_GET_REASON(unsigned long e); void ERR_clear_error(void); void ERR_remove_thread_state(const CRYPTO_THREADID *tid); void ERR_remove_thread_state(void); char *ERR_error_string(unsigned long e, char *buf); const char *ERR_lib_error_string(unsigned long e); Loading Loading @@ -164,15 +164,14 @@ TBA more details =head1 INTERNALS The error queues are stored in a hash table with one B<ERR_STATE> entry for each pid. ERR_get_state() returns the current thread's The error queues are stored in a thread-local storage with one B<ERR_STATE> entry for each thread. ERR_get_state() returns the current thread's B<ERR_STATE>. An B<ERR_STATE> can hold up to B<ERR_NUM_ERRORS> error codes. When more error codes are added, the old ones are overwritten, on the assumption that the most recent errors are most important. Error strings are also stored in hash table. The hash tables can be obtained by calling ERR_get_err_state_table(void) and ERR_get_string_table(void) respectively. Error strings are also stored in a hash table that can be obtained by calling ERR_get_string_table(void). =head1 SEE ALSO Loading Loading
crypto/err/err.c +32 −166 Original line number Diff line number Diff line Loading @@ -112,13 +112,13 @@ #include <stdarg.h> #include <string.h> #include <internal/cryptlib_int.h> #include <internal/threads.h> #include <openssl/lhash.h> #include <openssl/crypto.h> #include <openssl/buffer.h> #include <openssl/bio.h> #include <openssl/err.h> #include <openssl/opensslconf.h> #include "err_lcl.h" static void err_load_strings(int lib, ERR_STRING_DATA *str); Loading Loading @@ -231,25 +231,18 @@ static ERR_STRING_DATA ERR_str_reasons[] = { }; #endif static CRYPTO_ONCE err_init = CRYPTO_ONCE_STATIC_INIT; static CRYPTO_THREAD_LOCAL err_thread_local; /* Predeclarations of the "err_defaults" functions */ static LHASH_OF(ERR_STRING_DATA) *get_hash(int create, int lockit); static ERR_STRING_DATA *int_err_get_item(const ERR_STRING_DATA *); static LHASH_OF(ERR_STATE) *int_thread_get(int create, int lockit); static void int_thread_release(LHASH_OF(ERR_STATE) **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 *); /* * The internal state */ /* This is a struct so that REF_PRINT_COUNT works. */ static struct refcount { int references; } refcount = { 0 }; static LHASH_OF(ERR_STRING_DATA) *int_error_hash = NULL; static LHASH_OF(ERR_STATE) *int_thread_hash = NULL; static int int_err_library_number = ERR_LIB_USER; static unsigned long get_error_values(int inc, int top, const char **file, Loading Loading @@ -303,106 +296,6 @@ static ERR_STRING_DATA *int_err_get_item(const ERR_STRING_DATA *d) return p; } static unsigned long err_state_hash(const ERR_STATE *a) { return CRYPTO_THREADID_hash(&a->tid) * 13; } static int err_state_cmp(const ERR_STATE *a, const ERR_STATE *b) { return CRYPTO_THREADID_cmp(&a->tid, &b->tid); } static LHASH_OF(ERR_STATE) *int_thread_get(int create, int lockit) { LHASH_OF(ERR_STATE) *ret = NULL; if (lockit) CRYPTO_w_lock(CRYPTO_LOCK_ERR); if (!int_thread_hash && create) { int_thread_hash = lh_ERR_STATE_new(err_state_hash, err_state_cmp); } if (int_thread_hash != NULL) { refcount.references++; ret = int_thread_hash; } if (lockit) CRYPTO_w_unlock(CRYPTO_LOCK_ERR); return ret; } static void int_thread_release(LHASH_OF(ERR_STATE) **hash) { int i; if (hash == NULL || *hash == NULL) return; i = CRYPTO_add(&refcount.references, -1, CRYPTO_LOCK_ERR); REF_PRINT_COUNT(&refcount, "ERR"); if (i > 0) return; REF_ASSERT_ISNT(i < 0); *hash = NULL; } static ERR_STATE *int_thread_get_item(const ERR_STATE *d) { ERR_STATE *p = NULL; LHASH_OF(ERR_STATE) *hash; CRYPTO_r_lock(CRYPTO_LOCK_ERR); hash = int_thread_get(0, 0); if (hash) p = lh_ERR_STATE_retrieve(hash, d); CRYPTO_r_unlock(CRYPTO_LOCK_ERR); int_thread_release(&hash); return p; } static ERR_STATE *int_thread_set_item(ERR_STATE *d) { ERR_STATE *p = NULL; LHASH_OF(ERR_STATE) *hash; CRYPTO_w_lock(CRYPTO_LOCK_ERR); hash = int_thread_get(1, 0); if (hash) p = lh_ERR_STATE_insert(hash, d); CRYPTO_w_unlock(CRYPTO_LOCK_ERR); int_thread_release(&hash); return p; } static void int_thread_del_item(const ERR_STATE *d) { ERR_STATE *p = NULL; LHASH_OF(ERR_STATE) *hash; CRYPTO_w_lock(CRYPTO_LOCK_ERR); hash = int_thread_get(0, 0); if (hash) { p = lh_ERR_STATE_delete(hash, d); /* If there are no other references, and we just removed the * last item, delete the int_thread_hash */ if (refcount.references == 1 && int_thread_hash && lh_ERR_STATE_num_items(int_thread_hash) == 0) { refcount.references = 0; lh_ERR_STATE_free(int_thread_hash); int_thread_hash = NULL; hash = NULL; } } CRYPTO_w_unlock(CRYPTO_LOCK_ERR); int_thread_release(&hash); ERR_STATE_free(p); } #ifndef OPENSSL_NO_ERR # define NUM_SYS_STR_REASONS 127 # define LEN_SYS_STR_REASON 32 Loading Loading @@ -768,7 +661,6 @@ void ERR_error_string_n(unsigned long e, char *buf, size_t len) } } /* BAD for multi-threading: uses a local buffer if ret == NULL */ /* * ERR_error_string_n should be used instead for ret != NULL as * ERR_error_string cannot know how large the buffer is Loading @@ -789,16 +681,6 @@ LHASH_OF(ERR_STRING_DATA) *ERR_get_string_table(void) return get_hash(0, 1); } LHASH_OF(ERR_STATE) *ERR_get_err_state_table(void) { return int_thread_get(0, 1); } void ERR_release_err_state_table(LHASH_OF(ERR_STATE) **hash) { int_thread_release(hash); } const char *ERR_lib_error_string(unsigned long e) { ERR_STRING_DATA d, *p; Loading Loading @@ -838,68 +720,52 @@ const char *ERR_reason_error_string(unsigned long e) return ((p == NULL) ? NULL : p->string); } void ERR_remove_thread_state(const CRYPTO_THREADID *id) void ERR_remove_thread_state(void) { ERR_STATE tmp; ERR_STATE *state = ERR_get_state(); if (state == NULL) return; if (id) CRYPTO_THREADID_cpy(&tmp.tid, id); else CRYPTO_THREADID_current(&tmp.tid); /* * thread_del_item automatically destroys the LHASH if the number of * items reaches zero. */ int_thread_del_item(&tmp); CRYPTO_THREAD_set_local(&err_thread_local, NULL); ERR_STATE_free(state); } #if OPENSSL_API_COMPAT < 0x10000000L void ERR_remove_state(unsigned long pid) { ERR_remove_thread_state(NULL); ERR_remove_thread_state(); } #endif static void err_do_init(void) { CRYPTO_THREAD_init_local(&err_thread_local, NULL); } ERR_STATE *ERR_get_state(void) { static ERR_STATE fallback; ERR_STATE *ret, tmp, *tmpp = NULL; int i; CRYPTO_THREADID tid; ERR_STATE *state = NULL; CRYPTO_THREADID_current(&tid); CRYPTO_THREADID_cpy(&tmp.tid, &tid); ret = int_thread_get_item(&tmp); CRYPTO_THREAD_run_once(&err_init, err_do_init); /* ret == the error state, if NULL, make a new one */ if (ret == NULL) { ret = OPENSSL_malloc(sizeof(*ret)); if (ret == NULL) return (&fallback); CRYPTO_THREADID_cpy(&ret->tid, &tid); ret->top = 0; ret->bottom = 0; for (i = 0; i < ERR_NUM_ERRORS; i++) { ret->err_data[i] = NULL; ret->err_data_flags[i] = 0; } tmpp = int_thread_set_item(ret); /* To check if insertion failed, do a get. */ if (int_thread_get_item(ret) != ret) { ERR_STATE_free(ret); /* could not insert it */ return (&fallback); state = CRYPTO_THREAD_get_local(&err_thread_local); if (state == NULL) { state = OPENSSL_zalloc(sizeof(*state)); if (state == NULL) return NULL; if (!CRYPTO_THREAD_set_local(&err_thread_local, state)) { ERR_STATE_free(state); return NULL; } /* * If a race occurred in this function and we came second, tmpp is * the first one that we just replaced. */ ERR_STATE_free(tmpp); /* Ignore failures from these */ OPENSSL_init_crypto(OPENSSL_INIT_LOAD_CRYPTO_STRINGS, NULL); ossl_init_thread_start(OPENSSL_INIT_THREAD_ERR_STATE); } return ret; return state; } int ERR_get_next_error_library(void) Loading
crypto/err/err_lcl.hdeleted 100644 → 0 +0 −2 Original line number Diff line number Diff line DEFINE_LHASH_OF(ERR_STATE);
crypto/init.c +2 −2 Original line number Diff line number Diff line Loading @@ -360,9 +360,9 @@ static void ossl_init_thread_stop(struct thread_local_inits_st *locals) if (locals->err_state) { #ifdef OPENSSL_INIT_DEBUG fprintf(stderr, "OPENSSL_INIT: ossl_init_thread_stop: " "ERR_remove_thread_state(NULL)\n"); "ERR_remove_thread_state()\n"); #endif ERR_remove_thread_state(NULL); ERR_remove_thread_state(); } OPENSSL_free(locals); Loading
doc/crypto/ERR_remove_state.pod +6 −8 Original line number Diff line number Diff line Loading @@ -8,7 +8,7 @@ ERR_remove_thread_state, ERR_remove_state - free a thread's error queue #include <openssl/err.h> void ERR_remove_thread_state(const CRYPTO_THREADID *tid); void ERR_remove_thread_state(void); Deprecated: Loading @@ -18,17 +18,16 @@ Deprecated: =head1 DESCRIPTION ERR_remove_thread_state() frees the error queue associated with thread B<tid>. If B<tid> == B<NULL>, the current thread will have its error queue removed. ERR_remove_thread_state() frees the error queue associated with the current thread. Since error queue data structures are allocated automatically for new threads, they must be freed when threads are terminated in order to avoid memory leaks. ERR_remove_state is deprecated and has been replaced by ERR_remove_thread_state. Since threads in OpenSSL are no longer identified by unsigned long values any argument to this function is ignored. Calling ERR_remove_state is equivalent to B<ERR_remove_thread_state(NULL)>. ERR_remove_thread_state. Any argument to this function is ignored and calling ERR_remove_state is equivalent to B<ERR_remove_thread_state()>. =head1 RETURN VALUE Loading @@ -41,7 +40,6 @@ L<err(3)> =head1 HISTORY ERR_remove_state() was deprecated in OpenSSL 1.0.0 when ERR_remove_thread_state() was introduced and thread IDs were introduced to identify threads instead of 'unsigned long'. was deprecated in OpenSSL 1.0.0 when ERR_remove_thread_state() was introduced. =cut
doc/crypto/err.pod +5 −6 Original line number Diff line number Diff line Loading @@ -22,7 +22,7 @@ err - error codes int ERR_GET_REASON(unsigned long e); void ERR_clear_error(void); void ERR_remove_thread_state(const CRYPTO_THREADID *tid); void ERR_remove_thread_state(void); char *ERR_error_string(unsigned long e, char *buf); const char *ERR_lib_error_string(unsigned long e); Loading Loading @@ -164,15 +164,14 @@ TBA more details =head1 INTERNALS The error queues are stored in a hash table with one B<ERR_STATE> entry for each pid. ERR_get_state() returns the current thread's The error queues are stored in a thread-local storage with one B<ERR_STATE> entry for each thread. ERR_get_state() returns the current thread's B<ERR_STATE>. An B<ERR_STATE> can hold up to B<ERR_NUM_ERRORS> error codes. When more error codes are added, the old ones are overwritten, on the assumption that the most recent errors are most important. Error strings are also stored in hash table. The hash tables can be obtained by calling ERR_get_err_state_table(void) and ERR_get_string_table(void) respectively. Error strings are also stored in a hash table that can be obtained by calling ERR_get_string_table(void). =head1 SEE ALSO Loading