Commit 748cb9a1 authored by Bernd Edlinger's avatar Bernd Edlinger Committed by Rich Salz
Browse files

Combined patch for the more or less obvious issues



Fixed a memory leak in ASN1_digest and ASN1_item_digest.

asn1_template_noexp_d2i call ASN1_item_ex_free(&skfield,...) on error.

Reworked error handling in asn1_item_ex_combine_new:
- call ASN1_item_ex_free and return the correct error code if ASN1_template_new failed.
- dont call ASN1_item_ex_free if ASN1_OP_NEW_PRE failed.

Reworked error handing in x509_name_ex_d2i and x509_name_encode.

Fixed error handling in int_ctx_new and EVP_PKEY_CTX_dup.

Fixed a memory leak in def_get_class if lh_EX_CLASS_ITEM_insert fails due to OOM:
- to figure out if the insertion succeeded, use lh_EX_CLASS_ITEM_retrieve again.
- on error, p will be NULL, and gen needs to be cleaned up again.

int_free_ex_data needs to have a fallback solution if unable to allocate "storage":
- if free_func is non-zero this must be called to clean up all memory.

Fixed error handling in pkey_hmac_copy.

Fixed error handling in ssleay_rand_add and ssleay_rand_bytes.

Fixed error handling in X509_STORE_new.

Fixed a memory leak in ssl3_get_key_exchange.

Check for null pointer in ssl3_write_bytes.

Check for null pointer in ssl3_get_cert_verify.

Fixed a memory leak in ssl_cert_dup.

Fixes #2087 #2094 #2103 #2104 #2105 #2106 #2107 #2108 #2110 #2111 #2112 #2115

Reviewed-by: default avatarRichard Levitte <levitte@openssl.org>
Reviewed-by: default avatarRich Salz <rsalz@openssl.org>
(Merged from https://github.com/openssl/openssl/pull/2127)
parent efe83986
Loading
Loading
Loading
Loading
+6 −2
Original line number Diff line number Diff line
@@ -86,8 +86,10 @@ int ASN1_digest(i2d_of_void *i2d, const EVP_MD *type, char *data,
    p = str;
    i2d(data, &p);

    if (!EVP_Digest(str, i, md, len, type, NULL))
    if (!EVP_Digest(str, i, md, len, type, NULL)) {
        OPENSSL_free(str);
        return 0;
    }
    OPENSSL_free(str);
    return (1);
}
@@ -104,8 +106,10 @@ int ASN1_item_digest(const ASN1_ITEM *it, const EVP_MD *type, void *asn,
    if (!str)
        return (0);

    if (!EVP_Digest(str, i, md, len, type, NULL))
    if (!EVP_Digest(str, i, md, len, type, NULL)) {
        OPENSSL_free(str);
        return 0;
    }
    OPENSSL_free(str);
    return (1);
}
+1 −0
Original line number Diff line number Diff line
@@ -673,6 +673,7 @@ static int asn1_template_noexp_d2i(ASN1_VALUE **val,
            }
            len -= p - q;
            if (!sk_ASN1_VALUE_push((STACK_OF(ASN1_VALUE) *)*val, skfield)) {
                ASN1_item_ex_free(&skfield, ASN1_ITEM_ptr(tt->item));
                ASN1err(ASN1_F_ASN1_TEMPLATE_NOEXP_D2I, ERR_R_MALLOC_FAILURE);
                goto err;
            }
+7 −4
Original line number Diff line number Diff line
@@ -158,7 +158,7 @@ static int asn1_item_ex_combine_new(ASN1_VALUE **pval, const ASN1_ITEM *it,
        }
        asn1_set_choice_selector(pval, -1, it);
        if (asn1_cb && !asn1_cb(ASN1_OP_NEW_POST, pval, it, NULL))
            goto auxerr;
            goto auxerr2;
        break;

    case ASN1_ITYPE_NDEF_SEQUENCE:
@@ -186,10 +186,10 @@ static int asn1_item_ex_combine_new(ASN1_VALUE **pval, const ASN1_ITEM *it,
        for (i = 0, tt = it->templates; i < it->tcount; tt++, i++) {
            pseqval = asn1_get_field_ptr(pval, tt);
            if (!ASN1_template_new(pseqval, tt))
                goto memerr;
                goto memerr2;
        }
        if (asn1_cb && !asn1_cb(ASN1_OP_NEW_POST, pval, it, NULL))
            goto auxerr;
            goto auxerr2;
        break;
    }
#ifdef CRYPTO_MDEBUG
@@ -198,6 +198,8 @@ static int asn1_item_ex_combine_new(ASN1_VALUE **pval, const ASN1_ITEM *it,
#endif
    return 1;

 memerr2:
    ASN1_item_ex_free(pval, it);
 memerr:
    ASN1err(ASN1_F_ASN1_ITEM_EX_COMBINE_NEW, ERR_R_MALLOC_FAILURE);
#ifdef CRYPTO_MDEBUG
@@ -206,9 +208,10 @@ static int asn1_item_ex_combine_new(ASN1_VALUE **pval, const ASN1_ITEM *it,
#endif
    return 0;

 auxerr2:
    ASN1_item_ex_free(pval, it);
 auxerr:
    ASN1err(ASN1_F_ASN1_ITEM_EX_COMBINE_NEW, ASN1_R_AUX_ERROR);
    ASN1_item_ex_free(pval, it);
#ifdef CRYPTO_MDEBUG
    if (it->sname)
        CRYPTO_pop_info();
+21 −14
Original line number Diff line number Diff line
@@ -178,6 +178,16 @@ static void x509_name_ex_free(ASN1_VALUE **pval, const ASN1_ITEM *it)
    *pval = NULL;
}

static void local_sk_X509_NAME_ENTRY_free(STACK_OF(X509_NAME_ENTRY) *ne)
{
    sk_X509_NAME_ENTRY_free(ne);
}

static void local_sk_X509_NAME_ENTRY_pop_free(STACK_OF(X509_NAME_ENTRY) *ne)
{
    sk_X509_NAME_ENTRY_pop_free(ne, X509_NAME_ENTRY_free);
}

static int x509_name_ex_d2i(ASN1_VALUE **val,
                            const unsigned char **in, long len,
                            const ASN1_ITEM *it, int tag, int aclass,
@@ -228,13 +238,14 @@ static int x509_name_ex_d2i(ASN1_VALUE **val,
            entry->set = i;
            if (!sk_X509_NAME_ENTRY_push(nm.x->entries, entry))
                goto err;
            sk_X509_NAME_ENTRY_set(entries, j, NULL);
        }
        sk_X509_NAME_ENTRY_free(entries);
    }
    sk_STACK_OF_X509_NAME_ENTRY_free(intname.s);
    ret = x509_name_canon(nm.x);
    if (!ret)
        goto err;
    sk_STACK_OF_X509_NAME_ENTRY_pop_free(intname.s,
                                         local_sk_X509_NAME_ENTRY_free);
    nm.x->modified = 0;
    *val = nm.a;
    *in = p;
@@ -242,6 +253,8 @@ static int x509_name_ex_d2i(ASN1_VALUE **val,
 err:
    if (nm.x != NULL)
        X509_NAME_free(nm.x);
    sk_STACK_OF_X509_NAME_ENTRY_pop_free(intname.s,
                                         local_sk_X509_NAME_ENTRY_pop_free);
    ASN1err(ASN1_F_X509_NAME_EX_D2I, ERR_R_NESTED_ASN1_ERROR);
    return 0;
}
@@ -267,16 +280,6 @@ static int x509_name_ex_i2d(ASN1_VALUE **val, unsigned char **out,
    return ret;
}

static void local_sk_X509_NAME_ENTRY_free(STACK_OF(X509_NAME_ENTRY) *ne)
{
    sk_X509_NAME_ENTRY_free(ne);
}

static void local_sk_X509_NAME_ENTRY_pop_free(STACK_OF(X509_NAME_ENTRY) *ne)
{
    sk_X509_NAME_ENTRY_pop_free(ne, X509_NAME_ENTRY_free);
}

static int x509_name_encode(X509_NAME *a)
{
    union {
@@ -299,8 +302,10 @@ static int x509_name_encode(X509_NAME *a)
            entries = sk_X509_NAME_ENTRY_new_null();
            if (!entries)
                goto memerr;
            if (!sk_STACK_OF_X509_NAME_ENTRY_push(intname.s, entries))
            if (!sk_STACK_OF_X509_NAME_ENTRY_push(intname.s, entries)) {
                sk_X509_NAME_ENTRY_free(entries);
                goto memerr;
            }
            set = entry->set;
        }
        if (!sk_X509_NAME_ENTRY_push(entries, entry))
@@ -370,8 +375,10 @@ static int x509_name_canon(X509_NAME *a)
            entries = sk_X509_NAME_ENTRY_new_null();
            if (!entries)
                goto err;
            if (!sk_STACK_OF_X509_NAME_ENTRY_push(intname, entries))
            if (!sk_STACK_OF_X509_NAME_ENTRY_push(intname, entries)) {
                sk_X509_NAME_ENTRY_free(entries);
                goto err;
            }
            set = entry->set;
        }
        tmpentry = X509_NAME_ENTRY_new();
+2 −0
Original line number Diff line number Diff line
@@ -188,6 +188,7 @@ static EVP_PKEY_CTX *int_ctx_new(EVP_PKEY *pkey, ENGINE *e, int id)

    if (pmeth->init) {
        if (pmeth->init(ret) <= 0) {
            ret->pmeth = NULL;
            EVP_PKEY_CTX_free(ret);
            return NULL;
        }
@@ -315,6 +316,7 @@ EVP_PKEY_CTX *EVP_PKEY_CTX_dup(EVP_PKEY_CTX *pctx)
    if (pctx->pmeth->copy(rctx, pctx) > 0)
        return rctx;

    rctx->pmeth = NULL;
    EVP_PKEY_CTX_free(rctx);
    return NULL;

Loading