Rename OPENSSL_NO_THREADS, part 1.

BoringSSL depends on the platform's locking APIs to make internal global
state thread-safe, including the PRNG. On some single-threaded embedded
platforms, locking APIs may not exist, so this dependency may be disabled
with a build flag.

Doing so means the consumer promises the library will never be used in any
multi-threaded address space. It causes BoringSSL to be globally thread-unsafe.
Setting it inappropriately will subtly and unpredictably corrupt memory and
leak secret keys.

Unfortunately, folks sometimes misinterpreted OPENSSL_NO_THREADS as skipping an
internal thread pool or disabling an optionally extra-thread-safe mode. This is
not and has never been the case. Rename it to
OPENSSL_NO_THREADS_CORRUPT_MEMORY_AND_LEAK_SECRETS_IF_THREADED to clarify what
this option does.

Update-Note: As a first step, this CL makes both OPENSSL_NO_THREADS and
OPENSSL_NO_THREADS_CORRUPT_MEMORY_AND_LEAK_SECRETS_IF_THREADED work. A later CL
will remove the old name, so migrate callers after or at the same time as
picking up this CL.

Change-Id: Ibe4964ae43eb7a52f08fd966fccb330c0cc11a8c
Reviewed-on: https://boringssl-review.googlesource.com/32084
Commit-Queue: David Benjamin <davidben@google.com>
CQ-Verified: CQ bot account: commit-bot@chromium.org <commit-bot@chromium.org>
Reviewed-by: Adam Langley <agl@google.com>
This commit is contained in:
David Benjamin 2018-09-22 16:52:48 -07:00 committed by CQ bot account: commit-bot@chromium.org
parent 1764d7a3ea
commit 5b33effa72
10 changed files with 43 additions and 21 deletions

View File

