diff options
author | Dr. Stephen Henson <steve@openssl.org> | 2016-10-02 14:13:40 +0100 |
---|---|---|
committer | Dr. Stephen Henson <steve@openssl.org> | 2016-10-17 14:34:00 +0100 |
commit | 6215f27a83c6b9089a217dd6deab1665e0ced516 (patch) | |
tree | 7385937a786ba409f7ef88146fd272edc279ade1 /crypto/asn1 | |
parent | ba6017a19346a169ca09bb67427ccf6fc56af0af (diff) |
Fix embedded string handling.
Don't rely on embedded flag to free strings correctly: it wont be
set if there is a malloc failure during initialisation.
Thanks to Guido Vranken for reporting this issue.
Reviewed-by: Rich Salz <rsalz@openssl.org>
(Merged from https://github.com/openssl/openssl/pull/1725)
Diffstat (limited to 'crypto/asn1')
-rw-r--r-- | crypto/asn1/a_type.c | 2 | ||||
-rw-r--r-- | crypto/asn1/asn1_lib.c | 12 | ||||
-rw-r--r-- | crypto/asn1/asn1_locl.h | 4 | ||||
-rw-r--r-- | crypto/asn1/tasn_fre.c | 10 |
4 files changed, 19 insertions, 9 deletions
diff --git a/crypto/asn1/a_type.c b/crypto/asn1/a_type.c index 42dbcbfffc..df42360e76 100644 --- a/crypto/asn1/a_type.c +++ b/crypto/asn1/a_type.c @@ -25,7 +25,7 @@ void ASN1_TYPE_set(ASN1_TYPE *a, int type, void *value) { if (a->value.ptr != NULL) { ASN1_TYPE **tmp_a = &a; - asn1_primitive_free((ASN1_VALUE **)tmp_a, NULL); + asn1_primitive_free((ASN1_VALUE **)tmp_a, NULL, 0); } a->type = type; if (type == V_ASN1_BOOLEAN) diff --git a/crypto/asn1/asn1_lib.c b/crypto/asn1/asn1_lib.c index 9dfe395399..8ca53b4ce4 100644 --- a/crypto/asn1/asn1_lib.c +++ b/crypto/asn1/asn1_lib.c @@ -11,6 +11,7 @@ #include <limits.h> #include "internal/cryptlib.h" #include <openssl/asn1.h> +#include "asn1_locl.h" static int asn1_get_length(const unsigned char **pp, int *inf, long *rl, long max); @@ -314,16 +315,23 @@ ASN1_STRING *ASN1_STRING_type_new(int type) return (ret); } -void ASN1_STRING_free(ASN1_STRING *a) +void asn1_string_embed_free(ASN1_STRING *a, int embed) { if (a == NULL) return; if (!(a->flags & ASN1_STRING_FLAG_NDEF)) OPENSSL_free(a->data); - if (!(a->flags & ASN1_STRING_FLAG_EMBED)) + if (embed == 0) OPENSSL_free(a); } +void ASN1_STRING_free(ASN1_STRING *a) +{ + if (a == NULL) + return; + asn1_string_embed_free(a, a->flags & ASN1_STRING_FLAG_EMBED); +} + void ASN1_STRING_clear_free(ASN1_STRING *a) { if (a == NULL) diff --git a/crypto/asn1/asn1_locl.h b/crypto/asn1/asn1_locl.h index 56c99541d5..5f597bd98f 100644 --- a/crypto/asn1/asn1_locl.h +++ b/crypto/asn1/asn1_locl.h @@ -45,6 +45,8 @@ DEFINE_STACK_OF(MIME_HEADER) /* Month values for printing out times */ extern const char *_asn1_mon[12]; +void asn1_string_embed_free(ASN1_STRING *a, int embed); + int asn1_get_choice_selector(ASN1_VALUE **pval, const ASN1_ITEM *it); int asn1_set_choice_selector(ASN1_VALUE **pval, int value, const ASN1_ITEM *it); @@ -63,7 +65,7 @@ int asn1_enc_restore(int *len, unsigned char **out, ASN1_VALUE **pval, int asn1_enc_save(ASN1_VALUE **pval, const unsigned char *in, int inlen, const ASN1_ITEM *it); -void asn1_primitive_free(ASN1_VALUE **pval, const ASN1_ITEM *it); +void asn1_primitive_free(ASN1_VALUE **pval, const ASN1_ITEM *it, int embed); void asn1_template_free(ASN1_VALUE **pval, const ASN1_TEMPLATE *tt); ASN1_OBJECT *c2i_ASN1_OBJECT(ASN1_OBJECT **a, const unsigned char **pp, diff --git a/crypto/asn1/tasn_fre.c b/crypto/asn1/tasn_fre.c index f730d110bf..3c98efb363 100644 --- a/crypto/asn1/tasn_fre.c +++ b/crypto/asn1/tasn_fre.c @@ -52,11 +52,11 @@ static void asn1_item_embed_free(ASN1_VALUE **pval, const ASN1_ITEM *it, if (it->templates) asn1_template_free(pval, it->templates); else - asn1_primitive_free(pval, it); + asn1_primitive_free(pval, it, embed); break; case ASN1_ITYPE_MSTRING: - asn1_primitive_free(pval, it); + asn1_primitive_free(pval, it, embed); break; case ASN1_ITYPE_CHOICE: @@ -147,7 +147,7 @@ void asn1_template_free(ASN1_VALUE **pval, const ASN1_TEMPLATE *tt) } } -void asn1_primitive_free(ASN1_VALUE **pval, const ASN1_ITEM *it) +void asn1_primitive_free(ASN1_VALUE **pval, const ASN1_ITEM *it, int embed) { int utype; @@ -195,12 +195,12 @@ void asn1_primitive_free(ASN1_VALUE **pval, const ASN1_ITEM *it) break; case V_ASN1_ANY: - asn1_primitive_free(pval, NULL); + asn1_primitive_free(pval, NULL, 0); OPENSSL_free(*pval); break; default: - ASN1_STRING_free((ASN1_STRING *)*pval); + asn1_string_embed_free((ASN1_STRING *)*pval, embed); break; } *pval = NULL; |