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);

Reply via email to