Hi, Could you please review the below patch?
Regards, Sana Kazi On Thu, 16 Dec 2021 at 16:23, Sana Kazi <sanakazis...@gmail.com> wrote: > Add patch to fix CVE-2021-43527 which causes heap overflow in nss. > > Signed-off-by: Sana Kazi <sana.k...@kpit.com> > Signed-off-by: Sana Kazi <sanakazis...@gmail.com> > --- > .../nss/nss/CVE-2021-43527.patch | 283 ++++++++++++++++++ > meta-oe/recipes-support/nss/nss_3.51.1.bb | 1 + > 2 files changed, 284 insertions(+) > create mode 100644 meta-oe/recipes-support/nss/nss/CVE-2021-43527.patch > > 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 @@ > +Description: fix heap overflow when verifying DSA/RSA-PSS DER-encoded > signatures > +Origin: Provided by Mozilla > + > +CVE: CVE-2021-43527 > +Upstream-Status: Backport [ > http://archive.ubuntu.com/ubuntu/pool/main/n/nss/nss_3.35-2ubuntu2.13.debian.tar.xz > ] > +Comment: Refreshed hunk 1 and 6 due to fuzz > +Signed-off-by: Sana Kazi <sana.k...@kpit.com> > + > +--- a/nss/lib/cryptohi/secvfy.c > ++++ b/nss/lib/cryptohi/secvfy.c > +@@ -164,6 +164,37 @@ > + PR_FALSE /*XXX: unsafeAllowMissingParameters*/); > + } > + > ++static unsigned int > ++checkedSignatureLen(const SECKEYPublicKey *pubk) > ++{ > ++ unsigned int sigLen = SECKEY_SignatureLen(pubk); > ++ if (sigLen == 0) { > ++ /* Error set by SECKEY_SignatureLen */ > ++ return sigLen; > ++ } > ++ unsigned int maxSigLen; > ++ switch (pubk->keyType) { > ++ case rsaKey: > ++ case rsaPssKey: > ++ maxSigLen = (RSA_MAX_MODULUS_BITS + 7) / 8; > ++ break; > ++ case dsaKey: > ++ maxSigLen = DSA_MAX_SIGNATURE_LEN; > ++ break; > ++ case ecKey: > ++ maxSigLen = 2 * MAX_ECKEY_LEN; > ++ break; > ++ default: > ++ PORT_SetError(SEC_ERROR_UNSUPPORTED_KEYALG); > ++ return 0; > ++ } > ++ if (sigLen > maxSigLen) { > ++ PORT_SetError(SEC_ERROR_INVALID_KEY); > ++ return 0; > ++ } > ++ return sigLen; > ++} > ++ > + /* > + * decode the ECDSA or DSA signature from it's DER wrapping. > + * The unwrapped/raw signature is placed in the buffer pointed > +@@ -174,38 +205,38 @@ decodeECorDSASignature(SECOidTag algid, > + unsigned int len) > + { > + SECItem *dsasig = NULL; /* also used for ECDSA */ > +- SECStatus rv = SECSuccess; > + > +- if ((algid != SEC_OID_ANSIX9_DSA_SIGNATURE) && > +- (algid != SEC_OID_ANSIX962_EC_PUBLIC_KEY)) { > +- if (sig->len != len) { > +- PORT_SetError(SEC_ERROR_BAD_DER); > +- return SECFailure; > ++ /* Safety: Ensure algId is as expected and that signature size is > within maxmimums */ > ++ if (algid == SEC_OID_ANSIX9_DSA_SIGNATURE) { > ++ if (len > DSA_MAX_SIGNATURE_LEN) { > ++ goto loser; > + } > +- > +- PORT_Memcpy(dsig, sig->data, sig->len); > +- return SECSuccess; > +- } > +- > +- if (algid == SEC_OID_ANSIX962_EC_PUBLIC_KEY) { > ++ } else if (algid == SEC_OID_ANSIX962_EC_PUBLIC_KEY) { > + if (len > MAX_ECKEY_LEN * 2) { > +- PORT_SetError(SEC_ERROR_BAD_DER); > +- return SECFailure; > ++ goto loser; > + } > +- } > +- dsasig = DSAU_DecodeDerSigToLen((SECItem *)sig, len); > +- > +- if ((dsasig == NULL) || (dsasig->len != len)) { > +- rv = SECFailure; > + } else { > +- PORT_Memcpy(dsig, dsasig->data, dsasig->len); > ++ goto loser; > + } > + > +- if (dsasig != NULL) > ++ /* Decode and pad to length */ > ++ dsasig = DSAU_DecodeDerSigToLen((SECItem *)sig, len); > ++ if (dsasig == NULL) { > ++ goto loser; > ++ } > ++ if (dsasig->len != len) { > + SECITEM_FreeItem(dsasig, PR_TRUE); > +- if (rv == SECFailure) > +- PORT_SetError(SEC_ERROR_BAD_DER); > +- return rv; > ++ goto loser; > ++ } > ++ > ++ PORT_Memcpy(dsig, dsasig->data, len); > ++ SECITEM_FreeItem(dsasig, PR_TRUE); > ++ > ++ return SECSuccess; > ++ > ++loser: > ++ PORT_SetError(SEC_ERROR_BAD_DER); > ++ return SECFailure; > + } > + > + const SEC_ASN1Template hashParameterTemplate[] = > +@@ -231,7 +262,7 @@ SECStatus > + sec_DecodeSigAlg(const SECKEYPublicKey *key, SECOidTag sigAlg, > + const SECItem *param, SECOidTag *encalg, SECOidTag > *hashalg) > + { > +- int len; > ++ unsigned int len; > + PLArenaPool *arena; > + SECStatus rv; > + SECItem oid; > +@@ -458,48 +489,52 @@ vfy_CreateContext(const SECKEYPublicKey > + cx->pkcs1RSADigestInfo = NULL; > + rv = SECSuccess; > + if (sig) { > +- switch (type) { > +- case rsaKey: > +- rv = recoverPKCS1DigestInfo(hashAlg, &cx->hashAlg, > +- &cx->pkcs1RSADigestInfo, > +- &cx->pkcs1RSADigestInfoLen, > +- cx->key, > +- sig, wincx); > +- break; > +- case rsaPssKey: > +- sigLen = SECKEY_SignatureLen(key); > +- if (sigLen == 0) { > +- /* error set by SECKEY_SignatureLen */ > +- rv = SECFailure; > ++ rv = SECFailure; > ++ if (type == rsaKey) { > ++ rv = recoverPKCS1DigestInfo(hashAlg, &cx->hashAlg, > ++ &cx->pkcs1RSADigestInfo, > ++ &cx->pkcs1RSADigestInfoLen, > ++ cx->key, > ++ sig, wincx); > ++ } else { > ++ sigLen = checkedSignatureLen(key); > ++ /* Check signature length is within limits */ > ++ if (sigLen == 0) { > ++ /* error set by checkedSignatureLen */ > ++ rv = SECFailure; > ++ goto loser; > ++ } > ++ if (sigLen > sizeof(cx->u)) { > ++ PORT_SetError(SEC_ERROR_BAD_SIGNATURE); > ++ rv = SECFailure; > ++ goto loser; > ++ } > ++ switch (type) { > ++ case rsaPssKey: > ++ if (sig->len != sigLen) { > ++ PORT_SetError(SEC_ERROR_BAD_SIGNATURE); > ++ rv = SECFailure; > ++ goto loser; > ++ } > ++ PORT_Memcpy(cx->u.buffer, sig->data, sigLen); > ++ rv = SECSuccess; > + break; > +- } > +- if (sig->len != sigLen) { > +- PORT_SetError(SEC_ERROR_BAD_SIGNATURE); > +- rv = SECFailure; > ++ case ecKey: > ++ case dsaKey: > ++ /* decodeECorDSASignature will check sigLen == > sig->len after padding */ > ++ rv = decodeECorDSASignature(encAlg, sig, > cx->u.buffer, sigLen); > + break; > +- } > +- PORT_Memcpy(cx->u.buffer, sig->data, sigLen); > +- break; > +- case dsaKey: > +- case ecKey: > +- sigLen = SECKEY_SignatureLen(key); > +- if (sigLen == 0) { > +- /* error set by SECKEY_SignatureLen */ > ++ default: > ++ /* Unreachable */ > + rv = SECFailure; > +- break; > +- } > +- rv = decodeECorDSASignature(encAlg, sig, cx->u.buffer, > sigLen); > +- break; > +- default: > +- rv = SECFailure; > +- PORT_SetError(SEC_ERROR_UNSUPPORTED_KEYALG); > +- break; > ++ goto loser; > ++ } > ++ } > ++ if (rv != SECSuccess) { > ++ goto loser; > + } > + } > + > +- if (rv) > +- goto loser; > +- > + /* check hash alg again, RSA may have changed it.*/ > + if (HASH_GetHashTypeByOidTag(cx->hashAlg) == HASH_AlgNULL) { > + /* error set by HASH_GetHashTypeByOidTag */ > +@@ -634,11 +669,16 @@ VFY_EndWithSignature(VFYContext *cx, SEC > + switch (cx->key->keyType) { > + case ecKey: > + case dsaKey: > +- dsasig.data = cx->u.buffer; > +- dsasig.len = SECKEY_SignatureLen(cx->key); > ++ dsasig.len = checkedSignatureLen(cx->key); > + if (dsasig.len == 0) { > + return SECFailure; > + } > ++ if (dsasig.len > sizeof(cx->u)) { > ++ PORT_SetError(SEC_ERROR_BAD_SIGNATURE); > ++ return SECFailure; > ++ } > ++ dsasig.data = cx->u.buffer; > ++ > + if (sig) { > + rv = decodeECorDSASignature(cx->encAlg, sig, dsasig.data, > + dsasig.len); > +@@ -667,8 +698,13 @@ > + } > + > + rsasig.data = cx->u.buffer; > +- rsasig.len = SECKEY_SignatureLen(cx->key); > ++ rsasig.len = checkedSignatureLen(cx->key); > + if (rsasig.len == 0) { > ++ /* Error set by checkedSignatureLen */ > ++ return SECFailure; > ++ } > ++ if (rsasig.len > sizeof(cx->u)) { > ++ PORT_SetError(SEC_ERROR_BAD_SIGNATURE); > > + return SECFailure; > + } > + if (sig) { > +@@ -743,7 +788,6 @@ vfy_VerifyDigest(const SECItem *digest, > + SECStatus rv; > + VFYContext *cx; > + SECItem dsasig; /* also used for ECDSA */ > +- > + rv = SECFailure; > + > + cx = vfy_CreateContext(key, sig, encAlg, hashAlg, NULL, wincx); > +@@ -751,19 +795,25 @@ vfy_VerifyDigest(const SECItem *digest, > + switch (key->keyType) { > + case rsaKey: > + rv = verifyPKCS1DigestInfo(cx, digest); > ++ /* Error (if any) set by verifyPKCS1DigestInfo */ > + break; > +- case dsaKey: > + case ecKey: > ++ case dsaKey: > + dsasig.data = cx->u.buffer; > +- dsasig.len = SECKEY_SignatureLen(cx->key); > ++ dsasig.len = checkedSignatureLen(cx->key); > + if (dsasig.len == 0) { > ++ /* Error set by checkedSignatureLen */ > ++ rv = SECFailure; > + break; > + } > +- if (PK11_Verify(cx->key, &dsasig, (SECItem *)digest, > cx->wincx) != > +- SECSuccess) { > ++ if (dsasig.len > sizeof(cx->u)) { > ++ PORT_SetError(SEC_ERROR_BAD_SIGNATURE); > ++ rv = SECFailure; > ++ break; > ++ } > ++ rv = PK11_Verify(cx->key, &dsasig, (SECItem *)digest, > cx->wincx); > ++ if (rv != SECSuccess) { > + PORT_SetError(SEC_ERROR_BAD_SIGNATURE); > +- } else { > +- rv = SECSuccess; > + } > + break; > + 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 > file://CVE-2020-6829_12400.patch \ > file://CVE-2020-12403_1.patch \ > file://CVE-2020-12403_2.patch \ > + file://CVE-2021-43527.patch \ > " > > SRC_URI[md5sum] = "6acaf1ddff69306ae30a908881c6f233" > -- > 2.17.1 > >
-=-=-=-=-=-=-=-=-=-=-=- Links: You receive all messages sent to this group. View/Reply Online (#94477): https://lists.openembedded.org/g/openembedded-devel/message/94477 Mute This Topic: https://lists.openembedded.org/mt/87764680/21656 Group Owner: openembedded-devel+ow...@lists.openembedded.org Unsubscribe: https://lists.openembedded.org/g/openembedded-devel/unsub [arch...@mail-archive.com] -=-=-=-=-=-=-=-=-=-=-=-