Closed
Bug 334183
Opened 18 years ago
Closed 18 years ago
Double free on error because CERT_FindCertIssuer unexpectedly calls CERT_DestroyCertificate
Categories
(NSS :: Libraries, defect, P2)
Tracking
(Not tracked)
RESOLVED
FIXED
3.11.1
People
(Reporter: timeless, Assigned: alvolkov.bgs)
References
()
Details
(Keywords: coverity, crash, Whiteboard: [sg:nse] [CID 672 668 665 664 416 412 -- false positive])
Attachments
(1 file, 1 obsolete file)
1.41 KB,
patch
|
alvolkov.bgs
:
review+
|
Details | Diff | Splinter Review |
this is the chain to the first death: CERT_DestroyCertificate CERT_FindCertIssuer seckey_UpdateCertPQGChain SECKEY_UpdateCertPQG CERT_ExtractPublicKey CRMF_CreateEncryptedKeyWithEncryptedValue nsSetEscrowAuthority This is the second free: CERT_DestroyCertificate nsSetEscrowAuthority The return on not found could be reordered, but we'll need to verify that there aren't any other possible codepaths.
Updated•18 years ago
|
Group: security
Whiteboard: [sg:critical?]
it also happens in nsNSSCertificate::GetChain
Summary: Double free on error under nsSetEscrowAuthority → Double free on error under nsSetEscrowAuthority also nsNSSCertificate::GetChain
see bug 334238, same problem, but i actually spent a bit of time thinking about what's going on. at this point i'm fairly certain that CERT_FindCertIssuer doesn't own the cert and has no right to delete it.
more instances: first free: CERT_DestroyCertificate CERT_FindCertIssuer CERT_FilterCertListByCANames second free: CERT_DestroyCertificate CERT_FilterCertListByCANames
Assignee: kengert → nobody
Component: Security: UI → Libraries
Product: Core → NSS
QA Contact: libraries
Version: Trunk → 4.0
CERT_DestroyCertificate CERT_FindCertIssuer seckey_UpdateCertPQGChain SECKEY_UpdateCertPQG CERT_ExtractPublicKey sec_pkcs7_encoder_start_encrypt CERT_DestroyCertificate sec_pkcs7_encoder_start_encrypt
Summary: Double free on error under nsSetEscrowAuthority also nsNSSCertificate::GetChain → Double free on error because CERT_FindCertIssuer unexpectedly calls CERT_DestroyCertificate
*** Bug 334238 has been marked as a duplicate of this bug. ***
first stack: CERT_DestroyCertificate CERT_FindCertIssuer seckey_UpdateCertPQGChain SECKEY_UpdateCertPQG CERT_ExtractPublicKey SECKEY_ConvertToPublicKey second stack: CERT_DestroyCertificate SECKEY_ConvertToPublicKey --- CERT_DestroyCertificate CERT_FindCertIssuer cert_VerifyCertChain CERT_DestroyCertificate cert_VerifyCertChain
CERT_DestroyCertificate CERT_FindCertIssuer cert_VerifyCertChain CERT_DestroyCertificate cert_VerifyCertChain
CERT_DestroyCertificate CERT_FindCertIssuer seckey_UpdateCertPQGChain SECKEY_UpdateCertPQG CERT_ExtractPublicKey NSS_CMSUtil_EncryptSymKey_MISSI CERT_DestroyCertificate NSS_CMSUtil_EncryptSymKey_MISSI
Attachment #218645 -
Flags: review?(nelson)
Comment 10•18 years ago
|
||
Comment on attachment 218645 [details] [diff] [review] this would make us stop destroying it I don't believe this patch is correct. The call to CERT_DestroyCertificate is attempting to free the newly created reference to that certificate, which new refrerence is now held in chain[0]. (I'm sure that is VERY inobvious). Failing to destroy the newly created reference in chain[0] will leak that reference. See bug 225525 for some other possible explanations for the issue you're trying to resolve. > /* > * Find the issuer of a cert. Use the authorityKeyID if it exists. > */ > CERTCertificate * > CERT_FindCertIssuer(CERTCertificate *cert, int64 validTime, SECCertUsage usage) > { > NSSCertificate *me; > NSSTime *nssTime; > NSSTrustDomain *td; > NSSCryptoContext *cc; > NSSCertificate *chain[3]; > NSSUsage nssUsage; > PRStatus status; > > me = STAN_GetNSSCertificate(cert); > if (!me) { > PORT_SetError(SEC_ERROR_NO_MEMORY); > return NULL; > } > nssTime = NSSTime_SetPRTime(NULL, validTime); > nssUsage.anyUsage = PR_FALSE; > nssUsage.nss3usage = usage; > nssUsage.nss3lookingForCA = PR_TRUE; > memset(chain, 0, 3*sizeof(NSSCertificate *)); > td = STAN_GetDefaultTrustDomain(); > cc = STAN_GetDefaultCryptoContext(); > (void)NSSCertificate_BuildChain(me, nssTime, &nssUsage, NULL, > chain, 2, NULL, &status, td, cc); > nss_ZFreeIf(nssTime); > if (status == PR_SUCCESS) { > /* if it's a root, the chain will only have one cert */ > if (!chain[1]) { > /* already has a reference from the call to BuildChain */ > return cert; >- } else { >- CERT_DestroyCertificate(cert); /* the first cert in the chain */ Although it may be very inobvious, I believe the above call to CERT_DestroyCertificate is equivalent to this line of code: NSSCertificate_Destroy(chain[0]); You could add a run time test to ensure that they are equivalent, e.g. PORT_Assert(me == chain[0]); In the event that you ever found that me != chain[0], then the NSSCertificate_Destroy(chain[0]) would be correct and the call to CERT_DestroyCertificate would not. So, I'd argue that changing the code to call NSSCertificate_Destroy(chain[0]) is more correct and more obviously correct. But simply leaking the new reference in chain[0] seems like it should not be an option. >- return STAN_GetCERTCertificate(chain[1]); /* return the 2nd */ > } >+ return STAN_GetCERTCertificate(chain[1]); /* return the 2nd */ > } else { > if (chain[0]) { > CERT_DestroyCertificate(cert); Note that the very same issue applies to the line just above, also. Its destruction of cert is no more or less valid than the one a few lines earlier. The reason for doing it is the same, and the solution to the inobviousness is the same. > } > PORT_SetError (SEC_ERROR_UNKNOWN_ISSUER); > } > return NULL;
Attachment #218645 -
Flags: review?(nelson) → review-
Comment 11•18 years ago
|
||
Julien, this may be related to the work you're doing on bug 225525.
Comment 12•18 years ago
|
||
Of all the coverity bugs filed against NSS recently, this one worries me most. When me == chain[0], I think this code is correct as is. And me should always match chain[0]. But I wouldn't be shocked to learn that sometimes me != chain[0] especially in light of bug 225525. So, I'd suggest making some changes to a) help us detect this case, and b) reduce the damage that occurs when it happens. patch forthcoming.
OS: Linux → All
Priority: -- → P2
Hardware: PC → All
Target Milestone: --- → 3.1.1
Comment 13•18 years ago
|
||
This is not intended to be a fix as much as problem detection and damage control.
Attachment #218645 -
Attachment is obsolete: true
Attachment #218745 -
Flags: review?(julien.pierre.bugs)
Updated•18 years ago
|
Target Milestone: 3.1.1 → 3.11.1
Version: 4.0 → 3.11
Updated•18 years ago
|
Attachment #218745 -
Flags: review?(alexei.volkov.bugs)
Assignee | ||
Updated•18 years ago
|
Attachment #218745 -
Flags: review?(alexei.volkov.bugs) → review+
Assignee | ||
Comment 14•18 years ago
|
||
tip: /cvsroot/mozilla/security/nss/lib/certhigh/certvfy.c,v <-- certvfy.c new revision: 1.47; previous revision: 1.46 3.11 branch: /cvsroot/mozilla/security/nss/lib/certhigh/certvfy.c,v <-- certvfy.c new revision: 1.44.10.3; previous revision: 1.44.10.2
Status: NEW → RESOLVED
Closed: 18 years ago
Resolution: --- → FIXED
Assignee | ||
Updated•18 years ago
|
Assignee: nobody → alexei.volkov.bugs
Comment 15•18 years ago
|
||
Comment on attachment 218745 [details] [diff] [review] detect me != chain[0] and free chain[0] removing old review request, now that bug is resolved/fixed.
Attachment #218745 -
Flags: review?(julien.pierre.bugs)
Comment 16•18 years ago
|
||
CID 672 This was a false positive. The "fix" we put in was to make the false positive more obvious to coverity.
Group: security
Whiteboard: [sg:critical?] → [sg:critical?] CID 672
Assignee | ||
Updated•18 years ago
|
Whiteboard: [sg:critical?] CID 672 → [sg:critical?] [CID 672 668]
Assignee | ||
Updated•18 years ago
|
Whiteboard: [sg:critical?] [CID 672 668] → [sg:critical?] [CID 672 668 665]
Assignee | ||
Updated•18 years ago
|
Whiteboard: [sg:critical?] [CID 672 668 665] → [sg:critical?] [CID 672 668 665 664]
Assignee | ||
Updated•18 years ago
|
Whiteboard: [sg:critical?] [CID 672 668 665 664] → [sg:critical?] [CID 672 668 665 664416 ]
Assignee | ||
Updated•18 years ago
|
Whiteboard: [sg:critical?] [CID 672 668 665 664416 ] → [sg:critical?] [CID 672 668 665 664 416]
Assignee | ||
Updated•18 years ago
|
Whiteboard: [sg:critical?] [CID 672 668 665 664 416] → [sg:critical?] [CID 672 668 665 664 416 412]
Updated•18 years ago
|
Whiteboard: [sg:critical?] [CID 672 668 665 664 416 412] → [sg:nse] [CID 672 668 665 664 416 412 -- false positive]
You need to log in
before you can comment on or make changes to this bug.
Description
•