]> git.ipfire.org Git - thirdparty/openssl.git/commitdiff
Adds missing checks of return from XXX_up_ref(). feature/evp_skey
authorFrederik Wedel-Heinen <frederik.wedel-heinen@dencrypt.dk>
Sat, 28 Dec 2024 09:13:48 +0000 (10:13 +0100)
committerTomas Mraz <tomas@openssl.org>
Tue, 18 Feb 2025 15:32:59 +0000 (16:32 +0100)
Reviewed-by: Saša Nedvědický <sashan@openssl.org>
Reviewed-by: Tomas Mraz <tomas@openssl.org>
(Merged from https://github.com/openssl/openssl/pull/26294)

45 files changed:
apps/list.c
apps/s_client.c
apps/s_server.c
apps/speed.c
crypto/cms/cms_env.c
crypto/cms/cms_kari.c
crypto/cms/cms_sd.c
crypto/cms/cms_smime.c
crypto/evp/asymcipher.c
crypto/evp/digest.c
crypto/evp/evp_enc.c
crypto/evp/exchange.c
crypto/evp/kdf_meth.c
crypto/evp/kem.c
crypto/evp/mac_meth.c
crypto/evp/p_legacy.c
crypto/evp/p_lib.c
crypto/evp/pmeth_lib.c
crypto/evp/signature.c
crypto/pkcs7/pk7_lib.c
crypto/store/store_lib.c
crypto/store/store_meth.c
crypto/ts/ts_rsp_sign.c
crypto/ts/ts_rsp_verify.c
crypto/x509/pcy_tree.c
crypto/x509/x509_cmp.c
crypto/x509/x509_vfy.c
doc/internal/man3/evp_generic_fetch.pod
providers/implementations/ciphers/cipher_aes_siv_hw.c
ssl/bio_ssl.c
ssl/s3_lib.c
ssl/ssl_cert.c
ssl/ssl_lib.c
ssl/ssl_rsa.c
ssl/ssl_rsa_legacy.c
ssl/ssl_sess.c
ssl/statem/statem_clnt.c
test/bio_prefix_text.c
test/cmp_client_test.c
test/cmp_protect_test.c
test/crltest.c
test/evp_extra_test.c
test/helpers/ssltestlib.c
test/quicapitest.c
test/sslapitest.c

index b8baee37357072e68f37cd08d29b3ac97af7b1cf..e69be3185c6261925b8053be28f36412bb343da1 100644 (file)
@@ -104,8 +104,9 @@ static void collect_ciphers(EVP_CIPHER *cipher, void *stack)
     STACK_OF(EVP_CIPHER) *cipher_stack = stack;
 
     if (is_cipher_fetchable(cipher)
-            && sk_EVP_CIPHER_push(cipher_stack, cipher) > 0)
-        EVP_CIPHER_up_ref(cipher);
+            && EVP_CIPHER_up_ref(cipher)
+            && sk_EVP_CIPHER_push(cipher_stack, cipher) <= 0)
+        EVP_CIPHER_free(cipher); /* up-ref successful but push to stack failed */
 }
 
 static void list_ciphers(const char *prefix)
@@ -188,8 +189,9 @@ static void collect_digests(EVP_MD *digest, void *stack)
     STACK_OF(EVP_MD) *digest_stack = stack;
 
     if (is_digest_fetchable(digest)
-            && sk_EVP_MD_push(digest_stack, digest) > 0)
-        EVP_MD_up_ref(digest);
+            && EVP_MD_up_ref(digest)
+            && sk_EVP_MD_push(digest_stack, digest) <= 0)
+        EVP_MD_free(digest); /* up-ref successful but push to stack failed */
 }
 
 static void list_digests(const char *prefix)
@@ -320,8 +322,9 @@ static void collect_kdfs(EVP_KDF *kdf, void *stack)
     STACK_OF(EVP_KDF) *kdf_stack = stack;
 
     if (is_kdf_fetchable(kdf)
-            && sk_EVP_KDF_push(kdf_stack, kdf) > 0)
-        EVP_KDF_up_ref(kdf);
+            && EVP_KDF_up_ref(kdf)
+            && sk_EVP_KDF_push(kdf_stack, kdf) <= 0)
+        EVP_KDF_free(kdf); /* up-ref successful but push to stack failed */
 }
 
 static void list_kdfs(void)
@@ -390,8 +393,9 @@ static void collect_rands(EVP_RAND *rand, void *stack)
     STACK_OF(EVP_RAND) *rand_stack = stack;
 
     if (is_rand_fetchable(rand)
-            && sk_EVP_RAND_push(rand_stack, rand) > 0)
-        EVP_RAND_up_ref(rand);
+            && EVP_RAND_up_ref(rand)
+            && sk_EVP_RAND_push(rand_stack, rand) <= 0)
+        EVP_RAND_free(rand); /* up-ref successful but push to stack failed */
 }
 
 static void list_random_generators(void)
@@ -516,8 +520,9 @@ static void collect_encoders(OSSL_ENCODER *encoder, void *stack)
     STACK_OF(OSSL_ENCODER) *encoder_stack = stack;
 
     if (is_encoder_fetchable(encoder)
-            && sk_OSSL_ENCODER_push(encoder_stack, encoder) > 0)
-        OSSL_ENCODER_up_ref(encoder);
+            && OSSL_ENCODER_up_ref(encoder)
+            && sk_OSSL_ENCODER_push(encoder_stack, encoder) <= 0)
+        OSSL_ENCODER_free(encoder); /* up-ref successful but push to stack failed */
 }
 
 static void list_encoders(void)
@@ -581,8 +586,9 @@ static void collect_decoders(OSSL_DECODER *decoder, void *stack)
     STACK_OF(OSSL_DECODER) *decoder_stack = stack;
 
     if (is_decoder_fetchable(decoder)
-            && sk_OSSL_DECODER_push(decoder_stack, decoder) > 0)
-        OSSL_DECODER_up_ref(decoder);
+            && OSSL_DECODER_up_ref(decoder)
+            && sk_OSSL_DECODER_push(decoder_stack, decoder) <= 0)
+        OSSL_DECODER_free(decoder); /* up-ref successful but push to stack failed */
 }
 
 static void list_decoders(void)
@@ -643,8 +649,9 @@ static void collect_keymanagers(EVP_KEYMGMT *km, void *stack)
     STACK_OF(EVP_KEYMGMT) *km_stack = stack;
 
     if (is_keymgmt_fetchable(km)
-            && sk_EVP_KEYMGMT_push(km_stack, km) > 0)
-        EVP_KEYMGMT_up_ref(km);
+            && EVP_KEYMGMT_up_ref(km)
+            && sk_EVP_KEYMGMT_push(km_stack, km) <= 0)
+        EVP_KEYMGMT_free(km); /* up-ref successful but push to stack failed */
 }
 
 static void list_keymanagers(void)
@@ -761,8 +768,9 @@ static void collect_signatures(EVP_SIGNATURE *sig, void *stack)
     STACK_OF(EVP_SIGNATURE) *sig_stack = stack;
 
     if (is_signature_fetchable(sig)
-            && sk_EVP_SIGNATURE_push(sig_stack, sig) > 0)
-        EVP_SIGNATURE_up_ref(sig);
+            && EVP_SIGNATURE_up_ref(sig)
+            && sk_EVP_SIGNATURE_push(sig_stack, sig) <= 0)
+        EVP_SIGNATURE_free(sig); /* up-ref successful but push to stack failed */
 }
 
 static void list_signatures(void)
@@ -905,8 +913,9 @@ static void collect_kem(EVP_KEM *kem, void *stack)
     STACK_OF(EVP_KEM) *kem_stack = stack;
 
     if (is_kem_fetchable(kem)
-            && sk_EVP_KEM_push(kem_stack, kem) > 0)
-        EVP_KEM_up_ref(kem);
+            && EVP_KEM_up_ref(kem)
+            && sk_EVP_KEM_push(kem_stack, kem) <= 0)
+        EVP_KEM_free(kem); /* up-ref successful but push to stack failed */
 }
 
 static void list_kems(void)
@@ -964,8 +973,9 @@ static void collect_asymciph(EVP_ASYM_CIPHER *asym_cipher, void *stack)
     STACK_OF(EVP_ASYM_CIPHER) *asym_cipher_stack = stack;
 
     if (is_asym_cipher_fetchable(asym_cipher)
-            && sk_EVP_ASYM_CIPHER_push(asym_cipher_stack, asym_cipher) > 0)
-        EVP_ASYM_CIPHER_up_ref(asym_cipher);
+            && EVP_ASYM_CIPHER_up_ref(asym_cipher)
+            && sk_EVP_ASYM_CIPHER_push(asym_cipher_stack, asym_cipher) <= 0)
+        EVP_ASYM_CIPHER_free(asym_cipher); /* up-ref successful but push to stack failed */
 }
 
 static void list_asymciphers(void)
@@ -1026,8 +1036,9 @@ static void collect_kex(EVP_KEYEXCH *kex, void *stack)
     STACK_OF(EVP_KEYEXCH) *kex_stack = stack;
 
     if (is_keyexch_fetchable(kex)
-            && sk_EVP_KEYEXCH_push(kex_stack, kex) > 0)
-        EVP_KEYEXCH_up_ref(kex);
+            && EVP_KEYEXCH_up_ref(kex)
+            && sk_EVP_KEYEXCH_push(kex_stack, kex) <= 0)
+        EVP_KEYEXCH_free(kex); /* up-ref successful but push to stack failed */
 }
 
 static void list_keyexchanges(void)
@@ -1306,8 +1317,9 @@ static void collect_store_loaders(OSSL_STORE_LOADER *store, void *stack)
 {
     STACK_OF(OSSL_STORE_LOADER) *store_stack = stack;
 
-    if (sk_OSSL_STORE_LOADER_push(store_stack, store) > 0)
-        OSSL_STORE_LOADER_up_ref(store);
+    if (OSSL_STORE_LOADER_up_ref(store)
+            && sk_OSSL_STORE_LOADER_push(store_stack, store) <= 0)
+        OSSL_STORE_LOADER_free(store); /* up-ref successful but push to stack failed */
 }
 
 static void list_store_loaders(void)
index c922653ee773e767356bdac658566553654a0437..d98bf3bbe68f78a95c27b1ee8c6adbfee6015a6e 100644 (file)
@@ -208,7 +208,8 @@ static int psk_use_session_cb(SSL *s, const EVP_MD *md,
     const SSL_CIPHER *cipher = NULL;
 
     if (psksess != NULL) {
-        SSL_SESSION_up_ref(psksess);
+        if (!SSL_SESSION_up_ref(psksess))
+            goto err;
         usesess = psksess;
     } else {
         long key_len;
index 888e8f62cf0a02136ba75d90d5618143f238c91c..0d5dd397d8719b1fc26b634f5772086e1c0c9fe8 100644 (file)
@@ -209,7 +209,9 @@ static int psk_find_session_cb(SSL *ssl, const unsigned char *identity,
     }
 
     if (psksess != NULL) {
-        SSL_SESSION_up_ref(psksess);
+        if (!SSL_SESSION_up_ref(psksess))
+            return 0;
+
         *sess = psksess;
         return 1;
     }
index 972e576760d7d9ac4eabe7b156b7ab659b7a6e09..f87598677a468759a6160135795e373cea00b575 100644 (file)
@@ -1817,9 +1817,9 @@ static void collect_kem(EVP_KEM *kem, void *stack)
     STACK_OF(EVP_KEM) *kem_stack = stack;
 
     if (is_kem_fetchable(kem)
-            && sk_EVP_KEM_push(kem_stack, kem) > 0) {
-        EVP_KEM_up_ref(kem);
-    }
+            && EVP_KEM_up_ref(kem)
+            && sk_EVP_KEM_push(kem_stack, kem) <= 0)
+        EVP_KEM_free(kem); /* up-ref successful but push to stack failed */
 }
 
 static int kem_locate(const char *algo, unsigned int *idx)
@@ -1849,8 +1849,9 @@ static void collect_signatures(EVP_SIGNATURE *sig, void *stack)
     STACK_OF(EVP_SIGNATURE) *sig_stack = stack;
 
     if (is_signature_fetchable(sig)
-            && sk_EVP_SIGNATURE_push(sig_stack, sig) > 0)
-        EVP_SIGNATURE_up_ref(sig);
+            && EVP_SIGNATURE_up_ref(sig)
+            && sk_EVP_SIGNATURE_push(sig_stack, sig) <= 0)
+        EVP_SIGNATURE_free(sig); /* up-ref successful but push to stack failed */
 }
 
 static int sig_locate(const char *algo, unsigned int *idx)
index 71059edc9ad02c99b396e362abec2b2fb0707ab3..8423ca3f150d6f2bdd75d598a1681811f65039b2 100644 (file)
@@ -357,8 +357,12 @@ static int cms_RecipientInfo_ktri_init(CMS_RecipientInfo *ri, X509 *recip,
     if (!ossl_cms_set1_SignerIdentifier(ktri->rid, recip, idtype, ctx))
         return 0;
 
-    X509_up_ref(recip);
-    EVP_PKEY_up_ref(pk);
+    if (!X509_up_ref(recip))
+        return 0;
+    if (!EVP_PKEY_up_ref(pk)) {
+        X509_free(recip);
+        return 0;
+    }
 
     ktri->pkey = pk;
     ktri->recip = recip;
index 0fd3d062a3e6ecc8d897c258dc3a8b2ac15c9634..d5c85c2b0e1f79e4aca4101303acf56027447400 100644 (file)
@@ -405,7 +405,9 @@ int ossl_cms_RecipientInfo_kari_init(CMS_RecipientInfo *ri,  X509 *recip,
             return 0;
     }
 
-    EVP_PKEY_up_ref(recipPubKey);
+    if (!EVP_PKEY_up_ref(recipPubKey))
+        return 0;
+
     rek->pkey = recipPubKey;
     return 1;
 }
index aa83c7eaf880c0542e117a9219c3e14f97d50d57..04b21455a90ec74dbd946d493a0371b186cb1dd1 100644 (file)
@@ -356,8 +356,12 @@ CMS_SignerInfo *CMS_add1_signer(CMS_ContentInfo *cms,
     /* Call for side-effect of computing hash and caching extensions */
     X509_check_purpose(signer, -1, -1);
 
-    X509_up_ref(signer);
-    EVP_PKEY_up_ref(pk);
+    if (!X509_up_ref(signer))
+        goto err;
+    if (!EVP_PKEY_up_ref(pk)) {
+        X509_free(signer);
+        goto err;
+    }
 
     si->cms_ctx = ctx;
     si->pkey = pk;
@@ -633,7 +637,8 @@ STACK_OF(X509) *CMS_get0_signers(CMS_ContentInfo *cms)
 void CMS_SignerInfo_set1_signer_cert(CMS_SignerInfo *si, X509 *signer)
 {
     if (signer != NULL) {
-        X509_up_ref(signer);
+        if (!X509_up_ref(signer))
+            return;
         EVP_PKEY_free(si->pkey);
         si->pkey = X509_get_pubkey(signer);
     }
index 27abae7461bf5f90e4ea224729f1ca82d7555118..bd6f96cf94fc2145318d98005954a9f30faebe1b 100644 (file)
@@ -753,7 +753,8 @@ int CMS_decrypt_set1_pkey_and_peer(CMS_ContentInfo *cms, EVP_PKEY *pk,
         }
         /* If we have a cert, try matching RecipientInfo, else try them all */
         else if (cert == NULL || !CMS_RecipientInfo_ktri_cert_cmp(ri, cert)) {
-            EVP_PKEY_up_ref(pk);
+            if (!EVP_PKEY_up_ref(pk))
+                return 0;
             CMS_RecipientInfo_set0_pkey(ri, pk);
             r = CMS_RecipientInfo_decrypt(cms, ri);
             CMS_RecipientInfo_set0_pkey(ri, NULL);
index 945c917c962f33ea7924a5b4191d3d3bbe2124e2..f02a98512fa55372b5b3163cd0a7201ada95e433 100644 (file)
@@ -334,12 +334,13 @@ static EVP_ASYM_CIPHER *evp_asym_cipher_new(OSSL_PROVIDER *prov)
     if (cipher == NULL)
         return NULL;
 
-    if (!CRYPTO_NEW_REF(&cipher->refcnt, 1)) {
+    if (!CRYPTO_NEW_REF(&cipher->refcnt, 1)
+            || !ossl_provider_up_ref(prov)) {
+        CRYPTO_FREE_REF(&cipher->refcnt);
         OPENSSL_free(cipher);
         return NULL;
     }
     cipher->prov = prov;
-    ossl_provider_up_ref(prov);
 
     return cipher;
 }
index 4b8a9bb27daab990aee14a0aba87854d4fe688b3..c42e5dc132fd8cea2f64d097b15f50ce4df3a2e2 100644 (file)
@@ -630,6 +630,10 @@ int EVP_MD_CTX_copy_ex(EVP_MD_CTX *out, const EVP_MD_CTX *in)
     } else {
         evp_md_ctx_reset_ex(out, 1);
         digest_change = (out->fetched_digest != in->fetched_digest);
+
+        if (digest_change && in->fetched_digest != NULL
+            && !EVP_MD_up_ref(in->fetched_digest))
+            return 0;
         if (digest_change && out->fetched_digest != NULL)
             EVP_MD_free(out->fetched_digest);
         *out = *in;
@@ -637,9 +641,6 @@ int EVP_MD_CTX_copy_ex(EVP_MD_CTX *out, const EVP_MD_CTX *in)
         out->pctx = NULL;
         out->algctx = NULL;
 
-        if (digest_change && in->fetched_digest != NULL)
-            EVP_MD_up_ref(in->fetched_digest);
-
         if (in->algctx != NULL) {
             out->algctx = in->digest->dupctx(in->algctx);
             if (out->algctx == NULL) {
@@ -1030,16 +1031,14 @@ static void *evp_md_from_algorithm(int name_id,
     if (!evp_names_do_all(prov, name_id, set_legacy_nid, &md->type)
             || md->type == -1) {
         ERR_raise(ERR_LIB_EVP, ERR_R_INTERNAL_ERROR);
-        EVP_MD_free(md);
-        return NULL;
+        goto err;
     }
 #endif
 
     md->name_id = name_id;
-    if ((md->type_name = ossl_algorithm_get1_first_name(algodef)) == NULL) {
-        EVP_MD_free(md);
-        return NULL;
-    }
+    if ((md->type_name = ossl_algorithm_get1_first_name(algodef)) == NULL)
+        goto err;
+
     md->description = algodef->algorithm_description;
 
     for (; fns->function_id != 0; fns++) {
@@ -1130,21 +1129,24 @@ static void *evp_md_from_algorithm(int name_id,
          * The "digest" function can standalone. We at least need one way to
          * generate digests.
          */
-        EVP_MD_free(md);
         ERR_raise(ERR_LIB_EVP, EVP_R_INVALID_PROVIDER_FUNCTIONS);
-        return NULL;
+        goto err;
     }
+    if (prov != NULL && !ossl_provider_up_ref(prov))
+        goto err;
+
     md->prov = prov;
-    if (prov != NULL)
-        ossl_provider_up_ref(prov);
 
     if (!evp_md_cache_constants(md)) {
-        EVP_MD_free(md);
         ERR_raise(ERR_LIB_EVP, EVP_R_CACHE_CONSTANTS_FAILED);
-        md = NULL;
+        goto err;
     }
 
     return md;
+
+err:
+    EVP_MD_free(md);
+    return NULL;
 }
 
 static int evp_md_up_ref(void *md)
index 2b7f5ffde9f9d3165ca8837629301570747d7b6b..30ce835b8392064a39cb7d152f7b6a5023b3bd4d 100644 (file)
@@ -1891,16 +1891,14 @@ static void *evp_cipher_from_algorithm(const int name_id,
     if (!evp_names_do_all(prov, name_id, set_legacy_nid, &cipher->nid)
             || cipher->nid == -1) {
         ERR_raise(ERR_LIB_EVP, ERR_R_INTERNAL_ERROR);
-        EVP_CIPHER_free(cipher);
-        return NULL;
+        goto err;
     }
 #endif
 
     cipher->name_id = name_id;
-    if ((cipher->type_name = ossl_algorithm_get1_first_name(algodef)) == NULL) {
-        EVP_CIPHER_free(cipher);
-        return NULL;
-    }
+    if ((cipher->type_name = ossl_algorithm_get1_first_name(algodef)) == NULL)
+        goto err;
+
     cipher->description = algodef->algorithm_description;
 
     for (; fns->function_id != 0; fns++) {
@@ -2033,21 +2031,24 @@ static void *evp_cipher_from_algorithm(const int name_id,
          * functions, or a single "cipher" function. In all cases we need both
          * the "newctx" and "freectx" functions.
          */
-        EVP_CIPHER_free(cipher);
         ERR_raise(ERR_LIB_EVP, EVP_R_INVALID_PROVIDER_FUNCTIONS);
-        return NULL;
+        goto err;
     }
+    if (prov != NULL && !ossl_provider_up_ref(prov))
+        goto err;
+
     cipher->prov = prov;
-    if (prov != NULL)
-        ossl_provider_up_ref(prov);
 
     if (!evp_cipher_cache_constants(cipher)) {
-        EVP_CIPHER_free(cipher);
         ERR_raise(ERR_LIB_EVP, EVP_R_CACHE_CONSTANTS_FAILED);
-        cipher = NULL;
+        goto err;
     }
 
     return cipher;
+
+err:
+    EVP_CIPHER_free(cipher);
+    return NULL;
 }
 
 static int evp_cipher_up_ref(void *cipher)
index 693caa56c9995aac1c8a4aa16bf70db5405cb59c..0c27d34ba44f548375adfd4b1e347f3b57104610 100644 (file)
@@ -35,12 +35,13 @@ static EVP_KEYEXCH *evp_keyexch_new(OSSL_PROVIDER *prov)
     if (exchange == NULL)
         return NULL;
 
-    if (!CRYPTO_NEW_REF(&exchange->refcnt, 1)) {
+    if (!CRYPTO_NEW_REF(&exchange->refcnt, 1)
+        || !ossl_provider_up_ref(prov)) {
+        CRYPTO_FREE_REF(&exchange->refcnt);
         OPENSSL_free(exchange);
         return NULL;
     }
     exchange->prov = prov;
-    ossl_provider_up_ref(prov);
 
     return exchange;
 }
@@ -493,17 +494,20 @@ int EVP_PKEY_derive_set_peer_ex(EVP_PKEY_CTX *ctx, EVP_PKEY *peer,
         return -1;
     }
 
+    if (!EVP_PKEY_up_ref(peer))
+        return -1;
+
     EVP_PKEY_free(ctx->peerkey);
     ctx->peerkey = peer;
 
     ret = ctx->pmeth->ctrl(ctx, EVP_PKEY_CTRL_PEER_KEY, 1, peer);
 
     if (ret <= 0) {
+        EVP_PKEY_free(ctx->peerkey);
         ctx->peerkey = NULL;
         return ret;
     }
 
-    EVP_PKEY_up_ref(peer);
     return 1;
 #endif
 }
index 5ee36b2b4213ee8af0afb7d347d35dac6b4cf29e..ba80d5c874ae733780eca02ab205df26188821b6 100644 (file)
@@ -68,10 +68,9 @@ static void *evp_kdf_from_algorithm(int name_id,
         return NULL;
     }
     kdf->name_id = name_id;
-    if ((kdf->type_name = ossl_algorithm_get1_first_name(algodef)) == NULL) {
-        evp_kdf_free(kdf);
-        return NULL;
-    }
+    if ((kdf->type_name = ossl_algorithm_get1_first_name(algodef)) == NULL)
+        goto err;
+
     kdf->description = algodef->algorithm_description;
 
     for (; fns->function_id != 0; fns++) {
@@ -145,15 +144,19 @@ static void *evp_kdf_from_algorithm(int name_id,
          * a derive function, and a complete set of context management
          * functions.
          */
-        evp_kdf_free(kdf);
         ERR_raise(ERR_LIB_EVP, EVP_R_INVALID_PROVIDER_FUNCTIONS);
-        return NULL;
+        goto err;
     }
+    if (prov != NULL && !ossl_provider_up_ref(prov))
+        goto err;
+
     kdf->prov = prov;
-    if (prov != NULL)
-        ossl_provider_up_ref(prov);
 
     return kdf;
+
+err:
+    evp_kdf_free(kdf);
+    return NULL;
 }
 
 EVP_KDF *EVP_KDF_fetch(OSSL_LIB_CTX *libctx, const char *algorithm,
index 6cb7ea8a8e6622949a2a5f9766dccdcb367bc94c..4b6583851017fccf540e35794ad0b604f1575916 100644 (file)
@@ -288,12 +288,13 @@ static EVP_KEM *evp_kem_new(OSSL_PROVIDER *prov)
     if (kem == NULL)
         return NULL;
 
-    if (!CRYPTO_NEW_REF(&kem->refcnt, 1)) {
+    if (!CRYPTO_NEW_REF(&kem->refcnt, 1)
+        || !ossl_provider_up_ref(prov)) {
+        CRYPTO_FREE_REF(&kem->refcnt);
         OPENSSL_free(kem);
         return NULL;
     }
     kem->prov = prov;
-    ossl_provider_up_ref(prov);
 
     return kem;
 }
index 403234c8a2ef1fa599c093493fb70a8930352ee2..8f8d4ccaa830e106508b4796dc4db3edc2e99a7c 100644 (file)
@@ -64,13 +64,13 @@ static void *evp_mac_from_algorithm(int name_id,
 
     if ((mac = evp_mac_new()) == NULL) {
         ERR_raise(ERR_LIB_EVP, ERR_R_EVP_LIB);
-        return NULL;
+        goto err;
     }
     mac->name_id = name_id;
-    if ((mac->type_name = ossl_algorithm_get1_first_name(algodef)) == NULL) {
-        evp_mac_free(mac);
-        return NULL;
-    }
+
+    if ((mac->type_name = ossl_algorithm_get1_first_name(algodef)) == NULL)
+        goto err;
+
     mac->description = algodef->algorithm_description;
 
     for (; fns->function_id != 0; fns++) {
@@ -159,15 +159,20 @@ static void *evp_mac_from_algorithm(int name_id,
          * a complete set of "mac" functions, and a complete set of context
          * management functions, as well as the size function.
          */
-        evp_mac_free(mac);
         ERR_raise(ERR_LIB_EVP, EVP_R_INVALID_PROVIDER_FUNCTIONS);
-        return NULL;
+        goto err;
     }
+
+    if (prov != NULL && !ossl_provider_up_ref(prov))
+        goto err;
+
     mac->prov = prov;
-    if (prov != NULL)
-        ossl_provider_up_ref(prov);
 
     return mac;
+
+err:
+    evp_mac_free(mac);
+    return NULL;
 }
 
 EVP_MAC *EVP_MAC_fetch(OSSL_LIB_CTX *libctx, const char *algorithm,
index 6c65e7e1947a5e6aa020ef72af1a6a7cba88c84b..3334be5df1d02b54b4d0e88cebdb85ad219de9b5 100644 (file)
 
 int EVP_PKEY_set1_RSA(EVP_PKEY *pkey, RSA *key)
 {
-    int ret = EVP_PKEY_assign_RSA(pkey, key);
+    int ret;
+
+    if (!RSA_up_ref(key))
+        return 0;
+
+    ret = EVP_PKEY_assign_RSA(pkey, key);
+
+    if (!ret)
+        RSA_free(key);
 
-    if (ret)
-        RSA_up_ref(key);
     return ret;
 }
 
@@ -49,8 +55,9 @@ RSA *EVP_PKEY_get1_RSA(EVP_PKEY *pkey)
 {
     RSA *ret = evp_pkey_get0_RSA_int(pkey);
 
-    if (ret != NULL)
-        RSA_up_ref(ret);
+    if (ret != NULL && !RSA_up_ref(ret))
+        ret = NULL;
+
     return ret;
 }
 
index 64ef8109831165f852533e98bc8b945faddb8a33..9e275a116d2acdb641aa96c5688d84de2e8a6517 100644 (file)
@@ -897,17 +897,25 @@ const DSA *EVP_PKEY_get0_DSA(const EVP_PKEY *pkey)
 
 int EVP_PKEY_set1_DSA(EVP_PKEY *pkey, DSA *key)
 {
-    int ret = EVP_PKEY_assign_DSA(pkey, key);
-    if (ret)
-        DSA_up_ref(key);
+    int ret;
+
+    if (!DSA_up_ref(key))
+        return 0;
+
+    ret = EVP_PKEY_assign_DSA(pkey, key);
+
+    if (!ret)
+        DSA_free(key);
+
     return ret;
 }
 DSA *EVP_PKEY_get1_DSA(EVP_PKEY *pkey)
 {
     DSA *ret = evp_pkey_get0_DSA_int(pkey);
 
-    if (ret != NULL)
-        DSA_up_ref(ret);
+    if (ret != NULL && !DSA_up_ref(ret))
+        return NULL;
+
     return ret;
 }
 # endif /*  OPENSSL_NO_DSA */
@@ -973,10 +981,14 @@ int EVP_PKEY_set1_DH(EVP_PKEY *pkey, DH *dhkey)
     else
         type = DH_get0_q(dhkey) == NULL ? EVP_PKEY_DH : EVP_PKEY_DHX;
 
+    if (!DH_up_ref(dhkey))
+        return 0;
+
     ret = EVP_PKEY_assign(pkey, type, dhkey);
 
-    if (ret)
-        DH_up_ref(dhkey);
+    if (!ret)
+        DH_free(dhkey);
+
     return ret;
 }
 
@@ -998,8 +1010,9 @@ DH *EVP_PKEY_get1_DH(EVP_PKEY *pkey)
 {
     DH *ret = evp_pkey_get0_DH_int(pkey);
 
-    if (ret != NULL)
-        DH_up_ref(ret);
+    if (ret != NULL && !DH_up_ref(ret))
+        ret = NULL;
+
     return ret;
 }
 # endif
index eb8c37eaf6306527f8f849a947eccb049312a9ad..bed22158c7aaeed9857fca4897dcb25ca6f13c3f 100644 (file)
@@ -321,9 +321,13 @@ static EVP_PKEY_CTX *int_ctx_new(OSSL_LIB_CTX *libctx,
     ret->engine = e;
     ret->pmeth = pmeth;
     ret->operation = EVP_PKEY_OP_UNDEFINED;
+
+    if (pkey != NULL && !EVP_PKEY_up_ref(pkey)) {
+        EVP_PKEY_CTX_free(ret);
+        return NULL;
+    }
+
     ret->pkey = pkey;
-    if (pkey != NULL)
-        EVP_PKEY_up_ref(pkey);
 
     if (pmeth != NULL && pmeth->init != NULL) {
         if (pmeth->init(ret) <= 0) {
@@ -461,8 +465,9 @@ EVP_PKEY_CTX *EVP_PKEY_CTX_dup(const EVP_PKEY_CTX *pctx)
     if (rctx == NULL)
         return NULL;
 
-    if (pctx->pkey != NULL)
-        EVP_PKEY_up_ref(pctx->pkey);
+    if (pctx->pkey != NULL && !EVP_PKEY_up_ref(pctx->pkey))
+        goto err;
+
     rctx->pkey = pctx->pkey;
     rctx->operation = pctx->operation;
     rctx->libctx = pctx->libctx;
@@ -569,8 +574,9 @@ EVP_PKEY_CTX *EVP_PKEY_CTX_dup(const EVP_PKEY_CTX *pctx)
     rctx->engine = pctx->engine;
 # endif
 
-    if (pctx->peerkey != NULL)
-        EVP_PKEY_up_ref(pctx->peerkey);
+    if (pctx->peerkey != NULL && !EVP_PKEY_up_ref(pctx->peerkey))
+        goto err;
+
     rctx->peerkey = pctx->peerkey;
 
     if (pctx->pmeth == NULL) {
index 08082108ea30b369f37b3ceb5753ce0fb8c50b3d..b6f414981c42aa5a63d01b16e0dec4abbbf9ffff 100644 (file)
@@ -37,13 +37,14 @@ static EVP_SIGNATURE *evp_signature_new(OSSL_PROVIDER *prov)
     if (signature == NULL)
         return NULL;
 
-    if (!CRYPTO_NEW_REF(&signature->refcnt, 1)) {
+    if (!CRYPTO_NEW_REF(&signature->refcnt, 1)
+        || !ossl_provider_up_ref(prov)) {
+        CRYPTO_FREE_REF(&signature->refcnt);
         OPENSSL_free(signature);
         return NULL;
     }
 
     signature->prov = prov;
-    ossl_provider_up_ref(prov);
 
     return signature;
 }
index d7c5f1afbe4d3ccf2d2ce6963a74ff6be3219748..f30478979554c3bd3f4da9ccd3031bc01c063df5 100644 (file)
@@ -299,7 +299,8 @@ int PKCS7_add_crl(PKCS7 *p7, X509_CRL *crl)
         return 0;
     }
 
-    X509_CRL_up_ref(crl);
+    if (!X509_CRL_up_ref(crl))
+        return 0;
     if (!sk_X509_CRL_push(*sk, crl)) {
         X509_CRL_free(crl);
         return 0;
@@ -363,7 +364,9 @@ int PKCS7_SIGNER_INFO_set(PKCS7_SIGNER_INFO *p7i, X509 *x509, EVP_PKEY *pkey,
         return 0;
 
     /* lets keep the pkey around for a while */
-    EVP_PKEY_up_ref(pkey);
+    if (!EVP_PKEY_up_ref(pkey))
+        return 0;
+
     p7i->pkey = pkey;
 
     /* Set the algorithms */
@@ -663,7 +666,9 @@ int PKCS7_RECIP_INFO_set(PKCS7_RECIP_INFO *p7i, X509 *x509)
         goto err;
     }
 finished:
-    X509_up_ref(x509);
+    if (!X509_up_ref(x509))
+        goto err;
+
     p7i->cert = x509;
 
     return 1;
index 82874e8a52eb5b5305bef11d9bb8b360711b401d..6b5a5487cbd0e86e3aa38f3cfbf9d15b5ab145df 100644 (file)
@@ -742,7 +742,8 @@ EVP_PKEY *OSSL_STORE_INFO_get0_PARAMS(const OSSL_STORE_INFO *info)
 EVP_PKEY *OSSL_STORE_INFO_get1_PARAMS(const OSSL_STORE_INFO *info)
 {
     if (info->type == OSSL_STORE_INFO_PARAMS) {
-        EVP_PKEY_up_ref(info->_.params);
+        if (!EVP_PKEY_up_ref(info->_.params))
+            return NULL;
         return info->_.params;
     }
     ERR_raise(ERR_LIB_OSSL_STORE, OSSL_STORE_R_NOT_PARAMETERS);
@@ -759,7 +760,8 @@ EVP_PKEY *OSSL_STORE_INFO_get0_PUBKEY(const OSSL_STORE_INFO *info)
 EVP_PKEY *OSSL_STORE_INFO_get1_PUBKEY(const OSSL_STORE_INFO *info)
 {
     if (info->type == OSSL_STORE_INFO_PUBKEY) {
-        EVP_PKEY_up_ref(info->_.pubkey);
+        if (!EVP_PKEY_up_ref(info->_.pubkey))
+            return NULL;
         return info->_.pubkey;
     }
     ERR_raise(ERR_LIB_OSSL_STORE, OSSL_STORE_R_NOT_A_PUBLIC_KEY);
@@ -776,7 +778,8 @@ EVP_PKEY *OSSL_STORE_INFO_get0_PKEY(const OSSL_STORE_INFO *info)
 EVP_PKEY *OSSL_STORE_INFO_get1_PKEY(const OSSL_STORE_INFO *info)
 {
     if (info->type == OSSL_STORE_INFO_PKEY) {
-        EVP_PKEY_up_ref(info->_.pkey);
+        if (!EVP_PKEY_up_ref(info->_.pkey))
+            return NULL;
         return info->_.pkey;
     }
     ERR_raise(ERR_LIB_OSSL_STORE, OSSL_STORE_R_NOT_A_PRIVATE_KEY);
@@ -793,7 +796,8 @@ X509 *OSSL_STORE_INFO_get0_CERT(const OSSL_STORE_INFO *info)
 X509 *OSSL_STORE_INFO_get1_CERT(const OSSL_STORE_INFO *info)
 {
     if (info->type == OSSL_STORE_INFO_CERT) {
-        X509_up_ref(info->_.x509);
+        if (!X509_up_ref(info->_.x509))
+            return NULL;
         return info->_.x509;
     }
     ERR_raise(ERR_LIB_OSSL_STORE, OSSL_STORE_R_NOT_A_CERTIFICATE);
@@ -810,7 +814,8 @@ X509_CRL *OSSL_STORE_INFO_get0_CRL(const OSSL_STORE_INFO *info)
 X509_CRL *OSSL_STORE_INFO_get1_CRL(const OSSL_STORE_INFO *info)
 {
     if (info->type == OSSL_STORE_INFO_CRL) {
-        X509_CRL_up_ref(info->_.crl);
+        if (!X509_CRL_up_ref(info->_.crl))
+            return NULL;
         return info->_.crl;
     }
     ERR_raise(ERR_LIB_OSSL_STORE, OSSL_STORE_R_NOT_A_CRL);
index 6ac8fd5f9374b61f47125c65eca0d334dde46cd9..9333de46f080ecc2784f7ba684a7bd3b9cfd1e10 100644 (file)
@@ -48,12 +48,15 @@ static OSSL_STORE_LOADER *new_loader(OSSL_PROVIDER *prov)
     OSSL_STORE_LOADER *loader;
 
     if ((loader = OPENSSL_zalloc(sizeof(*loader))) == NULL
-        || !CRYPTO_NEW_REF(&loader->refcnt, 1)) {
+        || !CRYPTO_NEW_REF(&loader->refcnt, 1)
+        || !ossl_provider_up_ref(prov)) {
+        if (loader != NULL)
+            CRYPTO_FREE_REF(&loader->refcnt);
         OPENSSL_free(loader);
         return NULL;
     }
+
     loader->prov = prov;
-    ossl_provider_up_ref(prov);
 
     return loader;
 }
index 17f553c1de803c0fab8cd15d69f78da572a68a50..093b517a266321abbdd42c51e5f898e8d98df86a 100644 (file)
@@ -142,17 +142,22 @@ int TS_RESP_CTX_set_signer_cert(TS_RESP_CTX *ctx, X509 *signer)
         ERR_raise(ERR_LIB_TS, TS_R_INVALID_SIGNER_CERTIFICATE_PURPOSE);
         return 0;
     }
+    if (!X509_up_ref(signer))
+        return 0;
+
     X509_free(ctx->signer_cert);
     ctx->signer_cert = signer;
-    X509_up_ref(ctx->signer_cert);
+
     return 1;
 }
 
 int TS_RESP_CTX_set_signer_key(TS_RESP_CTX *ctx, EVP_PKEY *key)
 {
+    if (!EVP_PKEY_up_ref(key))
+        return 0;
+
     EVP_PKEY_free(ctx->signer_key);
     ctx->signer_key = key;
-    EVP_PKEY_up_ref(ctx->signer_key);
 
     return 1;
 }
index cdeac8ef8f564452f4b218d37c0e991619c42750..c816ebedb94fd98df6d5e8a0962a22bbcf8c527c 100644 (file)
@@ -150,8 +150,10 @@ int TS_RESP_verify_signature(PKCS7 *token, STACK_OF(X509) *certs,
     }
 
     if (signer_out) {
+        if (!X509_up_ref(signer))
+            goto err;
+
         *signer_out = signer;
-        X509_up_ref(signer);
     }
     ret = 1;
 
index 7692dc21e6d70308c7f70f852259e49cbf90b989..6012cd25e1efefe35cd9c5cb2d58c39ae7c1ff40 100644 (file)
@@ -211,7 +211,9 @@ static int tree_init(X509_POLICY_TREE **ptree, STACK_OF(X509) *certs,
         /* Access the cache which we now know exists */
         cache = ossl_policy_cache_set(x);
 
-        X509_up_ref(x);
+        if (!X509_up_ref(x))
+            goto bad_tree;
+
         (++level)->cert = x;
 
         if (!cache->anyPolicy)
index 84e270c725f2c51c25900a578670bb1a1d611261..6b79c8a94f2bfe94bcd7b05e79f0d993b01c7128 100644 (file)
@@ -216,13 +216,15 @@ int X509_add_cert(STACK_OF(X509) *sk, X509 *cert, int flags)
         if (ret != 0)
             return ret > 0 ? 1 : 0;
     }
+    if ((flags & X509_ADD_FLAG_UP_REF) != 0 && !X509_up_ref(cert))
+        return 0;
     if (!sk_X509_insert(sk, cert,
                         (flags & X509_ADD_FLAG_PREPEND) != 0 ? 0 : -1)) {
+        if ((flags & X509_ADD_FLAG_UP_REF) != 0)
+            X509_free(cert);
         ERR_raise(ERR_LIB_X509, ERR_R_CRYPTO_LIB);
         return 0;
     }
-    if ((flags & X509_ADD_FLAG_UP_REF) != 0)
-        (void)X509_up_ref(cert);
     return 1;
 }
 
index bdd1b9161c1dff0e40112a1fc3f0adb9b9b2960f..385f4136d418886eea3ea01f5f5d38e2c3fb6282 100644 (file)
@@ -1219,12 +1219,13 @@ static int get_crl_sk(X509_STORE_CTX *ctx, X509_CRL **pcrl, X509_CRL **pdcrl,
     }
 
     if (best_crl != NULL) {
+        if (!X509_CRL_up_ref(best_crl))
+            return 0;
         X509_CRL_free(*pcrl);
         *pcrl = best_crl;
         *pissuer = best_crl_issuer;
         *pscore = best_score;
         *preasons = best_reasons;
-        X509_CRL_up_ref(best_crl);
         X509_CRL_free(*pdcrl);
         *pdcrl = NULL;
         get_delta_sk(ctx, pdcrl, pscore, best_crl, crls);
@@ -1310,10 +1311,16 @@ static void get_delta_sk(X509_STORE_CTX *ctx, X509_CRL **dcrl, int *pscore,
     for (i = 0; i < sk_X509_CRL_num(crls); i++) {
         delta = sk_X509_CRL_value(crls, i);
         if (check_delta_base(delta, base)) {
+            if (!X509_CRL_up_ref(delta)) {
+                *dcrl = NULL;
+                return;
+            }
+
+            *dcrl = delta;
+
             if (check_crl_time(ctx, delta, 0))
                 *pscore |= CRL_SCORE_TIME_DELTA;
-            X509_CRL_up_ref(delta);
-            *dcrl = delta;
+
             return;
         }
     }
@@ -3001,11 +3008,15 @@ static int dane_match_cert(X509_STORE_CTX *ctx, X509 *cert, int depth)
             if (DANETLS_USAGE_BIT(usage) & DANETLS_DANE_MASK)
                 matched = 1;
             if (matched || dane->mdpth < 0) {
-                dane->mdpth = depth;
-                dane->mtlsa = t;
+                if (!X509_up_ref(cert)) {
+                    matched = -1;
+                    break;
+                }
+
                 OPENSSL_free(dane->mcert);
                 dane->mcert = cert;
-                X509_up_ref(cert);
+                dane->mdpth = depth;
+                dane->mtlsa = t;
             }
             break;
         }
index 8057a7170eca884e662b7a4964d8b2ea52c3adef..4048c9193625ae0619da2ff5885a8a8087e535b2 100644 (file)
@@ -121,10 +121,8 @@ And here's the implementation of the FOO method fetcher:
         if ((foo = OPENSSL_zalloc(sizeof(*foo))) == NULL)
             return NULL;
 
-        if (!CRYPTO_NEW_REF(&foo->refcnt, 1)) {
-            OPENSSL_free(foo);
-            return NULL;
-        }
+        if (!CRYPTO_NEW_REF(&foo->refcnt, 1))
+            goto err;
 
         foo->name_id = name_id;
 
@@ -147,11 +145,18 @@ And here's the implementation of the FOO method fetcher:
                 break;
             }
         }
+        if (prov != NULL && !ossl_provider_up_ref(prov))
+            goto err;
+
         foo->prov = prov;
-        if (prov)
-            ossl_provider_up_ref(prov);
 
         return foo;
+
+    err:
+        if (foo != NULL)
+            CRYPTO_FREE_REF(&foo->refcnt);
+        OPENSSL_free(foo);
+        return NULL
     }
 
     EVP_FOO_meth_free(EVP_FOO *foo)
index fb302c3a88c64d21d16cb602a063f3264d33cfd1..ac5931c4bb87ce5dbcecc5c803ace24d68d6ace8 100644 (file)
@@ -61,16 +61,20 @@ static int aes_siv_dupctx(void *in_vctx, void *out_vctx)
     PROV_AES_SIV_CTX *in = (PROV_AES_SIV_CTX *)in_vctx;
     PROV_AES_SIV_CTX *out = (PROV_AES_SIV_CTX *)out_vctx;
 
+    if (in->cbc != NULL && !EVP_CIPHER_up_ref(in->cbc))
+        return 0;
+    if (in->ctr != NULL && !EVP_CIPHER_up_ref(in->ctr)) {
+        EVP_CIPHER_free(in->cbc);
+        return 0;
+    }
+
     *out = *in;
     out->siv.cipher_ctx = NULL;
     out->siv.mac_ctx_init = NULL;
     out->siv.mac = NULL;
     if (!ossl_siv128_copy_ctx(&out->siv, &in->siv))
         return 0;
-    if (out->cbc != NULL)
-        EVP_CIPHER_up_ref(out->cbc);
-    if (out->ctr != NULL)
-        EVP_CIPHER_up_ref(out->ctr);
+
     return 1;
 }
 
index a76a7e2de6d100695eb6d560437bdc30cae76e37..8d10b2fdd5279d2bd4d75928bdadea6b91b95d5c 100644 (file)
@@ -299,10 +299,13 @@ static long ssl_ctrl(BIO *b, int cmd, long num, void *ptr)
         bs->ssl = ssl;
         bio = SSL_get_rbio(ssl);
         if (bio != NULL) {
+            if (!BIO_up_ref(bio)) {
+                ret = 0;
+                break;
+            }
             if (next != NULL)
                 BIO_push(bio, next);
             BIO_set_next(b, bio);
-            BIO_up_ref(bio);
         }
         BIO_set_init(b, 1);
         break;
@@ -338,8 +341,10 @@ static long ssl_ctrl(BIO *b, int cmd, long num, void *ptr)
              * We are going to pass ownership of next to the SSL object...but
              * we don't own a reference to pass yet - so up ref
              */
-            BIO_up_ref(next);
-            SSL_set_bio(ssl, next, next);
+            if (!BIO_up_ref(next))
+                ret = 0;
+            else
+                SSL_set_bio(ssl, next, next);
         }
         break;
     case BIO_CTRL_POP:
index 254cf9128a370d2d977b7328bf17aa3297a84aad..ecb7968897e360f7980079d2ddaa812f583116f9 100644 (file)
@@ -3854,7 +3854,9 @@ long ssl3_ctrl(SSL *s, int cmd, long larg, void *parg)
         if (sc->session == NULL || sc->s3.peer_tmp == NULL) {
             return 0;
         } else {
-            EVP_PKEY_up_ref(sc->s3.peer_tmp);
+            if (!EVP_PKEY_up_ref(sc->s3.peer_tmp))
+                return 0;
+
             *(EVP_PKEY **)parg = sc->s3.peer_tmp;
             return 1;
         }
@@ -3863,7 +3865,9 @@ long ssl3_ctrl(SSL *s, int cmd, long larg, void *parg)
         if (sc->session == NULL || sc->s3.tmp.pkey == NULL) {
             return 0;
         } else {
-            EVP_PKEY_up_ref(sc->s3.tmp.pkey);
+            if (!EVP_PKEY_up_ref(sc->s3.tmp.pkey))
+                return 0;
+
             *(EVP_PKEY **)parg = sc->s3.tmp.pkey;
             return 1;
         }
index 276b489c60ebe4f8c146b0d00102c5c86eb01c38..85ad121bef541a8c67cd7f2b27765206569f4682 100644 (file)
@@ -119,8 +119,9 @@ CERT *ssl_cert_dup(CERT *cert)
     }
 
     if (cert->dh_tmp != NULL) {
+        if (!EVP_PKEY_up_ref(cert->dh_tmp))
+            goto err;
         ret->dh_tmp = cert->dh_tmp;
-        EVP_PKEY_up_ref(ret->dh_tmp);
     }
 
     ret->dh_tmp_cb = cert->dh_tmp_cb;
@@ -131,13 +132,15 @@ CERT *ssl_cert_dup(CERT *cert)
         CERT_PKEY *rpk = ret->pkeys + i;
 
         if (cpk->x509 != NULL) {
+            if (!X509_up_ref(cpk->x509))
+                goto err;
             rpk->x509 = cpk->x509;
-            X509_up_ref(rpk->x509);
         }
 
         if (cpk->privatekey != NULL) {
+            if (!EVP_PKEY_up_ref(cpk->privatekey))
+                goto err;
             rpk->privatekey = cpk->privatekey;
-            EVP_PKEY_up_ref(cpk->privatekey);
         }
 
         if (cpk->chain) {
@@ -201,12 +204,14 @@ CERT *ssl_cert_dup(CERT *cert)
     ret->cert_cb_arg = cert->cert_cb_arg;
 
     if (cert->verify_store) {
-        X509_STORE_up_ref(cert->verify_store);
+        if (!X509_STORE_up_ref(cert->verify_store))
+            goto err;
         ret->verify_store = cert->verify_store;
     }
 
     if (cert->chain_store) {
-        X509_STORE_up_ref(cert->chain_store);
+        if (!X509_STORE_up_ref(cert->chain_store))
+            goto err;
         ret->chain_store = cert->chain_store;
     }
 
@@ -350,9 +355,12 @@ int ssl_cert_add0_chain_cert(SSL_CONNECTION *s, SSL_CTX *ctx, X509 *x)
 
 int ssl_cert_add1_chain_cert(SSL_CONNECTION *s, SSL_CTX *ctx, X509 *x)
 {
-    if (!ssl_cert_add0_chain_cert(s, ctx, x))
+    if (!X509_up_ref(x))
+        return 0;
+    if (!ssl_cert_add0_chain_cert(s, ctx, x)) {
+        X509_free(x);
         return 0;
-    X509_up_ref(x);
+    }
     return 1;
 }
 
@@ -1162,14 +1170,17 @@ int ssl_build_cert_chain(SSL_CONNECTION *s, SSL_CTX *ctx, int flags)
 int ssl_cert_set_cert_store(CERT *c, X509_STORE *store, int chain, int ref)
 {
     X509_STORE **pstore;
+
+    if (ref && store && !X509_STORE_up_ref(store))
+        return 0;
+
     if (chain)
         pstore = &c->chain_store;
     else
         pstore = &c->verify_store;
     X509_STORE_free(*pstore);
     *pstore = store;
-    if (ref && store)
-        X509_STORE_up_ref(store);
+
     return 1;
 }
 
index fb11e72d6b910b2470b78af7af5639b7cb6f82b0..e27c87505320255a741a27ccc27f537e9aaabc4c 100644 (file)
@@ -703,30 +703,30 @@ SSL *SSL_new(SSL_CTX *ctx)
 
 int ossl_ssl_init(SSL *ssl, SSL_CTX *ctx, const SSL_METHOD *method, int type)
 {
-    ssl->type = type;
+    if (!SSL_CTX_up_ref(ctx))
+        return 0;
 
     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 (ssl->lock == NULL || !CRYPTO_NEW_REF(&ssl->references, 1))
+        goto err;
 
     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;
+        goto err;
     }
 
-    SSL_CTX_up_ref(ctx);
     ssl->ctx = ctx;
-
+    ssl->type = type;
     ssl->defltmeth = ssl->method = method;
 
     return 1;
+
+err:
+    CRYPTO_THREAD_lock_free(ssl->lock);
+    ssl->lock = NULL;
+    SSL_CTX_free(ctx);
+    return 0;
 }
 
 SSL *ossl_ssl_connection_new_int(SSL_CTX *ctx, SSL *user_ssl,
@@ -824,7 +824,10 @@ SSL *ossl_ssl_connection_new_int(SSL_CTX *ctx, SSL *user_ssl,
     s->ext.ocsp.exts = NULL;
     s->ext.ocsp.resp = NULL;
     s->ext.ocsp.resp_len = 0;
-    SSL_CTX_up_ref(ctx);
+
+    if (!SSL_CTX_up_ref(ctx))
+        goto err;
+
     s->session_ctx = ctx;
     if (ctx->ext.ecpointformats) {
         s->ext.ecpointformats =
@@ -1964,8 +1967,8 @@ X509 *SSL_get1_peer_certificate(const SSL *s)
 {
     X509 *r = SSL_get0_peer_certificate(s);
 
-    if (r != NULL)
-        X509_up_ref(r);
+    if (r != NULL && !X509_up_ref(r))
+        return NULL;
 
     return r;
 }
@@ -4726,8 +4729,7 @@ void ssl_update_cache(SSL_CONNECTION *s, int mode)
          * TLSv1.3 without early data because some applications just want to
          * know about the creation of a session and aren't doing a full cache.
          */
-        if (s->session_ctx->new_session_cb != NULL) {
-            SSL_SESSION_up_ref(s->session);
+        if (s->session_ctx->new_session_cb != NULL && SSL_SESSION_up_ref(s->session)) {
             if (!s->session_ctx->new_session_cb(SSL_CONNECTION_GET_USER_SSL(s),
                                                 s->session))
                 SSL_SESSION_free(s->session);
@@ -5437,24 +5439,19 @@ SSL_CTX *SSL_set_SSL_CTX(SSL *ssl, SSL_CTX *ctx)
     if (ctx == NULL)
         ctx = sc->session_ctx;
     new_cert = ssl_cert_dup(ctx->cert);
-    if (new_cert == NULL) {
-        return NULL;
-    }
-
-    if (!custom_exts_copy_flags(&new_cert->custext, &sc->cert->custext)) {
-        ssl_cert_free(new_cert);
-        return NULL;
-    }
-
-    ssl_cert_free(sc->cert);
-    sc->cert = new_cert;
+    if (new_cert == NULL)
+        goto err;
+    if (!custom_exts_copy_flags(&new_cert->custext, &sc->cert->custext))
+        goto err;
 
     /*
      * Program invariant: |sid_ctx| has fixed size (SSL_MAX_SID_CTX_LENGTH),
      * so setter APIs must prevent invalid lengths from entering the system.
      */
     if (!ossl_assert(sc->sid_ctx_length <= sizeof(sc->sid_ctx)))
-        return NULL;
+        goto err;
+    if (!SSL_CTX_up_ref(ctx))
+        goto err;
 
     /*
      * If the session ID context matches that of the parent SSL_CTX,
@@ -5469,11 +5466,16 @@ SSL_CTX *SSL_set_SSL_CTX(SSL *ssl, SSL_CTX *ctx)
         memcpy(&sc->sid_ctx, &ctx->sid_ctx, sizeof(sc->sid_ctx));
     }
 
-    SSL_CTX_up_ref(ctx);
+    ssl_cert_free(sc->cert);
+    sc->cert = new_cert;
     SSL_CTX_free(ssl->ctx);     /* decrement reference count */
     ssl->ctx = ctx;
 
     return ssl->ctx;
+
+err:
+    ssl_cert_free(new_cert);
+    return NULL;
 }
 
 int SSL_CTX_set_default_verify_paths(SSL_CTX *ctx)
@@ -5698,8 +5700,9 @@ void SSL_CTX_set_cert_store(SSL_CTX *ctx, X509_STORE *store)
 
 void SSL_CTX_set1_cert_store(SSL_CTX *ctx, X509_STORE *store)
 {
-    if (store != NULL)
-        X509_STORE_up_ref(store);
+    if (store != NULL && !X509_STORE_up_ref(store))
+        return;
+
     SSL_CTX_set_cert_store(ctx, store);
 }
 
index 160c9b3cc26daedb7e84d9f4d5bd50d9bc4d37ac..ce64651f350dcda52e6e581f5946bff0e9f9ff9b 100644 (file)
@@ -142,9 +142,10 @@ static int ssl_set_pkey(CERT *c, EVP_PKEY *pkey, SSL_CTX *ctx)
     if (c->pkeys[i].x509 != NULL
             && !X509_check_private_key(c->pkeys[i].x509, pkey))
         return 0;
+    if (!EVP_PKEY_up_ref(pkey))
+        return 0;
 
     EVP_PKEY_free(c->pkeys[i].privatekey);
-    EVP_PKEY_up_ref(pkey);
     c->pkeys[i].privatekey = pkey;
     c->key = &c->pkeys[i];
     return 1;
@@ -296,8 +297,10 @@ static int ssl_set_cert(CERT *c, X509 *x, SSL_CTX *ctx)
         }
     }
 
+    if (!X509_up_ref(x))
+        return 0;
+
     X509_free(c->pkeys[i].x509);
-    X509_up_ref(x);
     c->pkeys[i].x509 = x;
     c->key = &(c->pkeys[i]);
 
@@ -1047,21 +1050,27 @@ static int ssl_set_cert_and_key(SSL *ssl, SSL_CTX *ctx, X509 *x509, EVP_PKEY *pr
 
     if (chain != NULL) {
         dup_chain = X509_chain_up_ref(chain);
-        if  (dup_chain == NULL) {
+        if (dup_chain == NULL) {
             ERR_raise(ERR_LIB_SSL, ERR_R_X509_LIB);
             goto out;
         }
     }
 
+    if (!X509_up_ref(x509))
+        goto out;
+
+    if (!EVP_PKEY_up_ref(privatekey)) {
+        X509_free(x509);
+        goto out;
+    }
+
     OSSL_STACK_OF_X509_free(c->pkeys[i].chain);
     c->pkeys[i].chain = dup_chain;
 
     X509_free(c->pkeys[i].x509);
-    X509_up_ref(x509);
     c->pkeys[i].x509 = x509;
 
     EVP_PKEY_free(c->pkeys[i].privatekey);
-    EVP_PKEY_up_ref(privatekey);
     c->pkeys[i].privatekey = privatekey;
 
     c->key = &(c->pkeys[i]);
index de63c5b47a789d45deb6b5881e53353076d9ad94..410c98e682b95c2ba2f75244dd7aa0d70e6ec4f9 100644 (file)
@@ -28,7 +28,11 @@ int SSL_use_RSAPrivateKey(SSL *ssl, RSA *rsa)
         return 0;
     }
 
-    RSA_up_ref(rsa);
+    if (!RSA_up_ref(rsa)) {
+        EVP_PKEY_free(pkey);
+        return 0;
+    }
+
     if (EVP_PKEY_assign_RSA(pkey, rsa) <= 0) {
         RSA_free(rsa);
         EVP_PKEY_free(pkey);
@@ -115,7 +119,11 @@ int SSL_CTX_use_RSAPrivateKey(SSL_CTX *ctx, RSA *rsa)
         return 0;
     }
 
-    RSA_up_ref(rsa);
+    if (!RSA_up_ref(rsa)) {
+        EVP_PKEY_free(pkey);
+        return 0;
+    }
+
     if (EVP_PKEY_assign_RSA(pkey, rsa) <= 0) {
         RSA_free(rsa);
         EVP_PKEY_free(pkey);
index e19abf26ec2181cc5c2e38ad0f765616f0e1218c..40c258b7bfcc8bcdd58c5df7a6e067d27b643c44 100644 (file)
@@ -83,8 +83,8 @@ SSL_SESSION *SSL_get1_session(SSL *ssl)
     if (!CRYPTO_THREAD_read_lock(ssl->lock))
         return NULL;
     sess = SSL_get_session(ssl);
-    if (sess != NULL)
-        SSL_SESSION_up_ref(sess);
+    if (sess != NULL && !SSL_SESSION_up_ref(sess))
+        sess = NULL;
     CRYPTO_THREAD_unlock(ssl->lock);
     return sess;
 }
@@ -513,7 +513,10 @@ SSL_SESSION *lookup_sess_in_cache(SSL_CONNECTION *s,
         ret = lh_SSL_SESSION_retrieve(s->session_ctx->sessions, &data);
         if (ret != NULL) {
             /* don't allow other threads to steal it: */
-            SSL_SESSION_up_ref(ret);
+            if (!SSL_SESSION_up_ref(ret)) {
+                CRYPTO_THREAD_unlock(s->session_ctx->lock);
+                return NULL;
+            }
         }
         CRYPTO_THREAD_unlock(s->session_ctx->lock);
         if (ret == NULL)
@@ -543,8 +546,8 @@ SSL_SESSION *lookup_sess_in_cache(SSL_CONNECTION *s,
              * reference count itself [i.e. copy == 0], or things won't be
              * thread-safe).
              */
-            if (copy)
-                SSL_SESSION_up_ref(ret);
+            if (copy && !SSL_SESSION_up_ref(ret))
+                return NULL;
 
             /*
              * Add the externally cached session to the internal cache as
@@ -727,7 +730,8 @@ int SSL_CTX_add_session(SSL_CTX *ctx, SSL_SESSION *c)
      * it has two ways of access: each session is in a doubly linked list and
      * an lhash
      */
-    SSL_SESSION_up_ref(c);
+    if (!SSL_SESSION_up_ref(c))
+        return 0;
     /*
      * if session c is in already in cache, we take back the increment later
      */
@@ -891,16 +895,20 @@ int SSL_set_session(SSL *s, SSL_SESSION *session)
     if (sc == NULL)
         return 0;
 
+    if (session != NULL && !SSL_SESSION_up_ref(session))
+        return 0;
+
     ssl_clear_bad_session(sc);
     if (s->defltmeth != s->method) {
-        if (!SSL_set_ssl_method(s, s->defltmeth))
+        if (!SSL_set_ssl_method(s, s->defltmeth)) {
+            SSL_SESSION_free(session);
             return 0;
+        }
     }
 
-    if (session != NULL) {
-        SSL_SESSION_up_ref(session);
+    if (session != NULL)
         sc->verify_result = session->verify_result;
-    }
+
     SSL_SESSION_free(sc->session);
     sc->session = session;
 
index eafd7a295a00c4956c04eff5716e59e134e942d0..101c93ca45de794268fa56b2c938cb2502a1d57d 100644 (file)
@@ -2141,8 +2141,12 @@ WORK_STATE tls_post_process_server_certificate(SSL_CONNECTION *s,
         }
     }
 
+    if (!X509_up_ref(x)) {
+        SSLfatal(s, SSL_AD_INTERNAL_ERROR, ERR_R_INTERNAL_ERROR);
+        return WORK_ERROR;
+    }
+
     X509_free(s->session->peer);
-    X509_up_ref(x);
     s->session->peer = x;
     s->session->verify_result = s->verify_result;
     /* Ensure there is no RPK */
index 79ff8ec4a274c19596256a0246082fffc0a617c9..ae35f594dcc357aebd076cc0d625b6bba852af6f 100644 (file)
@@ -101,8 +101,10 @@ static int setup_bio_chain(const char *progname)
     if (chain != NULL) {
         size_t i;
 
+        if (!BIO_up_ref(bio_out)) /* Protection against freeing */
+            goto err;
+
         next = bio_out;
-        BIO_up_ref(next);        /* Protection against freeing */
 
         for (i = 0; n > 0; i++, n--) {
             BIO *curr = BIO_new(BIO_f_prefix());
index bacdac35c579b2742028290e53ff45c750fc5c30..dd5ed00d2e32be6e6d6c0628301e9519f8f52b8e 100644 (file)
@@ -276,7 +276,9 @@ static int test_exec_KUR_ses(int transfer_error, int pubkey, int raverified)
     if (pubkey) {
         EVP_PKEY *key = raverified /* wrong key */ ? server_key : client_key;
 
-        EVP_PKEY_up_ref(key);
+        if (!EVP_PKEY_up_ref(key))
+            return 0;
+
         OSSL_CMP_CTX_set0_newPkey(fixture->cmp_ctx, 0 /* not priv */, key);
         OSSL_CMP_SRV_CTX_set_accept_raverified(fixture->srv_ctx, 1);
     }
index 89f342458ec4e58d7b7effba4102ec0104d85e3a..4eac1664e11e964ebb27c362d7b4555fe63b6473 100644 (file)
@@ -262,11 +262,11 @@ static int test_MSG_protect_certificate_based_without_cert(void)
     if (!TEST_ptr(fixture->msg =
                   OSSL_CMP_MSG_dup(ir_unprotected))
             || !TEST_true(SET_OPT_UNPROTECTED_SEND(ctx, 0))
+            || !TEST_true(EVP_PKEY_up_ref(server_key))
             || !TEST_true(OSSL_CMP_CTX_set0_newPkey(ctx, 1, server_key))) {
         tear_down(fixture);
         fixture = NULL;
     }
-    EVP_PKEY_up_ref(server_key);
     EXECUTE_TEST(execute_MSG_protect_test, tear_down);
     return result;
 }
index 37fa6c13c264822228782a77bb952b11dbe9e7d7..aee7173f59c75527ccd48d2ca1ef6bb72b7dc59f 100644 (file)
@@ -266,9 +266,13 @@ static int verify(X509 *leaf, X509 *root, STACK_OF(X509_CRL) *crls,
         goto err;
 
     /* Create a stack; upref the cert because we free it below. */
-    X509_up_ref(root);
-    if (!TEST_true(sk_X509_push(roots, root))
-        || !TEST_true(X509_STORE_CTX_init(ctx, store, leaf, NULL)))
+    if (!TEST_true(X509_up_ref(root)))
+        goto err;
+    if (!TEST_true(sk_X509_push(roots, root))) {
+        X509_free(root);
+        goto err;
+    }
+    if (!TEST_true(X509_STORE_CTX_init(ctx, store, leaf, NULL)))
         goto err;
     X509_STORE_CTX_set0_trusted_stack(ctx, roots);
     X509_STORE_CTX_set0_crls(ctx, crls);
@@ -302,13 +306,29 @@ static STACK_OF(X509_CRL) *make_CRL_stack(X509_CRL *x1, X509_CRL *x2)
 {
     STACK_OF(X509_CRL) *sk = sk_X509_CRL_new_null();
 
-    sk_X509_CRL_push(sk, x1);
-    X509_CRL_up_ref(x1);
+    if (x1 != NULL) {
+        if (!X509_CRL_up_ref(x1))
+            goto err;
+        if (!sk_X509_CRL_push(sk, x1)) {
+            X509_CRL_free(x1);
+            goto err;
+        }
+    }
+
     if (x2 != NULL) {
-        sk_X509_CRL_push(sk, x2);
-        X509_CRL_up_ref(x2);
+        if (!X509_CRL_up_ref(x2))
+            goto err;
+        if (!sk_X509_CRL_push(sk, x2)) {
+            X509_CRL_free(x2);
+            goto err;
+        }
     }
+
     return sk;
+
+err:
+    sk_X509_CRL_pop_free(sk, X509_CRL_free);
+    return NULL;
 }
 
 static int test_basic_crl(void)
index 5fc9accea8068458307de9f96f0247b921d70ca7..085ef583455787ad8fc7fa6af042c5cc85dff58e 100644 (file)
@@ -3159,7 +3159,9 @@ static int test_EVP_PKEY_check(int i)
 #ifndef OPENSSL_NO_DEPRECATED_3_0
     ctx2 = EVP_PKEY_CTX_new_id(0xdefaced, NULL);
     /* assign the pkey directly, as an internal test */
-    EVP_PKEY_up_ref(pkey);
+    if (!EVP_PKEY_up_ref(pkey))
+        goto done;
+
     ctx2->pkey = pkey;
 
     if (!TEST_int_eq(EVP_PKEY_check(ctx2), 0xbeef))
index 07e0756803cadfe2b7721d853a34911cb214e682..6d637ab8f9fe3fa8ae43eecd99c45d51b6ebe304 100644 (file)
@@ -1190,9 +1190,14 @@ int create_ssl_objects(SSL_CTX *serverctx, SSL_CTX *clientctx, SSL **sssl,
     BIO_set_mem_eof_return(c_to_s_bio, -1);
 
     /* Up ref these as we are passing them to two SSL objects */
+    if (!BIO_up_ref(s_to_c_bio))
+        goto error;
+    if (!BIO_up_ref(c_to_s_bio)) {
+        BIO_free(s_to_c_bio);
+        goto error;
+    }
+
     SSL_set_bio(serverssl, c_to_s_bio, s_to_c_bio);
-    BIO_up_ref(s_to_c_bio);
-    BIO_up_ref(c_to_s_bio);
     SSL_set_bio(clientssl, s_to_c_bio, c_to_s_bio);
     *sssl = serverssl;
     *cssl = clientssl;
index 530a736eed875ec181948888384f8babc434c1a4..1a483f6c182d28bec6a480bfefb85006eceb22b7 100644 (file)
@@ -1290,11 +1290,9 @@ static int use_session_cb(SSL *ssl, const EVP_MD *md, const unsigned char **id,
 {
     use_session_cb_cnt++;
 
-    if (clientpsk == NULL)
+    if (clientpsk == NULL || !SSL_SESSION_up_ref(clientpsk))
         return 0;
 
-    SSL_SESSION_up_ref(clientpsk);
-
     *sess = clientpsk;
     *id = (const unsigned char *)pskid;
     *idlen = strlen(pskid);
@@ -1307,15 +1305,16 @@ static int find_session_cb(SSL *ssl, const unsigned char *identity,
 {
     find_session_cb_cnt++;
 
-    if (serverpsk == NULL)
+    if (serverpsk == NULL || !SSL_SESSION_up_ref(serverpsk))
         return 0;
 
     /* Identity should match that set by the client */
     if (strlen(pskid) != identity_len
-            || strncmp(pskid, (const char *)identity, identity_len) != 0)
+            || strncmp(pskid, (const char *)identity, identity_len) != 0) {
+        SSL_SESSION_free(serverpsk);
         return 0;
+    }
 
-    SSL_SESSION_up_ref(serverpsk);
     *sess = serverpsk;
 
     return 1;
@@ -1341,10 +1340,9 @@ static int test_quic_psk(void)
     find_session_cb_cnt = 0;
 
     clientpsk = serverpsk = create_a_psk(clientquic, SHA384_DIGEST_LENGTH);
-    if (!TEST_ptr(clientpsk))
-        goto end;
     /* We already had one ref. Add another one */
-    SSL_SESSION_up_ref(clientpsk);
+    if (!TEST_ptr(clientpsk) || !TEST_true(SSL_SESSION_up_ref(clientpsk)))
+        goto end;
 
     if (!TEST_true(qtest_create_quic_connection(qtserv, clientquic))
             || !TEST_int_eq(1, find_session_cb_cnt)
index 935c8e58c446cad5c7d0f2c4abc9f8bc7ecfa39e..e87e48960070b77f8d81964f8570650e30391a1a 100644 (file)
@@ -2693,9 +2693,8 @@ static int test_psk_tickets(void)
                                       NULL, NULL)))
         goto end;
     clientpsk = serverpsk = create_a_psk(clientssl, SHA384_DIGEST_LENGTH);
-    if (!TEST_ptr(clientpsk))
+    if (!TEST_ptr(clientpsk) || !TEST_true(SSL_SESSION_up_ref(clientpsk)))
         goto end;
-    SSL_SESSION_up_ref(clientpsk);
 
     if (!TEST_true(create_ssl_connection(serverssl, clientssl,
                                                 SSL_ERROR_NONE))
@@ -3005,10 +3004,12 @@ static int test_ssl_set_bio(int idx)
          * each BIO that will have ownership transferred in the SSL_set_bio()
          * call
          */
-        if (irbio != NULL)
-            BIO_up_ref(irbio);
-        if (iwbio != NULL && iwbio != irbio)
-            BIO_up_ref(iwbio);
+        if (irbio != NULL && !BIO_up_ref(irbio))
+            goto end;
+        if (iwbio != NULL && iwbio != irbio && !BIO_up_ref(iwbio)) {
+            BIO_free(irbio);
+            goto end;
+        }
     }
 
     if (conntype != CONNTYPE_NO_CONNECTION
@@ -3028,11 +3029,17 @@ static int test_ssl_set_bio(int idx)
     if (nrbio != NULL
             && nrbio != irbio
             && (nwbio != iwbio || nrbio != nwbio))
-        BIO_up_ref(nrbio);
+        if (!TEST_true(BIO_up_ref(nrbio)))
+            goto end;
     if (nwbio != NULL
             && nwbio != nrbio
             && (nwbio != iwbio || (nwbio == iwbio && irbio == iwbio)))
-        BIO_up_ref(nwbio);
+        if (!TEST_true(BIO_up_ref(nwbio))) {
+            if (nrbio != irbio
+                    && (nwbio != iwbio || nrbio != nwbio))
+                BIO_free(nrbio);
+            goto end;
+        }
 
     SSL_set_bio(clientssl, nrbio, nwbio);
 
@@ -3277,8 +3284,8 @@ static int use_session_cb(SSL *ssl, const EVP_MD *md, const unsigned char **id,
         return 0;
     }
 
-    if (clientpsk != NULL)
-        SSL_SESSION_up_ref(clientpsk);
+    if (clientpsk != NULL && !SSL_SESSION_up_ref(clientpsk))
+        return 0;
 
     *sess = clientpsk;
     *id = (const unsigned char *)pskid;
@@ -3337,7 +3344,9 @@ static int find_session_cb(SSL *ssl, const unsigned char *identity,
         return 1;
     }
 
-    SSL_SESSION_up_ref(serverpsk);
+    if (!SSL_SESSION_up_ref(serverpsk))
+        return 0;
+
     *sess = serverpsk;
 
     return 1;