Closed Bug 334448 Opened 19 years ago Closed 19 years ago

oom Crash in crmf_copy_cert_req_msg

Categories

(NSS :: Libraries, defect, P2)

3.11
All
Linux
defect

Tracking

(Not tracked)

RESOLVED FIXED
3.11.2

People

(Reporter: timeless, Assigned: alvolkov.bgs)

References

()

Details

(4 keywords, Whiteboard: CID 212)

Attachments

(2 files, 2 obsolete files)

found by coverity
Attachment #218791 - Flags: review?(nelson)
Comment on attachment 218791 [details] [diff] [review] free arena if object isn't constructed > newReqMsg = PORT_ArenaZNew(poolp, CRMFCertReqMsg); > newReqMsg->poolp = poolp; > if (newReqMsg == NULL) { > goto loser; As long as you're here, check for null /before/ dereferencing newReqMsg->poolp. > newReqMsg->pop = crmf_copy_pop(poolp, srcReqMsg->pop); > if (newReqMsg->pop == NULL) { > goto loser; This is fine here, but looking in crmf_copy_pop it looks like it leaks newPOP if it hits any of the three "goto loser" cases.
Target Milestone: --- → 3.11.1
Priority: -- → P2
Hardware: PC → All
Comment on attachment 218791 [details] [diff] [review] free arena if object isn't constructed > newReqMsg = PORT_ArenaZNew(poolp, CRMFCertReqMsg); > newReqMsg->poolp = poolp; > if (newReqMsg == NULL) { Dan's right. That crash has to be fixed. This patch didn't address that. > loser: > if (newReqMsg != NULL) { >- CRMF_DestroyCertReqMsg(newReqMsg); >+ if (newReqMsg->certReq) { >+ CRMF_DestroyCertReqMsg(newReqMsg); >+ } else { >+ PORT_FreeArena(poolp, PR_TRUE); >+ } The right way to destroy a CertReqMsg is to call CRMF_DestroyCertReqMsg, even if the CertReqMsg is incomplete. If CRMF_DestroyCertReqMsg crashes when the CertReqMsg is incomplete, then the patch should fix THAT, rather than incorporate some of the logic that belongs in CRMF_DestroyCertReqMsg into every one of its callers.
Attachment #218791 - Flags: review?(nelson) → review-
> > newReqMsg->pop = crmf_copy_pop(poolp, srcReqMsg->pop); > > if (newReqMsg->pop == NULL) { > > goto loser; > > This is fine here, but looking in crmf_copy_pop it looks like it leaks newPOP > if it hits any of the three "goto loser" cases. > Yes, the newPOP object leaks in crmf_copy_pop. PORT_ArenaMark, PORT_ArenaUnmark, PORT_ArenaRelease should be used in the function.
Attached patch fix for crash and some leaks (obsolete) — Splinter Review
Assignee: nobody → alexei.volkov.bugs
Status: NEW → ASSIGNED
Attachment #219376 - Flags: review?(nelson)
Comment on attachment 219376 [details] [diff] [review] fix for crash and some leaks r- I see no calls to PORT_ArenaUnmark here. Every ArenaMark has to be either Released or Unmarked. On some platforms, in some builds, a Mark acquires a lock. That lock is release by calling either Release or Unmark. Unmark removes the mark, and leaves the arena intact, and clears the lock. Release frees anything allocating since the mark was made, removes the mark, and clears the lock.
Attachment #219376 - Flags: review?(nelson) → review-
Attached patch Be more conservative with pool. (obsolete) — Splinter Review
Modification to the previous patch: PORT_ArenaUnmark is added.
Attachment #219376 - Attachment is obsolete: true
Attachment #219767 - Flags: review?(nelson)
Comment on attachment 219767 [details] [diff] [review] Be more conservative with pool. This patch is fine, as far as it goes, but it doesn't address the original OOM crash. Here's the change that's needed for that. > newReqMsg = PORT_ArenaZNew(poolp, CRMFCertReqMsg); >- newReqMsg->poolp = poolp; > if (newReqMsg == NULL) { > goto loser; >+ newReqMsg->poolp = poolp;
Attachment #219767 - Attachment description: fix → Be more conservative with pool.
Comment on attachment 219767 [details] [diff] [review] Be more conservative with pool. r- because it doesn't prevent the oom crash. Otherwise it's OK.
Attachment #219767 - Flags: review?(nelson) → review-
I think moving pool assignment below "if" is not enough. When failure occures at 517, we still have crash in CRMF_DestroyCertReqMsg function. 517 newReqMsg->certReq = crmf_copy_cert_request(poolp, srcReqMsg->certReq); 518 if (newReqMsg->certReq == NULL) { 519 goto loser; 520 } This is why the third patch has changes to CRMF_DestroyCertReqMsg function.
Attachment #219767 - Attachment is obsolete: true
Attachment #220067 - Flags: review?(nelson)
Comment on attachment 220067 [details] [diff] [review] address the root issue of the bug r=nelson for the 3.11 branch (not 3.11.1 branch) and the trunk. I think this patch is no less correct than the old code in all respects, but as I review the patched code, there are still a few areas where the original code seems, uh, suspicious. So, IMO, it's ok to check in these changes (on the branches indicated above), but before marking the bug resolved/fixed there might be a few more changes worth consideration. >Index: crmfreq.c > SECStatus > CRMF_DestroyCertReqMsg(CRMFCertReqMsg *inCertReqMsg) > { > PORT_Assert(inCertReqMsg != NULL && inCertReqMsg->poolp != NULL); That assertion should be followed by an if statement that detects those conditions and deal with them gracefully in non-debug builds, e.g. set an error code and return SECFailure. >- if (!inCertReqMsg->isDecoded) { >+ if (!inCertReqMsg->isDecoded && inCertReqMsg->certReq) { > if (inCertReqMsg->certReq->certTemplate.extensions != NULL) { > PORT_Free(inCertReqMsg->certReq->certTemplate.extensions); > } > if (inCertReqMsg->certReq->controls != NULL) { > PORT_Free(inCertReqMsg->certReq->controls); > } > } > PORT_FreeArena(inCertReqMsg->poolp, PR_TRUE); > return SECSuccess; > } The above block is a part that seems suspicious. Cert request messages can be either (a) locally generated (to be DER encoded and then sent off to a remote server) or (b) received in the server from a remote client and then DER decoded. IOW, the message can be either input to encoder or output of decoder. The "isDecoded" flag serves to tell us which case we're dealing with on this stack. The decoded case always implies that the decoded parts are in an arena pool (because the decoder always decodes into a pool). The code here seems to be saying: if we're in a pool, and we're decoded, then explicitly free the extensions (rather than implicitly freeing them when the pool is freed). That's suspicious. It might be right (in which case it must be that the extensions and controls were not allocated from the pool), but there should be some comments explaining that, if so.
Attachment #220067 - Flags: review?(nelson) → review+
Target Milestone: 3.11.1 → 3.11.2
Status: ASSIGNED → RESOLVED
Closed: 19 years ago
Resolution: --- → FIXED
CID 212
Whiteboard: CID 212
should this be considered for fixing in firefox 2.0.0.4?
Flags: blocking1.8.1.4?
Flags: blocking1.8.1.4?
Group: security
You need to log in before you can comment on or make changes to this bug.

Attachment

General

Creator:
Created:
Updated:
Size: