Skip to content

Commit e49a861

Browse files
authored
Merge pull request #3001 from bluca/sodium_global_init
Problem: global random init/deinit breaks existing applications
2 parents 4d9fc80 + 8f5fc70 commit e49a861

1 file changed

Lines changed: 20 additions & 6 deletions

File tree

src/random.cpp

Lines changed: 20 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -86,6 +86,14 @@ uint32_t zmq::generate_random ()
8686
// order fiasco, this is done using function-local statics, if the
8787
// compiler implementation supports thread-safe initialization of those.
8888
// Otherwise, we fall back to global statics.
89+
// HOWEVER, this initialisation code imposes ordering constraints, which
90+
// are not obvious to users of libzmq, and may lead to problems if atexit
91+
// or similar methods are used for cleanup.
92+
// In that case, a strict ordering is imposed whereas the contexts MUST
93+
// be initialised BEFORE registering the cleanup with atexit. CZMQ is an
94+
// example. Hence we make the choice to restrict this global transition
95+
// mechanism ONLY to Tweenacl + *NIX (when using /dev/urandom) as it is
96+
// the less risky option.
8997

9098
// TODO if there is some other user of libsodium besides libzmq, this must
9199
// be synchronized by the application. This should probably also be
@@ -105,18 +113,16 @@ uint32_t zmq::generate_random ()
105113
#endif
106114

107115
#if !ZMQ_HAVE_THREADSAFE_STATIC_LOCAL_INIT \
108-
&& (defined(ZMQ_USE_LIBSODIUM) \
109-
|| (defined(ZMQ_USE_TWEETNACL) && !defined(ZMQ_HAVE_WINDOWS) \
110-
&& !defined(ZMQ_HAVE_GETRANDOM)))
116+
&& (defined(ZMQ_USE_TWEETNACL) && !defined(ZMQ_HAVE_WINDOWS) \
117+
&& !defined(ZMQ_HAVE_GETRANDOM))
111118
static unsigned int random_refcount = 0;
112119
static zmq::mutex_t random_sync;
113120
#endif
114121

115122
static void manage_random (bool init)
116123
{
117-
#if defined(ZMQ_USE_LIBSODIUM) \
118-
|| (defined(ZMQ_USE_TWEETNACL) && !defined(ZMQ_HAVE_WINDOWS) \
119-
&& !defined(ZMQ_HAVE_GETRANDOM))
124+
#if defined(ZMQ_USE_TWEETNACL) && !defined(ZMQ_HAVE_WINDOWS) \
125+
&& !defined(ZMQ_HAVE_GETRANDOM)
120126

121127
#if ZMQ_HAVE_THREADSAFE_STATIC_LOCAL_INIT
122128
static int random_refcount = 0;
@@ -140,6 +146,14 @@ static void manage_random (bool init)
140146
randombytes_close ();
141147
}
142148
}
149+
150+
#elif defined(ZMQ_USE_LIBSODIUM)
151+
if (init) {
152+
int rc = sodium_init ();
153+
zmq_assert (rc != -1);
154+
} else {
155+
randombytes_close ();
156+
}
143157
#endif
144158
}
145159

0 commit comments

Comments
 (0)