[openssl-commits] [openssl] OpenSSL_1_1_0-stable update

Richard Levitte levitte at openssl.org
Sat Feb 4 23:58:48 UTC 2017


The branch OpenSSL_1_1_0-stable has been updated
       via  5d0634a93bdc18e753d641c4563cb18f685e148f (commit)
       via  ac162301b45a7458ced227437922141c692383ae (commit)
      from  86d9b572e184262f8c14e8c31f87caa300691d39 (commit)


- Log -----------------------------------------------------------------
commit 5d0634a93bdc18e753d641c4563cb18f685e148f
Author: Bernd Edlinger <bernd.edlinger at hotmail.de>
Date:   Sat Dec 31 13:01:11 2016 +0100

    Combined patch against OpenSSL_1_1_0-stable branch for the following issues:
    
    Fixed a memory leak in ASN1_digest and ASN1_item_digest.
    Reworked error handling in asn1_item_embed_new.
    Fixed error handling in int_ctx_new and EVP_PKEY_CTX_dup.
    Fixed a memory leak in CRYPTO_free_ex_data.
    Reworked error handing in x509_name_ex_d2i, x509_name_encode and x509_name_canon.
    Check for null pointer in tls_process_cert_verify.
    
    Fixes #2103 #2104 #2105 #2109 #2111 #2115
    
    Reviewed-by: Rich Salz <rsalz at openssl.org>
    Reviewed-by: Richard Levitte <levitte at openssl.org>
    (Merged from https://github.com/openssl/openssl/pull/2163)

commit ac162301b45a7458ced227437922141c692383ae
Author: Todd Short <tshort at akamai.com>
Date:   Tue Jan 31 15:32:50 2017 -0500

    Majority rules, use session_ctx vs initial_ctx
    
    session_ctx and initial_ctx are aliases of each other, and with the
    opaque data structures, there's no need to keep both around. Since
    there were more references of session_ctx, replace all instances of
    initial_ctx with session_ctx.
    
    Reviewed-by: Rich Salz <rsalz at openssl.org>
    Reviewed-by: Richard Levitte <levitte at openssl.org>
    (Merged from https://github.com/openssl/openssl/pull/2340)

-----------------------------------------------------------------------

Summary of changes:
 crypto/asn1/a_digest.c   |  8 ++++++--
 crypto/asn1/tasn_new.c   | 13 ++++++++-----
 crypto/evp/pmeth_lib.c   |  2 ++
 crypto/ex_data.c         | 20 +++++++++++--------
 crypto/x509/x_name.c     | 50 +++++++++++++++++++-----------------------------
 ssl/ssl_lib.c            |  6 +++---
 ssl/ssl_locl.h           |  3 +--
 ssl/statem/statem_srvr.c |  7 ++++++-
 ssl/t1_lib.c             | 18 ++++++++---------
 9 files changed, 67 insertions(+), 60 deletions(-)

diff --git a/crypto/asn1/a_digest.c b/crypto/asn1/a_digest.c
index 2f9b63b..46bff0d 100644
--- a/crypto/asn1/a_digest.c
+++ b/crypto/asn1/a_digest.c
@@ -37,8 +37,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);
 }
@@ -55,8 +57,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);
 }
diff --git a/crypto/asn1/tasn_new.c b/crypto/asn1/tasn_new.c
index 897120d..e9b8377 100644
--- a/crypto/asn1/tasn_new.c
+++ b/crypto/asn1/tasn_new.c
@@ -100,7 +100,7 @@ int asn1_item_embed_new(ASN1_VALUE **pval, const ASN1_ITEM *it, int embed)
         }
         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:
@@ -125,15 +125,15 @@ int asn1_item_embed_new(ASN1_VALUE **pval, const ASN1_ITEM *it, int embed)
         }
         /* 0 : init. lock */
         if (asn1_do_lock(pval, 0, it) < 0)
