From: Clemens Lang Date: Wed, 24 May 2023 11:12:54 +0000 (+0200) Subject: x509: Handle ossl_policy_level_add_node errors X-Git-Tag: OpenSSL_1_1_1u~3 X-Git-Url: http://git.ipfire.org/cgi-bin/gitweb.cgi?a=commitdiff_plain;h=3cc6933555a0c66328ec659b5bb86c57b6402e1e;p=thirdparty%2Fopenssl.git x509: Handle ossl_policy_level_add_node errors The invocation of ossl_policy_level_add_node in tree_calculate_user_set did not have any error handling. Add it to prevent a memory leak for the allocated extra policy data. Also add error handling to sk_X509_POLICY_NODE_push to ensure that if a new node was allocated, but could not be added to the stack, it is freed correctly. Fix error handling if tree->user_policies cannot be allocated by returning 0, indicating failure, rather than 1. Signed-off-by: Clemens Lang Reviewed-by: Dmitry Belyavskiy Reviewed-by: Matt Caswell Reviewed-by: Bernd Edlinger Reviewed-by: Tomas Mraz (Merged from https://github.com/openssl/openssl/pull/21066) --- diff --git a/crypto/x509v3/pcy_tree.c b/crypto/x509v3/pcy_tree.c index 6c7fd354050..3c504e82c68 100644 --- a/crypto/x509v3/pcy_tree.c +++ b/crypto/x509v3/pcy_tree.c @@ -25,6 +25,8 @@ # define OPENSSL_POLICY_TREE_NODES_MAX 1000 #endif +static void exnode_free(X509_POLICY_NODE *node); + /* * Enable this to print out the complete policy tree at various point during * evaluation. @@ -572,15 +574,24 @@ static int tree_calculate_user_set(X509_POLICY_TREE *tree, extra->qualifier_set = anyPolicy->data->qualifier_set; extra->flags = POLICY_DATA_FLAG_SHARED_QUALIFIERS | POLICY_DATA_FLAG_EXTRA_NODE; - node = level_add_node(NULL, extra, anyPolicy->parent, tree, 1); + node = level_add_node(NULL, extra, anyPolicy->parent, + tree, 1); + if (node == NULL) { + policy_data_free(extra); + return 0; + } } if (!tree->user_policies) { tree->user_policies = sk_X509_POLICY_NODE_new_null(); - if (!tree->user_policies) - return 1; + if (!tree->user_policies) { + exnode_free(node); + return 0; + } } - if (!sk_X509_POLICY_NODE_push(tree->user_policies, node)) + if (!sk_X509_POLICY_NODE_push(tree->user_policies, node)) { + exnode_free(node); return 0; + } } return 1; }