From 68e1f0edb82cb86f42bcae0fc87d7aa800f255ee Mon Sep 17 00:00:00 2001 From: Kamil Dudka Date: Wed, 27 May 2009 16:30:12 +0200 Subject: Fix various memory leaks and free internal objects on module unload. Elio helped me to complete the patch. 501080 --- ckpem.h | 3 ++- pinst.c | 12 ++++++++++++ pobject.c | 27 ++++++++++++++++++--------- prsa.c | 21 ++++++++++++++++----- util.c | 9 ++++++++- 5 files changed, 56 insertions(+), 16 deletions(-) diff --git a/ckpem.h b/ckpem.h index 5587333..866d0ea 100644 --- a/ckpem.h +++ b/ckpem.h @@ -116,7 +116,6 @@ struct pemInternalObjectStr { CK_OBJECT_CLASS objClass; NSSItem hashKey; NSSItem id; - void *idData; unsigned char hashKeyData[128]; SECItem *derCert; char *nickname; @@ -225,6 +224,8 @@ pemInternalObject * CreateObject(CK_OBJECT_CLASS objClass, pemObjectType type, SECItem *certDER, SECItem *keyDER, char *filename, int objid, CK_SLOT_ID slotID); +void pem_DestroyInternalObject (pemInternalObject *io); + /* prsa.c */ unsigned int pem_PrivateModulusLen(pemLOWKEYPrivateKey *privk); diff --git a/pinst.c b/pinst.c index 0a80803..c995b14 100644 --- a/pinst.c +++ b/pinst.c @@ -487,10 +487,22 @@ pem_Finalize NSSCKFWInstance * fwInstance ) { + int i; + plog("pem_Finalize\n"); if (!pemInitialized) return; + for (i = 0; i < pem_nobjs; ++i) + pem_DestroyInternalObject(gobj[i]); + + nss_ZFreeIf(gobj); + gobj = NULL; + + pem_nobjs = 0; + size = 0; + count = 0; + PR_AtomicSet(&pemInitialized, PR_FALSE); return; diff --git a/pobject.c b/pobject.c index 96204e9..dff2156 100644 --- a/pobject.c +++ b/pobject.c @@ -572,34 +572,43 @@ pem_DestroyInternalObject nss_ZFreeIf(io->u.cert.labelData); nss_ZFreeIf(io->u.cert.key.privateKey); nss_ZFreeIf(io->u.cert.key.pubKey); - nss_ZFreeIf(io->idData); + /* go through */ + case pemTrust: + nss_ZFreeIf(io->id.data); nss_ZFreeIf(io->nickname); + nss_ZFreeIf(io->derCert->data); nss_ZFreeIf(io->derCert); if (io->u.cert.subject.size > 0) { - PR_Free(io->u.cert.subject.data); + nss_ZFreeIf(io->u.cert.subject.data); } if (io->u.cert.issuer.size > 0) { - PR_Free(io->u.cert.issuer.data); + nss_ZFreeIf(io->u.cert.issuer.data); } if (io->u.cert.serial.size > 0) { - PR_Free(io->u.cert.serial.data); + nss_ZFreeIf(io->u.cert.serial.data); } break; case pemBareKey: + nss_ZFreeIf(io->u.key.key.coefficient.data); + nss_ZFreeIf(io->u.key.key.exponent2.data); + nss_ZFreeIf(io->u.key.key.exponent1.data); + nss_ZFreeIf(io->u.key.key.prime2.data); + nss_ZFreeIf(io->u.key.key.prime1.data); + nss_ZFreeIf(io->u.key.key.privateExponent.data); + nss_ZFreeIf(io->u.key.key.exponent.data); + nss_ZFreeIf(io->u.key.key.modulus.data); + nss_ZFreeIf(io->u.key.key.privateKey->data); nss_ZFreeIf(io->u.key.key.privateKey); nss_ZFreeIf(io->u.key.key.pubKey); - nss_ZFreeIf(io->idData); + nss_ZFreeIf(io->id.data); nss_ZFreeIf(io->nickname); + nss_ZFreeIf(io->derCert->data); nss_ZFreeIf(io->derCert); /* strdup'd in ReadDERFromFile */ if (io->u.key.ivstring) free(io->u.key.ivstring); break; - case pemTrust: - nss_ZFreeIf(io->idData); - nss_ZFreeIf(io->nickname); - nss_ZFreeIf(io->derCert); } nss_ZFreeIf(io); return; diff --git a/prsa.c b/prsa.c index 0b79cd8..ad66f6c 100644 --- a/prsa.c +++ b/prsa.c @@ -113,6 +113,7 @@ pem_DestroyPrivateKey(pemLOWKEYPrivateKey * privk) if (privk && privk->arena) { PORT_FreeArena(privk->arena, PR_TRUE); } + nss_ZFreeIf(privk); } void @@ -124,11 +125,6 @@ pem_PopulateModulusExponent(pemInternalObject * io) PLArenaPool *arena; SECStatus rv; - arena = PORT_NewArena(2048); - if (!arena) { - return; - } - /* make sure we have the right objects */ if (((const NSSItem *) NULL == classItem) || (sizeof(CK_OBJECT_CLASS) != classItem->size) || @@ -139,6 +135,11 @@ pem_PopulateModulusExponent(pemInternalObject * io) return; } + arena = PORT_NewArena(2048); + if (!arena) { + return; + } + lpk = (pemLOWKEYPrivateKey *) nss_ZAlloc(NULL, sizeof(pemLOWKEYPrivateKey)); if (lpk == NULL) { @@ -159,12 +160,14 @@ pem_PopulateModulusExponent(pemInternalObject * io) return; } + nss_ZFreeIf(io->u.key.key.modulus.data); io->u.key.key.modulus.data = (void *) nss_ZAlloc(NULL, lpk->u.rsa.modulus.len); io->u.key.key.modulus.size = lpk->u.rsa.modulus.len; nsslibc_memcpy(io->u.key.key.modulus.data, lpk->u.rsa.modulus.data, lpk->u.rsa.modulus.len); + nss_ZFreeIf(io->u.key.key.exponent.data); io->u.key.key.exponent.data = (void *) nss_ZAlloc(NULL, lpk->u.rsa.publicExponent.len); io->u.key.key.exponent.size = lpk->u.rsa.publicExponent.len; @@ -172,6 +175,7 @@ pem_PopulateModulusExponent(pemInternalObject * io) lpk->u.rsa.publicExponent.data, lpk->u.rsa.publicExponent.len); + nss_ZFreeIf(io->u.key.key.privateExponent.data); io->u.key.key.privateExponent.data = (void *) nss_ZAlloc(NULL, lpk->u.rsa.privateExponent.len); io->u.key.key.privateExponent.size = lpk->u.rsa.privateExponent.len; @@ -179,30 +183,35 @@ pem_PopulateModulusExponent(pemInternalObject * io) lpk->u.rsa.privateExponent.data, lpk->u.rsa.privateExponent.len); + nss_ZFreeIf(io->u.key.key.prime1.data); io->u.key.key.prime1.data = (void *) nss_ZAlloc(NULL, lpk->u.rsa.prime1.len); io->u.key.key.prime1.size = lpk->u.rsa.prime1.len; nsslibc_memcpy(io->u.key.key.prime1.data, lpk->u.rsa.prime1.data, lpk->u.rsa.prime1.len); + nss_ZFreeIf(io->u.key.key.prime2.data); io->u.key.key.prime2.data = (void *) nss_ZAlloc(NULL, lpk->u.rsa.prime2.len); io->u.key.key.prime2.size = lpk->u.rsa.prime2.len; nsslibc_memcpy(io->u.key.key.prime2.data, lpk->u.rsa.prime2.data, lpk->u.rsa.prime2.len); + nss_ZFreeIf(io->u.key.key.exponent1.data); io->u.key.key.exponent1.data = (void *) nss_ZAlloc(NULL, lpk->u.rsa.exponent1.len); io->u.key.key.exponent1.size = lpk->u.rsa.exponent1.len; nsslibc_memcpy(io->u.key.key.exponent1.data, lpk->u.rsa.exponent1.data, lpk->u.rsa.exponent1.len); + nss_ZFreeIf(io->u.key.key.exponent2.data); io->u.key.key.exponent2.data = (void *) nss_ZAlloc(NULL, lpk->u.rsa.exponent2.len); io->u.key.key.exponent2.size = lpk->u.rsa.exponent2.len; nsslibc_memcpy(io->u.key.key.exponent2.data, lpk->u.rsa.exponent2.data, lpk->u.rsa.exponent2.len); + nss_ZFreeIf(io->u.key.key.coefficient.data); io->u.key.key.coefficient.data = (void *) nss_ZAlloc(NULL, lpk->u.rsa.coefficient.len); io->u.key.key.coefficient.size = lpk->u.rsa.coefficient.len; @@ -271,6 +280,8 @@ pem_mdCryptoOperationRSAPriv_Create lpk->arena = arena; lpk->keyType = pemLOWKEYRSAKey; prepare_low_rsa_priv_key_for_asn1(lpk); + + nss_ZFreeIf(iKey->u.key.key.modulus.data); iKey->u.key.key.modulus.data = (void *) nss_ZAlloc(NULL, lpk->u.rsa.modulus.len); iKey->u.key.key.modulus.size = lpk->u.rsa.modulus.len; diff --git a/util.c b/util.c index 2ea4f96..319a870 100644 --- a/util.c +++ b/util.c @@ -202,6 +202,8 @@ ReadDERFromFile(SECItem *** derlist, char *filename, PRBool ascii, } } der = (SECItem *) malloc(sizeof(SECItem)); + if (der == NULL) + goto loser; char *trailer = NULL; asc = body; @@ -221,10 +223,15 @@ ReadDERFromFile(SECItem *** derlist, char *filename, PRBool ascii, /* Convert to binary */ rv = ATOB_ConvertAsciiToItem(der, body); if (rv) { + free(der); goto loser; } - if ((certsonly && !key) || (!certsonly && key)) + if ((certsonly && !key) || (!certsonly && key)) { PUT_Object(der, error); + } else { + free(der->data); + free(der); + } } /* while */ } else { /* No headers and footers, translate the blob */ der = nss_ZNEW(NULL, SECItem); -- cgit