Make bssl_shim's setup logic infallible
Trying to handle malloc failures here is a bit tedious. Just suppress
malloc failures because nothing useful can progress when we can't even
allocate ex_data.
Change-Id: Ieaf417bcf9285783a76097319782282ce74e4734
Reviewed-on: https://boringssl-review.googlesource.com/c/boringssl/+/66648
Commit-Queue: David Benjamin <davidben@google.com>
Reviewed-by: Bob Beck <bbe@google.com>
diff --git a/crypto/internal.h b/crypto/internal.h
index 5894d18..b5e27f5 100644
--- a/crypto/internal.h
+++ b/crypto/internal.h
@@ -271,8 +271,20 @@
// should be called in between independent tests, at a point where failure from
// a previous test will not impact subsequent ones.
OPENSSL_EXPORT void OPENSSL_reset_malloc_counter_for_testing(void);
+
+// OPENSSL_disable_malloc_failures_for_testing, when malloc testing is enabled,
+// disables simulated malloc failures. Calls to |OPENSSL_malloc| will not
+// increment the malloc counter or synthesize failures. This may be used to skip
+// simulating malloc failures in some region of code.
+OPENSSL_EXPORT void OPENSSL_disable_malloc_failures_for_testing(void);
+
+// OPENSSL_enable_malloc_failures_for_testing, when malloc testing is enabled,
+// re-enables simulated malloc failures.
+OPENSSL_EXPORT void OPENSSL_enable_malloc_failures_for_testing(void);
#else
OPENSSL_INLINE void OPENSSL_reset_malloc_counter_for_testing(void) {}
+OPENSSL_INLINE void OPENSSL_disable_malloc_failures_for_testing(void) {}
+OPENSSL_INLINE void OPENSSL_enable_malloc_failures_for_testing(void) {}
#endif
#if defined(__has_builtin)
diff --git a/crypto/mem.c b/crypto/mem.c
index 9e81476..0f286f8 100644
--- a/crypto/mem.c
+++ b/crypto/mem.c
@@ -138,7 +138,7 @@
static uint64_t current_malloc_count = 0;
static uint64_t malloc_number_to_fail = 0;
static int malloc_failure_enabled = 0, break_on_malloc_fail = 0,
- any_malloc_failed = 0;
+ any_malloc_failed = 0, disable_malloc_failures = 0;
static void malloc_exit_handler(void) {
CRYPTO_MUTEX_lock_read(&malloc_failure_lock);
@@ -168,7 +168,7 @@
static int should_fail_allocation() {
static CRYPTO_once_t once = CRYPTO_ONCE_INIT;
CRYPTO_once(&once, init_malloc_failure);
- if (!malloc_failure_enabled) {
+ if (!malloc_failure_enabled || disable_malloc_failures) {
return 0;
}
@@ -195,6 +195,20 @@
CRYPTO_MUTEX_unlock_write(&malloc_failure_lock);
}
+void OPENSSL_disable_malloc_failures_for_testing(void) {
+ CRYPTO_MUTEX_lock_write(&malloc_failure_lock);
+ BSSL_CHECK(!disable_malloc_failures);
+ disable_malloc_failures = 1;
+ CRYPTO_MUTEX_unlock_write(&malloc_failure_lock);
+}
+
+void OPENSSL_enable_malloc_failures_for_testing(void) {
+ CRYPTO_MUTEX_lock_write(&malloc_failure_lock);
+ BSSL_CHECK(disable_malloc_failures);
+ disable_malloc_failures = 0;
+ CRYPTO_MUTEX_unlock_write(&malloc_failure_lock);
+}
+
#else
static int should_fail_allocation(void) { return 0; }
#endif
diff --git a/ssl/test/test_config.cc b/ssl/test/test_config.cc
index 71812c5..d359894 100644
--- a/ssl/test/test_config.cc
+++ b/ssl/test/test_config.cc
@@ -531,30 +531,35 @@
return true;
}
-static CRYPTO_once_t once = CRYPTO_ONCE_INIT;
-static int g_config_index = 0;
-static CRYPTO_BUFFER_POOL *g_pool = nullptr;
+static CRYPTO_BUFFER_POOL *BufferPool() {
+ static CRYPTO_BUFFER_POOL *pool = [&] {
+ OPENSSL_disable_malloc_failures_for_testing();
+ CRYPTO_BUFFER_POOL *ret = CRYPTO_BUFFER_POOL_new();
+ BSSL_CHECK(ret != nullptr);
+ OPENSSL_enable_malloc_failures_for_testing();
+ return ret;
+ }();
+ return pool;
+}
-static bool InitGlobals() {
- CRYPTO_once(&once, [] {
- g_config_index = SSL_get_ex_new_index(0, NULL, NULL, NULL, NULL);
- g_pool = CRYPTO_BUFFER_POOL_new();
- });
- return g_config_index >= 0 && g_pool != nullptr;
+static int TestConfigExDataIndex() {
+ static int index = [&] {
+ OPENSSL_disable_malloc_failures_for_testing();
+ int ret = SSL_get_ex_new_index(0, nullptr, nullptr, nullptr, nullptr);
+ BSSL_CHECK(ret >= 0);
+ OPENSSL_enable_malloc_failures_for_testing();
+ return ret;
+ }();
+ return index;
}
bool SetTestConfig(SSL *ssl, const TestConfig *config) {
- if (!InitGlobals()) {
- return false;
- }
- return SSL_set_ex_data(ssl, g_config_index, (void *)config) == 1;
+ return SSL_set_ex_data(ssl, TestConfigExDataIndex(), (void *)config) == 1;
}
const TestConfig *GetTestConfig(const SSL *ssl) {
- if (!InitGlobals()) {
- return nullptr;
- }
- return static_cast<const TestConfig *>(SSL_get_ex_data(ssl, g_config_index));
+ return static_cast<const TestConfig *>(
+ SSL_get_ex_data(ssl, TestConfigExDataIndex()));
}
static int LegacyOCSPCallback(SSL *ssl, void *arg) {
@@ -1416,17 +1421,13 @@
}
bssl::UniquePtr<SSL_CTX> TestConfig::SetupCtx(SSL_CTX *old_ctx) const {
- if (!InitGlobals()) {
- return nullptr;
- }
-
bssl::UniquePtr<SSL_CTX> ssl_ctx(
SSL_CTX_new(is_dtls ? DTLS_method() : TLS_method()));
if (!ssl_ctx) {
return nullptr;
}
- SSL_CTX_set0_buffer_pool(ssl_ctx.get(), g_pool);
+ SSL_CTX_set0_buffer_pool(ssl_ctx.get(), BufferPool());
std::string cipher_list = "ALL:TLS_ECDHE_RSA_WITH_AES_128_CBC_SHA256";
if (!cipher.empty()) {