diff options
author | Eelco Dolstra <eelco.dolstra@logicblox.com> | 2016-02-22T13·49+0100 |
---|---|---|
committer | Eelco Dolstra <eelco.dolstra@logicblox.com> | 2016-02-22T14·51+0100 |
commit | 840056af04561e7fed31c459948be7c0e038864a (patch) | |
tree | 6175fd163cc973c50a50046b000837a3016ccc0b /src/libmain | |
parent | d361901bfe50f43ed1b94e89c95718b072f07821 (diff) |
Make OpenSSL usage thread-safe
OpenSSL can randomly segfault unless we register a callback function to do locking. https://www.openssl.org/docs/manmaster/crypto/threads.html
Diffstat (limited to 'src/libmain')
-rw-r--r-- | src/libmain/local.mk | 2 | ||||
-rw-r--r-- | src/libmain/shared.cc | 24 | ||||
-rw-r--r-- | src/libmain/shared.hh | 4 |
3 files changed, 26 insertions, 4 deletions
diff --git a/src/libmain/local.mk b/src/libmain/local.mk index 16dbf752823d..4ff114e4b332 100644 --- a/src/libmain/local.mk +++ b/src/libmain/local.mk @@ -6,6 +6,8 @@ libmain_DIR := $(d) libmain_SOURCES := $(wildcard $(d)/*.cc) +libutil_LDFLAGS = $(OPENSSL_LIBS) + libmain_LIBS = libstore libutil libformat libmain_ALLOW_UNDEFINED = 1 diff --git a/src/libmain/shared.cc b/src/libmain/shared.cc index 88ed52497fb9..8f2aa842036a 100644 --- a/src/libmain/shared.cc +++ b/src/libmain/shared.cc @@ -5,10 +5,11 @@ #include "store-api.hh" #include "util.hh" -#include <iostream> +#include <algorithm> #include <cctype> #include <exception> -#include <algorithm> +#include <iostream> +#include <mutex> #include <cstdlib> #include <sys/time.h> @@ -16,7 +17,7 @@ #include <unistd.h> #include <signal.h> -extern char * * environ; +#include <openssl/crypto.h> namespace nix { @@ -103,7 +104,18 @@ string getArg(const string & opt, } -void detectStackOverflow(); +/* OpenSSL is not thread-safe by default - it will randomly crash + unless the user supplies a mutex locking function. So let's do + that. */ +static std::vector<std::mutex> opensslLocks; + +static void opensslLockCallback(int mode, int type, const char * file, int line) +{ + if (mode & CRYPTO_LOCK) + opensslLocks[type].lock(); + else + opensslLocks[type].unlock(); +} void initNix() @@ -119,6 +131,10 @@ void initNix() if (getEnv("IN_SYSTEMD") == "1") logType = ltSystemd; + /* Initialise OpenSSL locking. */ + opensslLocks = std::vector<std::mutex>(CRYPTO_num_locks()); + CRYPTO_set_locking_callback(opensslLockCallback); + settings.processEnvironment(); settings.loadConfFile(); diff --git a/src/libmain/shared.hh b/src/libmain/shared.hh index 3f3f6f7232e0..0682267fa376 100644 --- a/src/libmain/shared.hh +++ b/src/libmain/shared.hh @@ -101,4 +101,8 @@ struct PrintFreed }; +/* Install a SIGSEGV handler to detect stack overflows. */ +void detectStackOverflow(); + + } |