diff options
author | Oliver Mihatsch <oliver.mihatsch@virtual-solution.com> | 2021-04-12 16:46:16 +0200 |
---|---|---|
committer | Tomas Mraz <tomas@openssl.org> | 2021-07-02 16:17:11 +0200 |
commit | 3a1d2b59522163ebb83bb68e13c896188dc222c6 (patch) | |
tree | 9023a97857ecaec6e5c66b7bb3ae8ea609b1d0f1 /crypto | |
parent | 5cffc49f7213c718ebcc2c1236cdd8c2fae7fb28 (diff) |
Fix memory leak in i2d_ASN1_bio_stream
When creating a signed S/MIME message using SMIME_write_CMS()
if the reading from the bio fails, the state is therefore
still ASN1_STATE_START when BIO_flush() is called by i2d_ASN1_bio_stream().
This results in calling asn1_bio_flush_ex cleanup but will only
reset retry flags as the state is not ASN1_STATE_POST_COPY.
Therefore 48 bytes (Linux x86_64) leaked since the
ndef_prefix_free / ndef_suffix_free callbacks are not executed
and the ndef_aux structure is not freed.
By always calling free function callback in asn1_bio_free() the
memory leak is fixed.
Reviewed-by: Paul Dale <pauli@openssl.org>
Reviewed-by: Tomas Mraz <tomas@openssl.org>
(Merged from https://github.com/openssl/openssl/pull/14844)
Diffstat (limited to 'crypto')
-rw-r--r-- | crypto/asn1/bio_asn1.c | 5 | ||||
-rw-r--r-- | crypto/asn1/bio_ndef.c | 3 |
2 files changed, 8 insertions, 0 deletions
diff --git a/crypto/asn1/bio_asn1.c b/crypto/asn1/bio_asn1.c index fa81b3a28a..f792c08806 100644 --- a/crypto/asn1/bio_asn1.c +++ b/crypto/asn1/bio_asn1.c @@ -138,6 +138,11 @@ static int asn1_bio_free(BIO *b) if (ctx == NULL) return 0; + if (ctx->prefix_free != NULL) + ctx->prefix_free(b, &ctx->ex_buf, &ctx->ex_len, &ctx->ex_arg); + if (ctx->suffix_free != NULL) + ctx->suffix_free(b, &ctx->ex_buf, &ctx->ex_len, &ctx->ex_arg); + OPENSSL_free(ctx->buf); OPENSSL_free(ctx); BIO_set_data(b, NULL); diff --git a/crypto/asn1/bio_ndef.c b/crypto/asn1/bio_ndef.c index df462d741a..d94e3a3644 100644 --- a/crypto/asn1/bio_ndef.c +++ b/crypto/asn1/bio_ndef.c @@ -143,6 +143,9 @@ static int ndef_prefix_free(BIO *b, unsigned char **pbuf, int *plen, ndef_aux = *(NDEF_SUPPORT **)parg; + if (ndef_aux == NULL) + return 0; + OPENSSL_free(ndef_aux->derbuf); ndef_aux->derbuf = NULL; |