-            goto memerr;
+            goto memerr2;
         asn1_enc_init(pval, 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;
     }
 #ifndef OPENSSL_NO_CRYPTO_MDEBUG
@@ -141,6 +141,8 @@ int asn1_item_embed_new(ASN1_VALUE **pval, const ASN1_ITEM *it, int embed)
 #endif
     return 1;
 
+ memerr2:
+    ASN1_item_ex_free(pval, it);
  memerr:
     ASN1err(ASN1_F_ASN1_ITEM_EMBED_NEW, ERR_R_MALLOC_FAILURE);
 #ifndef OPENSSL_NO_CRYPTO_MDEBUG
@@ -148,9 +150,10 @@ int asn1_item_embed_new(ASN1_VALUE **pval, const ASN1_ITEM *it, int embed)
 #endif
     return 0;
 
+ auxerr2:
+    ASN1_item_ex_free(pval, it);
  auxerr:
     ASN1err(ASN1_F_ASN1_ITEM_EMBED_NEW, ASN1_R_AUX_ERROR);
-    ASN1_item_ex_free(pval, it);
 #ifndef OPENSSL_NO_CRYPTO_MDEBUG
     OPENSSL_mem_debug_pop();
 #endif
diff --git a/crypto/evp/pmeth_lib.c b/crypto/evp/pmeth_lib.c
index 169639b..b7f06be 100644
--- a/crypto/evp/pmeth_lib.c
+++ b/crypto/evp/pmeth_lib.c
@@ -133,6 +133,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;
         }
@@ -258,6 +259,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;
 
diff --git a/crypto/ex_data.c b/crypto/ex_data.c
index bb1af0b..84b6555 100644
--- a/crypto/ex_data.c
+++ b/crypto/ex_data.c
@@ -307,11 +307,12 @@ void CRYPTO_free_ex_data(int class_index, void *obj, CRYPTO_EX_DATA *ad)
     int mx, i;
     EX_CALLBACKS *ip;
     void *ptr;
+    EX_CALLBACK *f;
     EX_CALLBACK *stack[10];
     EX_CALLBACK **storage = NULL;
 
     if ((ip = get_and_lock(class_index)) == NULL)
-        return;
+        goto err;
 
     mx = sk_EX_CALLBACK_num(ip->meth);
     if (mx > 0) {
@@ -325,20 +326,23 @@ void CRYPTO_free_ex_data(int class_index, void *obj, CRYPTO_EX_DATA *ad)
     }
     CRYPTO_THREAD_unlock(ex_data_lock);
 
-    if (mx > 0 && storage == NULL) {
-        CRYPTOerr(CRYPTO_F_CRYPTO_FREE_EX_DATA, ERR_R_MALLOC_FAILURE);
-        return;
-    }
     for (i = 0; i < mx; i++) {
-        if (storage[i] && storage[i]->free_func) {
+        if (storage != NULL)
+            f = storage[i];
+        else {
+            CRYPTO_THREAD_write_lock(ex_data_lock);
+            f = sk_EX_CALLBACK_value(ip->meth, i);
+            CRYPTO_THREAD_unlock(ex_data_lock);
+        }
+        if (f != NULL && f->free_func != NULL) {
             ptr = CRYPTO_get_ex_data(ad, i);
-            storage[i]->free_func(obj, ptr, ad, i,
-                                  storage[i]->argl, storage[i]->argp);
+            f->free_func(obj, ptr, ad, i, f->argl, f->argp);
         }
     }
 
     if (storage != stack)
         OPENSSL_free(storage);
+ err:
     sk_void_free(ad->sk);
     ad->sk = NULL;
 }
diff --git a/crypto/x509/x_name.c b/crypto/x509/x_name.c
index c863c69..97d735f 100644
--- a/crypto/x509/x_name.c
+++ b/crypto/x509/x_name.c
@@ -125,9 +125,14 @@ static void x509_name_ex_free(ASN1_VALUE **pval, const ASN1_ITEM *it)
     *pval = NULL;
 }
 
