[Pkg-openssl-changes] r689 - in openssl/branches/squeeze/debian: . patches
Kurt Roeckx
kroeckx at moszumanska.debian.org
Mon Aug 11 19:36:05 UTC 2014
Author: kroeckx
Date: 2014-08-11 19:36:05 +0000 (Mon, 11 Aug 2014)
New Revision: 689
Added:
openssl/branches/squeeze/debian/patches/Added-comment-for-the-frag-reassembly-NULL-case-as-p.patch
openssl/branches/squeeze/debian/patches/Applying-same-fix-as-in-dtls1_process_out_of_seq_mes.patch
openssl/branches/squeeze/debian/patches/Avoid-double-free-when-processing-DTLS-packets.patch
openssl/branches/squeeze/debian/patches/Fix-DTLS-anonymous-EC-DH-denial-of-service.patch
openssl/branches/squeeze/debian/patches/Fix-DTLS-handshake-message-size-checks.patch
openssl/branches/squeeze/debian/patches/Fix-OID-handling.patch
openssl/branches/squeeze/debian/patches/Fix-memory-leak-from-zero-length-DTLS-fragments.patch
openssl/branches/squeeze/debian/patches/Fix-protocol-downgrade-bug-in-case-of-fragmented-pac.patch
openssl/branches/squeeze/debian/patches/Fix-return-code-for-truncated-DTLS-fragment.patch
openssl/branches/squeeze/debian/patches/Remove-some-duplicate-DTLS-code.patch
Modified:
openssl/branches/squeeze/debian/changelog
openssl/branches/squeeze/debian/patches/series
Log:
Fix for CVE-2014-3510
Fix for CVE-2014-3507
Fix for CVE-2014-3506
Fix for CVE-2014-3505
Fix for CVE-2014-3508
Modified: openssl/branches/squeeze/debian/changelog
===================================================================
--- openssl/branches/squeeze/debian/changelog 2014-08-06 22:22:34 UTC (rev 688)
+++ openssl/branches/squeeze/debian/changelog 2014-08-11 19:36:05 UTC (rev 689)
@@ -1,3 +1,13 @@
+openssl (0.9.8o-4squeeze17) squeeze-lts; urgency=medium
+
+ * Fix for CVE-2014-3510
+ * Fix for CVE-2014-3507
+ * Fix for CVE-2014-3506
+ * Fix for CVE-2014-3505
+ * Fix for CVE-2014-3508
+
+ -- Kurt Roeckx <kurt at roeckx.be> Wed, 06 Aug 2014 21:14:30 +0200
+
openssl (0.9.8o-4squeeze16) squeeze-lts; urgency=medium
* Update CVE-2014-0224 patch: Accept CCS after sending finished.
Added: openssl/branches/squeeze/debian/patches/Added-comment-for-the-frag-reassembly-NULL-case-as-p.patch
===================================================================
--- openssl/branches/squeeze/debian/patches/Added-comment-for-the-frag-reassembly-NULL-case-as-p.patch (rev 0)
+++ openssl/branches/squeeze/debian/patches/Added-comment-for-the-frag-reassembly-NULL-case-as-p.patch 2014-08-11 19:36:05 UTC (rev 689)
@@ -0,0 +1,31 @@
+From 2feb3f6dc5f774089673947b8054da05ef5a8acd Mon Sep 17 00:00:00 2001
+From: Matt Caswell <matt at openssl.org>
+Date: Thu, 24 Jul 2014 23:33:34 +0100
+Subject: [PATCH 02/10] Added comment for the frag->reassembly == NULL case as
+ per feedback from Emilia
+MIME-Version: 1.0
+Content-Type: text/plain; charset=UTF-8
+Content-Transfer-Encoding: 8bit
+
+Reviewed-by: Emilia Käsper <emilia at openssl.org>
+---
+ ssl/d1_both.c | 3 ++-
+ 1 file changed, 2 insertions(+), 1 deletion(-)
+
+diff --git a/ssl/d1_both.c b/ssl/d1_both.c
+index b808f04..9bc416c 100644
+--- a/ssl/d1_both.c
++++ b/ssl/d1_both.c
+@@ -633,7 +633,8 @@ dtls1_reassemble_fragment(SSL *s, struct hm_header_st* msg_hdr, int *ok)
+
+
+ /* If message is already reassembled, this must be a
+- * retransmit and can be dropped.
++ * retransmit and can be dropped. In this case item != NULL and so frag
++ * does not need to be freed.
+ */
+ if (frag->reassembly == NULL)
+ {
+--
+2.0.1
+
Added: openssl/branches/squeeze/debian/patches/Applying-same-fix-as-in-dtls1_process_out_of_seq_mes.patch
===================================================================
--- openssl/branches/squeeze/debian/patches/Applying-same-fix-as-in-dtls1_process_out_of_seq_mes.patch (rev 0)
+++ openssl/branches/squeeze/debian/patches/Applying-same-fix-as-in-dtls1_process_out_of_seq_mes.patch 2014-08-11 19:36:05 UTC (rev 689)
@@ -0,0 +1,36 @@
+From 202dd6345a24df561b1feea60a77d1406983196d Mon Sep 17 00:00:00 2001
+From: Matt Caswell <matt at openssl.org>
+Date: Thu, 24 Jul 2014 23:54:28 +0100
+Subject: [PATCH 06/10] Applying same fix as in
+ dtls1_process_out_of_seq_message. A truncated DTLS fragment would cause *ok
+ to be clear, but the return value would still be the number of bytes read.
+MIME-Version: 1.0
+Content-Type: text/plain; charset=UTF-8
+Content-Transfer-Encoding: 8bit
+
+Problem identified by Emilia Käsper, based on previous issue/patch by Adam
+Langley.
+
+Reviewed-by: Emilia Käsper <emilia at openssl.org>
+---
+ ssl/d1_both.c | 4 +++-
+ 1 file changed, 3 insertions(+), 1 deletion(-)
+
+diff --git a/ssl/d1_both.c b/ssl/d1_both.c
+index 961ac51..3a4819f 100644
+--- a/ssl/d1_both.c
++++ b/ssl/d1_both.c
+@@ -657,7 +657,9 @@ dtls1_reassemble_fragment(SSL *s, struct hm_header_st* msg_hdr, int *ok)
+ /* read the body of the fragment (header has already been read */
+ i = s->method->ssl_read_bytes(s,SSL3_RT_HANDSHAKE,
+ frag->fragment + msg_hdr->frag_off,frag_len,0);
+- if (i<=0 || (unsigned long)i!=frag_len)
++ if ((unsigned long)i!=frag_len)
++ i=-1;
++ if (i<=0)
+ goto err;
+
+ RSMBLY_BITMASK_MARK(frag->reassembly, (long)msg_hdr->frag_off,
+--
+2.0.1
+
Added: openssl/branches/squeeze/debian/patches/Avoid-double-free-when-processing-DTLS-packets.patch
===================================================================
--- openssl/branches/squeeze/debian/patches/Avoid-double-free-when-processing-DTLS-packets.patch (rev 0)
+++ openssl/branches/squeeze/debian/patches/Avoid-double-free-when-processing-DTLS-packets.patch 2014-08-11 19:36:05 UTC (rev 689)
@@ -0,0 +1,52 @@
+From 4a5adb49d716864b3452ad039bb36ee9e6025ceb Mon Sep 17 00:00:00 2001
+From: Adam Langley <agl at imperialviolet.org>
+Date: Fri, 6 Jun 2014 14:19:21 -0700
+Subject: [PATCH 01/10] Avoid double free when processing DTLS packets.
+MIME-Version: 1.0
+Content-Type: text/plain; charset=UTF-8
+Content-Transfer-Encoding: 8bit
+
+The |item| variable, in both of these cases, may contain a pointer to a
+|pitem| structure within |s->d1->buffered_messages|. It was being freed
+in the error case while still being in |buffered_messages|. When the
+error later caused the |SSL*| to be destroyed, the item would be double
+freed.
+
+Thanks to Wah-Teh Chang for spotting that the fix in 1632ef74 was
+inconsistent with the other error paths (but correct).
+
+Fixes CVE-2014-3505
+
+Reviewed-by: Matt Caswell <matt at openssl.org>
+Reviewed-by: Emilia Käsper <emilia at openssl.org>
+---
+ ssl/d1_both.c | 6 ++----
+ 1 file changed, 2 insertions(+), 4 deletions(-)
+
+diff --git a/ssl/d1_both.c b/ssl/d1_both.c
+index fe3a96c..b808f04 100644
+--- a/ssl/d1_both.c
++++ b/ssl/d1_both.c
+@@ -687,8 +687,7 @@ dtls1_reassemble_fragment(SSL *s, struct hm_header_st* msg_hdr, int *ok)
+ return DTLS1_HM_FRAGMENT_RETRY;
+
+ err:
+- if (frag != NULL) dtls1_hm_fragment_free(frag);
+- if (item != NULL) OPENSSL_free(item);
++ if (frag != NULL && item == NULL) dtls1_hm_fragment_free(frag);
+ *ok = 0;
+ return i;
+ }
+@@ -772,8 +771,7 @@ dtls1_process_out_of_seq_message(SSL *s, struct hm_header_st* msg_hdr, int *ok)
+ return DTLS1_HM_FRAGMENT_RETRY;
+
+ err:
+- if ( frag != NULL) dtls1_hm_fragment_free(frag);
+- if ( item != NULL) OPENSSL_free(item);
++ if (frag != NULL && item == NULL) dtls1_hm_fragment_free(frag);
+ *ok = 0;
+ return i;
+ }
+--
+2.0.1
+
Added: openssl/branches/squeeze/debian/patches/Fix-DTLS-anonymous-EC-DH-denial-of-service.patch
===================================================================
--- openssl/branches/squeeze/debian/patches/Fix-DTLS-anonymous-EC-DH-denial-of-service.patch (rev 0)
+++ openssl/branches/squeeze/debian/patches/Fix-DTLS-anonymous-EC-DH-denial-of-service.patch 2014-08-11 19:36:05 UTC (rev 689)
@@ -0,0 +1,72 @@
+From e01e4b5f0181ddfc6a1923cd539a6ad81651dccc Mon Sep 17 00:00:00 2001
+From: =?UTF-8?q?Emilia=20K=C3=A4sper?= <emilia at openssl.org>
+Date: Thu, 24 Jul 2014 22:15:29 +0200
+Subject: [PATCH 09/10] Fix DTLS anonymous EC(DH) denial of service
+
+CVE-2014-3510
+
+Reviewed-by: Dr. Stephen Henson <steve at openssl.org>
+---
+ ssl/d1_clnt.c | 16 ++++++++++++++--
+ ssl/s3_clnt.c | 7 +++++++
+ 2 files changed, 21 insertions(+), 2 deletions(-)
+
+diff --git a/ssl/d1_clnt.c b/ssl/d1_clnt.c
+index ac24bfb..58a3b46 100644
+--- a/ssl/d1_clnt.c
++++ b/ssl/d1_clnt.c
+@@ -796,6 +796,13 @@ int dtls1_send_client_key_exchange(SSL *s)
+ RSA *rsa;
+ unsigned char tmp_buf[SSL_MAX_MASTER_KEY_LENGTH];
+
++ if (s->session->sess_cert == NULL)
++ {
++ /* We should always have a server certificate with SSL_kRSA. */
++ SSLerr(SSL_F_DTLS1_SEND_CLIENT_KEY_EXCHANGE,ERR_R_INTERNAL_ERROR);
++ goto err;
++ }
++
+ if (s->session->sess_cert->peer_rsa_tmp != NULL)
+ rsa=s->session->sess_cert->peer_rsa_tmp;
+ else
+@@ -986,6 +993,13 @@ int dtls1_send_client_key_exchange(SSL *s)
+ {
+ DH *dh_srvr,*dh_clnt;
+
++ if (s->session->sess_cert == NULL)
++ {
++ ssl3_send_alert(s,SSL3_AL_FATAL,SSL_AD_UNEXPECTED_MESSAGE);
++ SSLerr(SSL_F_DTLS1_SEND_CLIENT_KEY_EXCHANGE,SSL_R_UNEXPECTED_MESSAGE);
++ goto err;
++ }
++
+ if (s->session->sess_cert->peer_dh_tmp != NULL)
+ dh_srvr=s->session->sess_cert->peer_dh_tmp;
+ else
+@@ -1226,5 +1240,3 @@ int dtls1_send_client_certificate(SSL *s)
+ /* SSL3_ST_CW_CERT_D */
+ return(dtls1_do_write(s,SSL3_RT_HANDSHAKE));
+ }
+-
+-
+diff --git a/ssl/s3_clnt.c b/ssl/s3_clnt.c
+index 4b41a2b..c11048e 100644
+--- a/ssl/s3_clnt.c
++++ b/ssl/s3_clnt.c
+@@ -1916,6 +1916,13 @@ int ssl3_send_client_key_exchange(SSL *s)
+ RSA *rsa;
+ unsigned char tmp_buf[SSL_MAX_MASTER_KEY_LENGTH];
+
++ if (s->session->sess_cert == NULL)
++ {
++ /* We should always have a server certificate with SSL_kRSA. */
++ SSLerr(SSL_F_SSL3_SEND_CLIENT_KEY_EXCHANGE,ERR_R_INTERNAL_ERROR);
++ goto err;
++ }
++
+ if (s->session->sess_cert->peer_rsa_tmp != NULL)
+ rsa=s->session->sess_cert->peer_rsa_tmp;
+ else
+--
+2.0.1
+
Added: openssl/branches/squeeze/debian/patches/Fix-DTLS-handshake-message-size-checks.patch
===================================================================
--- openssl/branches/squeeze/debian/patches/Fix-DTLS-handshake-message-size-checks.patch (rev 0)
+++ openssl/branches/squeeze/debian/patches/Fix-DTLS-handshake-message-size-checks.patch 2014-08-11 19:36:05 UTC (rev 689)
@@ -0,0 +1,87 @@
+From 59942ead835a57fed92b175a4ade50e41b33f8f8 Mon Sep 17 00:00:00 2001
+From: Matt Caswell <matt at openssl.org>
+Date: Fri, 6 Jun 2014 14:25:52 -0700
+Subject: [PATCH 03/10] Fix DTLS handshake message size checks.
+MIME-Version: 1.0
+Content-Type: text/plain; charset=UTF-8
+Content-Transfer-Encoding: 8bit
+
+In |dtls1_reassemble_fragment|, the value of
+|msg_hdr->frag_off+frag_len| was being checked against the maximum
+handshake message size, but then |msg_len| bytes were allocated for the
+fragment buffer. This means that so long as the fragment was within the
+allowed size, the pending handshake message could consume 16MB + 2MB
+(for the reassembly bitmap). Approx 10 outstanding handshake messages
+are allowed, meaning that an attacker could consume ~180MB per DTLS
+connection.
+
+In the non-fragmented path (in |dtls1_process_out_of_seq_message|), no
+check was applied.
+
+Fixes CVE-2014-3506
+
+Wholly based on patch by Adam Langley with one minor amendment.
+
+Reviewed-by: Emilia Käsper <emilia at openssl.org>
+---
+ ssl/d1_both.c | 29 ++++++++++++++++-------------
+ 1 file changed, 16 insertions(+), 13 deletions(-)
+
+diff --git a/ssl/d1_both.c b/ssl/d1_both.c
+index 9bc416c..e0eed12 100644
+--- a/ssl/d1_both.c
++++ b/ssl/d1_both.c
+@@ -581,6 +581,16 @@ dtls1_retrieve_buffered_fragment(SSL *s, long max, int *ok)
+ return 0;
+ }
+
++/* dtls1_max_handshake_message_len returns the maximum number of bytes
++ * permitted in a DTLS handshake message for |s|. The minimum is 16KB, but may
++ * be greater if the maximum certificate list size requires it. */
++static unsigned long dtls1_max_handshake_message_len(const SSL *s)
++ {
++ unsigned long max_len = DTLS1_HM_HEADER_LENGTH + SSL3_RT_MAX_ENCRYPTED_LENGTH;
++ if (max_len < (unsigned long)s->max_cert_list)
++ return s->max_cert_list;
++ return max_len;
++ }
+
+ static int
+ dtls1_reassemble_fragment(SSL *s, struct hm_header_st* msg_hdr, int *ok)
+@@ -589,20 +599,10 @@ dtls1_reassemble_fragment(SSL *s, struct hm_header_st* msg_hdr, int *ok)
+ pitem *item = NULL;
+ int i = -1, is_complete;
+ PQ_64BIT seq64;
+- unsigned long frag_len = msg_hdr->frag_len, max_len;
+-
+- if ((msg_hdr->frag_off+frag_len) > msg_hdr->msg_len)
+- goto err;
+-
+- /* Determine maximum allowed message size. Depends on (user set)
+- * maximum certificate length, but 16k is minimum.
+- */
+- if (DTLS1_HM_HEADER_LENGTH + SSL3_RT_MAX_ENCRYPTED_LENGTH < s->max_cert_list)
+- max_len = s->max_cert_list;
+- else
+- max_len = DTLS1_HM_HEADER_LENGTH + SSL3_RT_MAX_ENCRYPTED_LENGTH;
++ unsigned long frag_len = msg_hdr->frag_len;
+
+- if ((msg_hdr->frag_off+frag_len) > max_len)
++ if ((msg_hdr->frag_off+frag_len) > msg_hdr->msg_len ||
++ msg_hdr->msg_len > dtls1_max_handshake_message_len(s))
+ goto err;
+
+ /* Try to find item in queue */
+@@ -743,6 +743,9 @@ dtls1_process_out_of_seq_message(SSL *s, struct hm_header_st* msg_hdr, int *ok)
+ if (frag_len && frag_len < msg_hdr->msg_len)
+ return dtls1_reassemble_fragment(s, msg_hdr, ok);
+
++ if (frag_len > dtls1_max_handshake_message_len(s))
++ goto err;
++
+ frag = dtls1_hm_fragment_new(frag_len, 0);
+ if ( frag == NULL)
+ goto err;
+--
+2.0.1
+
Added: openssl/branches/squeeze/debian/patches/Fix-OID-handling.patch
===================================================================
--- openssl/branches/squeeze/debian/patches/Fix-OID-handling.patch (rev 0)
+++ openssl/branches/squeeze/debian/patches/Fix-OID-handling.patch 2014-08-11 19:36:05 UTC (rev 689)
@@ -0,0 +1,131 @@
+From bae1ad3427106dbfe5a0bb285cfa52a4b61b24f4 Mon Sep 17 00:00:00 2001
+From: Emilia Kasper <emilia at openssl.org>
+Date: Wed, 2 Jul 2014 19:02:33 +0200
+Subject: [PATCH 10/10] Fix OID handling:
+
+- Upon parsing, reject OIDs with invalid base-128 encoding.
+- Always NUL-terminate the destination buffer in OBJ_obj2txt printing function.
+
+CVE-2014-3508
+
+Reviewed-by: Dr. Stephen Henson <steve at openssl.org>
+Reviewed-by: Kurt Roeckx <kurt at openssl.org>
+Reviewed-by: Tim Hudson <tjh at openssl.org>
+---
+ crypto/asn1/a_object.c | 30 +++++++++++++++++++++---------
+ crypto/objects/obj_dat.c | 16 +++++++++-------
+ 2 files changed, 30 insertions(+), 16 deletions(-)
+
+Index: openssl-0.9.8o/crypto/asn1/a_object.c
+===================================================================
+--- openssl-0.9.8o.orig/crypto/asn1/a_object.c 2010-03-07 16:40:31.000000000 +0000
++++ openssl-0.9.8o/crypto/asn1/a_object.c 2014-08-06 19:40:22.090480888 +0000
+@@ -285,16 +285,28 @@
+ ASN1_OBJECT_free(ret);
+ return(NULL);
+ }
++
+ ASN1_OBJECT *c2i_ASN1_OBJECT(ASN1_OBJECT **a, const unsigned char **pp,
+ long len)
+ {
+ ASN1_OBJECT *ret=NULL;
+ const unsigned char *p;
+- int i;
+- /* Sanity check OID encoding: can't have leading 0x80 in
+- * subidentifiers, see: X.690 8.19.2
++ int i, length;
++
++ /* Sanity check OID encoding.
++ * Need at least one content octet.
++ * MSB must be clear in the last octet.
++ * can't have leading 0x80 in subidentifiers, see: X.690 8.19.2
+ */
+- for (i = 0, p = *pp + 1; i < len - 1; i++, p++)
++ if (len <= 0 || len > INT_MAX || pp == NULL || (p = *pp) == NULL ||
++ p[len - 1] & 0x80)
++ {
++ ASN1err(ASN1_F_C2I_ASN1_OBJECT,ASN1_R_INVALID_OBJECT_ENCODING);
++ return NULL;
++ }
++ /* Now 0 < len <= INT_MAX, so the cast is safe. */
++ length = (int)len;
++ for (i = 0; i < length; i++, p++)
+ {
+ if (*p == 0x80 && (!i || !(p[-1] & 0x80)))
+ {
+@@ -313,20 +325,20 @@
+ else ret=(*a);
+
+ p= *pp;
+- if ((ret->data == NULL) || (ret->length < len))
++ if ((ret->data == NULL) || (ret->length < length))
+ {
+ if (ret->data != NULL) OPENSSL_free(ret->data);
+- ret->data=(unsigned char *)OPENSSL_malloc(len ? (int)len : 1);
++ ret->data=(unsigned char *)OPENSSL_malloc(length);
+ ret->flags|=ASN1_OBJECT_FLAG_DYNAMIC_DATA;
+ if (ret->data == NULL)
+ { i=ERR_R_MALLOC_FAILURE; goto err; }
+ }
+- memcpy(ret->data,p,(int)len);
+- ret->length=(int)len;
++ memcpy(ret->data,p,length);
++ ret->length=length;
+ ret->sn=NULL;
+ ret->ln=NULL;
+ /* ret->flags=ASN1_OBJECT_FLAG_DYNAMIC; we know it is dynamic */
+- p+=len;
++ p+=length;
+
+ if (a != NULL) (*a)=ret;
+ *pp=p;
+Index: openssl-0.9.8o/crypto/objects/obj_dat.c
+===================================================================
+--- openssl-0.9.8o.orig/crypto/objects/obj_dat.c 2009-11-10 01:00:37.000000000 +0000
++++ openssl-0.9.8o/crypto/objects/obj_dat.c 2014-08-06 19:36:39.959096721 +0000
+@@ -444,11 +444,12 @@
+ unsigned char *p;
+ char tbuf[DECIMAL_SIZE(i)+DECIMAL_SIZE(l)+2];
+
+- if ((a == NULL) || (a->data == NULL)) {
+- buf[0]='\0';
+- return(0);
+- }
++ /* Ensure that, at every state, |buf| is NUL-terminated. */
++ if (buf && buf_len > 0)
++ buf[0] = '\0';
+
++ if ((a == NULL) || (a->data == NULL))
++ return(0);
+
+ if (!no_name && (nid=OBJ_obj2nid(a)) != NID_undef)
+ {
+@@ -527,9 +528,10 @@
+ i=(int)(l/40);
+ l-=(long)(i*40);
+ }
+- if (buf && (buf_len > 0))
++ if (buf && (buf_len > 1))
+ {
+ *buf++ = i + '0';
++ *buf = '\0';
+ buf_len--;
+ }
+ n++;
+@@ -544,9 +546,10 @@
+ i = strlen(bndec);
+ if (buf)
+ {
+- if (buf_len > 0)
++ if (buf_len > 1)
+ {
+ *buf++ = '.';
++ *buf = '\0';
+ buf_len--;
+ }
+ BUF_strlcpy(buf,bndec,buf_len);
+@@ -786,4 +789,3 @@
+ OPENSSL_free(buf);
+ return(ok);
+ }
+-
Added: openssl/branches/squeeze/debian/patches/Fix-memory-leak-from-zero-length-DTLS-fragments.patch
===================================================================
--- openssl/branches/squeeze/debian/patches/Fix-memory-leak-from-zero-length-DTLS-fragments.patch (rev 0)
+++ openssl/branches/squeeze/debian/patches/Fix-memory-leak-from-zero-length-DTLS-fragments.patch 2014-08-11 19:36:05 UTC (rev 689)
@@ -0,0 +1,79 @@
+From 0a2b055b7719b832b0027fd16793dd000825effb Mon Sep 17 00:00:00 2001
+From: Adam Langley <agl at imperialviolet.org>
+Date: Fri, 6 Jun 2014 14:30:33 -0700
+Subject: [PATCH 04/10] Fix memory leak from zero-length DTLS fragments.
+MIME-Version: 1.0
+Content-Type: text/plain; charset=UTF-8
+Content-Transfer-Encoding: 8bit
+
+The |pqueue_insert| function can fail if one attempts to insert a
+duplicate sequence number. When handling a fragment of an out of
+sequence message, |dtls1_process_out_of_seq_message| would not call
+|dtls1_reassemble_fragment| if the fragment's length was zero. It would
+then allocate a fresh fragment and attempt to insert it, but ignore the
+return value, leaking the fragment.
+
+This allows an attacker to exhaust the memory of a DTLS peer.
+
+Fixes CVE-2014-3507
+
+Reviewed-by: Matt Caswell <matt at openssl.org>
+Reviewed-by: Emilia Käsper <emilia at openssl.org>
+---
+ ssl/d1_both.c | 22 +++++++++++++++++++---
+ 1 file changed, 19 insertions(+), 3 deletions(-)
+
+Index: openssl-0.9.8o/ssl/d1_both.c
+===================================================================
+--- openssl-0.9.8o.orig/ssl/d1_both.c 2014-08-06 19:44:35.197217357 +0000
++++ openssl-0.9.8o/ssl/d1_both.c 2014-08-06 19:44:38.485148954 +0000
+@@ -617,6 +617,9 @@
+ msg_hdr->msg_len > dtls1_max_handshake_message_len(s))
+ goto err;
+
++ if (frag_len == 0)
++ return DTLS1_HM_FRAGMENT_RETRY;
++
+ /* Try to find item in queue */
+ pq_64bit_init(&seq64);
+ pq_64bit_assign_word(&seq64, msg_hdr->seq);
+@@ -694,7 +697,12 @@
+ i = -1;
+ }
+
+- pqueue_insert(s->d1->buffered_messages, item);
++ item = pqueue_insert(s->d1->buffered_messages, item);
++ /* pqueue_insert fails iff a duplicate item is inserted.
++ * However, |item| cannot be a duplicate. If it were,
++ * |pqueue_find|, above, would have returned it and control
++ * would never have reached this branch. */
++ OPENSSL_assert(item != NULL);
+ }
+
+ return DTLS1_HM_FRAGMENT_RETRY;
+@@ -752,7 +760,7 @@
+ }
+ else
+ {
+- if (frag_len && frag_len < msg_hdr->msg_len)
++ if (frag_len < msg_hdr->msg_len)
+ return dtls1_reassemble_fragment(s, msg_hdr, ok);
+
+ if (frag_len > dtls1_max_handshake_message_len(s))
+@@ -781,7 +789,15 @@
+ if ( item == NULL)
+ goto err;
+
+- pqueue_insert(s->d1->buffered_messages, item);
++ item = pqueue_insert(s->d1->buffered_messages, item);
++ /* pqueue_insert fails iff a duplicate item is inserted.
++ * However, |item| cannot be a duplicate. If it were,
++ * |pqueue_find|, above, would have returned it. Then, either
++ * |frag_len| != |msg_hdr->msg_len| in which case |item| is set
++ * to NULL and it will have been processed with
++ * |dtls1_reassemble_fragment|, above, or the record will have
++ * been discarded. */
++ OPENSSL_assert(item != NULL);
+ }
+
+ return DTLS1_HM_FRAGMENT_RETRY;
Added: openssl/branches/squeeze/debian/patches/Fix-protocol-downgrade-bug-in-case-of-fragmented-pac.patch
===================================================================
--- openssl/branches/squeeze/debian/patches/Fix-protocol-downgrade-bug-in-case-of-fragmented-pac.patch (rev 0)
+++ openssl/branches/squeeze/debian/patches/Fix-protocol-downgrade-bug-in-case-of-fragmented-pac.patch 2014-08-11 19:36:05 UTC (rev 689)
@@ -0,0 +1,86 @@
+From 91a5ef1e22bd41b2567faa90f016b460d973a974 Mon Sep 17 00:00:00 2001
+From: David Benjamin <davidben at google.com>
+Date: Wed, 23 Jul 2014 22:32:21 +0200
+Subject: [PATCH 08/10] Fix protocol downgrade bug in case of fragmented
+ packets
+MIME-Version: 1.0
+Content-Type: text/plain; charset=UTF-8
+Content-Transfer-Encoding: 8bit
+
+CVE-2014-3511
+
+Reviewed-by: Emilia Käsper <emilia at openssl.org>
+Reviewed-by: Bodo Möller <bodo at openssl.org>
+---
+ ssl/s23_srvr.c | 30 +++++++++++++++++++++++-------
+ 1 file changed, 23 insertions(+), 7 deletions(-)
+
+diff --git a/ssl/s23_srvr.c b/ssl/s23_srvr.c
+index be05911..e544853 100644
+--- a/ssl/s23_srvr.c
++++ b/ssl/s23_srvr.c
+@@ -328,23 +328,19 @@ int ssl23_get_client_hello(SSL *s)
+ * Client Hello message, this would be difficult, and we'd have
+ * to read more records to find out.
+ * No known SSL 3.0 client fragments ClientHello like this,
+- * so we simply assume TLS 1.0 to avoid protocol version downgrade
+- * attacks. */
++ * so we simply reject such connections to avoid
++ * protocol version downgrade attacks. */
+ if (p[3] == 0 && p[4] < 6)
+ {
+-#if 0
+ SSLerr(SSL_F_SSL23_GET_CLIENT_HELLO,SSL_R_RECORD_TOO_SMALL);
+ goto err;
+-#else
+- v[1] = TLS1_VERSION_MINOR;
+-#endif
+ }
+ /* if major version number > 3 set minor to a value
+ * which will use the highest version 3 we support.
+ * If TLS 2.0 ever appears we will need to revise
+ * this....
+ */
+- else if (p[9] > SSL3_VERSION_MAJOR)
++ if (p[9] > SSL3_VERSION_MAJOR)
+ v[1]=0xff;
+ else
+ v[1]=p[10]; /* minor version according to client_version */
+@@ -412,14 +408,34 @@ int ssl23_get_client_hello(SSL *s)
+ v[0] = p[3]; /* == SSL3_VERSION_MAJOR */
+ v[1] = p[4];
+
++ /* An SSLv3/TLSv1 backwards-compatible CLIENT-HELLO in an SSLv2
++ * header is sent directly on the wire, not wrapped as a TLS
++ * record. It's format is:
++ * Byte Content
++ * 0-1 msg_length
++ * 2 msg_type
++ * 3-4 version
++ * 5-6 cipher_spec_length
++ * 7-8 session_id_length
++ * 9-10 challenge_length
++ * ... ...
++ */
+ n=((p[0]&0x7f)<<8)|p[1];
+ if (n > (1024*4))
+ {
+ SSLerr(SSL_F_SSL23_GET_CLIENT_HELLO,SSL_R_RECORD_TOO_LARGE);
+ goto err;
+ }
++ if (n < 9)
++ {
++ SSLerr(SSL_F_SSL23_GET_CLIENT_HELLO,SSL_R_RECORD_LENGTH_MISMATCH);
++ goto err;
++ }
+
+ j=ssl23_read_bytes(s,n+2);
++ /* We previously read 11 bytes, so if j > 0, we must have
++ * j == n+2 == s->packet_length. We have at least 11 valid
++ * packet bytes. */
+ if (j <= 0) return(j);
+
+ ssl3_finish_mac(s, s->packet+2, s->packet_length-2);
+--
+2.0.1
+
Added: openssl/branches/squeeze/debian/patches/Fix-return-code-for-truncated-DTLS-fragment.patch
===================================================================
--- openssl/branches/squeeze/debian/patches/Fix-return-code-for-truncated-DTLS-fragment.patch (rev 0)
+++ openssl/branches/squeeze/debian/patches/Fix-return-code-for-truncated-DTLS-fragment.patch 2014-08-11 19:36:05 UTC (rev 689)
@@ -0,0 +1,43 @@
+From 0b3b1167e1d72a568dae7bb5778de377250e6280 Mon Sep 17 00:00:00 2001
+From: Adam Langley <agl at imperialviolet.org>
+Date: Fri, 6 Jun 2014 14:44:20 -0700
+Subject: [PATCH 05/10] Fix return code for truncated DTLS fragment.
+MIME-Version: 1.0
+Content-Type: text/plain; charset=UTF-8
+Content-Transfer-Encoding: 8bit
+
+Previously, a truncated DTLS fragment in
+|dtls1_process_out_of_seq_message| would cause *ok to be cleared, but
+the return value would still be the number of bytes read. This would
+cause |dtls1_get_message| not to consider it an error and it would
+continue processing as normal until the calling function noticed that
+*ok was zero.
+
+I can't see an exploit here because |dtls1_get_message| uses
+|s->init_num| as the length, which will always be zero from what I can
+see.
+
+Reviewed-by: Matt Caswell <matt at openssl.org>
+Reviewed-by: Emilia Käsper <emilia at openssl.org>
+---
+ ssl/d1_both.c | 4 +++-
+ 1 file changed, 3 insertions(+), 1 deletion(-)
+
+diff --git a/ssl/d1_both.c b/ssl/d1_both.c
+index 99325e8..961ac51 100644
+--- a/ssl/d1_both.c
++++ b/ssl/d1_both.c
+@@ -765,7 +765,9 @@ dtls1_process_out_of_seq_message(SSL *s, struct hm_header_st* msg_hdr, int *ok)
+ /* read the body of the fragment (header has already been read) */
+ i = s->method->ssl_read_bytes(s,SSL3_RT_HANDSHAKE,
+ frag->fragment,frag_len,0);
+- if (i<=0 || (unsigned long)i!=frag_len)
++ if ((unsigned long)i!=frag_len)
++ i = -1;
++ if (i<=0)
+ goto err;
+ }
+
+--
+2.0.1
+
Added: openssl/branches/squeeze/debian/patches/Remove-some-duplicate-DTLS-code.patch
===================================================================
--- openssl/branches/squeeze/debian/patches/Remove-some-duplicate-DTLS-code.patch (rev 0)
+++ openssl/branches/squeeze/debian/patches/Remove-some-duplicate-DTLS-code.patch 2014-08-11 19:36:05 UTC (rev 689)
@@ -0,0 +1,62 @@
+From 9cfb1ed70502b6ea0bd963b2ec278b70d5f11190 Mon Sep 17 00:00:00 2001
+From: Adam Langley <agl at imperialviolet.org>
+Date: Fri, 6 Jun 2014 14:47:07 -0700
+Subject: [PATCH 07/10] Remove some duplicate DTLS code.
+MIME-Version: 1.0
+Content-Type: text/plain; charset=UTF-8
+Content-Transfer-Encoding: 8bit
+
+In |dtls1_process_out_of_seq_message|, we know that
+|frag_len| <= |msg_hdr->msg_len| so the later tests for |frag_len <
+msg_hdr->msg_len| can be more clearly written as |frag_len !=
+msg_hdr->msg_len|, since that's the only remaining case.
+
+Reviewed-by: Matt Caswell <matt at openssl.org>
+Reviewed-by: Emilia Käsper <emilia at openssl.org>
+---
+ ssl/d1_both.c | 8 ++++----
+ 1 file changed, 4 insertions(+), 4 deletions(-)
+
+diff --git a/ssl/d1_both.c b/ssl/d1_both.c
+index 3a4819f..d2bbb6b 100644
+--- a/ssl/d1_both.c
++++ b/ssl/d1_both.c
+@@ -593,7 +593,7 @@ static unsigned long dtls1_max_handshake_message_len(const SSL *s)
+ }
+
+ static int
+-dtls1_reassemble_fragment(SSL *s, struct hm_header_st* msg_hdr, int *ok)
++dtls1_reassemble_fragment(SSL *s, const struct hm_header_st* msg_hdr, int *ok)
+ {
+ hm_fragment *frag = NULL;
+ pitem *item = NULL;
+@@ -705,7 +705,7 @@ err:
+
+
+ static int
+-dtls1_process_out_of_seq_message(SSL *s, struct hm_header_st* msg_hdr, int *ok)
++dtls1_process_out_of_seq_message(SSL *s, const struct hm_header_st* msg_hdr, int *ok)
+ {
+ int i=-1;
+ hm_fragment *frag = NULL;
+@@ -725,7 +725,7 @@ dtls1_process_out_of_seq_message(SSL *s, struct hm_header_st* msg_hdr, int *ok)
+ /* If we already have an entry and this one is a fragment,
+ * don't discard it and rather try to reassemble it.
+ */
+- if (item != NULL && frag_len < msg_hdr->msg_len)
++ if (item != NULL && frag_len != msg_hdr->msg_len)
+ item = NULL;
+
+ /* Discard the message if sequence number was already there, is
+@@ -750,7 +750,7 @@ dtls1_process_out_of_seq_message(SSL *s, struct hm_header_st* msg_hdr, int *ok)
+ }
+ else
+ {
+- if (frag_len < msg_hdr->msg_len)
++ if (frag_len != msg_hdr->msg_len)
+ return dtls1_reassemble_fragment(s, msg_hdr, ok);
+
+ if (frag_len > dtls1_max_handshake_message_len(s))
+--
+2.0.1
+
Modified: openssl/branches/squeeze/debian/patches/series
===================================================================
--- openssl/branches/squeeze/debian/patches/series 2014-08-06 22:22:34 UTC (rev 688)
+++ openssl/branches/squeeze/debian/patches/series 2014-08-11 19:36:05 UTC (rev 689)
@@ -46,3 +46,13 @@
CVE-2014-3470.patch
CVE-2014-0224.patch
CVE-2012-4929.patch
+Avoid-double-free-when-processing-DTLS-packets.patch
+Added-comment-for-the-frag-reassembly-NULL-case-as-p.patch
+Fix-DTLS-handshake-message-size-checks.patch
+Fix-memory-leak-from-zero-length-DTLS-fragments.patch
+Fix-return-code-for-truncated-DTLS-fragment.patch
+Applying-same-fix-as-in-dtls1_process_out_of_seq_mes.patch
+Remove-some-duplicate-DTLS-code.patch
+Fix-protocol-downgrade-bug-in-case-of-fragmented-pac.patch
+Fix-DTLS-anonymous-EC-DH-denial-of-service.patch
+Fix-OID-handling.patch
More information about the Pkg-openssl-changes
mailing list