From a94b06057fb74b1505c6d3c06cd6a4328b3959a6 Mon Sep 17 00:00:00 2001 From: Futaura Date: Fri, 28 Jun 2024 13:41:16 +0100 Subject: [PATCH] Refactored locking and mutex routines (implemented OpenSSL mutex routines to also use in the existing locking routines) --- CHANGES.md | 3 + openssl/crypto/thread/arch/thread_amissl.c | 61 +++++++++++ openssl/crypto/thread/build.info | 1 + openssl/crypto/threads_amissl.c | 117 ++++++++------------- openssl/include/internal/rcu.h | 4 +- openssl/include/internal/thread_arch.h | 2 + openssl/ssl/quic/quic_local.h | 4 - 7 files changed, 115 insertions(+), 77 deletions(-) create mode 100644 openssl/crypto/thread/arch/thread_amissl.c diff --git a/CHANGES.md b/CHANGES.md index 307a6d82b..5248f878d 100644 --- a/CHANGES.md +++ b/CHANGES.md @@ -1,3 +1,6 @@ +- Refactored the OpenSSL locking and mutex routines to remove the + unnecessary duplication of code. + ## AmiSSL 5.16 (7.6.2024) - Updated OpenSSL backend to full compatibility with the latest diff --git a/openssl/crypto/thread/arch/thread_amissl.c b/openssl/crypto/thread/arch/thread_amissl.c new file mode 100644 index 000000000..1eca21bc6 --- /dev/null +++ b/openssl/crypto/thread/arch/thread_amissl.c @@ -0,0 +1,61 @@ +/* + * Copyright 2019-2023 The OpenSSL Project Authors. All Rights Reserved. + * + * Licensed under the Apache License 2.0 (the "License"). You may not use + * this file except in compliance with the License. You can obtain a copy + * in the file LICENSE in the source distribution or at + * https://www.openssl.org/source/license.html + */ + +#include + +#if defined(OPENSSL_THREADS_AMISSL) + +# include + +# if defined(__amigaos4__) + +# define ALLOC_LOCK(mutex) mutex = AllocSysObject(ASOT_MUTEX, NULL) +# define FREE_LOCK(mutex) if (mutex != NULL) FreeSysObject(ASOT_MUTEX, mutex) +# define OBTAIN_LOCK(mutex) MutexObtain(mutex) +# define ATTEMPT_LOCK(mutex) MutexAttempt(mutex) +# define RELEASE_LOCK(mutex) MutexRelease(mutex) + +# else + +# define ALLOC_LOCK(sem) if ((sem = OPENSSL_zalloc(sizeof(struct SignalSemaphore))) != NULL) InitSemaphore((struct SignalSemaphore *)sem) +# define FREE_LOCK(sem) if (sem != NULL) OPENSSL_free(sem) +# define OBTAIN_LOCK(sem) ObtainSemaphore((struct SignalSemaphore *)sem) +# define ATTEMPT_LOCK(sem) AttemptSemaphore((struct SignalSemaphore *)sem) +# define RELEASE_LOCK(sem) ReleaseSemaphore((struct SignalSemaphore *)sem) + +# endif + +CRYPTO_MUTEX *ossl_crypto_mutex_new(void) +{ + CRYPTO_MUTEX *mutex; + ALLOC_LOCK(mutex); + return mutex; +} + +void ossl_crypto_mutex_lock(CRYPTO_MUTEX *mutex) +{ + OBTAIN_LOCK(mutex); +} + +int ossl_crypto_mutex_try_lock(CRYPTO_MUTEX *mutex) +{ + return ATTEMPT_LOCK(mutex); +} + +void ossl_crypto_mutex_unlock(CRYPTO_MUTEX *mutex) +{ + RELEASE_LOCK(mutex); +} + +void ossl_crypto_mutex_free(CRYPTO_MUTEX **mutex) +{ + FREE_LOCK(*mutex); + *mutex = NULL; +} +#endif diff --git a/openssl/crypto/thread/build.info b/openssl/crypto/thread/build.info index 191e25e20..de9224c2e 100644 --- a/openssl/crypto/thread/build.info +++ b/openssl/crypto/thread/build.info @@ -2,6 +2,7 @@ LIBS=../../libcrypto $THREADS_ARCH=\ arch.c \ + arch/thread_amissl.c \ arch/thread_win.c arch/thread_posix.c arch/thread_none.c IF[{- !$disabled{'thread-pool'} -}] diff --git a/openssl/crypto/threads_amissl.c b/openssl/crypto/threads_amissl.c index fe7211e8d..bff6e8a3f 100644 --- a/openssl/crypto/threads_amissl.c +++ b/openssl/crypto/threads_amissl.c @@ -24,6 +24,7 @@ #include #include +#include "internal/thread_arch.h" #include "internal/rcu.h" #include "rcu_internal.h" @@ -32,29 +33,15 @@ # include # if defined(__amigaos4__) - -# define ALLOC_LOCK(mutex, noop) mutex = AllocSysObject(ASOT_MUTEX, NULL) -# define FREE_LOCK(mutex) if (mutex != NULL) FreeSysObject(ASOT_MUTEX, mutex) -# define OBTAIN_LOCK(mutex) MutexObtain(mutex) -# define OBTAIN_SHARED_LOCK(mutex) OBTAIN_LOCK(mutex) -# define RELEASE_LOCK(mutex) MutexRelease(mutex) - -static APTR RunOnceLock = NULL; - +# define OBTAIN_SHARED_LOCK(mutex) ossl_crypto_mutex_lock(mutex) # else - -# define ALLOC_LOCK(sem, type) if ((sem = OPENSSL_zalloc(sizeof(type))) != NULL) InitSemaphore((struct SignalSemaphore *)sem) -# define FREE_LOCK(sem) if (sem != NULL) OPENSSL_free(sem) -# define OBTAIN_LOCK(sem) ObtainSemaphore((struct SignalSemaphore *)sem) # define OBTAIN_SHARED_LOCK(sem) ObtainSemaphoreShared((struct SignalSemaphore *)sem) -# define RELEASE_LOCK(sem) ReleaseSemaphore((struct SignalSemaphore *)sem) - -static struct SignalSemaphore *RunOnceLock = NULL; - # endif +static CRYPTO_MUTEX *RunOnceLock = NULL; + struct rcu_lock_st { - CRYPTO_RWLOCK *lock; + CRYPTO_MUTEX *mutex; struct rcu_cb_item *cb_items; }; @@ -64,7 +51,7 @@ CRYPTO_RCU_LOCK *ossl_rcu_lock_new(int num_writers) if((lock = OPENSSL_zalloc(sizeof(*lock)))) { - if((lock->lock = CRYPTO_THREAD_lock_new())) + if((lock->mutex = ossl_crypto_mutex_new())) { return lock; } @@ -76,28 +63,28 @@ CRYPTO_RCU_LOCK *ossl_rcu_lock_new(int num_writers) void ossl_rcu_lock_free(CRYPTO_RCU_LOCK *lock) { - CRYPTO_THREAD_lock_free(lock->lock); + ossl_crypto_mutex_free(&lock->mutex); OPENSSL_free(lock); } void ossl_rcu_read_lock(CRYPTO_RCU_LOCK *lock) { - CRYPTO_THREAD_read_lock(lock->lock); + OBTAIN_SHARED_LOCK(lock->mutex); } void ossl_rcu_write_lock(CRYPTO_RCU_LOCK *lock) { - CRYPTO_THREAD_write_lock(lock->lock); + ossl_crypto_mutex_lock(lock->mutex); } void ossl_rcu_write_unlock(CRYPTO_RCU_LOCK *lock) { - CRYPTO_THREAD_unlock(lock->lock); + ossl_crypto_mutex_unlock(lock->mutex); } void ossl_rcu_read_unlock(CRYPTO_RCU_LOCK *lock) { - CRYPTO_THREAD_unlock(lock->lock); + ossl_crypto_mutex_unlock(lock->mutex); } void ossl_synchronize_rcu(CRYPTO_RCU_LOCK *lock) @@ -105,7 +92,7 @@ void ossl_synchronize_rcu(CRYPTO_RCU_LOCK *lock) struct rcu_cb_item *items; struct rcu_cb_item *tmp; - CRYPTO_THREAD_write_lock(lock->lock); + ossl_crypto_mutex_lock(lock->mutex); items = lock->cb_items; lock->cb_items = NULL; @@ -117,7 +104,7 @@ void ossl_synchronize_rcu(CRYPTO_RCU_LOCK *lock) items = tmp; } - CRYPTO_THREAD_unlock(lock->lock); + ossl_crypto_mutex_unlock(lock->mutex); } int ossl_rcu_call(CRYPTO_RCU_LOCK *lock, rcu_cb_fn cb, void *data) @@ -127,14 +114,14 @@ int ossl_rcu_call(CRYPTO_RCU_LOCK *lock, rcu_cb_fn cb, void *data) if (new == NULL) return 0; - CRYPTO_THREAD_write_lock(lock->lock); + ossl_crypto_mutex_lock(lock->mutex); new->fn = cb; new->data = data; new->next = lock->cb_items; lock->cb_items = new; - CRYPTO_THREAD_unlock(lock->lock); + ossl_crypto_mutex_unlock(lock->mutex); return 1; } @@ -151,21 +138,19 @@ void ossl_rcu_assign_uptr(void **p, void **v) int CRYPTO_THREAD_setup(void) { - ALLOC_LOCK(RunOnceLock, struct SignalSemaphore); + RunOnceLock = ossl_crypto_mutex_new(); return (RunOnceLock != NULL) ? 1 : 0; } int CRYPTO_THREAD_cleanup(void) { - FREE_LOCK(RunOnceLock); + ossl_crypto_mutex_free(&RunOnceLock); return 1; } CRYPTO_RWLOCK *CRYPTO_THREAD_lock_new(void) { - CRYPTO_RWLOCK *lock; - ALLOC_LOCK(lock, struct SignalSemaphore); - return lock; + return (CRYPTO_RWLOCK *)ossl_crypto_mutex_new(); } __owur int CRYPTO_THREAD_read_lock(CRYPTO_RWLOCK *lock) @@ -176,31 +161,32 @@ __owur int CRYPTO_THREAD_read_lock(CRYPTO_RWLOCK *lock) __owur int CRYPTO_THREAD_write_lock(CRYPTO_RWLOCK *lock) { - OBTAIN_LOCK(lock); + ossl_crypto_mutex_lock(lock); return 1; } int CRYPTO_THREAD_unlock(CRYPTO_RWLOCK *lock) { - RELEASE_LOCK(lock); + ossl_crypto_mutex_unlock(lock); return 1; } void CRYPTO_THREAD_lock_free(CRYPTO_RWLOCK *lock) { - FREE_LOCK(lock); + CRYPTO_MUTEX *mutex = (CRYPTO_MUTEX *)lock; + ossl_crypto_mutex_free(&mutex); } int CRYPTO_THREAD_run_once(CRYPTO_ONCE *once, void (*init)(void)) { - OBTAIN_LOCK(RunOnceLock); + ossl_crypto_mutex_lock(RunOnceLock); if (*once == CRYPTO_ONCE_STATIC_INIT) { init(); *once = 1; } - RELEASE_LOCK(RunOnceLock); + ossl_crypto_mutex_unlock(RunOnceLock); return 1; } @@ -211,40 +197,27 @@ typedef struct thread_entry_st void *data; } THREAD_ENTRY; -# if defined(__amigaos4__) +typedef struct thread_key_st +{ + CRYPTO_MUTEX *mutex; + LHASH_OF(THREAD_ENTRY) *hashtable; +} THREAD_KEY; -# define ALLOC_THREAD_KEY(key) \ +# define ALLOC_THREAD_KEY(key) \ if ((key = OPENSSL_malloc(sizeof(THREAD_KEY)))) { \ - if ((ALLOC_LOCK(key->lock, 0)) == NULL) { \ + if ((key->mutex = ossl_crypto_mutex_new()) == NULL) { \ OPENSSL_free(key); \ key = NULL; \ } \ } -# define FREE_THREAD_KEY(key) if (key != NULL) { FREE_LOCK(key->lock); OPENSSL_free(key); } -# define LOCK_THREAD_KEY(key) OBTAIN_LOCK(key->lock) -# define LOCK_SHARED_THREAD_KEY(key) OBTAIN_LOCK(key->lock) -# define UNLOCK_THREAD_KEY(key) RELEASE_LOCK(key->lock) - -typedef struct thread_key_st -{ - APTR lock; - LHASH_OF(THREAD_ENTRY) *hashtable; -} THREAD_KEY; +# define FREE_THREAD_KEY(key) if (key != NULL) { ossl_crypto_mutex_free(&key->mutex); OPENSSL_free(key); } +# define LOCK_THREAD_KEY(key) ossl_crypto_mutex_lock(key->mutex) +# define UNLOCK_THREAD_KEY(key) ossl_crypto_mutex_unlock(key->mutex) +# if defined(__amigaos4__) +# define LOCK_SHARED_THREAD_KEY(key) LOCK_THREAD_KEY(key) # else - -# define ALLOC_THREAD_KEY(key) ALLOC_LOCK(key, THREAD_KEY) -# define FREE_THREAD_KEY(key) FREE_LOCK(&(key->lock)) -# define LOCK_THREAD_KEY(key) OBTAIN_LOCK(&(key->lock)) -# define LOCK_SHARED_THREAD_KEY(key) OBTAIN_SHARED_LOCK(&(key->lock)) -# define UNLOCK_THREAD_KEY(key) RELEASE_LOCK(&(key->lock)) - -typedef struct thread_key_st -{ - struct SignalSemaphore lock; - LHASH_OF(THREAD_ENTRY) *hashtable; -} THREAD_KEY; - +# define LOCK_SHARED_THREAD_KEY(key) OBTAIN_SHARED_LOCK(key->mutex) # endif DEFINE_LHASH_OF_EX(THREAD_ENTRY); @@ -380,12 +353,12 @@ int CRYPTO_atomic_add(int *val, int amount, int *ret, CRYPTO_RWLOCK *lock) if (lock == NULL) return 0; - CRYPTO_THREAD_write_lock(lock); + ossl_crypto_mutex_lock(lock); *val += amount; *ret = *val; - CRYPTO_THREAD_unlock(lock); + ossl_crypto_mutex_unlock(lock); return 1; } @@ -396,12 +369,12 @@ int CRYPTO_atomic_or(uint64_t *val, uint64_t op, uint64_t *ret, if (lock == NULL) return 0; - CRYPTO_THREAD_write_lock(lock); + ossl_crypto_mutex_lock(lock); *val |= op; *ret = *val; - CRYPTO_THREAD_unlock(lock); + ossl_crypto_mutex_unlock(lock); return 1; } @@ -411,11 +384,11 @@ int CRYPTO_atomic_load(uint64_t *val, uint64_t *ret, CRYPTO_RWLOCK *lock) if (lock == NULL) return 0; - CRYPTO_THREAD_read_lock(lock); + ossl_crypto_mutex_lock(lock); *ret = *val; - CRYPTO_THREAD_unlock(lock); + ossl_crypto_mutex_unlock(lock); return 1; } @@ -425,11 +398,11 @@ int CRYPTO_atomic_load_int(int *val, int *ret, CRYPTO_RWLOCK *lock) if (lock == NULL) return 0; - CRYPTO_THREAD_read_lock(lock); + ossl_crypto_mutex_lock(lock); *ret = *val; - CRYPTO_THREAD_unlock(lock); + ossl_crypto_mutex_unlock(lock); return 1; } diff --git a/openssl/include/internal/rcu.h b/openssl/include/internal/rcu.h index 7716a1c7f..aee2f4c29 100644 --- a/openssl/include/internal/rcu.h +++ b/openssl/include/internal/rcu.h @@ -9,7 +9,9 @@ #ifndef OPENSSL_RCU_H # define OPENSSL_RCU_H -# pragma once +# if defined(__GNUC__) && (__GNUC__ > 3 || (__GNUC__ == 3 && __GNUC_MINOR__ > 3)) +# pragma once +# endif typedef void (*rcu_cb_fn)(void *data); diff --git a/openssl/include/internal/thread_arch.h b/openssl/include/internal/thread_arch.h index aba9362e8..7cccc8745 100644 --- a/openssl/include/internal/thread_arch.h +++ b/openssl/include/internal/thread_arch.h @@ -21,6 +21,8 @@ # define OPENSSL_THREADS_POSIX # elif defined(OPENSSL_THREADS) && defined(OPENSSL_SYS_VMS) # define OPENSSL_THREADS_POSIX +# elif defined(OPENSSL_THREADS) && defined(OPENSSL_SYS_AMIGA) +# define OPENSSL_THREADS_AMISSL # elif defined(OPENSSL_THREADS) && defined(OPENSSL_SYS_WINDOWS) && \ defined(_WIN32_WINNT) # if _WIN32_WINNT >= 0x0600 diff --git a/openssl/ssl/quic/quic_local.h b/openssl/ssl/quic/quic_local.h index 259564fe2..d6518fd6b 100644 --- a/openssl/ssl/quic/quic_local.h +++ b/openssl/ssl/quic/quic_local.h @@ -26,10 +26,6 @@ # ifndef OPENSSL_NO_QUIC -# if defined(OPENSSL_SYS_AMIGA) -# undef OPENSSL_THREADS -# endif - /* * QUIC stream SSL object (QSSO) type. This implements the API personality layer * for QSSO objects, wrapping the QUIC-native QUIC_STREAM object and tracking