Skip to content
Permalink
Browse files

Merge PR #3109: SSL: remove multi-OpenSSL sanity check.

This PR removes the sanity check for multiple copies of OpenSSL.

It also ensures Mumble always initializes its own copy of OpenSSL, even when Mumble and Qt are using distinct versions of OpenSSL.

See commit messages for more information.
  • Loading branch information...
mkrautz committed May 31, 2017
2 parents 30a9176 + f544524 commit 13bc12d3d00f3fa2cd001e4fb78375c5b86e1058
Showing with 6 additions and 81 deletions.
  1. +6 −80 src/SSL.cpp
  2. +0 −1 src/SSL.h
@@ -5,92 +5,18 @@

#include "murmur_pch.h"

// Needed for MumbleSSL::qsslSanityCheck()
#ifdef Q_OS_LINUX
# include <dlfcn.h>
# include <link.h>
#endif

#include "SSL.h"

#include "Version.h"

void MumbleSSL::initialize() {
// Let Qt initialize OpenSSL...
QSslSocket::supportsSsl();

// Check that we aren't in a situation where
// Qt has dynamically loaded *another*
// version/soname of libssl and/or libcrypto
// alongside the copy we link against ourselves.
//
// This can happen when Qt is built without the
// -openssl-linked configure option. When Qt is
// built without -openssl-linked, it will try
// to dynamically load the OpenSSL libraries.
// When Qt dynamically loads OpenSSL and there
// are multiple version of libcrypto and libssl
// available on the system, it is possible for
// Qt to load another version of OpenSSL in
// addition to the one our binary is linked
// against. Typically, this will happen if
// Mumble or Murmur are linked against
// an older version, and a newer version is
// available on the system as well.
//
// If we're in a situation where two version of
// OpenSSL's libraries are loaded into our process,
// we abort immediately. Things WILL go wrong.
MumbleSSL::qsslSanityCheck();
}

// Check that we haven't loaded multiple copies of OpenSSL
// into our process by accident.
void MumbleSSL::qsslSanityCheck() {
#ifdef Q_OS_LINUX
struct link_map *lm = NULL;
void *self = dlopen(NULL, RTLD_NOW);
if (self == NULL) {
qFatal("SSL: could not dlopen program binary");
}

if (dlinfo(self, RTLD_DI_LINKMAP, &lm) == -1) {
qFatal("SSL: unable to acquire link_map: %s", dlerror());
}
if (lm == NULL) {
qFatal("SSL: link_map is NULL");
}

QStringList libssl;
QStringList libcrypto;
// Initialize our copy of OpenSSL.
SSL_library_init(); // Safe to discard return value, per OpenSSL man pages.
SSL_load_error_strings();

while (lm != NULL) {
QString name = QString::fromLocal8Bit(lm->l_name);
if (name.contains(QLatin1String("libssl"))) {
libssl << name;
} else if (name.contains(QLatin1String("libcrypto"))) {
libcrypto << name;
}
lm = lm->l_next;
}

bool ok = true;
if (libcrypto.size() == 0 || libssl.size() == 0) {
qFatal("SSL library query failed: %i libcrypto's and %i libssl's found.", libcrypto.size(), libssl.size());
}
if (libssl.size() > 1) {
qCritical("Found multiple libssl.so copies in binary: %s", qPrintable(libssl.join(QLatin1String(", "))));
ok = false;
}
if (libcrypto.size() > 1) {
qCritical("Found multiple libcrypto.so copies in binary: %s", qPrintable(libcrypto.join(QLatin1String(", "))));
ok = false;
}

if (!ok) {
qFatal("Aborting due to previous errors");
}
#endif
// Let Qt initialize its copy of OpenSSL, if it's different than
// Mumble's.
QSslSocket::supportsSsl();
}

QString MumbleSSL::defaultOpenSSLCipherString() {
@@ -13,7 +13,6 @@
class MumbleSSL {
public:
static void initialize();
static void qsslSanityCheck();
static QString defaultOpenSSLCipherString();
static QList<QSslCipher> ciphersFromOpenSSLCipherString(QString cipherString);
static void addSystemCA();

0 comments on commit 13bc12d

Please sign in to comment.
You can’t perform that action at this time.