Welcome to mirror list, hosted at ThFree Co, Russian Federation.

github.com/mumble-voip/mumble.git - Unnamed repository; edit this file 'description' to name the repository.
summaryrefslogtreecommitdiff
path: root/src/tests
diff options
context:
space:
mode:
authorMikkel Krautz <mikkel@krautz.dk>2017-07-16 11:48:49 +0300
committerMikkel Krautz <mikkel@krautz.dk>2017-07-17 11:19:21 +0300
commitf6fb4d8b7567f11e64856762bcc9b434d2926268 (patch)
tree2cd09018af30f1fa7d0b64b9b1e1c5383aea6d1f /src/tests
parent6892c8b29abe5e36bcc7a96a34dbeb5bbde4da0e (diff)
src/tests: add TestSSLLocks test for testing our OpenSSL locking implementation.
This test tests that our SSLLocks class works correctly. Note: Since OpenSSL 1.1, OpenSSL provides their own locking for Windows and POSIX systems. So if you're playing around with this test, you should only be able to make it crash OpenSSL versions prior to 1.1.
Diffstat (limited to 'src/tests')
-rw-r--r--src/tests/TestSSLLocks/TestSSLLocks.cpp106
-rw-r--r--src/tests/TestSSLLocks/TestSSLLocks.pro12
-rw-r--r--src/tests/tests.pro3
3 files changed, 120 insertions, 1 deletions
diff --git a/src/tests/TestSSLLocks/TestSSLLocks.cpp b/src/tests/TestSSLLocks/TestSSLLocks.cpp
new file mode 100644
index 000000000..9963c4350
--- /dev/null
+++ b/src/tests/TestSSLLocks/TestSSLLocks.cpp
@@ -0,0 +1,106 @@
+// Copyright 2005-2017 The Mumble Developers. All rights reserved.
+// Use of this source code is governed by a BSD-style license
+// that can be found in the LICENSE file at the root of the
+// Mumble source tree or at <https://www.mumble.info/LICENSE>.
+
+#include <QtCore>
+#include <QtTest>
+
+#include "SSL.h"
+#include "QAtomicIntCompat.h"
+
+#include <openssl/rand.h>
+
+/// SSLRacer is a thread that runs operations on OpenSSL's
+/// RAND infrastructure, in an attempt to crash/segfault
+/// the test process.
+///
+/// The thread can either query OpenSSL for random bytes, or
+/// seed the RAND system. This is controlled by the |seed|
+/// parameter to the constructor.
+class SSLRacer : public QThread {
+public:
+ bool m_seed;
+ QAtomicInt *m_running;
+
+ SSLRacer(QAtomicInt *running, bool seed)
+ : m_seed(seed)
+ , m_running(running) {
+ }
+
+ void run() {
+ unsigned char buf[64];
+ while (QAtomicIntLoad(*m_running) == 1) {
+ for (int i = 0; i < 1024; i++) {
+ if (m_seed) {
+ RAND_seed(buf, sizeof(buf));
+ } else {
+ RAND_bytes(buf, sizeof(buf));
+ }
+ }
+ }
+ }
+};
+
+class TestSSLLocks : public QObject {
+ Q_OBJECT
+ private slots:
+ void initTestCase();
+ void cleanupTestCase();
+ void stress();
+};
+
+void TestSSLLocks::initTestCase() {
+ // For OpenSSL < 1.1, if you comment out this line,
+ // you'll be running OpenSSL without locking callbacks
+ // enabled. That'll make this test fail by crashing/segfaulting.
+ MumbleSSL::initialize();
+}
+
+void TestSSLLocks::cleanupTestCase() {
+ MumbleSSL::destroy();
+}
+
+/// Stress test that our locking callbacks for OpenSSL are set up and
+/// working correctly.
+///
+/// We do this by spawning a bunch of SSLStresser threads. Some of the
+/// threads will try to read random bytes in a tight loop. Other threads
+/// will, at the same time, try to add/seed random bytes to the OpenSSL
+/// RAND system.
+///
+/// The idea is that without proper locking, the data races we're causing
+/// should quite quickly cause the process to crash.
+void TestSSLLocks::stress() {
+ std::vector<SSLRacer *> racers;
+ QAtomicInt running(1);
+
+ // Spawn 24 threads in total. 12 readers, and 12 writers.
+ // Don't be too careful about cleaning up the threads. We'll either
+ // pass or crash, so the threads will be cleaned up either way.
+ int nthreads = 24;
+ for (int i = 0; i < nthreads; i++) {
+ bool seeder = i % 2;
+ SSLRacer *racer = new SSLRacer(&running, seeder);
+ racers.push_back(racer);
+ racer->start();
+ }
+
+ // Wait 2 seconds for a crash/segfault.
+ // If we don't crash within 2 seconds, we expect
+ // that our locking implementation works.
+ QTest::qSleep(2000);
+
+ // Signal to the racers that they should stop.
+ running.fetchAndStoreOrdered(0);
+
+ // Wait for all racers to complete.
+ for (size_t i = 0; i < racers.size(); i++) {
+ SSLRacer *racer = racers.at(i);
+ racer->wait();
+ delete racer;
+ }
+}
+
+QTEST_MAIN(TestSSLLocks)
+#include "TestSSLLocks.moc"
diff --git a/src/tests/TestSSLLocks/TestSSLLocks.pro b/src/tests/TestSSLLocks/TestSSLLocks.pro
new file mode 100644
index 000000000..443c1b257
--- /dev/null
+++ b/src/tests/TestSSLLocks/TestSSLLocks.pro
@@ -0,0 +1,12 @@
+# Copyright 2005-2017 The Mumble Developers. All rights reserved.
+# Use of this source code is governed by a BSD-style license
+# that can be found in the LICENSE file at the root of the
+# Mumble source tree or at <https://www.mumble.info/LICENSE>.
+
+include(../test.pri)
+
+QT += network
+
+TARGET = TestSSLLocks
+SOURCES = SSL.cpp SSLLocks.cpp TestSSLLocks.cpp
+HEADERS = SSL.h SSLLocks.h
diff --git a/src/tests/tests.pro b/src/tests/tests.pro
index 2b608453b..5ba7cf603 100644
--- a/src/tests/tests.pro
+++ b/src/tests/tests.pro
@@ -16,4 +16,5 @@ SUBDIRS += \
TestUnresolvedServerAddress \
TestServerAddress \
TestServerResolver \
- TestSelfSignedCertificate
+ TestSelfSignedCertificate \
+ TestSSLLocks