-static void name_entry_stack_free(STACK_OF(X509_NAME_ENTRY) *ents)
+static void local_sk_X509_NAME_ENTRY_free(STACK_OF(X509_NAME_ENTRY) *ne)
 {
-    sk_X509_NAME_ENTRY_pop_free(ents, X509_NAME_ENTRY_free);
+    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,
@@ -180,33 +185,24 @@ 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);
         }
     }
-    /*
-     * All entries have now been pushed to nm->x.entries
-     * free up the stacks in intname.s but not the entries
-     * themselves.
-     */
-    sk_STACK_OF_X509_NAME_ENTRY_pop_free(intname.s, sk_X509_NAME_ENTRY_free);
-    intname.s = NULL;
     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;
     return ret;
 
  err:
-    /* If intname.s is not NULL only some entries exist in nm->x.entries:
-     * zero references in nm->x.entries list. Since all entries exist
-     * in intname.s we can free them all there
-     */
-    if (intname.s != NULL) {
-        sk_X509_NAME_ENTRY_zero(nm.x->entries);
-        sk_STACK_OF_X509_NAME_ENTRY_pop_free(intname.s, name_entry_stack_free);
-    }
-    X509_NAME_free(nm.x);
+    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;
 }
@@ -232,16 +228,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 {
@@ -264,8 +250,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))
@@ -333,8 +321,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();
diff --git a/ssl/ssl_lib.c b/ssl/ssl_lib.c
index 002b2e5..1698f13 100644
--- a/ssl/ssl_lib.c
+++ b/ssl/ssl_lib.c
@@ -600,7 +600,7 @@ SSL *SSL_new(SSL_CTX *ctx)
     s->tlsext_ocsp_resp = NULL;
     s->tlsext_ocsp_resplen = -1;
     SSL_CTX_up_ref(ctx);
