From 43a07d6dd44cc9594a6cfecc464b69a7c4142d5f Mon Sep 17 00:00:00 2001 From: Pauli Date: Thu, 22 Jun 2023 09:39:36 +1000 Subject: [PATCH] tls: update to structure based atomics Reviewed-by: Tomas Mraz Reviewed-by: Matt Caswell (Merged from https://github.com/openssl/openssl/pull/21260) --- ssl/ssl_cert.c | 14 ++++---------- ssl/ssl_cert_comp.c | 9 ++++----- ssl/ssl_lib.c | 26 ++++++++++++++++++-------- ssl/ssl_local.h | 3 --- ssl/ssl_sess.c | 20 ++++++-------------- 5 files changed, 32 insertions(+), 40 deletions(-) diff --git a/ssl/ssl_cert.c b/ssl/ssl_cert.c index 20407d1277..126be668fd 100644 --- a/ssl/ssl_cert.c +++ b/ssl/ssl_cert.c @@ -78,13 +78,10 @@ CERT *ssl_cert_new(size_t ssl_pkey_num) } ret->key = &(ret->pkeys[SSL_PKEY_RSA]); - ret->references = 1; ret->sec_cb = ssl_security_default_callback; ret->sec_level = OPENSSL_TLS_SECURITY_LEVEL; ret->sec_ex = NULL; - ret->lock = CRYPTO_THREAD_lock_new(); - if (ret->lock == NULL) { - ERR_raise(ERR_LIB_SSL, ERR_R_CRYPTO_LIB); + if (!CRYPTO_NEW_REF(&ret->references, 1)) { OPENSSL_free(ret->pkeys); OPENSSL_free(ret); return NULL; @@ -111,11 +108,8 @@ CERT *ssl_cert_dup(CERT *cert) return NULL; } - ret->references = 1; ret->key = &ret->pkeys[cert->key - cert->pkeys]; - ret->lock = CRYPTO_THREAD_lock_new(); - if (ret->lock == NULL) { - ERR_raise(ERR_LIB_SSL, ERR_R_CRYPTO_LIB); + if (!CRYPTO_NEW_REF(&ret->references, 1)) { OPENSSL_free(ret->pkeys); OPENSSL_free(ret); return NULL; @@ -272,7 +266,7 @@ void ssl_cert_free(CERT *c) if (c == NULL) return; - CRYPTO_DOWN_REF(&c->references, &i, c->lock); + CRYPTO_DOWN_REF(&c->references, &i); REF_PRINT_COUNT("CERT", c); if (i > 0) return; @@ -291,7 +285,7 @@ void ssl_cert_free(CERT *c) OPENSSL_free(c->psk_identity_hint); #endif OPENSSL_free(c->pkeys); - CRYPTO_THREAD_lock_free(c->lock); + CRYPTO_FREE_REF(&c->references); OPENSSL_free(c); } diff --git a/ssl/ssl_cert_comp.c b/ssl/ssl_cert_comp.c index f782c4eee1..ebc92b0039 100644 --- a/ssl/ssl_cert_comp.c +++ b/ssl/ssl_cert_comp.c @@ -64,10 +64,9 @@ static OSSL_COMP_CERT *OSSL_COMP_CERT_new(unsigned char *data, size_t len, size_ if (!ossl_comp_has_alg(alg) || data == NULL || (ret = OPENSSL_zalloc(sizeof(*ret))) == NULL - || (ret->lock = CRYPTO_THREAD_lock_new()) == NULL) + || !CRYPTO_NEW_REF(&ret->references, 1)) goto err; - ret->references = 1; ret->data = data; ret->len = len; ret->orig_len = orig_len; @@ -136,21 +135,21 @@ void OSSL_COMP_CERT_free(OSSL_COMP_CERT *cc) if (cc == NULL) return; - CRYPTO_DOWN_REF(&cc->references, &i, cc->lock); + CRYPTO_DOWN_REF(&cc->references, &i); REF_PRINT_COUNT("OSSL_COMP_CERT", cc); if (i > 0) return; REF_ASSERT_ISNT(i < 0); OPENSSL_free(cc->data); - CRYPTO_THREAD_lock_free(cc->lock); + CRYPTO_FREE_REF(&cc->references); OPENSSL_free(cc); } int OSSL_COMP_CERT_up_ref(OSSL_COMP_CERT *cc) { int i; - if (CRYPTO_UP_REF(&cc->references, &i, cc->lock) <= 0) + if (CRYPTO_UP_REF(&cc->references, &i) <= 0) return 0; REF_PRINT_COUNT("OSSL_COMP_CERT", cc); diff --git a/ssl/ssl_lib.c b/ssl/ssl_lib.c index 51a78fa383..6caa1f5fe0 100644 --- a/ssl/ssl_lib.c +++ b/ssl/ssl_lib.c @@ -707,13 +707,18 @@ int ossl_ssl_init(SSL *ssl, SSL_CTX *ctx, const SSL_METHOD *method, int type) { ssl->type = type; - ssl->references = 1; ssl->lock = CRYPTO_THREAD_lock_new(); if (ssl->lock == NULL) return 0; + if (!CRYPTO_NEW_REF(&ssl->references, 1)) { + CRYPTO_THREAD_lock_free(ssl->lock); + return 0; + } + if (!CRYPTO_new_ex_data(CRYPTO_EX_INDEX_SSL, ssl, &ssl->ex_data)) { CRYPTO_THREAD_lock_free(ssl->lock); + CRYPTO_FREE_REF(&ssl->references); ssl->lock = NULL; return 0; } @@ -969,7 +974,7 @@ int SSL_up_ref(SSL *s) { int i; - if (CRYPTO_UP_REF(&s->references, &i, s->lock) <= 0) + if (CRYPTO_UP_REF(&s->references, &i) <= 0) return 0; REF_PRINT_COUNT("SSL", s); @@ -1374,7 +1379,7 @@ void SSL_free(SSL *s) if (s == NULL) return; - CRYPTO_DOWN_REF(&s->references, &i, s->lock); + CRYPTO_DOWN_REF(&s->references, &i); REF_PRINT_COUNT("SSL", s); if (i > 0) return; @@ -1387,6 +1392,7 @@ void SSL_free(SSL *s) SSL_CTX_free(s->ctx); CRYPTO_THREAD_lock_free(s->lock); + CRYPTO_FREE_REF(&s->references); OPENSSL_free(s); } @@ -1974,7 +1980,7 @@ int SSL_copy_session_id(SSL *t, const SSL *f) return 0; } - CRYPTO_UP_REF(&fsc->cert->references, &i, fsc->cert->lock); + CRYPTO_UP_REF(&fsc->cert->references, &i); ssl_cert_free(tsc->cert); tsc->cert = fsc->cert; if (!SSL_set_session_id_context(t, fsc->sid_ctx, (int)fsc->sid_ctx_length)) { @@ -3779,12 +3785,15 @@ SSL_CTX *SSL_CTX_new_ex(OSSL_LIB_CTX *libctx, const char *propq, ERR_raise(ERR_LIB_SSL, SSL_R_X509_VERIFICATION_SETUP_PROBLEMS); goto err; } + ret = OPENSSL_zalloc(sizeof(*ret)); if (ret == NULL) goto err; /* Init the reference counting before any call to SSL_CTX_free */ - ret->references = 1; + if (!CRYPTO_NEW_REF(&ret->references, 1)) + goto err; + ret->lock = CRYPTO_THREAD_lock_new(); if (ret->lock == NULL) { ERR_raise(ERR_LIB_SSL, ERR_R_CRYPTO_LIB); @@ -4029,7 +4038,7 @@ int SSL_CTX_up_ref(SSL_CTX *ctx) { int i; - if (CRYPTO_UP_REF(&ctx->references, &i, ctx->lock) <= 0) + if (CRYPTO_UP_REF(&ctx->references, &i) <= 0) return 0; REF_PRINT_COUNT("SSL_CTX", ctx); @@ -4045,7 +4054,7 @@ void SSL_CTX_free(SSL_CTX *a) if (a == NULL) return; - CRYPTO_DOWN_REF(&a->references, &i, a->lock); + CRYPTO_DOWN_REF(&a->references, &i); REF_PRINT_COUNT("SSL_CTX", a); if (i > 0) return; @@ -4130,6 +4139,7 @@ void SSL_CTX_free(SSL_CTX *a) OPENSSL_free(a->server_cert_type); CRYPTO_THREAD_lock_free(a->lock); + CRYPTO_FREE_REF(&a->references); #ifdef TSAN_REQUIRES_LOCKING CRYPTO_THREAD_lock_free(a->tsan_lock); #endif @@ -4815,7 +4825,7 @@ SSL *SSL_dup(SSL *s) /* If we're not quiescent, just up_ref! */ if (!SSL_in_init(s) || !SSL_in_before(s)) { - CRYPTO_UP_REF(&s->references, &i, s->lock); + CRYPTO_UP_REF(&s->references, &i); return s; } diff --git a/ssl/ssl_local.h b/ssl/ssl_local.h index decb02a207..1c01377e14 100644 --- a/ssl/ssl_local.h +++ b/ssl/ssl_local.h @@ -571,7 +571,6 @@ struct ssl_session_st { size_t ticket_appdata_len; uint32_t flags; SSL_CTX *owner; - CRYPTO_RWLOCK *lock; }; /* Extended master secret support */ @@ -1965,7 +1964,6 @@ struct ossl_comp_cert_st { size_t len; size_t orig_len; CRYPTO_REF_COUNT references; - CRYPTO_RWLOCK *lock; int alg; }; typedef struct ossl_comp_cert_st OSSL_COMP_CERT; @@ -2107,7 +2105,6 @@ typedef struct cert_st { char *psk_identity_hint; # endif CRYPTO_REF_COUNT references; /* >1 only if SSL_copy_session_id is used */ - CRYPTO_RWLOCK *lock; } CERT; # define FP_ICC (int (*)(const void *,const void *)) diff --git a/ssl/ssl_sess.c b/ssl/ssl_sess.c index 6d5e87f687..486d938c94 100644 --- a/ssl/ssl_sess.c +++ b/ssl/ssl_sess.c @@ -110,20 +110,17 @@ SSL_SESSION *SSL_SESSION_new(void) return NULL; ss->verify_result = 1; /* avoid 0 (= X509_V_OK) just in case */ - ss->references = 1; /* 5 minute timeout by default */ ss->timeout = ossl_seconds2time(60 * 5 + 4); ss->time = ossl_time_now(); ssl_session_calculate_timeout(ss); - ss->lock = CRYPTO_THREAD_lock_new(); - if (ss->lock == NULL) { - ERR_raise(ERR_LIB_SSL, ERR_R_CRYPTO_LIB); + if (!CRYPTO_NEW_REF(&ss->references, 1)) { OPENSSL_free(ss); return NULL; } if (!CRYPTO_new_ex_data(CRYPTO_EX_INDEX_SSL_SESSION, ss, &ss->ex_data)) { - CRYPTO_THREAD_lock_free(ss->lock); + CRYPTO_FREE_REF(&ss->references); OPENSSL_free(ss); return NULL; } @@ -174,13 +171,8 @@ SSL_SESSION *ssl_session_dup(const SSL_SESSION *src, int ticket) dest->next = NULL; dest->owner = NULL; - dest->references = 1; - - dest->lock = CRYPTO_THREAD_lock_new(); - if (dest->lock == NULL) { - ERR_raise(ERR_LIB_SSL, ERR_R_CRYPTO_LIB); + if (!CRYPTO_NEW_REF(&dest->references, 1)) goto err; - } if (!CRYPTO_new_ex_data(CRYPTO_EX_INDEX_SSL_SESSION, dest, &dest->ex_data)) { ERR_raise(ERR_LIB_SSL, ERR_R_CRYPTO_LIB); @@ -821,7 +813,7 @@ void SSL_SESSION_free(SSL_SESSION *ss) if (ss == NULL) return; - CRYPTO_DOWN_REF(&ss->references, &i, ss->lock); + CRYPTO_DOWN_REF(&ss->references, &i); REF_PRINT_COUNT("SSL_SESSION", ss); if (i > 0) return; @@ -845,7 +837,7 @@ void SSL_SESSION_free(SSL_SESSION *ss) #endif OPENSSL_free(ss->ext.alpn_selected); OPENSSL_free(ss->ticket_appdata); - CRYPTO_THREAD_lock_free(ss->lock); + CRYPTO_FREE_REF(&ss->references); OPENSSL_clear_free(ss, sizeof(*ss)); } @@ -853,7 +845,7 @@ int SSL_SESSION_up_ref(SSL_SESSION *ss) { int i; - if (CRYPTO_UP_REF(&ss->references, &i, ss->lock) <= 0) + if (CRYPTO_UP_REF(&ss->references, &i) <= 0) return 0; REF_PRINT_COUNT("SSL_SESSION", ss); -- 2.34.1