Remove CRYPTO_MUTEX from public headers

We no longer need to define CRYPTO_MUTEX in public headers. This
simplifies a pile of things. First, we can now use pthread_rwlock_t
without any fuss, rather than trying to guess the size on glibc.

As a result, CRYPTO_MUTEX and CRYPTO_STATIC_MUTEX can be merged into one
type. We can almost do this to CRYPTO_refcount_t too. BIO is the one
straggler remaining.

Fixed: 325
Change-Id: Ie93c9f553c0f02ce594b959c041b00fc15ba51d2
Reviewed-on: https://boringssl-review.googlesource.com/c/boringssl/+/60611
Commit-Queue: David Benjamin <davidben@google.com>
Reviewed-by: Bob Beck <bbe@google.com>
main-with-bazel
David Benjamin 1 year ago committed by Boringssl LUCI CQ
parent d4553e0538
commit 04c3d40f06
  1. 10
      crypto/asn1/a_strnid.c
  2. 6
      crypto/bio/bio.c
  3. 2
      crypto/dsa/internal.h
  4. 7
      crypto/err/err.c
  5. 6
      crypto/ex_data.c
  6. 11
      crypto/fipsmodule/delocate.h
  7. 2
      crypto/fipsmodule/dh/internal.h
  8. 8
      crypto/fipsmodule/ec/ec.c
  9. 6
      crypto/fipsmodule/rand/fork_detect.c
  10. 22
      crypto/fipsmodule/rand/rand.c
  11. 1
      crypto/fipsmodule/rsa/internal.h
  12. 57
      crypto/internal.h
  13. 15
      crypto/mem.c
  14. 42
      crypto/obj/obj.c
  15. 1
      crypto/pool/internal.h
  16. 6
      crypto/rand_extra/deterministic.c
  17. 8
      crypto/thread_none.c
  18. 41
      crypto/thread_pthread.c
  19. 8
      crypto/thread_test.cc
  20. 31
      crypto/thread_win.c
  21. 14
      crypto/x509/by_dir.c
  22. 1
      crypto/x509/internal.h
  23. 10
      crypto/x509/x_crl.c
  24. 14
      crypto/x509/x_pubkey.c
  25. 28
      include/openssl/thread.h

