diff options
-rw-r--r-- | meta-oe/recipes-support/nss/nss/CVE-2021-43527.patch | 283 | ||||
-rw-r--r-- | meta-oe/recipes-support/nss/nss_3.51.1.bb | 1 |
2 files changed, 284 insertions, 0 deletions
diff --git a/meta-oe/recipes-support/nss/nss/CVE-2021-43527.patch b/meta-oe/recipes-support/nss/nss/CVE-2021-43527.patch new file mode 100644 index 000000000..cf3ea63ca --- /dev/null +++ b/meta-oe/recipes-support/nss/nss/CVE-2021-43527.patch | |||
@@ -0,0 +1,283 @@ | |||
1 | Description: fix heap overflow when verifying DSA/RSA-PSS DER-encoded signatures | ||
2 | Origin: Provided by Mozilla | ||
3 | |||
4 | CVE: CVE-2021-43527 | ||
5 | Upstream-Status: Backport [http://archive.ubuntu.com/ubuntu/pool/main/n/nss/nss_3.35-2ubuntu2.13.debian.tar.xz] | ||
6 | Comment: Refreshed hunk 1 and 6 due to fuzz | ||
7 | Signed-off-by: Sana Kazi <Sana.Kazi@kpit.com> | ||
8 | |||
9 | --- a/nss/lib/cryptohi/secvfy.c | ||
10 | +++ b/nss/lib/cryptohi/secvfy.c | ||
11 | @@ -164,6 +164,37 @@ | ||
12 | PR_FALSE /*XXX: unsafeAllowMissingParameters*/); | ||
13 | } | ||
14 | |||
15 | +static unsigned int | ||
16 | +checkedSignatureLen(const SECKEYPublicKey *pubk) | ||
17 | +{ | ||
18 | + unsigned int sigLen = SECKEY_SignatureLen(pubk); | ||
19 | + if (sigLen == 0) { | ||
20 | + /* Error set by SECKEY_SignatureLen */ | ||
21 | + return sigLen; | ||
22 | + } | ||
23 | + unsigned int maxSigLen; | ||
24 | + switch (pubk->keyType) { | ||
25 | + case rsaKey: | ||
26 | + case rsaPssKey: | ||
27 | + maxSigLen = (RSA_MAX_MODULUS_BITS + 7) / 8; | ||
28 | + break; | ||
29 | + case dsaKey: | ||
30 | + maxSigLen = DSA_MAX_SIGNATURE_LEN; | ||
31 | + break; | ||
32 | + case ecKey: | ||
33 | + maxSigLen = 2 * MAX_ECKEY_LEN; | ||
34 | + break; | ||
35 | + default: | ||
36 | + PORT_SetError(SEC_ERROR_UNSUPPORTED_KEYALG); | ||
37 | + return 0; | ||
38 | + } | ||
39 | + if (sigLen > maxSigLen) { | ||
40 | + PORT_SetError(SEC_ERROR_INVALID_KEY); | ||
41 | + return 0; | ||
42 | + } | ||
43 | + return sigLen; | ||
44 | +} | ||
45 | + | ||
46 | /* | ||
47 | * decode the ECDSA or DSA signature from it's DER wrapping. | ||
48 | * The unwrapped/raw signature is placed in the buffer pointed | ||
49 | @@ -174,38 +205,38 @@ decodeECorDSASignature(SECOidTag algid, | ||
50 | unsigned int len) | ||
51 | { | ||
52 | SECItem *dsasig = NULL; /* also used for ECDSA */ | ||
53 | - SECStatus rv = SECSuccess; | ||
54 | |||
55 | - if ((algid != SEC_OID_ANSIX9_DSA_SIGNATURE) && | ||
56 | - (algid != SEC_OID_ANSIX962_EC_PUBLIC_KEY)) { | ||
57 | - if (sig->len != len) { | ||
58 | - PORT_SetError(SEC_ERROR_BAD_DER); | ||
59 | - return SECFailure; | ||
60 | + /* Safety: Ensure algId is as expected and that signature size is within maxmimums */ | ||
61 | + if (algid == SEC_OID_ANSIX9_DSA_SIGNATURE) { | ||
62 | + if (len > DSA_MAX_SIGNATURE_LEN) { | ||
63 | + goto loser; | ||
64 | } | ||
65 | - | ||
66 | - PORT_Memcpy(dsig, sig->data, sig->len); | ||
67 | - return SECSuccess; | ||
68 | - } | ||
69 | - | ||
70 | - if (algid == SEC_OID_ANSIX962_EC_PUBLIC_KEY) { | ||
71 | + } else if (algid == SEC_OID_ANSIX962_EC_PUBLIC_KEY) { | ||
72 | if (len > MAX_ECKEY_LEN * 2) { | ||
73 | - PORT_SetError(SEC_ERROR_BAD_DER); | ||
74 | - return SECFailure; | ||
75 | + goto loser; | ||
76 | } | ||
77 | - } | ||
78 | - dsasig = DSAU_DecodeDerSigToLen((SECItem *)sig, len); | ||
79 | - | ||
80 | - if ((dsasig == NULL) || (dsasig->len != len)) { | ||
81 | - rv = SECFailure; | ||
82 | } else { | ||
83 | - PORT_Memcpy(dsig, dsasig->data, dsasig->len); | ||
84 | + goto loser; | ||
85 | } | ||
86 | |||
87 | - if (dsasig != NULL) | ||
88 | + /* Decode and pad to length */ | ||
89 | + dsasig = DSAU_DecodeDerSigToLen((SECItem *)sig, len); | ||
90 | + if (dsasig == NULL) { | ||
91 | + goto loser; | ||
92 | + } | ||
93 | + if (dsasig->len != len) { | ||
94 | SECITEM_FreeItem(dsasig, PR_TRUE); | ||
95 | - if (rv == SECFailure) | ||
96 | - PORT_SetError(SEC_ERROR_BAD_DER); | ||
97 | - return rv; | ||
98 | + goto loser; | ||
99 | + } | ||
100 | + | ||
101 | + PORT_Memcpy(dsig, dsasig->data, len); | ||
102 | + SECITEM_FreeItem(dsasig, PR_TRUE); | ||
103 | + | ||
104 | + return SECSuccess; | ||
105 | + | ||
106 | +loser: | ||
107 | + PORT_SetError(SEC_ERROR_BAD_DER); | ||
108 | + return SECFailure; | ||
109 | } | ||
110 | |||
111 | const SEC_ASN1Template hashParameterTemplate[] = | ||
112 | @@ -231,7 +262,7 @@ SECStatus | ||
113 | sec_DecodeSigAlg(const SECKEYPublicKey *key, SECOidTag sigAlg, | ||
114 | const SECItem *param, SECOidTag *encalg, SECOidTag *hashalg) | ||
115 | { | ||
116 | - int len; | ||
117 | + unsigned int len; | ||
118 | PLArenaPool *arena; | ||
119 | SECStatus rv; | ||
120 | SECItem oid; | ||
121 | @@ -458,48 +489,52 @@ vfy_CreateContext(const SECKEYPublicKey | ||
122 | cx->pkcs1RSADigestInfo = NULL; | ||
123 | rv = SECSuccess; | ||
124 | if (sig) { | ||
125 | - switch (type) { | ||
126 | - case rsaKey: | ||
127 | - rv = recoverPKCS1DigestInfo(hashAlg, &cx->hashAlg, | ||
128 | - &cx->pkcs1RSADigestInfo, | ||
129 | - &cx->pkcs1RSADigestInfoLen, | ||
130 | - cx->key, | ||
131 | - sig, wincx); | ||
132 | - break; | ||
133 | - case rsaPssKey: | ||
134 | - sigLen = SECKEY_SignatureLen(key); | ||
135 | - if (sigLen == 0) { | ||
136 | - /* error set by SECKEY_SignatureLen */ | ||
137 | - rv = SECFailure; | ||
138 | + rv = SECFailure; | ||
139 | + if (type == rsaKey) { | ||
140 | + rv = recoverPKCS1DigestInfo(hashAlg, &cx->hashAlg, | ||
141 | + &cx->pkcs1RSADigestInfo, | ||
142 | + &cx->pkcs1RSADigestInfoLen, | ||
143 | + cx->key, | ||
144 | + sig, wincx); | ||
145 | + } else { | ||
146 | + sigLen = checkedSignatureLen(key); | ||
147 | + /* Check signature length is within limits */ | ||
148 | + if (sigLen == 0) { | ||
149 | + /* error set by checkedSignatureLen */ | ||
150 | + rv = SECFailure; | ||
151 | + goto loser; | ||
152 | + } | ||
153 | + if (sigLen > sizeof(cx->u)) { | ||
154 | + PORT_SetError(SEC_ERROR_BAD_SIGNATURE); | ||
155 | + rv = SECFailure; | ||
156 | + goto loser; | ||
157 | + } | ||
158 | + switch (type) { | ||
159 | + case rsaPssKey: | ||
160 | + if (sig->len != sigLen) { | ||
161 | + PORT_SetError(SEC_ERROR_BAD_SIGNATURE); | ||
162 | + rv = SECFailure; | ||
163 | + goto loser; | ||
164 | + } | ||
165 | + PORT_Memcpy(cx->u.buffer, sig->data, sigLen); | ||
166 | + rv = SECSuccess; | ||
167 | break; | ||
168 | - } | ||
169 | - if (sig->len != sigLen) { | ||
170 | - PORT_SetError(SEC_ERROR_BAD_SIGNATURE); | ||
171 | - rv = SECFailure; | ||
172 | + case ecKey: | ||
173 | + case dsaKey: | ||
174 | + /* decodeECorDSASignature will check sigLen == sig->len after padding */ | ||
175 | + rv = decodeECorDSASignature(encAlg, sig, cx->u.buffer, sigLen); | ||
176 | break; | ||
177 | - } | ||
178 | - PORT_Memcpy(cx->u.buffer, sig->data, sigLen); | ||
179 | - break; | ||
180 | - case dsaKey: | ||
181 | - case ecKey: | ||
182 | - sigLen = SECKEY_SignatureLen(key); | ||
183 | - if (sigLen == 0) { | ||
184 | - /* error set by SECKEY_SignatureLen */ | ||
185 | + default: | ||
186 | + /* Unreachable */ | ||
187 | rv = SECFailure; | ||
188 | - break; | ||
189 | - } | ||
190 | - rv = decodeECorDSASignature(encAlg, sig, cx->u.buffer, sigLen); | ||
191 | - break; | ||
192 | - default: | ||
193 | - rv = SECFailure; | ||
194 | - PORT_SetError(SEC_ERROR_UNSUPPORTED_KEYALG); | ||
195 | - break; | ||
196 | + goto loser; | ||
197 | + } | ||
198 | + } | ||
199 | + if (rv != SECSuccess) { | ||
200 | + goto loser; | ||
201 | } | ||
202 | } | ||
203 | |||
204 | - if (rv) | ||
205 | - goto loser; | ||
206 | - | ||
207 | /* check hash alg again, RSA may have changed it.*/ | ||
208 | if (HASH_GetHashTypeByOidTag(cx->hashAlg) == HASH_AlgNULL) { | ||
209 | /* error set by HASH_GetHashTypeByOidTag */ | ||
210 | @@ -634,11 +669,16 @@ VFY_EndWithSignature(VFYContext *cx, SEC | ||
211 | switch (cx->key->keyType) { | ||
212 | case ecKey: | ||
213 | case dsaKey: | ||
214 | - dsasig.data = cx->u.buffer; | ||
215 | - dsasig.len = SECKEY_SignatureLen(cx->key); | ||
216 | + dsasig.len = checkedSignatureLen(cx->key); | ||
217 | if (dsasig.len == 0) { | ||
218 | return SECFailure; | ||
219 | } | ||
220 | + if (dsasig.len > sizeof(cx->u)) { | ||
221 | + PORT_SetError(SEC_ERROR_BAD_SIGNATURE); | ||
222 | + return SECFailure; | ||
223 | + } | ||
224 | + dsasig.data = cx->u.buffer; | ||
225 | + | ||
226 | if (sig) { | ||
227 | rv = decodeECorDSASignature(cx->encAlg, sig, dsasig.data, | ||
228 | dsasig.len); | ||
229 | @@ -667,8 +698,13 @@ | ||
230 | } | ||
231 | |||
232 | rsasig.data = cx->u.buffer; | ||
233 | - rsasig.len = SECKEY_SignatureLen(cx->key); | ||
234 | + rsasig.len = checkedSignatureLen(cx->key); | ||
235 | if (rsasig.len == 0) { | ||
236 | + /* Error set by checkedSignatureLen */ | ||
237 | + return SECFailure; | ||
238 | + } | ||
239 | + if (rsasig.len > sizeof(cx->u)) { | ||
240 | + PORT_SetError(SEC_ERROR_BAD_SIGNATURE); | ||
241 | return SECFailure; | ||
242 | } | ||
243 | if (sig) { | ||
244 | @@ -743,7 +788,6 @@ vfy_VerifyDigest(const SECItem *digest, | ||
245 | SECStatus rv; | ||
246 | VFYContext *cx; | ||
247 | SECItem dsasig; /* also used for ECDSA */ | ||
248 | - | ||
249 | rv = SECFailure; | ||
250 | |||
251 | cx = vfy_CreateContext(key, sig, encAlg, hashAlg, NULL, wincx); | ||
252 | @@ -751,19 +795,25 @@ vfy_VerifyDigest(const SECItem *digest, | ||
253 | switch (key->keyType) { | ||
254 | case rsaKey: | ||
255 | rv = verifyPKCS1DigestInfo(cx, digest); | ||
256 | + /* Error (if any) set by verifyPKCS1DigestInfo */ | ||
257 | break; | ||
258 | - case dsaKey: | ||
259 | case ecKey: | ||
260 | + case dsaKey: | ||
261 | dsasig.data = cx->u.buffer; | ||
262 | - dsasig.len = SECKEY_SignatureLen(cx->key); | ||
263 | + dsasig.len = checkedSignatureLen(cx->key); | ||
264 | if (dsasig.len == 0) { | ||
265 | + /* Error set by checkedSignatureLen */ | ||
266 | + rv = SECFailure; | ||
267 | break; | ||
268 | } | ||
269 | - if (PK11_Verify(cx->key, &dsasig, (SECItem *)digest, cx->wincx) != | ||
270 | - SECSuccess) { | ||
271 | + if (dsasig.len > sizeof(cx->u)) { | ||
272 | + PORT_SetError(SEC_ERROR_BAD_SIGNATURE); | ||
273 | + rv = SECFailure; | ||
274 | + break; | ||
275 | + } | ||
276 | + rv = PK11_Verify(cx->key, &dsasig, (SECItem *)digest, cx->wincx); | ||
277 | + if (rv != SECSuccess) { | ||
278 | PORT_SetError(SEC_ERROR_BAD_SIGNATURE); | ||
279 | - } else { | ||
280 | - rv = SECSuccess; | ||
281 | } | ||
282 | break; | ||
283 | default: | ||
diff --git a/meta-oe/recipes-support/nss/nss_3.51.1.bb b/meta-oe/recipes-support/nss/nss_3.51.1.bb index 14f670c32..f03473b1a 100644 --- a/meta-oe/recipes-support/nss/nss_3.51.1.bb +++ b/meta-oe/recipes-support/nss/nss_3.51.1.bb | |||
@@ -39,6 +39,7 @@ SRC_URI = "http://ftp.mozilla.org/pub/mozilla.org/security/nss/releases/${VERSIO | |||
39 | file://CVE-2020-6829_12400.patch \ | 39 | file://CVE-2020-6829_12400.patch \ |
40 | file://CVE-2020-12403_1.patch \ | 40 | file://CVE-2020-12403_1.patch \ |
41 | file://CVE-2020-12403_2.patch \ | 41 | file://CVE-2020-12403_2.patch \ |
42 | file://CVE-2021-43527.patch \ | ||
42 | " | 43 | " |
43 | 44 | ||
44 | SRC_URI[md5sum] = "6acaf1ddff69306ae30a908881c6f233" | 45 | SRC_URI[md5sum] = "6acaf1ddff69306ae30a908881c6f233" |