@ -132,13 +132,13 @@
#endif #endif
#endif #endif
#if !defined(OPENSSL_NO_THREADS) && \ #if defined(OPENSSL_THREADS) && \
(!defined(OPENSSL_WINDOWS) || defined(__MINGW32__)) (!defined(OPENSSL_WINDOWS) || defined(__MINGW32__))
#include <pthread.h> #include <pthread.h>
#define OPENSSL_PTHREADS #define OPENSSL_PTHREADS
#endif #endif
#if !defined(OPENSSL_NO_THREADS) && !defined(OPENSSL_PTHREADS) && \ #if defined(OPENSSL_THREADS) && !defined(OPENSSL_PTHREADS) && \
defined(OPENSSL_WINDOWS) defined(OPENSSL_WINDOWS)
#define OPENSSL_WINDOWS_THREADS #define OPENSSL_WINDOWS_THREADS
OPENSSL_MSVC_PRAGMA(warning(push, 3)) OPENSSL_MSVC_PRAGMA(warning(push, 3))
@ -367,7 +367,7 @@ static inline int constant_time_select_int(crypto_word_t mask, int a, int b) {
// Thread-safe initialisation. // Thread-safe initialisation.
#if defined(OPENSSL_NO_THREADS) #if !defined(OPENSSL_THREADS)
typedef uint32_t CRYPTO_once_t; typedef uint32_t CRYPTO_once_t;
#define CRYPTO_ONCE_INIT 0 #define CRYPTO_ONCE_INIT 0
#elif defined(OPENSSL_WINDOWS_THREADS) #elif defined(OPENSSL_WINDOWS_THREADS)
@ -423,7 +423,7 @@ OPENSSL_EXPORT int CRYPTO_refcount_dec_and_test_zero(CRYPTO_refcount_t *count);
// thread.h as a structure large enough to fit the real type. The global lock is // thread.h as a structure large enough to fit the real type. The global lock is
// a different type so it may be initialized with platform initializer macros. // a different type so it may be initialized with platform initializer macros.
#if defined(OPENSSL_NO_THREADS) #if !defined(OPENSSL_THREADS)
struct CRYPTO_STATIC_MUTEX { struct CRYPTO_STATIC_MUTEX {
char padding; // Empty structs have different sizes in C and C++. char padding; // Empty structs have different sizes in C and C++.
}; };

View File

@ -18,7 +18,7 @@
#include "../test/test_util.h" #include "../test/test_util.h"
#if !defined(OPENSSL_NO_THREADS) #if defined(OPENSSL_THREADS)
#include <chrono> #include <chrono>
#include <thread> #include <thread>
#endif #endif
@ -61,7 +61,7 @@ TEST(PoolTest, Pooled) {
EXPECT_EQ(buf.get(), buf2.get()) << "CRYPTO_BUFFER_POOL did not dedup data."; EXPECT_EQ(buf.get(), buf2.get()) << "CRYPTO_BUFFER_POOL did not dedup data.";
} }
#if !defined(OPENSSL_NO_THREADS) #if defined(OPENSSL_THREADS)
TEST(PoolTest, Threads) { TEST(PoolTest, Threads) {
bssl::UniquePtr<CRYPTO_BUFFER_POOL> pool(CRYPTO_BUFFER_POOL_new()); bssl::UniquePtr<CRYPTO_BUFFER_POOL> pool(CRYPTO_BUFFER_POOL_new());
ASSERT_TRUE(pool); ASSERT_TRUE(pool);

View File

@ -20,7 +20,7 @@
#include "../test/test_util.h" #include "../test/test_util.h"
#if !defined(OPENSSL_NO_THREADS) #if defined(OPENSSL_THREADS)
#include <array> #include <array>
#include <thread> #include <thread>
#include <vector> #include <vector>
@ -146,7 +146,7 @@ TEST(RandTest, Fork) {
} }
#endif // !OPENSSL_WINDOWS && !BORINGSSL_UNSAFE_DETERMINISTIC_MODE #endif // !OPENSSL_WINDOWS && !BORINGSSL_UNSAFE_DETERMINISTIC_MODE
#if !defined(OPENSSL_NO_THREADS) #if defined(OPENSSL_THREADS)
static void RunConcurrentRands(size_t num_threads) { static void RunConcurrentRands(size_t num_threads) {
static const uint8_t kZeros[256] = {0}; static const uint8_t kZeros[256] = {0};

View File

@ -16,7 +16,7 @@
#include <gtest/gtest.h> #include <gtest/gtest.h>
#if !defined(OPENSSL_NO_THREADS) #if defined(OPENSSL_THREADS)
#include <thread> #include <thread>
#endif #endif
@ -43,7 +43,7 @@ TEST(RefCountTest, Basic) {
EXPECT_EQ(1u, count); EXPECT_EQ(1u, count);
} }
#if !defined(OPENSSL_NO_THREADS) #if defined(OPENSSL_THREADS)
// This test is primarily intended to run under ThreadSanitizer. // This test is primarily intended to run under ThreadSanitizer.
TEST(RefCountTest, Threads) { TEST(RefCountTest, Threads) {
CRYPTO_refcount_t count = 0; CRYPTO_refcount_t count = 0;

View File

@ -72,7 +72,7 @@
#include "../internal.h" #include "../internal.h"
#include "../test/test_util.h" #include "../test/test_util.h"
#if !defined(OPENSSL_NO_THREADS) #if defined(OPENSSL_THREADS)
#include <thread> #include <thread>
#include <vector> #include <vector>
#endif #endif
@ -1048,7 +1048,7 @@ TEST(RSATest, SqrtTwo) {
} }
#endif // !BORINGSSL_SHARED_LIBRARY #endif // !BORINGSSL_SHARED_LIBRARY
#if !defined(OPENSSL_NO_THREADS) #if defined(OPENSSL_THREADS)
TEST(RSATest, Threads) { TEST(RSATest, Threads) {
bssl::UniquePtr<RSA> rsa_template( bssl::UniquePtr<RSA> rsa_template(
RSA_private_key_from_bytes(kKey1, sizeof(kKey1) - 1)); RSA_private_key_from_bytes(kKey1, sizeof(kKey1) - 1));

View File

@ -14,7 +14,7 @@
#include "internal.h" #include "internal.h"
#if defined(OPENSSL_NO_THREADS) #if !defined(OPENSSL_THREADS)
void CRYPTO_MUTEX_init(CRYPTO_MUTEX *lock) {} void CRYPTO_MUTEX_init(CRYPTO_MUTEX *lock) {}
@ -56,4 +56,4 @@ int CRYPTO_set_thread_local(thread_local_data_t index, void *value,
return 1; return 1;
} }
#endif // OPENSSL_NO_THREADS #endif // !OPENSSL_THREADS

View File

@ -25,7 +25,7 @@
#include "test/test_util.h" #include "test/test_util.h"
#if !defined(OPENSSL_NO_THREADS) #if defined(OPENSSL_THREADS)
static unsigned g_once_init_called = 0; static unsigned g_once_init_called = 0;
@ -130,4 +130,4 @@ TEST(ThreadTest, RandState) {
thread.join(); thread.join();
} }
#endif // !OPENSSL_NO_THREADS #endif // OPENSSL_THREADS

View File

@ -136,14 +136,36 @@ extern "C" {
#if defined(TRUSTY) #if defined(TRUSTY)
#define OPENSSL_TRUSTY #define OPENSSL_TRUSTY
#define OPENSSL_NO_THREADS #define OPENSSL_NO_THREADS_CORRUPT_MEMORY_AND_LEAK_SECRETS_IF_THREADED
#endif #endif
#if defined(__ANDROID_API__) #if defined(__ANDROID_API__)
#define OPENSSL_ANDROID #define OPENSSL_ANDROID
#endif #endif
#if !defined(OPENSSL_NO_THREADS) // OPENSSL_NO_THREADS has been deprecated in favor of this much longer and
// louder name, to better reflect exactly what that option did.
//
// TODO(davidben): Remove this block when callers have migrated.
#if defined(OPENSSL_NO_THREADS) && \
!defined(OPENSSL_NO_THREADS_CORRUPT_MEMORY_AND_LEAK_SECRETS_IF_THREADED)
#define OPENSSL_NO_THREADS_CORRUPT_MEMORY_AND_LEAK_SECRETS_IF_THREADED
#endif
// BoringSSL requires platform's locking APIs to make internal global state
// thread-safe, including the PRNG. On some single-threaded embedded platforms,
// locking APIs may not exist, so this dependency may be disabled with the
// following build flag.
//
// IMPORTANT: Doing so means the consumer promises the library will never be
// used in any multi-threaded context. It causes BoringSSL to be globally
// thread-unsafe. Setting it inappropriately will subtly and unpredictably
// corrupt memory and leak secret keys.
//
// Do not set this flag on any platform where threads are possible. BoringSSL
// maintainers will not provide support for any consumers that do so. Changes
// which break such unsupported configurations will not be reverted.
#if !defined(OPENSSL_NO_THREADS_CORRUPT_MEMORY_AND_LEAK_SECRETS_IF_THREADED)
#define OPENSSL_THREADS #define OPENSSL_THREADS
#endif #endif

View File

@ -66,7 +66,7 @@ extern "C" {
#endif #endif
#if defined(OPENSSL_NO_THREADS) #if !defined(OPENSSL_THREADS)
typedef struct crypto_mutex_st { typedef struct crypto_mutex_st {
char padding; // Empty structs have different sizes in C and C++. char padding; // Empty structs have different sizes in C and C++.
} CRYPTO_MUTEX; } CRYPTO_MUTEX;

View File

@ -48,7 +48,7 @@ OPENSSL_MSVC_PRAGMA(warning(pop))
#include <sys/time.h> #include <sys/time.h>
#endif #endif
#if !defined(OPENSSL_NO_THREADS) #if defined(OPENSSL_THREADS)
#include <thread> #include <thread>
#endif #endif
@ -4298,7 +4298,7 @@ TEST_P(SSLVersionTest, FakeIDsForTickets) {
// These tests test multi-threaded behavior. They are intended to run with // These tests test multi-threaded behavior. They are intended to run with
// ThreadSanitizer. // ThreadSanitizer.
#if !defined(OPENSSL_NO_THREADS) #if defined(OPENSSL_THREADS)
TEST_P(SSLVersionTest, SessionCacheThreads) { TEST_P(SSLVersionTest, SessionCacheThreads) {
SSL_CTX_set_options(server_ctx_.get(), SSL_OP_NO_TICKET); SSL_CTX_set_options(server_ctx_.get(), SSL_OP_NO_TICKET);
SSL_CTX_set_session_cache_mode(client_ctx_.get(), SSL_SESS_CACHE_BOTH); SSL_CTX_set_session_cache_mode(client_ctx_.get(), SSL_SESS_CACHE_BOTH);