Skip to content

Commit 3e14b7e

Browse files
authored
hvloader: add patch for CVE-2023-0464 (#9443)
1 parent cd7cf07 commit 3e14b7e

3 files changed

Lines changed: 229 additions & 4 deletions

File tree

SPECS-SIGNED/hvloader-signed/hvloader-signed.spec

Lines changed: 4 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -6,7 +6,7 @@
66
Summary: Signed HvLoader.efi for %{buildarch} systems
77
Name: hvloader-signed-%{buildarch}
88
Version: 1.0.1
9-
Release: 4%{?dist}
9+
Release: 5%{?dist}
1010
License: MIT
1111
Vendor: Microsoft Corporation
1212
Distribution: Mariner
@@ -69,6 +69,9 @@ popd
6969
/boot/efi/HvLoader.efi
7070

7171
%changelog
72+
* Wed Jun 19 2024 Archana Choudhary <archana1@microsoft.com> - 1.0.1-5
73+
- Update version for consistency with hvloader spec
74+
7275
* Thu Jun 06 2024 Archana Choudhary <archana1@microsoft.com> - 1.0.1-4
7376
- Update version for consistency with hvloader spec
7477

SPECS/hvloader/CVE-2023-0464.patch

Lines changed: 219 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,219 @@
1+
From 879f7080d7e141f415c79eaa3a8ac4a3dad0348b Mon Sep 17 00:00:00 2001
2+
From: Pauli <pauli@openssl.org>
3+
Date: Wed, 8 Mar 2023 15:28:20 +1100
4+
Subject: [PATCH] x509: excessive resource use verifying policy constraints
5+
6+
A security vulnerability has been identified in all supported versions
7+
of OpenSSL related to the verification of X.509 certificate chains
8+
that include policy constraints. Attackers may be able to exploit this
9+
vulnerability by creating a malicious certificate chain that triggers
10+
exponential use of computational resources, leading to a denial-of-service
11+
(DoS) attack on affected systems.
12+
13+
Fixes CVE-2023-0464
14+
15+
Reviewed-by: Tomas Mraz <tomas@openssl.org>
16+
Reviewed-by: Shane Lontis <shane.lontis@oracle.com>
17+
(Merged from https://github.com/openssl/openssl/pull/20569)
18+
---
19+
crypto/x509v3/pcy_local.h | 8 +++++++-
20+
crypto/x509v3/pcy_node.c | 12 +++++++++---
21+
crypto/x509v3/pcy_tree.c | 37 +++++++++++++++++++++++++++----------
22+
3 files changed, 43 insertions(+), 14 deletions(-)
23+
24+
diff --git a/CryptoPkg/Library/OpensslLib/openssl/crypto/x509v3/pcy_local.h b/CryptoPkg/Library/OpensslLib/openssl/crypto/x509v3/pcy_local.h
25+
index 5daf78de45850..344aa067659cd 100644
26+
--- a/CryptoPkg/Library/OpensslLib/openssl/crypto/x509v3/pcy_local.h
27+
+++ b/CryptoPkg/Library/OpensslLib/openssl/crypto/x509v3/pcy_local.h
28+
@@ -111,6 +111,11 @@ struct X509_POLICY_LEVEL_st {
29+
};
30+
31+
struct X509_POLICY_TREE_st {
32+
+ /* The number of nodes in the tree */
33+
+ size_t node_count;
34+
+ /* The maximum number of nodes in the tree */
35+
+ size_t node_maximum;
36+
+
37+
/* This is the tree 'level' data */
38+
X509_POLICY_LEVEL *levels;
39+
int nlevel;
40+
@@ -159,7 +164,8 @@ X509_POLICY_NODE *tree_find_sk(STACK_OF(X509_POLICY_NODE) *sk,
41+
X509_POLICY_NODE *level_add_node(X509_POLICY_LEVEL *level,
42+
X509_POLICY_DATA *data,
43+
X509_POLICY_NODE *parent,
44+
- X509_POLICY_TREE *tree);
45+
+ X509_POLICY_TREE *tree,
46+
+ int extra_data);
47+
void policy_node_free(X509_POLICY_NODE *node);
48+
int policy_node_match(const X509_POLICY_LEVEL *lvl,
49+
const X509_POLICY_NODE *node, const ASN1_OBJECT *oid);
50+
diff --git a/CryptoPkg/Library/OpensslLib/openssl/crypto/x509v3/pcy_node.c b/CryptoPkg/Library/OpensslLib/openssl/crypto/x509v3/pcy_node.c
51+
index e2d7b15322363..d574fb9d665dc 100644
52+
--- a/CryptoPkg/Library/OpensslLib/openssl/crypto/x509v3/pcy_node.c
53+
+++ b/CryptoPkg/Library/OpensslLib/openssl/crypto/x509v3/pcy_node.c
54+
@@ -59,10 +59,15 @@ X509_POLICY_NODE *level_find_node(const X509_POLICY_LEVEL *level,
55+
X509_POLICY_NODE *level_add_node(X509_POLICY_LEVEL *level,
56+
X509_POLICY_DATA *data,
57+
X509_POLICY_NODE *parent,
58+
- X509_POLICY_TREE *tree)
59+
+ X509_POLICY_TREE *tree,
60+
+ int extra_data)
61+
{
62+
X509_POLICY_NODE *node;
63+
64+
+ /* Verify that the tree isn't too large. This mitigates CVE-2023-0464 */
65+
+ if (tree->node_maximum > 0 && tree->node_count >= tree->node_maximum)
66+
+ return NULL;
67+
+
68+
node = OPENSSL_zalloc(sizeof(*node));
69+
if (node == NULL) {
70+
X509V3err(X509V3_F_LEVEL_ADD_NODE, ERR_R_MALLOC_FAILURE);
71+
@@ -70,7 +75,7 @@ X509_POLICY_NODE *level_add_node(X509_POLICY_LEVEL *level,
72+
}
73+
node->data = data;
74+
node->parent = parent;
75+
- if (level) {
76+
+ if (level != NULL) {
77+
if (OBJ_obj2nid(data->valid_policy) == NID_any_policy) {
78+
if (level->anyPolicy)
79+
goto node_error;
80+
@@ -90,7 +95,7 @@ X509_POLICY_NODE *level_add_node(X509_POLICY_LEVEL *level,
81+
}
82+
}
83+
84+
- if (tree) {
85+
+ if (extra_data) {
86+
if (tree->extra_data == NULL)
87+
tree->extra_data = sk_X509_POLICY_DATA_new_null();
88+
if (tree->extra_data == NULL){
89+
@@ -103,6 +108,7 @@ X509_POLICY_NODE *level_add_node(X509_POLICY_LEVEL *level,
90+
}
91+
}
92+
93+
+ tree->node_count++;
94+
if (parent)
95+
parent->nchild++;
96+
97+
diff --git a/CryptoPkg/Library/OpensslLib/openssl/crypto/x509v3/pcy_tree.c b/CryptoPkg/Library/OpensslLib/openssl/crypto/x509v3/pcy_tree.c
98+
index 6e8322cbc5e38..6c7fd35405000 100644
99+
--- a/CryptoPkg/Library/OpensslLib/openssl/crypto/x509v3/pcy_tree.c
100+
+++ b/CryptoPkg/Library/OpensslLib/openssl/crypto/x509v3/pcy_tree.c
101+
@@ -13,6 +13,18 @@
102+
103+
#include "pcy_local.h"
104+
105+
+/*
106+
+ * If the maximum number of nodes in the policy tree isn't defined, set it to
107+
+ * a generous default of 1000 nodes.
108+
+ *
109+
+ * Defining this to be zero means unlimited policy tree growth which opens the
110+
+ * door on CVE-2023-0464.
111+
+ */
112+
+
113+
+#ifndef OPENSSL_POLICY_TREE_NODES_MAX
114+
+# define OPENSSL_POLICY_TREE_NODES_MAX 1000
115+
+#endif
116+
+
117+
/*
118+
* Enable this to print out the complete policy tree at various point during
119+
* evaluation.
120+
@@ -168,6 +180,9 @@ static int tree_init(X509_POLICY_TREE **ptree, STACK_OF(X509) *certs,
121+
return X509_PCY_TREE_INTERNAL;
122+
}
123+
124+
+ /* Limit the growth of the tree to mitigate CVE-2023-0464 */
125+
+ tree->node_maximum = OPENSSL_POLICY_TREE_NODES_MAX;
126+
+
127+
/*
128+
* http://tools.ietf.org/html/rfc5280#section-6.1.2, figure 3.
129+
*
130+
@@ -184,7 +199,7 @@ static int tree_init(X509_POLICY_TREE **ptree, STACK_OF(X509) *certs,
131+
level = tree->levels;
132+
if ((data = policy_data_new(NULL, OBJ_nid2obj(NID_any_policy), 0)) == NULL)
133+
goto bad_tree;
134+
- if (level_add_node(level, data, NULL, tree) == NULL) {
135+
+ if (level_add_node(level, data, NULL, tree, 1) == NULL) {
136+
policy_data_free(data);
137+
goto bad_tree;
138+
}
139+
@@ -243,7 +258,8 @@ static int tree_init(X509_POLICY_TREE **ptree, STACK_OF(X509) *certs,
140+
* Return value: 1 on success, 0 otherwise
141+
*/
142+
static int tree_link_matching_nodes(X509_POLICY_LEVEL *curr,
143+
- X509_POLICY_DATA *data)
144+
+ X509_POLICY_DATA *data,
145+
+ X509_POLICY_TREE *tree)
146+
{
147+
X509_POLICY_LEVEL *last = curr - 1;
148+
int i, matched = 0;
149+
@@ -253,13 +269,13 @@ static int tree_link_matching_nodes(X509_POLICY_LEVEL *curr,
150+
X509_POLICY_NODE *node = sk_X509_POLICY_NODE_value(last->nodes, i);
151+
152+
if (policy_node_match(last, node, data->valid_policy)) {
153+
- if (level_add_node(curr, data, node, NULL) == NULL)
154+
+ if (level_add_node(curr, data, node, tree, 0) == NULL)
155+
return 0;
156+
matched = 1;
157+
}
158+
}
159+
if (!matched && last->anyPolicy) {
160+
- if (level_add_node(curr, data, last->anyPolicy, NULL) == NULL)
161+
+ if (level_add_node(curr, data, last->anyPolicy, tree, 0) == NULL)
162+
return 0;
163+
}
164+
return 1;
165+
@@ -272,7 +288,8 @@ static int tree_link_matching_nodes(X509_POLICY_LEVEL *curr,
166+
* Return value: 1 on success, 0 otherwise.
167+
*/
168+
static int tree_link_nodes(X509_POLICY_LEVEL *curr,
169+
- const X509_POLICY_CACHE *cache)
170+
+ const X509_POLICY_CACHE *cache,
171+
+ X509_POLICY_TREE *tree)
172+
{
173+
int i;
174+
175+
@@ -280,7 +297,7 @@ static int tree_link_nodes(X509_POLICY_LEVEL *curr,
176+
X509_POLICY_DATA *data = sk_X509_POLICY_DATA_value(cache->data, i);
177+
178+
/* Look for matching nodes in previous level */
179+
- if (!tree_link_matching_nodes(curr, data))
180+
+ if (!tree_link_matching_nodes(curr, data, tree))
181+
return 0;
182+
}
183+
return 1;
184+
@@ -311,7 +328,7 @@ static int tree_add_unmatched(X509_POLICY_LEVEL *curr,
185+
/* Curr may not have anyPolicy */
186+
data->qualifier_set = cache->anyPolicy->qualifier_set;
187+
data->flags |= POLICY_DATA_FLAG_SHARED_QUALIFIERS;
188+
- if (level_add_node(curr, data, node, tree) == NULL) {
189+
+ if (level_add_node(curr, data, node, tree, 1) == NULL) {
190+
policy_data_free(data);
191+
return 0;
192+
}
193+
@@ -373,7 +390,7 @@ static int tree_link_any(X509_POLICY_LEVEL *curr,
194+
}
195+
/* Finally add link to anyPolicy */
196+
if (last->anyPolicy &&
197+
- level_add_node(curr, cache->anyPolicy, last->anyPolicy, NULL) == NULL)
198+
+ level_add_node(curr, cache->anyPolicy, last->anyPolicy, tree, 0) == NULL)
199+
return 0;
200+
return 1;
201+
}
202+
@@ -555,7 +572,7 @@ static int tree_calculate_user_set(X509_POLICY_TREE *tree,
203+
extra->qualifier_set = anyPolicy->data->qualifier_set;
204+
extra->flags = POLICY_DATA_FLAG_SHARED_QUALIFIERS
205+
| POLICY_DATA_FLAG_EXTRA_NODE;
206+
- node = level_add_node(NULL, extra, anyPolicy->parent, tree);
207+
+ node = level_add_node(NULL, extra, anyPolicy->parent, tree, 1);
208+
}
209+
if (!tree->user_policies) {
210+
tree->user_policies = sk_X509_POLICY_NODE_new_null();
211+
@@ -582,7 +599,7 @@ static int tree_evaluate(X509_POLICY_TREE *tree)
212+
213+
for (i = 1; i < tree->nlevel; i++, curr++) {
214+
cache = policy_cache_set(curr->cert);
215+
- if (!tree_link_nodes(curr, cache))
216+
+ if (!tree_link_nodes(curr, cache, tree))
217+
return X509_PCY_TREE_INTERNAL;
218+
219+
if (!(curr->flags & X509_V_FLAG_INHIBIT_ANY)

SPECS/hvloader/hvloader.spec

Lines changed: 6 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -4,7 +4,7 @@
44
Summary: HvLoader.efi is an EFI application for loading an external hypervisor loader.
55
Name: hvloader
66
Version: 1.0.1
7-
Release: 4%{?dist}
7+
Release: 5%{?dist}
88
License: MIT
99
Vendor: Microsoft Corporation
1010
Distribution: Mariner
@@ -15,6 +15,7 @@ Source0: https://github.com/microsoft/HvLoader/archive/refs/tags/v%{versi
1515
Source1: https://github.com/tianocore/edk2/archive/refs/tags/%{edk2_tag}.tar.gz#/%{edk2_tag}-submodules.tar.gz
1616
Source2: target-x86.txt
1717
Patch0: CVE-2024-1298.patch
18+
Patch1: CVE-2023-0464.patch
1819
BuildRequires: bc
1920
BuildRequires: gcc
2021
BuildRequires: build-essential
@@ -37,8 +38,7 @@ and use those as configuration parameters. The first HvLoader.efi command line
3738
option is the path to hypervisor loader binary.
3839

3940
%prep
40-
%setup -T -a 0 -a 1 -c "%{name}-%{version}"
41-
%patch0 -p1
41+
%autosetup -a 0 -a 1 -c "%{name}-%{version}" -p1
4242
set -x
4343
ls -l
4444
mv %{name_github}-%{version} MdeModulePkg/Application
@@ -60,6 +60,9 @@ cp ./Build/MdeModule/RELEASE_GCC5/X64/MdeModulePkg/Application/%{name_github}-%{
6060
/boot/efi/HvLoader.efi
6161

6262
%changelog
63+
* Wed Jun 19 2024 Archana Choudhary <archana1@microsoft.com> - 1.0.1-5
64+
- Add patch to resolve CVE-2023-0464
65+
6366
* Thu Jun 06 2024 Archana Choudhary <archana1@microsoft.com> - 1.0.1-4
6467
- Add patch to resolve CVE-2024-1298
6568

0 commit comments

Comments
 (0)