mirror of
https://github.com/zeromq/libzmq.git
synced 2024-12-30 01:06:55 +08:00
Problem: global random init/deinit breaks existing applications
Solution: restrict it only to the original issue #2632, Tweetnacl on *NIX when using /dev/urandom, ie: without the new Linux getrandom() syscall. Existing applications might use atexit to register cleanup functions (like CZMQ does), and the current change as-is imposes an ordering that did not exist before - the context MUST be created BEFORE registering the cleanup with atexit. This is a backward incompatible change that is reported to cause aborts in some applications. Although libsodium's documentation says that its initialisation APIs is not thread-safe, nobody has ever reported an issue with it, so avoiding the global init/deinit in the libsodium case is the less risky option we have. Tweetnacl users on Windows and on Linux with getrandom (glibc 2.25 and Linux kernel 3.17) are not affected by the original issue. Fixes #2991
This commit is contained in:
parent
4d9fc8066f
commit
8f5fc705e4
@ -86,6 +86,14 @@ uint32_t zmq::generate_random ()
|
||||
// order fiasco, this is done using function-local statics, if the
|
||||
// compiler implementation supports thread-safe initialization of those.
|
||||
// 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
|
||||
// be synchronized by the application. This should probably also be
|
||||
@ -105,18 +113,16 @@ uint32_t zmq::generate_random ()
|
||||
#endif
|
||||
|
||||
#if !ZMQ_HAVE_THREADSAFE_STATIC_LOCAL_INIT \
|
||||
&& (defined(ZMQ_USE_LIBSODIUM) \
|
||||
|| (defined(ZMQ_USE_TWEETNACL) && !defined(ZMQ_HAVE_WINDOWS) \
|
||||
&& !defined(ZMQ_HAVE_GETRANDOM)))
|
||||
&& (defined(ZMQ_USE_TWEETNACL) && !defined(ZMQ_HAVE_WINDOWS) \
|
||||
&& !defined(ZMQ_HAVE_GETRANDOM))
|
||||
static unsigned int random_refcount = 0;
|
||||
static zmq::mutex_t random_sync;
|
||||
#endif
|
||||
|
||||
static void manage_random (bool init)
|
||||
{
|
||||
#if defined(ZMQ_USE_LIBSODIUM) \
|
||||
|| (defined(ZMQ_USE_TWEETNACL) && !defined(ZMQ_HAVE_WINDOWS) \
|
||||
&& !defined(ZMQ_HAVE_GETRANDOM))
|
||||
#if defined(ZMQ_USE_TWEETNACL) && !defined(ZMQ_HAVE_WINDOWS) \
|
||||
&& !defined(ZMQ_HAVE_GETRANDOM)
|
||||
|
||||
#if ZMQ_HAVE_THREADSAFE_STATIC_LOCAL_INIT
|
||||
static int random_refcount = 0;
|
||||
@ -140,6 +146,14 @@ static void manage_random (bool init)
|
||||
randombytes_close ();
|
||||
}
|
||||
}
|
||||
|
||||
#elif defined(ZMQ_USE_LIBSODIUM)
|
||||
if (init) {
|
||||
int rc = sodium_init ();
|
||||
zmq_assert (rc != -1);
|
||||
} else {
|
||||
randombytes_close ();
|
||||
}
|
||||
#endif
|
||||
}
|
||||
|
||||
|
Loading…
x
Reference in New Issue
Block a user