If dynamically-loadable ENGINEs are linked against a shared-library version
authorRichard Levitte <levitte@openssl.org>
Thu, 27 Nov 2003 16:41:26 +0000 (16:41 +0000)
committerRichard Levitte <levitte@openssl.org>
Thu, 27 Nov 2003 16:41:26 +0000 (16:41 +0000)
of libcrypto, then it is possible that when they are loaded they will share
the same static data as the loading application/library. This means it will
be too late to set memory/ERR/ex_data/[etc] callbacks, but entirely
unnecessary to try.

This change (and a great part of this comment) was implemented in
0.9.8-dev a long time ago, but slightly differently.  In 0.9.8-dev, a
specific function that just returns a pointer to some static object is
used. For 0.9.7x, we couldn't do that, since the way we handle feature
freezes is, among other, to not add any more non-static functions.
Instead, we use the function ERR_get_implementation() and compare the
returned value with fns->err_fns, a member of fns that already is
there, and which therefore can safely be used in this manner.

What happens is that if the loaded ENGINE's return value from this
function matches the loading application/library's return value - they
share static data. If they don't match, the loaded ENGINE has its own
copy of libcrypto's static data and so the callbacks need to be set.

crypto/engine/engine.h

index 9c3ab182d3799aab2945d6a07a3ae7cfd01ce8d0..a795a598403110a65f75007c4896c10e369dc472 100644 (file)
@@ -616,17 +616,20 @@ typedef int (*dynamic_bind_engine)(ENGINE *e, const char *id,
                                const dynamic_fns *fns);
 #define IMPLEMENT_DYNAMIC_BIND_FN(fn) \
        int bind_engine(ENGINE *e, const char *id, const dynamic_fns *fns) { \
-               if(!CRYPTO_set_mem_functions(fns->mem_fns.malloc_cb, \
-                       fns->mem_fns.realloc_cb, fns->mem_fns.free_cb)) \
-                       return 0; \
-               CRYPTO_set_locking_callback(fns->lock_fns.lock_locking_cb); \
-               CRYPTO_set_add_lock_callback(fns->lock_fns.lock_add_lock_cb); \
-               CRYPTO_set_dynlock_create_callback(fns->lock_fns.dynlock_create_cb); \
-               CRYPTO_set_dynlock_lock_callback(fns->lock_fns.dynlock_lock_cb); \
-               CRYPTO_set_dynlock_destroy_callback(fns->lock_fns.dynlock_destroy_cb); \
-               if(!CRYPTO_set_ex_data_implementation(fns->ex_data_fns)) \
-                       return 0; \
-               if(!ERR_set_implementation(fns->err_fns)) return 0; \
+               if (ERR_get_implementation() != fns->err_fns) \
+                       { \
+                       if(!CRYPTO_set_mem_functions(fns->mem_fns.malloc_cb, \
+                               fns->mem_fns.realloc_cb, fns->mem_fns.free_cb)) \
+                               return 0; \
+                       CRYPTO_set_locking_callback(fns->lock_fns.lock_locking_cb); \
+                       CRYPTO_set_add_lock_callback(fns->lock_fns.lock_add_lock_cb); \
+                       CRYPTO_set_dynlock_create_callback(fns->lock_fns.dynlock_create_cb); \
+                       CRYPTO_set_dynlock_lock_callback(fns->lock_fns.dynlock_lock_cb); \
+                       CRYPTO_set_dynlock_destroy_callback(fns->lock_fns.dynlock_destroy_cb); \
+                       if(!CRYPTO_set_ex_data_implementation(fns->ex_data_fns)) \
+                               return 0; \
+                       if(!ERR_set_implementation(fns->err_fns)) return 0; \
+                       } \
                if(!fn(e,id)) return 0; \
                return 1; }