@ -72,7 +72,7 @@
DEFINE_LHASH_OF(ASN1_STRING_TABLE)
static LHASH_OF(ASN1_STRING_TABLE) *string_tables = NULL;
static struct CRYPTO_STATIC_MUTEX string_tables_lock = CRYPTO_STATIC_MUTEX_INIT;
static CRYPTO_MUTEX string_tables_lock = CRYPTO_MUTEX_INIT;
void ASN1_STRING_set_default_mask(unsigned long mask) {}
@ -176,11 +176,11 @@ static const ASN1_STRING_TABLE *asn1_string_table_get(int nid) {
return tbl;
}
CRYPTO_STATIC_MUTEX_lock_read(&string_tables_lock);
CRYPTO_MUTEX_lock_read(&string_tables_lock);
if (string_tables != NULL) {
tbl = lh_ASN1_STRING_TABLE_retrieve(string_tables, &key);
}
CRYPTO_STATIC_MUTEX_unlock_read(&string_tables_lock);
CRYPTO_MUTEX_unlock_read(&string_tables_lock);
// Note returning |tbl| without the lock is only safe because
// |ASN1_STRING_TABLE_add| cannot modify or delete existing entries. If we
// wish to support that, this function must copy the result under a lock.
@ -196,7 +196,7 @@ int ASN1_STRING_TABLE_add(int nid, long minsize, long maxsize,
}
int ret = 0;
CRYPTO_STATIC_MUTEX_lock_write(&string_tables_lock);
CRYPTO_MUTEX_lock_write(&string_tables_lock);
if (string_tables == NULL) {
string_tables = lh_ASN1_STRING_TABLE_new(table_hash, table_cmp);
@ -232,7 +232,7 @@ int ASN1_STRING_TABLE_add(int nid, long minsize, long maxsize,
ret = 1;
err:
CRYPTO_STATIC_MUTEX_unlock_write(&string_tables_lock);
CRYPTO_MUTEX_unlock_write(&string_tables_lock);
return ret;
}

@ -628,14 +628,14 @@ void BIO_set_retry_special(BIO *bio) {
int BIO_set_write_buffer_size(BIO *bio, int buffer_size) { return 0; }
static struct CRYPTO_STATIC_MUTEX g_index_lock = CRYPTO_STATIC_MUTEX_INIT;
static CRYPTO_MUTEX g_index_lock = CRYPTO_MUTEX_INIT;
static int g_index = BIO_TYPE_START;
int BIO_get_new_index(void) {
CRYPTO_STATIC_MUTEX_lock_write(&g_index_lock);
CRYPTO_MUTEX_lock_write(&g_index_lock);
// If |g_index| exceeds 255, it will collide with the flags bits.
int ret = g_index > 255 ? -1 : g_index++;
CRYPTO_STATIC_MUTEX_unlock_write(&g_index_lock);
CRYPTO_MUTEX_unlock_write(&g_index_lock);
return ret;
}

@ -19,6 +19,8 @@
#include <openssl/thread.h>
#include "../internal.h"
#if defined(__cplusplus)
extern "C" {
#endif

@ -192,8 +192,7 @@ static int global_next_library = ERR_NUM_LIBS;
// global_next_library_mutex protects |global_next_library| from concurrent
// updates.
static struct CRYPTO_STATIC_MUTEX global_next_library_mutex =
CRYPTO_STATIC_MUTEX_INIT;
static CRYPTO_MUTEX global_next_library_mutex = CRYPTO_MUTEX_INIT;
static void err_state_free(void *statep) {
ERR_STATE *state = statep;
@ -367,9 +366,9 @@ void ERR_remove_thread_state(const CRYPTO_THREADID *tid) {
int ERR_get_next_error_library(void) {
int ret;
CRYPTO_STATIC_MUTEX_lock_write(&global_next_library_mutex);
CRYPTO_MUTEX_lock_write(&global_next_library_mutex);
ret = global_next_library++;
CRYPTO_STATIC_MUTEX_unlock_write(&global_next_library_mutex);
CRYPTO_MUTEX_unlock_write(&global_next_library_mutex);
return ret;
}

@ -144,13 +144,13 @@ int CRYPTO_get_ex_new_index(CRYPTO_EX_DATA_CLASS *ex_data_class, int *out_index,
funcs->free_func = free_func;
funcs->next = NULL;
CRYPTO_STATIC_MUTEX_lock_write(&ex_data_class->lock);
CRYPTO_MUTEX_lock_write(&ex_data_class->lock);
uint32_t num_funcs = CRYPTO_atomic_load_u32(&ex_data_class->num_funcs);
// The index must fit in |int|.
if (num_funcs > (size_t)(INT_MAX - ex_data_class->num_reserved)) {
OPENSSL_PUT_ERROR(CRYPTO, ERR_R_OVERFLOW);
CRYPTO_STATIC_MUTEX_unlock_write(&ex_data_class->lock);
CRYPTO_MUTEX_unlock_write(&ex_data_class->lock);
return 0;
}
@ -165,7 +165,7 @@ int CRYPTO_get_ex_new_index(CRYPTO_EX_DATA_CLASS *ex_data_class, int *out_index,
}
CRYPTO_atomic_store_u32(&ex_data_class->num_funcs, num_funcs + 1);
CRYPTO_STATIC_MUTEX_unlock_write(&ex_data_class->lock);
CRYPTO_MUTEX_unlock_write(&ex_data_class->lock);
*out_index = (int)num_funcs + ex_data_class->num_reserved;
return 1;
}

@ -27,9 +27,8 @@
type *name##_bss_get(void) __attribute__((const));
// For FIPS builds we require that CRYPTO_ONCE_INIT be zero.
#define DEFINE_STATIC_ONCE(name) DEFINE_BSS_GET(CRYPTO_once_t, name)
// For FIPS builds we require that CRYPTO_STATIC_MUTEX_INIT be zero.
#define DEFINE_STATIC_MUTEX(name) \
DEFINE_BSS_GET(struct CRYPTO_STATIC_MUTEX, name)
// For FIPS builds we require that CRYPTO_MUTEX_INIT be zero.
#define DEFINE_STATIC_MUTEX(name) DEFINE_BSS_GET(CRYPTO_MUTEX, name)
// For FIPS builds we require that CRYPTO_EX_DATA_CLASS_INIT be zero.
#define DEFINE_STATIC_EX_DATA_CLASS(name) \
DEFINE_BSS_GET(CRYPTO_EX_DATA_CLASS, name)
@ -40,9 +39,9 @@
#define DEFINE_STATIC_ONCE(name) \
static CRYPTO_once_t name = CRYPTO_ONCE_INIT; \
static CRYPTO_once_t *name##_bss_get(void) { return &name; }
#define DEFINE_STATIC_MUTEX(name) \
static struct CRYPTO_STATIC_MUTEX name = CRYPTO_STATIC_MUTEX_INIT; \
static struct CRYPTO_STATIC_MUTEX *name##_bss_get(void) { return &name; }
#define DEFINE_STATIC_MUTEX(name) \
static CRYPTO_MUTEX name = CRYPTO_MUTEX_INIT; \
static CRYPTO_MUTEX *name##_bss_get(void) { return &name; }
#define DEFINE_STATIC_EX_DATA_CLASS(name) \
static CRYPTO_EX_DATA_CLASS name = CRYPTO_EX_DATA_CLASS_INIT; \
static CRYPTO_EX_DATA_CLASS *name##_bss_get(void) { return &name; }

@ -19,6 +19,8 @@
#include <openssl/thread.h>
#include "../../internal.h"
#if defined(__cplusplus)
extern "C" {
#endif

@ -520,9 +520,9 @@ EC_GROUP *EC_GROUP_new_by_curve_name(int nid) {
return NULL;
}
CRYPTO_STATIC_MUTEX_lock_read(built_in_groups_lock_bss_get());
CRYPTO_MUTEX_lock_read(built_in_groups_lock_bss_get());
EC_GROUP *ret = *group_ptr;
CRYPTO_STATIC_MUTEX_unlock_read(built_in_groups_lock_bss_get());
CRYPTO_MUTEX_unlock_read(built_in_groups_lock_bss_get());
if (ret != NULL) {
return ret;
}
@ -533,7 +533,7 @@ EC_GROUP *EC_GROUP_new_by_curve_name(int nid) {
}
EC_GROUP *to_free = NULL;
CRYPTO_STATIC_MUTEX_lock_write(built_in_groups_lock_bss_get());
CRYPTO_MUTEX_lock_write(built_in_groups_lock_bss_get());
if (*group_ptr == NULL) {
*group_ptr = ret;
// Filling in |ret->curve_name| makes |EC_GROUP_free| and |EC_GROUP_dup|
@ -543,7 +543,7 @@ EC_GROUP *EC_GROUP_new_by_curve_name(int nid) {
to_free = ret;
ret = *group_ptr;
}
CRYPTO_STATIC_MUTEX_unlock_write(built_in_groups_lock_bss_get());
CRYPTO_MUTEX_unlock_write(built_in_groups_lock_bss_get());
EC_GROUP_free(to_free);
return ret;

@ -114,8 +114,8 @@ uint64_t CRYPTO_get_fork_generation(void) {
// The flag was zero. The generation number must be incremented, but other
// threads may have concurrently observed the zero, so take a lock before
// incrementing.
struct CRYPTO_STATIC_MUTEX *const lock = g_fork_detect_lock_bss_get();
CRYPTO_STATIC_MUTEX_lock_write(lock);
CRYPTO_MUTEX *const lock = g_fork_detect_lock_bss_get();
CRYPTO_MUTEX_lock_write(lock);
uint64_t current_generation = *generation_ptr;
if (CRYPTO_atomic_load_u32(flag_ptr) == 0) {
// A fork has occurred.
@ -130,7 +130,7 @@ uint64_t CRYPTO_get_fork_generation(void) {
*generation_ptr = current_generation;
CRYPTO_atomic_store_u32(flag_ptr, 1);
}
CRYPTO_STATIC_MUTEX_unlock_write(lock);
CRYPTO_MUTEX_unlock_write(lock);
return current_generation;
}

@ -92,7 +92,7 @@ DEFINE_STATIC_MUTEX(thread_states_list_lock);
static void rand_thread_state_clear_all(void) __attribute__((destructor));
static void rand_thread_state_clear_all(void) {
CRYPTO_STATIC_MUTEX_lock_write(thread_states_list_lock_bss_get());
CRYPTO_MUTEX_lock_write(thread_states_list_lock_bss_get());
for (struct rand_thread_state *cur = *thread_states_list_bss_get();
cur != NULL; cur = cur->next) {
CRYPTO_MUTEX_lock_write(&cur->clear_drbg_lock);
@ -115,7 +115,7 @@ static void rand_thread_state_free(void *state_in) {
}
#if defined(BORINGSSL_FIPS)
CRYPTO_STATIC_MUTEX_lock_write(thread_states_list_lock_bss_get());
CRYPTO_MUTEX_lock_write(thread_states_list_lock_bss_get());
if (state->prev != NULL) {
state->prev->next = state->next;
@ -127,7 +127,7 @@ static void rand_thread_state_free(void *state_in) {
state->next->prev = state->prev;
}
CRYPTO_STATIC_MUTEX_unlock_write(thread_states_list_lock_bss_get());
CRYPTO_MUTEX_unlock_write(thread_states_list_lock_bss_get());
CTR_DRBG_clear(&state->drbg);
#endif
@ -203,7 +203,7 @@ void RAND_load_entropy(const uint8_t *entropy, size_t entropy_len,
int want_additional_input) {
struct entropy_buffer *const buffer = entropy_buffer_bss_get();
CRYPTO_STATIC_MUTEX_lock_write(entropy_buffer_lock_bss_get());
CRYPTO_MUTEX_lock_write(entropy_buffer_lock_bss_get());
const size_t space = sizeof(buffer->bytes) - buffer->bytes_valid;
if (entropy_len > space) {
entropy_len = space;
@ -213,7 +213,7 @@ void RAND_load_entropy(const uint8_t *entropy, size_t entropy_len,
buffer->bytes_valid += entropy_len;
buffer->want_additional_input |=
want_additional_input && (entropy_len != 0);
CRYPTO_STATIC_MUTEX_unlock_write(entropy_buffer_lock_bss_get());
CRYPTO_MUTEX_unlock_write(entropy_buffer_lock_bss_get());
}
// get_seed_entropy fills |out_entropy_len| bytes of |out_entropy| from the
@ -225,11 +225,11 @@ static void get_seed_entropy(uint8_t *out_entropy, size_t out_entropy_len,
abort();
}
CRYPTO_STATIC_MUTEX_lock_write(entropy_buffer_lock_bss_get());
CRYPTO_MUTEX_lock_write(entropy_buffer_lock_bss_get());
while (buffer->bytes_valid < out_entropy_len) {
CRYPTO_STATIC_MUTEX_unlock_write(entropy_buffer_lock_bss_get());
CRYPTO_MUTEX_unlock_write(entropy_buffer_lock_bss_get());
RAND_need_entropy(out_entropy_len - buffer->bytes_valid);
CRYPTO_STATIC_MUTEX_lock_write(entropy_buffer_lock_bss_get());
CRYPTO_MUTEX_lock_write(entropy_buffer_lock_bss_get());
}
*out_want_additional_input = buffer->want_additional_input;
@ -241,7 +241,7 @@ static void get_seed_entropy(uint8_t *out_entropy, size_t out_entropy_len,
buffer->want_additional_input = 0;
}
CRYPTO_STATIC_MUTEX_unlock_write(entropy_buffer_lock_bss_get());
CRYPTO_MUTEX_unlock_write(entropy_buffer_lock_bss_get());
}
// rand_get_seed fills |seed| with entropy. In some cases, it will additionally
@ -397,7 +397,7 @@ void RAND_bytes_with_additional_data(uint8_t *out, size_t out_len,
#if defined(BORINGSSL_FIPS)
CRYPTO_MUTEX_init(&state->clear_drbg_lock);
if (state != &stack_state) {
CRYPTO_STATIC_MUTEX_lock_write(thread_states_list_lock_bss_get());
CRYPTO_MUTEX_lock_write(thread_states_list_lock_bss_get());
struct rand_thread_state **states_list = thread_states_list_bss_get();
state->next = *states_list;
if (state->next != NULL) {
@ -405,7 +405,7 @@ void RAND_bytes_with_additional_data(uint8_t *out, size_t out_len,
}
state->prev = NULL;
*states_list = state;
CRYPTO_STATIC_MUTEX_unlock_write(thread_states_list_lock_bss_get());
CRYPTO_MUTEX_unlock_write(thread_states_list_lock_bss_get());
}
#endif
}

@ -62,6 +62,7 @@
#include <openssl/bn.h>
#include <openssl/rsa.h>
#include "../../internal.h"
#if defined(__cplusplus)
extern "C" {

@ -735,37 +735,24 @@ OPENSSL_EXPORT int CRYPTO_refcount_dec_and_test_zero(CRYPTO_refcount_t *count);
// Locks.
//
// Two types of locks are defined: |CRYPTO_MUTEX|, which can be used in
// structures as normal, and |struct CRYPTO_STATIC_MUTEX|, which can be used as
// a global lock. A global lock must be initialised to the value
// |CRYPTO_STATIC_MUTEX_INIT|.
//
// |CRYPTO_MUTEX| can appear in public structures and so is defined in
// 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.
#if !defined(OPENSSL_THREADS)
struct CRYPTO_STATIC_MUTEX {
typedef struct crypto_mutex_st {
char padding; // Empty structs have different sizes in C and C++.
};
#define CRYPTO_STATIC_MUTEX_INIT { 0 }
} CRYPTO_MUTEX;
#define CRYPTO_MUTEX_INIT { 0 }
#elif defined(OPENSSL_WINDOWS_THREADS)
struct CRYPTO_STATIC_MUTEX {
SRWLOCK lock;
};
#define CRYPTO_STATIC_MUTEX_INIT { SRWLOCK_INIT }
typedef SRWLOCK CRYPTO_MUTEX;
#define CRYPTO_MUTEX_INIT SRWLOCK_INIT
#elif defined(OPENSSL_PTHREADS)
struct CRYPTO_STATIC_MUTEX {
pthread_rwlock_t lock;
};
#define CRYPTO_STATIC_MUTEX_INIT { PTHREAD_RWLOCK_INITIALIZER }
typedef pthread_rwlock_t CRYPTO_MUTEX;
#define CRYPTO_MUTEX_INIT PTHREAD_RWLOCK_INITIALIZER
#else
#error "Unknown threading library"
#endif
// CRYPTO_MUTEX_init initialises |lock|. If |lock| is a static variable, use a
// |CRYPTO_STATIC_MUTEX|.
// |CRYPTO_MUTEX_INIT|.
OPENSSL_EXPORT void CRYPTO_MUTEX_init(CRYPTO_MUTEX *lock);
// CRYPTO_MUTEX_lock_read locks |lock| such that other threads may also have a
@ -785,28 +772,6 @@ OPENSSL_EXPORT void CRYPTO_MUTEX_unlock_write(CRYPTO_MUTEX *lock);
// CRYPTO_MUTEX_cleanup releases all resources held by |lock|.
OPENSSL_EXPORT void CRYPTO_MUTEX_cleanup(CRYPTO_MUTEX *lock);
// CRYPTO_STATIC_MUTEX_lock_read locks |lock| such that other threads may also
// have a read lock, but none may have a write lock. The |lock| variable does
// not need to be initialised by any function, but must have been statically
// initialised with |CRYPTO_STATIC_MUTEX_INIT|.
OPENSSL_EXPORT void CRYPTO_STATIC_MUTEX_lock_read(
struct CRYPTO_STATIC_MUTEX *lock);
// CRYPTO_STATIC_MUTEX_lock_write locks |lock| such that no other thread has
// any type of lock on it. The |lock| variable does not need to be initialised
// by any function, but must have been statically initialised with
// |CRYPTO_STATIC_MUTEX_INIT|.
OPENSSL_EXPORT void CRYPTO_STATIC_MUTEX_lock_write(
struct CRYPTO_STATIC_MUTEX *lock);
// CRYPTO_STATIC_MUTEX_unlock_read unlocks |lock| for reading.
OPENSSL_EXPORT void CRYPTO_STATIC_MUTEX_unlock_read(
struct CRYPTO_STATIC_MUTEX *lock);
// CRYPTO_STATIC_MUTEX_unlock_write unlocks |lock| for writing.
OPENSSL_EXPORT void CRYPTO_STATIC_MUTEX_unlock_write(
struct CRYPTO_STATIC_MUTEX *lock);
#if defined(__cplusplus)
extern "C++" {
@ -892,7 +857,7 @@ typedef struct crypto_ex_data_func_st CRYPTO_EX_DATA_FUNCS;
// supports ex_data. It should defined as a static global within the module
// which defines that type.
typedef struct {
struct CRYPTO_STATIC_MUTEX lock;
CRYPTO_MUTEX lock;
// funcs is a linked list of |CRYPTO_EX_DATA_FUNCS| structures. It may be
// traversed without serialization only up to |num_funcs|. last points to the
// final entry of |funcs|, or NULL if empty.
@ -904,9 +869,9 @@ typedef struct {
uint8_t num_reserved;
} CRYPTO_EX_DATA_CLASS;
#define CRYPTO_EX_DATA_CLASS_INIT {CRYPTO_STATIC_MUTEX_INIT, NULL, NULL, 0, 0}
#define CRYPTO_EX_DATA_CLASS_INIT {CRYPTO_MUTEX_INIT, NULL, NULL, 0, 0}
#define CRYPTO_EX_DATA_CLASS_INIT_WITH_APP_DATA \
{CRYPTO_STATIC_MUTEX_INIT, NULL, NULL, 0, 1}
{CRYPTO_MUTEX_INIT, NULL, NULL, 0, 1}
// CRYPTO_get_ex_new_index allocates a new index for |ex_data_class| and writes
// it to |*out_index|. Each class of object should provide a wrapper function

@ -159,21 +159,20 @@ static const uint8_t kBoringSSLBinaryTag[18] = {
};
#if defined(BORINGSSL_MALLOC_FAILURE_TESTING)
static struct CRYPTO_STATIC_MUTEX malloc_failure_lock =
CRYPTO_STATIC_MUTEX_INIT;
static CRYPTO_MUTEX malloc_failure_lock = CRYPTO_MUTEX_INIT;
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;
static void malloc_exit_handler(void) {
CRYPTO_STATIC_MUTEX_lock_read(&malloc_failure_lock);
CRYPTO_MUTEX_lock_read(&malloc_failure_lock);
if (any_malloc_failed) {
// Signal to the test driver that some allocation failed, so it knows to
// increment the counter and continue.
_exit(88);
}
CRYPTO_STATIC_MUTEX_unlock_read(&malloc_failure_lock);
CRYPTO_MUTEX_unlock_read(&malloc_failure_lock);
}
static void init_malloc_failure(void) {
@ -200,11 +199,11 @@ static int should_fail_allocation() {
// We lock just so multi-threaded tests are still correct, but we won't test
// every malloc exhaustively.
CRYPTO_STATIC_MUTEX_lock_write(&malloc_failure_lock);
CRYPTO_MUTEX_lock_write(&malloc_failure_lock);
int should_fail = current_malloc_count == malloc_number_to_fail;
current_malloc_count++;
any_malloc_failed = any_malloc_failed || should_fail;
CRYPTO_STATIC_MUTEX_unlock_write(&malloc_failure_lock);
CRYPTO_MUTEX_unlock_write(&malloc_failure_lock);
if (should_fail && break_on_malloc_fail) {
raise(SIGTRAP);
@ -216,9 +215,9 @@ static int should_fail_allocation() {
}
void OPENSSL_reset_malloc_counter_for_testing(void) {
CRYPTO_STATIC_MUTEX_lock_write(&malloc_failure_lock);
CRYPTO_MUTEX_lock_write(&malloc_failure_lock);
current_malloc_count = 0;
CRYPTO_STATIC_MUTEX_unlock_write(&malloc_failure_lock);
CRYPTO_MUTEX_unlock_write(&malloc_failure_lock);
}
#else

@ -77,24 +77,20 @@
DEFINE_LHASH_OF(ASN1_OBJECT)
static struct CRYPTO_STATIC_MUTEX global_added_lock = CRYPTO_STATIC_MUTEX_INIT;
static CRYPTO_MUTEX global_added_lock = CRYPTO_MUTEX_INIT;
// These globals are protected by |global_added_lock|.
static LHASH_OF(ASN1_OBJECT) *global_added_by_data = NULL;
static LHASH_OF(ASN1_OBJECT) *global_added_by_nid = NULL;
static LHASH_OF(ASN1_OBJECT) *global_added_by_short_name = NULL;
static LHASH_OF(ASN1_OBJECT) *global_added_by_long_name = NULL;
static struct CRYPTO_STATIC_MUTEX global_next_nid_lock =
CRYPTO_STATIC_MUTEX_INIT;
static CRYPTO_MUTEX global_next_nid_lock = CRYPTO_MUTEX_INIT;
static unsigned global_next_nid = NUM_NID;
static int obj_next_nid(void) {
int ret;
CRYPTO_STATIC_MUTEX_lock_write(&global_next_nid_lock);
ret = global_next_nid++;
CRYPTO_STATIC_MUTEX_unlock_write(&global_next_nid_lock);
CRYPTO_MUTEX_lock_write(&global_next_nid_lock);
int ret = global_next_nid++;
CRYPTO_MUTEX_unlock_write(&global_next_nid_lock);
return ret;
}
@ -213,17 +209,17 @@ int OBJ_obj2nid(const ASN1_OBJECT *obj) {
return obj->nid;
}
CRYPTO_STATIC_MUTEX_lock_read(&global_added_lock);
CRYPTO_MUTEX_lock_read(&global_added_lock);
if (global_added_by_data != NULL) {
ASN1_OBJECT *match;
match = lh_ASN1_OBJECT_retrieve(global_added_by_data, obj);
if (match != NULL) {
CRYPTO_STATIC_MUTEX_unlock_read(&global_added_lock);
CRYPTO_MUTEX_unlock_read(&global_added_lock);
return match->nid;
}
}
CRYPTO_STATIC_MUTEX_unlock_read(&global_added_lock);
CRYPTO_MUTEX_unlock_read(&global_added_lock);
const uint16_t *nid_ptr =
bsearch(obj, kNIDsInOIDOrder, OPENSSL_ARRAY_SIZE(kNIDsInOIDOrder),
@ -259,18 +255,18 @@ static int short_name_cmp(const void *key, const void *element) {
}
int OBJ_sn2nid(const char *short_name) {
CRYPTO_STATIC_MUTEX_lock_read(&global_added_lock);
CRYPTO_MUTEX_lock_read(&global_added_lock);
if (global_added_by_short_name != NULL) {
ASN1_OBJECT *match, template;
template.sn = short_name;
match = lh_ASN1_OBJECT_retrieve(global_added_by_short_name, &template);
if (match != NULL) {
CRYPTO_STATIC_MUTEX_unlock_read(&global_added_lock);
CRYPTO_MUTEX_unlock_read(&global_added_lock);
return match->nid;
}
}
CRYPTO_STATIC_MUTEX_unlock_read(&global_added_lock);
CRYPTO_MUTEX_unlock_read(&global_added_lock);
const uint16_t *nid_ptr =
bsearch(short_name, kNIDsInShortNameOrder,
@ -294,18 +290,18 @@ static int long_name_cmp(const void *key, const void *element) {
}
int OBJ_ln2nid(const char *long_name) {
CRYPTO_STATIC_MUTEX_lock_read(&global_added_lock);
CRYPTO_MUTEX_lock_read(&global_added_lock);
if (global_added_by_long_name != NULL) {
ASN1_OBJECT *match, template;
template.ln = long_name;
match = lh_ASN1_OBJECT_retrieve(global_added_by_long_name, &template);
if (match != NULL) {
CRYPTO_STATIC_MUTEX_unlock_read(&global_added_lock);
CRYPTO_MUTEX_unlock_read(&global_added_lock);
return match->nid;
}
}
CRYPTO_STATIC_MUTEX_unlock_read(&global_added_lock);
CRYPTO_MUTEX_unlock_read(&global_added_lock);
const uint16_t *nid_ptr = bsearch(
long_name, kNIDsInLongNameOrder, OPENSSL_ARRAY_SIZE(kNIDsInLongNameOrder),
@ -349,18 +345,18 @@ ASN1_OBJECT *OBJ_nid2obj(int nid) {
return (ASN1_OBJECT *)&kObjects[nid];
}
CRYPTO_STATIC_MUTEX_lock_read(&global_added_lock);
CRYPTO_MUTEX_lock_read(&global_added_lock);
if (global_added_by_nid != NULL) {
ASN1_OBJECT *match, template;
template.nid = nid;
match = lh_ASN1_OBJECT_retrieve(global_added_by_nid, &template);
if (match != NULL) {
CRYPTO_STATIC_MUTEX_unlock_read(&global_added_lock);
CRYPTO_MUTEX_unlock_read(&global_added_lock);
return match;
}
}
CRYPTO_STATIC_MUTEX_unlock_read(&global_added_lock);
CRYPTO_MUTEX_unlock_read(&global_added_lock);
err:
OPENSSL_PUT_ERROR(OBJ, OBJ_R_UNKNOWN_NID);
@ -508,7 +504,7 @@ static int obj_add_object(ASN1_OBJECT *obj) {
obj->flags &= ~(ASN1_OBJECT_FLAG_DYNAMIC | ASN1_OBJECT_FLAG_DYNAMIC_STRINGS |
ASN1_OBJECT_FLAG_DYNAMIC_DATA);
CRYPTO_STATIC_MUTEX_lock_write(&global_added_lock);
CRYPTO_MUTEX_lock_write(&global_added_lock);
if (global_added_by_nid == NULL) {
global_added_by_nid = lh_ASN1_OBJECT_new(hash_nid, cmp_nid);
}
@ -548,7 +544,7 @@ static int obj_add_object(ASN1_OBJECT *obj) {
}
err:
CRYPTO_STATIC_MUTEX_unlock_write(&global_added_lock);
CRYPTO_MUTEX_unlock_write(&global_added_lock);
return ok;
}

@ -18,6 +18,7 @@
#include <openssl/lhash.h>
#include <openssl/thread.h>
#include "../internal.h"
#include "../lhash/internal.h"

@ -30,16 +30,16 @@
// multi-threaded program, replace this with a thread-local. (A mutex would not
// be deterministic.)
static uint64_t g_num_calls = 0;
static struct CRYPTO_STATIC_MUTEX g_num_calls_lock = CRYPTO_STATIC_MUTEX_INIT;
static CRYPTO_MUTEX g_num_calls_lock = CRYPTO_MUTEX_INIT;
void RAND_reset_for_fuzzing(void) { g_num_calls = 0; }
void CRYPTO_sysrand(uint8_t *out, size_t requested) {
static const uint8_t kZeroKey[32];
CRYPTO_STATIC_MUTEX_lock_write(&g_num_calls_lock);
CRYPTO_MUTEX_lock_write(&g_num_calls_lock);
uint64_t num_calls = g_num_calls++;
CRYPTO_STATIC_MUTEX_unlock_write(&g_num_calls_lock);
CRYPTO_MUTEX_unlock_write(&g_num_calls_lock);
uint8_t nonce[12];
OPENSSL_memset(nonce, 0, sizeof(nonce));

@ -28,14 +28,6 @@ void CRYPTO_MUTEX_unlock_write(CRYPTO_MUTEX *lock) {}
void CRYPTO_MUTEX_cleanup(CRYPTO_MUTEX *lock) {}
void CRYPTO_STATIC_MUTEX_lock_read(struct CRYPTO_STATIC_MUTEX *lock) {}
void CRYPTO_STATIC_MUTEX_lock_write(struct CRYPTO_STATIC_MUTEX *lock) {}
void CRYPTO_STATIC_MUTEX_unlock_read(struct CRYPTO_STATIC_MUTEX *lock) {}
void CRYPTO_STATIC_MUTEX_unlock_write(struct CRYPTO_STATIC_MUTEX *lock) {}
void CRYPTO_once(CRYPTO_once_t *once, void (*init)(void)) {
if (*once) {
return;

@ -23,67 +23,38 @@
#include <stdlib.h>
#include <string.h>
static_assert(sizeof(CRYPTO_MUTEX) >= sizeof(pthread_rwlock_t),
"CRYPTO_MUTEX is too small");
static_assert(alignof(CRYPTO_MUTEX) >= alignof(pthread_rwlock_t),
"CRYPTO_MUTEX has insufficient alignment");
void CRYPTO_MUTEX_init(CRYPTO_MUTEX *lock) {
if (pthread_rwlock_init((pthread_rwlock_t *) lock, NULL) != 0) {
if (pthread_rwlock_init(lock, NULL) != 0) {
abort();
}
}
void CRYPTO_MUTEX_lock_read(CRYPTO_MUTEX *lock) {
if (pthread_rwlock_rdlock((pthread_rwlock_t *) lock) != 0) {
if (pthread_rwlock_rdlock(lock) != 0) {
abort();
}
}
void CRYPTO_MUTEX_lock_write(CRYPTO_MUTEX *lock) {
if (pthread_rwlock_wrlock((pthread_rwlock_t *) lock) != 0) {
if (pthread_rwlock_wrlock(lock) != 0) {
abort();
}
}
void CRYPTO_MUTEX_unlock_read(CRYPTO_MUTEX *lock) {
if (pthread_rwlock_unlock((pthread_rwlock_t *) lock) != 0) {
if (pthread_rwlock_unlock(lock) != 0) {
abort();
}
}
void CRYPTO_MUTEX_unlock_write(CRYPTO_MUTEX *lock) {
if (pthread_rwlock_unlock((pthread_rwlock_t *) lock) != 0) {
if (pthread_rwlock_unlock(lock) != 0) {
abort();
}
}
void CRYPTO_MUTEX_cleanup(CRYPTO_MUTEX *lock) {
pthread_rwlock_destroy((pthread_rwlock_t *) lock);
}
void CRYPTO_STATIC_MUTEX_lock_read(struct CRYPTO_STATIC_MUTEX *lock) {
if (pthread_rwlock_rdlock(&lock->lock) != 0) {
abort();
}
}
void CRYPTO_STATIC_MUTEX_lock_write(struct CRYPTO_STATIC_MUTEX *lock) {
if (pthread_rwlock_wrlock(&lock->lock) != 0) {
abort();
}
}
void CRYPTO_STATIC_MUTEX_unlock_read(struct CRYPTO_STATIC_MUTEX *lock) {
if (pthread_rwlock_unlock(&lock->lock) != 0) {
abort();
}
}
void CRYPTO_STATIC_MUTEX_unlock_write(struct CRYPTO_STATIC_MUTEX *lock) {
if (pthread_rwlock_unlock(&lock->lock) != 0) {
abort();
}
pthread_rwlock_destroy(lock);
}
void CRYPTO_once(CRYPTO_once_t *once, void (*init)(void)) {

@ -57,8 +57,8 @@ TEST(ThreadTest, Once) {
static CRYPTO_once_t once_init_value = CRYPTO_ONCE_INIT;
static CRYPTO_once_t once_bss;
static struct CRYPTO_STATIC_MUTEX mutex_init_value = CRYPTO_STATIC_MUTEX_INIT;
static struct CRYPTO_STATIC_MUTEX mutex_bss;
static CRYPTO_MUTEX mutex_init_value = CRYPTO_MUTEX_INIT;
static CRYPTO_MUTEX mutex_bss;
static CRYPTO_EX_DATA_CLASS ex_data_class_value = CRYPTO_EX_DATA_CLASS_INIT;
static CRYPTO_EX_DATA_CLASS ex_data_class_bss;
@ -66,8 +66,8 @@ static CRYPTO_EX_DATA_CLASS ex_data_class_bss;
TEST(ThreadTest, InitZeros) {
if (FIPS_mode()) {
// Our FIPS tooling currently requires that |CRYPTO_ONCE_INIT|,
// |CRYPTO_STATIC_MUTEX_INIT| and |CRYPTO_EX_DATA_CLASS| are all zeros and
// so can be placed in the BSS section.
// |CRYPTO_MUTEX_INIT| and |CRYPTO_EX_DATA_CLASS| are all zeros and so can
// be placed in the BSS section.
EXPECT_EQ(Bytes((uint8_t *)&once_bss, sizeof(once_bss)),
Bytes((uint8_t *)&once_init_value, sizeof(once_init_value)));
EXPECT_EQ(Bytes((uint8_t *)&mutex_bss, sizeof(mutex_bss)),

@ -26,11 +26,6 @@ OPENSSL_MSVC_PRAGMA(warning(pop))
#include <stdlib.h>
#include <string.h>
static_assert(sizeof(CRYPTO_MUTEX) >= sizeof(SRWLOCK),
"CRYPTO_MUTEX is too small");
static_assert(alignof(CRYPTO_MUTEX) >= alignof(SRWLOCK),
"CRYPTO_MUTEX has insufficient alignment");
static BOOL CALLBACK call_once_init(INIT_ONCE *once, void *arg, void **out) {
void (**init)(void) = (void (**)(void))arg;
(**init)();
@ -44,45 +39,29 @@ void CRYPTO_once(CRYPTO_once_t *once, void (*init)(void)) {
}
void CRYPTO_MUTEX_init(CRYPTO_MUTEX *lock) {
InitializeSRWLock((SRWLOCK *) lock);
InitializeSRWLock(lock);
}
void CRYPTO_MUTEX_lock_read(CRYPTO_MUTEX *lock) {
AcquireSRWLockShared((SRWLOCK *) lock);
AcquireSRWLockShared(lock);
}
void CRYPTO_MUTEX_lock_write(CRYPTO_MUTEX *lock) {
AcquireSRWLockExclusive((SRWLOCK *) lock);
AcquireSRWLockExclusive(lock);
}
void CRYPTO_MUTEX_unlock_read(CRYPTO_MUTEX *lock) {
ReleaseSRWLockShared((SRWLOCK *) lock);
ReleaseSRWLockShared(lock);
}
void CRYPTO_MUTEX_unlock_write(CRYPTO_MUTEX *lock) {
ReleaseSRWLockExclusive((SRWLOCK *) lock);
ReleaseSRWLockExclusive(lock);
}
void CRYPTO_MUTEX_cleanup(CRYPTO_MUTEX *lock) {
// SRWLOCKs require no cleanup.
}
void CRYPTO_STATIC_MUTEX_lock_read(struct CRYPTO_STATIC_MUTEX *lock) {
AcquireSRWLockShared(&lock->lock);
}
void CRYPTO_STATIC_MUTEX_lock_write(struct CRYPTO_STATIC_MUTEX *lock) {
AcquireSRWLockExclusive(&lock->lock);
}
void CRYPTO_STATIC_MUTEX_unlock_read(struct CRYPTO_STATIC_MUTEX *lock) {
ReleaseSRWLockShared(&lock->lock);
}
void CRYPTO_STATIC_MUTEX_unlock_write(struct CRYPTO_STATIC_MUTEX *lock) {
ReleaseSRWLockExclusive(&lock->lock);
}
static SRWLOCK g_destructors_lock = SRWLOCK_INIT;
static thread_local_destructor_t g_destructors[NUM_OPENSSL_THREAD_LOCALS];

@ -238,7 +238,7 @@ static int add_cert_dir(BY_DIR *ctx, const char *dir, int type) {
// g_ent_hashes_lock protects the |hashes| member of all |BY_DIR_ENTRY|
// objects.
static struct CRYPTO_STATIC_MUTEX g_ent_hashes_lock = CRYPTO_STATIC_MUTEX_INIT;
static CRYPTO_MUTEX g_ent_hashes_lock = CRYPTO_MUTEX_INIT;
static int get_cert_by_subject(X509_LOOKUP *xl, int type, X509_NAME *name,
X509_OBJECT *ret) {
@ -304,7 +304,7 @@ static int get_cert_by_subject(X509_LOOKUP *xl, int type, X509_NAME *name,
}
if (type == X509_LU_CRL && ent->hashes) {
htmp.hash = h;
CRYPTO_STATIC_MUTEX_lock_read(&g_ent_hashes_lock);
CRYPTO_MUTEX_lock_read(&g_ent_hashes_lock);
if (sk_BY_DIR_HASH_find(ent->hashes, &idx, &htmp)) {
hent = sk_BY_DIR_HASH_value(ent->hashes, idx);
k = hent->suffix;
@ -312,7 +312,7 @@ static int get_cert_by_subject(X509_LOOKUP *xl, int type, X509_NAME *name,
hent = NULL;
k = 0;
}
CRYPTO_STATIC_MUTEX_unlock_read(&g_ent_hashes_lock);
CRYPTO_MUTEX_unlock_read(&g_ent_hashes_lock);
} else {
k = 0;
hent = NULL;
@ -357,7 +357,7 @@ static int get_cert_by_subject(X509_LOOKUP *xl, int type, X509_NAME *name,
// If a CRL, update the last file suffix added for this
if (type == X509_LU_CRL) {
CRYPTO_STATIC_MUTEX_lock_write(&g_ent_hashes_lock);
CRYPTO_MUTEX_lock_write(&g_ent_hashes_lock);
// Look for entry again in case another thread added an entry
// first.
if (!hent) {
@ -370,14 +370,14 @@ static int get_cert_by_subject(X509_LOOKUP *xl, int type, X509_NAME *name,
if (!hent) {
hent = OPENSSL_malloc(sizeof(BY_DIR_HASH));
if (hent == NULL) {
CRYPTO_STATIC_MUTEX_unlock_write(&g_ent_hashes_lock);
CRYPTO_MUTEX_unlock_write(&g_ent_hashes_lock);
ok = 0;
goto finish;
}
hent->hash = h;
hent->suffix = k;
if (!sk_BY_DIR_HASH_push(ent->hashes, hent)) {
CRYPTO_STATIC_MUTEX_unlock_write(&g_ent_hashes_lock);
CRYPTO_MUTEX_unlock_write(&g_ent_hashes_lock);
OPENSSL_free(hent);
ok = 0;
goto finish;
@ -387,7 +387,7 @@ static int get_cert_by_subject(X509_LOOKUP *xl, int type, X509_NAME *name,
hent->suffix = k;
}
CRYPTO_STATIC_MUTEX_unlock_write(&g_ent_hashes_lock);
CRYPTO_MUTEX_unlock_write(&g_ent_hashes_lock);
}
if (tmp != NULL) {

@ -64,6 +64,7 @@
#include <openssl/x509.h>
#include "../asn1/internal.h"
#include "../internal.h"
#if defined(__cplusplus)
extern "C" {

@ -430,7 +430,7 @@ static int crl_revoked_issuer_match(X509_CRL *crl, X509_NAME *nm,
return 0;
}
static struct CRYPTO_STATIC_MUTEX g_crl_sort_lock = CRYPTO_STATIC_MUTEX_INIT;
static CRYPTO_MUTEX g_crl_sort_lock = CRYPTO_MUTEX_INIT;
static int crl_lookup(X509_CRL *crl, X509_REVOKED **ret, ASN1_INTEGER *serial,
X509_NAME *issuer) {
@ -443,16 +443,16 @@ static int crl_lookup(X509_CRL *crl, X509_REVOKED **ret, ASN1_INTEGER *serial,
// Sort revoked into serial number order if not already sorted. Do this
// under a lock to avoid race condition.
CRYPTO_STATIC_MUTEX_lock_read(&g_crl_sort_lock);
CRYPTO_MUTEX_lock_read(&g_crl_sort_lock);
const int is_sorted = sk_X509_REVOKED_is_sorted(crl->crl->revoked);
CRYPTO_STATIC_MUTEX_unlock_read(&g_crl_sort_lock);
CRYPTO_MUTEX_unlock_read(&g_crl_sort_lock);
if (!is_sorted) {
CRYPTO_STATIC_MUTEX_lock_write(&g_crl_sort_lock);
CRYPTO_MUTEX_lock_write(&g_crl_sort_lock);
if (!sk_X509_REVOKED_is_sorted(crl->crl->revoked)) {
sk_X509_REVOKED_sort(crl->crl->revoked);
}
CRYPTO_STATIC_MUTEX_unlock_write(&g_crl_sort_lock);
CRYPTO_MUTEX_unlock_write(&g_crl_sort_lock);
}
if (!sk_X509_REVOKED_find(crl->crl->revoked, &idx, &rtmp)) {

@ -128,7 +128,7 @@ error:
// |X509_PUBKEY| objects. Really |X509_PUBKEY| should have a |CRYPTO_once_t|
// inside it for this, but |CRYPTO_once_t| is private and |X509_PUBKEY| is
// not.
static struct CRYPTO_STATIC_MUTEX g_pubkey_lock = CRYPTO_STATIC_MUTEX_INIT;
static CRYPTO_MUTEX g_pubkey_lock = CRYPTO_MUTEX_INIT;
EVP_PKEY *X509_PUBKEY_get(X509_PUBKEY *key) {
EVP_PKEY *ret = NULL;
@ -138,13 +138,13 @@ EVP_PKEY *X509_PUBKEY_get(X509_PUBKEY *key) {
goto error;
}
CRYPTO_STATIC_MUTEX_lock_read(&g_pubkey_lock);
CRYPTO_MUTEX_lock_read(&g_pubkey_lock);
if (key->pkey != NULL) {
CRYPTO_STATIC_MUTEX_unlock_read(&g_pubkey_lock);
CRYPTO_MUTEX_unlock_read(&g_pubkey_lock);
EVP_PKEY_up_ref(key->pkey);
return key->pkey;
}
CRYPTO_STATIC_MUTEX_unlock_read(&g_pubkey_lock);
CRYPTO_MUTEX_unlock_read(&g_pubkey_lock);
// Re-encode the |X509_PUBKEY| to DER and parse it.
int spki_len = i2d_X509_PUBKEY(key, &spki);
@ -160,14 +160,14 @@ EVP_PKEY *X509_PUBKEY_get(X509_PUBKEY *key) {
}
// Check to see if another thread set key->pkey first
CRYPTO_STATIC_MUTEX_lock_write(&g_pubkey_lock);
CRYPTO_MUTEX_lock_write(&g_pubkey_lock);
if (key->pkey) {
CRYPTO_STATIC_MUTEX_unlock_write(&g_pubkey_lock);
CRYPTO_MUTEX_unlock_write(&g_pubkey_lock);
EVP_PKEY_free(ret);
ret = key->pkey;
} else {
key->pkey = ret;
CRYPTO_STATIC_MUTEX_unlock_write(&g_pubkey_lock);
CRYPTO_MUTEX_unlock_write(&g_pubkey_lock);
}
OPENSSL_free(spki);

@ -66,34 +66,6 @@ extern "C" {
#endif
#if !defined(OPENSSL_THREADS)
typedef struct crypto_mutex_st {
char padding; // Empty structs have different sizes in C and C++.
} CRYPTO_MUTEX;
#elif defined(OPENSSL_WINDOWS)
// CRYPTO_MUTEX can appear in public header files so we really don't want to
// pull in windows.h. It's statically asserted that this structure is large
// enough to contain a Windows SRWLOCK by thread_win.c.
typedef union crypto_mutex_st {
void *handle;
} CRYPTO_MUTEX;
#elif !defined(__GLIBC__)
#if defined(OPENSSL_OPENBSD)
// OpenBSD does not guarantee pthread_rwlock_t in sys/types.h yet.
#include <pthread.h>
#endif
typedef pthread_rwlock_t CRYPTO_MUTEX;
#else
// On glibc, |pthread_rwlock_t| is hidden under feature flags, and we can't
// ensure that we'll be able to get it from a public header. It's statically
// asserted that this structure is large enough to contain a |pthread_rwlock_t|
// by thread_pthread.c.
typedef union crypto_mutex_st {
double alignment;
uint8_t padding[3*sizeof(int) + 5*sizeof(unsigned) + 16 + 8];
} CRYPTO_MUTEX;
#endif
// CRYPTO_refcount_t is the type of a reference count.
//
// Since some platforms use C11 atomics to access this, it should have the

Loading…
Cancel
Save