An ERR_STATE block (crypto/err.c) is stored in a global hashtable keyed
by thread-id. If threads are re-used (like the windows worker thread
concept), this scheme doesn't work. It looks like replacing the internal
int_thread_get_item/int_thread_set_item pair, or the higher-level
ERR_get_state/ERR_remove_state pair is the way to go.
The complications are (1) the code tries very hard to not expose any
functions or function-dispatch structures; and (2) I need to do this at
startup-time, and the code tries VERY hard to make err_fns_check calls all
over the place -- that latter part means replacing the
ERR_get/remove_state seems like the cleaner solution.
Attached is a proposed diff. Any comments?
/r$
--
Rich Salz Chief Security Architect
DataPower Technology http://www.datapower.com
XS40 XML Security Gateway http://www.datapower.com/products/xs40.html
--- err.h.orig Tue Sep 27 23:20:13 2005
+++ err.h Tue Sep 27 23:29:39 2005
@@ -274,6 +274,7 @@
void ERR_remove_state(unsigned long pid); /* if zero we look it up */
ERR_STATE *ERR_get_state(void);
+extern void ERR_set_state_funcs(ERR_STATE *(*get)(void), void
(*remove)(unsigned long));
#ifndef OPENSSL_NO_LHASH
LHASH *ERR_get_string_table(void);
--- err.c.orig Tue Sep 27 23:20:08 2005
+++ err.c Tue Sep 27 23:29:56 2005
@@ -122,6 +122,10 @@
static void err_load_strings(int lib, ERR_STRING_DATA *str);
static void ERR_STATE_free(ERR_STATE *s);
+
+static void (*int_remove_state_func)(unsigned long);
+static ERR_STATE *(*int_get_state_func)(void);
+
#ifndef OPENSSL_NO_ERR
static ERR_STRING_DATA ERR_str_libraries[]=
{
@@ -958,11 +962,24 @@
(long)((ERR_STATE *)b_void)->pid));
}
+void ERR_set_state_funcs(
+ ERR_STATE *(*get)(void),
+ void (*remove)(unsigned long))
+ {
+ int_get_state_func = get;
+ int_remove_state_func = remove;
+ }
+
+
void ERR_remove_state(unsigned long pid)
{
ERR_STATE tmp;
err_fns_check();
+ if (int_remove_state_func)
+ {
+ (*int_remove_state_func)(pid);
+ }
if (pid == 0)
pid=(unsigned long)CRYPTO_thread_id();
tmp.pid=pid;
@@ -971,6 +988,7 @@
ERRFN(thread_del_item)(&tmp);
}
+
ERR_STATE *ERR_get_state(void)
{
static ERR_STATE fallback;
@@ -979,6 +997,8 @@
unsigned long pid;
err_fns_check();
+ if (int_get_state_func)
+ return (*int_get_state_func)();
pid=(unsigned long)CRYPTO_thread_id();
tmp.pid=pid;
ret=ERRFN(thread_get_item)(&tmp);