From 04dc4edb447b4203c29b654a7beba61507eadc7b Mon Sep 17 00:00:00 2001 From: Richard Levitte Date: Thu, 27 Nov 2003 16:41:26 +0000 Subject: [PATCH] If dynamically-loadable ENGINEs are linked against a shared-library version 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 | 25 ++++++++++++++----------- 1 file changed, 14 insertions(+), 11 deletions(-) diff --git a/crypto/engine/engine.h b/crypto/engine/engine.h index 9c3ab182d3..a795a59840 100644 --- a/crypto/engine/engine.h +++ b/crypto/engine/engine.h @@ -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; } -- 2.25.1