summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorDr. Stephen Henson <steve@openssl.org>2016-10-02 14:13:40 +0100
committerDr. Stephen Henson <steve@openssl.org>2016-10-17 14:34:00 +0100
commit6215f27a83c6b9089a217dd6deab1665e0ced516 (patch)
tree7385937a786ba409f7ef88146fd272edc279ade1
parentba6017a19346a169ca09bb67427ccf6fc56af0af (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)
-rw-r--r--crypto/asn1/a_type.c2
-rw-r--r--crypto/asn1/asn1_lib.c12
-rw-r--r--crypto/asn1/asn1_locl.h4
-rw-r--r--crypto/asn1/tasn_fre.c10
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;