-    s->initial_ctx = ctx;
+    s->session_ctx = ctx;
 #ifndef OPENSSL_NO_EC
     if (ctx->tlsext_ecpointformatlist) {
         s->tlsext_ecpointformatlist =
@@ -999,7 +999,7 @@ void SSL_free(SSL *s)
     /* Free up if allocated */
 
     OPENSSL_free(s->tlsext_hostname);
-    SSL_CTX_free(s->initial_ctx);
+    SSL_CTX_free(s->session_ctx);
 #ifndef OPENSSL_NO_EC
     OPENSSL_free(s->tlsext_ecpointformatlist);
     OPENSSL_free(s->tlsext_ellipticcurvelist);
@@ -3380,7 +3380,7 @@ SSL_CTX *SSL_set_SSL_CTX(SSL *ssl, SSL_CTX *ctx)
     if (ssl->ctx == ctx)
         return ssl->ctx;
     if (ctx == NULL)
-        ctx = ssl->initial_ctx;
+        ctx = ssl->session_ctx;
     new_cert = ssl_cert_dup(ctx->cert);
     if (new_cert == NULL) {
         return NULL;
diff --git a/ssl/ssl_locl.h b/ssl/ssl_locl.h
index 9a997cf..1586a46 100644
--- a/ssl/ssl_locl.h
+++ b/ssl/ssl_locl.h
@@ -1077,7 +1077,7 @@ struct ssl_st {
     /* TLS pre-shared secret session resumption */
     tls_session_secret_cb_fn tls_session_secret_cb;
     void *tls_session_secret_cb_arg;
-    SSL_CTX *initial_ctx;       /* initial ctx, used to store sessions */
+    SSL_CTX *session_ctx;       /* initial ctx, used to store sessions */
 # ifndef OPENSSL_NO_NEXTPROTONEG
     /*
      * Next protocol negotiation. For the client, this is the protocol that
@@ -1089,7 +1089,6 @@ struct ssl_st {
     unsigned char *next_proto_negotiated;
     unsigned char next_proto_negotiated_len;
 # endif
-# define session_ctx initial_ctx
     /* What we'll do */
     STACK_OF(SRTP_PROTECTION_PROFILE) *srtp_profiles;
     /* What's been chosen */
diff --git a/ssl/statem/statem_srvr.c b/ssl/statem/statem_srvr.c
index fa84361..f875b3c 100644
--- a/ssl/statem/statem_srvr.c
+++ b/ssl/statem/statem_srvr.c
@@ -2715,6 +2715,11 @@ MSG_PROCESS_RETURN tls_process_cert_verify(SSL *s, PACKET *pkt)
 
     peer = s->session->peer;
     pkey = X509_get0_pubkey(peer);
+    if (pkey == NULL) {
+        al = SSL_AD_INTERNAL_ERROR;
+        goto f_err;
+    }
+
     type = X509_certificate_type(peer, pkey);
 
     if (!(type & EVP_PKT_SIGN)) {
@@ -2992,7 +2997,7 @@ int tls_construct_new_session_ticket(SSL *s)
     int len, slen_full, slen;
     SSL_SESSION *sess;
     unsigned int hlen;
-    SSL_CTX *tctx = s->initial_ctx;
+    SSL_CTX *tctx = s->session_ctx;
     unsigned char iv[EVP_MAX_IV_LENGTH];
     unsigned char key_name[TLSEXT_KEYNAME_LENGTH];
     int iv_len;
diff --git a/ssl/t1_lib.c b/ssl/t1_lib.c
index b75e568..f1e4d29 100644
--- a/ssl/t1_lib.c
+++ b/ssl/t1_lib.c
@@ -2684,12 +2684,12 @@ static int ssl_check_clienthello_tlsext_early(SSL *s)
         ret =
             s->ctx->tlsext_servername_callback(s, &al,
                                                s->ctx->tlsext_servername_arg);
-    else if (s->initial_ctx != NULL
-             && s->initial_ctx->tlsext_servername_callback != 0)
+    else if (s->session_ctx != NULL
+             && s->session_ctx->tlsext_servername_callback != 0)
         ret =
-            s->initial_ctx->tlsext_servername_callback(s, &al,
+            s->session_ctx->tlsext_servername_callback(s, &al,
                                                        s->
-                                                       initial_ctx->tlsext_servername_arg);
+                                                       session_ctx->tlsext_servername_arg);
 
     switch (ret) {
     case SSL_TLSEXT_ERR_ALERT_FATAL:
@@ -2863,12 +2863,12 @@ int ssl_check_serverhello_tlsext(SSL *s)
         ret =
             s->ctx->tlsext_servername_callback(s, &al,
                                                s->ctx->tlsext_servername_arg);
-    else if (s->initial_ctx != NULL
-             && s->initial_ctx->tlsext_servername_callback != 0)
+    else if (s->session_ctx != NULL
+             && s->session_ctx->tlsext_servername_callback != 0)
         ret =
-            s->initial_ctx->tlsext_servername_callback(s, &al,
+            s->session_ctx->tlsext_servername_callback(s, &al,
                                                        s->
-                                                       initial_ctx->tlsext_servername_arg);
+                                                       session_ctx->tlsext_servername_arg);
 
     /*
      * Ensure we get sensible values passed to tlsext_status_cb in the event
@@ -3084,7 +3084,7 @@ static int tls_decrypt_ticket(SSL *s, const unsigned char *etick,
     unsigned char tick_hmac[EVP_MAX_MD_SIZE];
     HMAC_CTX *hctx = NULL;
     EVP_CIPHER_CTX *ctx;
-    SSL_CTX *tctx = s->initial_ctx;
+    SSL_CTX *tctx = s->session_ctx;
 
     /* Initialize session ticket encryption and HMAC contexts */
     hctx = HMAC_CTX_new();


More information about the openssl-commits mailing list