Commit 6215f27a authored by Dr. Stephen Henson's avatar Dr. Stephen Henson
Browse files

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: default avatarRich Salz <rsalz@openssl.org>
(Merged from https://github.com/openssl/openssl/pull/1725)
parent ba6017a1
Loading
Loading
Loading
Loading
+1 −1
Original line number Diff line number Diff line
@@ -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)
+10 −2
Original line number Diff line number Diff line
@@ -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)
+3 −1
Original line number Diff line number Diff line
@@ -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,
+5 −5
Original line number Diff line number Diff line
@@ -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;