X-Git-Url: https://git.saurik.com/apple/security.git/blobdiff_plain/d8f41ccd20de16f8ebe2ccc84d47bf1cb2b26bbb..3f0f0d49a9b6c2c6d459239f5926d59314cdeacf:/libsecurity_smime/lib/cmsdecode.c diff --git a/libsecurity_smime/lib/cmsdecode.c b/libsecurity_smime/lib/cmsdecode.c index 29f501c8..2dd6f8ac 100644 --- a/libsecurity_smime/lib/cmsdecode.c +++ b/libsecurity_smime/lib/cmsdecode.c @@ -283,7 +283,7 @@ nss_cms_before_data(SecCmsDecoderRef p7dcx) goto loser; /* start the child decoder */ - childp7dcx->dcx = SEC_ASN1DecoderStart(poolp, childp7dcx->content.pointer, template, NULL); + childp7dcx->dcx = SEC_ASN1DecoderStart(poolp, childp7dcx->content.pointer, template, NULL, 0); if (childp7dcx->dcx == NULL) goto loser; @@ -374,9 +374,6 @@ static OSStatus nss_cms_after_end(SecCmsDecoderRef p7dcx) { OSStatus rv; - PLArenaPool *poolp; - - poolp = p7dcx->cmsg->poolp; switch (p7dcx->type) { case SEC_OID_PKCS7_SIGNED_DATA: @@ -522,6 +519,13 @@ nss_cms_decoder_work_data(SecCmsDecoderRef p7dcx, storage = cinfo->content.data; offset = storage->Length; + + /* check for potential overflow */ + if (len >= (size_t)(INT_MAX - storage->Length)) { + p7dcx->error = SEC_ERROR_NO_MEMORY; + goto loser; + } + if (storage->Length == 0) { dest = (unsigned char *)PORT_ArenaAlloc(p7dcx->cmsg->poolp, len); } else { @@ -603,7 +607,7 @@ SecCmsDecoderCreate(SecCmsContentCallback cb, void *cb_arg, goto loser; } - p7dcx->dcx = SEC_ASN1DecoderStart(cmsg->poolp, cmsg, SecCmsMessageTemplate, NULL); + p7dcx->dcx = SEC_ASN1DecoderStart(cmsg->poolp, cmsg, SecCmsMessageTemplate, NULL, 0); if (p7dcx->dcx == NULL) { PORT_Free (p7dcx); SecCmsMessageDestroy(cmsg); @@ -632,6 +636,10 @@ loser: OSStatus SecCmsDecoderUpdate(SecCmsDecoderRef p7dcx, const void *buf, CFIndex len) { + if (!p7dcx) { + return errSecParam; + } + if (p7dcx->dcx != NULL && p7dcx->error == 0) { /* if error is set already, don't bother */ if (SEC_ASN1DecoderUpdate (p7dcx->dcx, buf, len) != SECSuccess) { p7dcx->error = PORT_GetError(); @@ -661,11 +669,15 @@ SecCmsDecoderUpdate(SecCmsDecoderRef p7dcx, const void *buf, CFIndex len) void SecCmsDecoderDestroy(SecCmsDecoderRef p7dcx) { - /* XXXX what about inner decoders? running digests? decryption? */ - /* XXXX there's a leak here! */ + /* SecCmsMessageDestroy frees inner decoders and digests. */ SecCmsMessageDestroy(p7dcx->cmsg); + p7dcx->cmsg = NULL; if (p7dcx->dcx) (void)SEC_ASN1DecoderFinish(p7dcx->dcx); + /* Clear out references */ + p7dcx->cmsg = NULL; + p7dcx->dcx = NULL; + p7dcx->childp7dcx = NULL; PORT_Free(p7dcx); } @@ -683,7 +695,9 @@ SecCmsDecoderFinish(SecCmsDecoderRef p7dcx, SecCmsMessageRef *outMessage) if (p7dcx->dcx == NULL || SEC_ASN1DecoderFinish(p7dcx->dcx) != SECSuccess || nss_cms_after_end(p7dcx) != SECSuccess) { - SecCmsMessageDestroy(cmsg); + if (p7dcx->cmsg) { + SecCmsMessageDestroy(cmsg); + } result = PORT_GetError(); goto loser; } @@ -692,6 +706,10 @@ SecCmsDecoderFinish(SecCmsDecoderRef p7dcx, SecCmsMessageRef *outMessage) result = errSecSuccess; loser: + /* Clear out references */ + p7dcx->cmsg = NULL; + p7dcx->dcx = NULL; + p7dcx->childp7dcx = NULL; PORT_Free(p7dcx); return result; }