mirror of
https://github.com/zeromq/libzmq.git
synced 2024-12-27 07:31:03 +08:00
Problem: calling randombytes_close with libsodium can crash Contexts in other threads (#4242)
* add opt-out for randombytes_close Problem: randombytes_close is either a no-op or unsafe when a Context is running. Unfortunately, there does not appear to be a single always correct choice, so let builders pick between two not-great options. Opting out can leak an FD on /dev/urandom which may need to be closed explicitly. However, with the default behavior, using multiple contexts with CURVE can crash with no application-level workaround available. randombytes_close is not threadsafe and calling it while still in use by a Context can cause a crash. For implementations using /dev/[u]random, this can leave up to one leftover FD per process. The libsodium docs suggest that this function rarely needs to be called explicitly.
This commit is contained in:
parent
f6e99e72ec
commit
bcb659e00e
@ -258,6 +258,7 @@ endif()
|
|||||||
|
|
||||||
option(WITH_LIBSODIUM "Use libsodium instead of built-in tweetnacl" ON)
|
option(WITH_LIBSODIUM "Use libsodium instead of built-in tweetnacl" ON)
|
||||||
option(WITH_LIBSODIUM_STATIC "Use static libsodium library" OFF)
|
option(WITH_LIBSODIUM_STATIC "Use static libsodium library" OFF)
|
||||||
|
option(ENABLE_LIBSODIUM_RANDOMBYTES_CLOSE "Automatically close libsodium randombytes. Not threadsafe without getrandom()" ON)
|
||||||
option(ENABLE_CURVE "Enable CURVE security" ON)
|
option(ENABLE_CURVE "Enable CURVE security" ON)
|
||||||
|
|
||||||
if(ENABLE_CURVE)
|
if(ENABLE_CURVE)
|
||||||
@ -271,6 +272,9 @@ if(ENABLE_CURVE)
|
|||||||
endif()
|
endif()
|
||||||
set(ZMQ_USE_LIBSODIUM 1)
|
set(ZMQ_USE_LIBSODIUM 1)
|
||||||
set(ZMQ_HAVE_CURVE 1)
|
set(ZMQ_HAVE_CURVE 1)
|
||||||
|
if (ENABLE_LIBSODIUM_RANDOMBYTES_CLOSE)
|
||||||
|
set(ZMQ_LIBSODIUM_RANDOMBYTES_CLOSE 1)
|
||||||
|
endif()
|
||||||
else()
|
else()
|
||||||
message(
|
message(
|
||||||
WARNING
|
WARNING
|
||||||
|
20
configure.ac
20
configure.ac
@ -550,6 +550,20 @@ AS_IF([test "x$with_libsodium" = "xyes"], [
|
|||||||
AC_ARG_ENABLE([curve],
|
AC_ARG_ENABLE([curve],
|
||||||
[AS_HELP_STRING([--disable-curve], [disable CURVE security [default=no]])])
|
[AS_HELP_STRING([--disable-curve], [disable CURVE security [default=no]])])
|
||||||
|
|
||||||
|
AC_ARG_ENABLE(
|
||||||
|
[libsodium_randombytes_close],
|
||||||
|
[AS_HELP_STRING(
|
||||||
|
[--disable-libsodium_randombytes_close],
|
||||||
|
[Do not call libsodium randombytes_close() when terminating contexts.
|
||||||
|
If disabled, may leave one FD open on /dev/urandom
|
||||||
|
until randombytes_close() is called explicitly,
|
||||||
|
but fixes a crash when multiple contexts are used with CURVE.
|
||||||
|
Has no effect when getrandom() is available. [default=enabled]]
|
||||||
|
)],
|
||||||
|
[],
|
||||||
|
[enable_libsodium_randombytes_close=yes]
|
||||||
|
)
|
||||||
|
|
||||||
if test "x$enable_curve" = "xno"; then
|
if test "x$enable_curve" = "xno"; then
|
||||||
curve_library=""
|
curve_library=""
|
||||||
AC_MSG_NOTICE([CURVE security is disabled])
|
AC_MSG_NOTICE([CURVE security is disabled])
|
||||||
@ -558,6 +572,12 @@ elif test "x$with_libsodium" = "xyes"; then
|
|||||||
AC_MSG_NOTICE([Using libsodium for CURVE security])
|
AC_MSG_NOTICE([Using libsodium for CURVE security])
|
||||||
AC_DEFINE(ZMQ_HAVE_CURVE, [1], [Using curve encryption])
|
AC_DEFINE(ZMQ_HAVE_CURVE, [1], [Using curve encryption])
|
||||||
AC_DEFINE(ZMQ_USE_LIBSODIUM, [1], [Using libsodium for curve encryption])
|
AC_DEFINE(ZMQ_USE_LIBSODIUM, [1], [Using libsodium for curve encryption])
|
||||||
|
if test "x$enable_libsodium_randombytes_close" = "xyes"; then
|
||||||
|
AC_DEFINE(ZMQ_LIBSODIUM_RANDOMBYTES_CLOSE, [1], [Automatically close libsodium randombytes. Not threadsafe without getrandom()])
|
||||||
|
else
|
||||||
|
AC_MSG_NOTICE([Disabling libsodium randombytes_close(). randombytes_close() may need to be called in applcation code.])
|
||||||
|
fi
|
||||||
|
|
||||||
curve_library="libsodium"
|
curve_library="libsodium"
|
||||||
enable_curve="yes"
|
enable_curve="yes"
|
||||||
|
|
||||||
|
@ -151,8 +151,13 @@ static void manage_random (bool init_)
|
|||||||
if (init_) {
|
if (init_) {
|
||||||
int rc = sodium_init ();
|
int rc = sodium_init ();
|
||||||
zmq_assert (rc != -1);
|
zmq_assert (rc != -1);
|
||||||
|
#if defined(ZMQ_LIBSODIUM_RANDOMBYTES_CLOSE)
|
||||||
} else {
|
} else {
|
||||||
|
// randombytes_close either a no-op or not threadsafe
|
||||||
|
// doing this without refcounting can cause crashes
|
||||||
|
// if called while a context is active
|
||||||
randombytes_close ();
|
randombytes_close ();
|
||||||
|
#endif
|
||||||
}
|
}
|
||||||
#else
|
#else
|
||||||
LIBZMQ_UNUSED (init_);
|
LIBZMQ_UNUSED (init_);
|
||||||
|
Loading…
x
Reference in New Issue
Block a user