Unverified Commit e49a861f authored by Simon Giesecke's avatar Simon Giesecke Committed by GitHub

Merge pull request #3001 from bluca/sodium_global_init

Problem:  global random init/deinit breaks existing applications
parents 4d9fc806 8f5fc705
...@@ -86,6 +86,14 @@ uint32_t zmq::generate_random () ...@@ -86,6 +86,14 @@ uint32_t zmq::generate_random ()
// order fiasco, this is done using function-local statics, if the // order fiasco, this is done using function-local statics, if the
// compiler implementation supports thread-safe initialization of those. // compiler implementation supports thread-safe initialization of those.
// Otherwise, we fall back to global statics. // Otherwise, we fall back to global statics.
// HOWEVER, this initialisation code imposes ordering constraints, which
// are not obvious to users of libzmq, and may lead to problems if atexit
// or similar methods are used for cleanup.
// In that case, a strict ordering is imposed whereas the contexts MUST
// be initialised BEFORE registering the cleanup with atexit. CZMQ is an
// example. Hence we make the choice to restrict this global transition
// mechanism ONLY to Tweenacl + *NIX (when using /dev/urandom) as it is
// the less risky option.
// TODO if there is some other user of libsodium besides libzmq, this must // TODO if there is some other user of libsodium besides libzmq, this must
// be synchronized by the application. This should probably also be // be synchronized by the application. This should probably also be
...@@ -105,18 +113,16 @@ uint32_t zmq::generate_random () ...@@ -105,18 +113,16 @@ uint32_t zmq::generate_random ()
#endif #endif
#if !ZMQ_HAVE_THREADSAFE_STATIC_LOCAL_INIT \ #if !ZMQ_HAVE_THREADSAFE_STATIC_LOCAL_INIT \
&& (defined(ZMQ_USE_LIBSODIUM) \ && (defined(ZMQ_USE_TWEETNACL) && !defined(ZMQ_HAVE_WINDOWS) \
|| (defined(ZMQ_USE_TWEETNACL) && !defined(ZMQ_HAVE_WINDOWS) \ && !defined(ZMQ_HAVE_GETRANDOM))
&& !defined(ZMQ_HAVE_GETRANDOM)))
static unsigned int random_refcount = 0; static unsigned int random_refcount = 0;
static zmq::mutex_t random_sync; static zmq::mutex_t random_sync;
#endif #endif
static void manage_random (bool init) static void manage_random (bool init)
{ {
#if defined(ZMQ_USE_LIBSODIUM) \ #if defined(ZMQ_USE_TWEETNACL) && !defined(ZMQ_HAVE_WINDOWS) \
|| (defined(ZMQ_USE_TWEETNACL) && !defined(ZMQ_HAVE_WINDOWS) \ && !defined(ZMQ_HAVE_GETRANDOM)
&& !defined(ZMQ_HAVE_GETRANDOM))
#if ZMQ_HAVE_THREADSAFE_STATIC_LOCAL_INIT #if ZMQ_HAVE_THREADSAFE_STATIC_LOCAL_INIT
static int random_refcount = 0; static int random_refcount = 0;
...@@ -140,6 +146,14 @@ static void manage_random (bool init) ...@@ -140,6 +146,14 @@ static void manage_random (bool init)
randombytes_close (); randombytes_close ();
} }
} }
#elif defined(ZMQ_USE_LIBSODIUM)
if (init) {
int rc = sodium_init ();
zmq_assert (rc != -1);
} else {
randombytes_close ();
}
#endif #endif
} }
......
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment