From 364b6e63eacad84859b261f8bb945ca51fba9021 Mon Sep 17 00:00:00 2001 From: Bernd Edlinger Date: Wed, 15 Nov 2023 20:49:51 +0100 Subject: [PATCH] Fix a possible use after free in X509v3_asid_add_id_or_range And clean up partially created choice objects, which have still the default type = -1 from ASIdentifierChoice_new(). Fixes #22700 Reviewed-by: Todd Short Reviewed-by: Tomas Mraz (Merged from https://github.com/openssl/openssl/pull/22745) (cherry picked from commit 49e9436af3d85963fd6156b7d6f33e0734bf5ba9) --- crypto/x509/v3_asid.c | 17 +++++++++++++---- 1 file changed, 13 insertions(+), 4 deletions(-) diff --git a/crypto/x509/v3_asid.c b/crypto/x509/v3_asid.c index 86577d6ca48..4a719d4d118 100644 --- a/crypto/x509/v3_asid.c +++ b/crypto/x509/v3_asid.c @@ -169,8 +169,11 @@ int X509v3_asid_add_inherit(ASIdentifiers *asid, int which) if (*choice == NULL) { if ((*choice = ASIdentifierChoice_new()) == NULL) return 0; - if (((*choice)->u.inherit = ASN1_NULL_new()) == NULL) + if (((*choice)->u.inherit = ASN1_NULL_new()) == NULL) { + ASIdentifierChoice_free(*choice); + *choice = NULL; return 0; + } (*choice)->type = ASIdentifierChoice_inherit; } return (*choice)->type == ASIdentifierChoice_inherit; @@ -196,18 +199,23 @@ int X509v3_asid_add_id_or_range(ASIdentifiers *asid, default: return 0; } - if (*choice != NULL && (*choice)->type == ASIdentifierChoice_inherit) + if (*choice != NULL && (*choice)->type != ASIdentifierChoice_asIdsOrRanges) return 0; if (*choice == NULL) { if ((*choice = ASIdentifierChoice_new()) == NULL) return 0; (*choice)->u.asIdsOrRanges = sk_ASIdOrRange_new(ASIdOrRange_cmp); - if ((*choice)->u.asIdsOrRanges == NULL) + if ((*choice)->u.asIdsOrRanges == NULL) { + ASIdentifierChoice_free(*choice); + *choice = NULL; return 0; + } (*choice)->type = ASIdentifierChoice_asIdsOrRanges; } if ((aor = ASIdOrRange_new()) == NULL) return 0; + if (!sk_ASIdOrRange_reserve((*choice)->u.asIdsOrRanges, 1)) + goto err; if (max == NULL) { aor->type = ASIdOrRange_id; aor->u.id = min; @@ -220,7 +228,8 @@ int X509v3_asid_add_id_or_range(ASIdentifiers *asid, ASN1_INTEGER_free(aor->u.range->max); aor->u.range->max = max; } - if (!(sk_ASIdOrRange_push((*choice)->u.asIdsOrRanges, aor))) + /* Cannot fail due to the reservation above */ + if (!ossl_assert(sk_ASIdOrRange_push((*choice)->u.asIdsOrRanges, aor))) goto err; return 1; -- 2.47.2