From 1537fcb001c4f666893aa2bdeed7880e9c6a83b2 Mon Sep 17 00:00:00 2001 From: Brian Carlstrom Date: Mon, 29 Nov 2010 17:45:48 -0800 Subject: [PATCH] Patch for CVE-2010-3864 OpenSSL Security Advisory [16 November 2010] TLS extension parsing race condition. (UPDATED) CVE-2010-3864 http://www.openssl.org/news/secadv_20101116-2.txt Bug: 3201137 Change-Id: Ie3e38b9e02ac35eb8c782e0bcd19ce29ac457f29 --- openssl.config | 5 ++ patches/README | 8 +++ patches/secadv_20101116-2.patch | 99 +++++++++++++++++++++++++++++++++ ssl/t1_lib.c | 60 ++++++++++++++------ 4 files changed, 154 insertions(+), 18 deletions(-) create mode 100644 patches/secadv_20101116-2.patch diff --git a/openssl.config b/openssl.config index 8f56273287..1eb1d40dbe 100644 --- a/openssl.config +++ b/openssl.config @@ -165,6 +165,7 @@ progs.patch \ small_records.patch \ handshake_cutthrough.patch \ jsse.patch \ +secadv_20101116-2.patch \ " OPENSSL_PATCHES_progs_SOURCES="\ @@ -209,3 +210,7 @@ ssl/ssl_locl.h ssl/ssl_rsa.c \ ssl/ssl_sess.c \ " + +OPENSSL_PATCHES_secadv_20101116_2_SOURCES="\ +ssl/t1_lib.c \ +" diff --git a/patches/README b/patches/README index 4b182ddcd0..bc98ee1a80 100644 --- a/patches/README +++ b/patches/README @@ -27,3 +27,11 @@ jsse.patch Support for JSSE implementation based on OpenSSL. +secadv_20101116-2.patch + +OpenSSL Security Advisory [16 November 2010] +TLS extension parsing race condition. (UPDATED) +CVE-2010-3864 +http://www.openssl.org/news/secadv_20101116-2.txt + + diff --git a/patches/secadv_20101116-2.patch b/patches/secadv_20101116-2.patch new file mode 100644 index 0000000000..cd13136aee --- /dev/null +++ b/patches/secadv_20101116-2.patch @@ -0,0 +1,99 @@ +--- openssl-1.0.0.orig/ssl/t1_lib.c 15 Jun 2010 17:25:15 -0000 1.64.2.14 ++++ openssl-1.0.0/ssl/t1_lib.c 15 Nov 2010 15:26:19 -0000 +@@ -714,14 +714,23 @@ + switch (servname_type) + { + case TLSEXT_NAMETYPE_host_name: +- if (s->session->tlsext_hostname == NULL) ++ if (!s->hit) + { +- if (len > TLSEXT_MAXLEN_host_name || +- ((s->session->tlsext_hostname = OPENSSL_malloc(len+1)) == NULL)) ++ if(s->session->tlsext_hostname) ++ { ++ *al = SSL_AD_DECODE_ERROR; ++ return 0; ++ } ++ if (len > TLSEXT_MAXLEN_host_name) + { + *al = TLS1_AD_UNRECOGNIZED_NAME; + return 0; + } ++ if ((s->session->tlsext_hostname = OPENSSL_malloc(len+1)) == NULL) ++ { ++ *al = TLS1_AD_INTERNAL_ERROR; ++ return 0; ++ } + memcpy(s->session->tlsext_hostname, sdata, len); + s->session->tlsext_hostname[len]='\0'; + if (strlen(s->session->tlsext_hostname) != len) { +@@ -734,7 +743,8 @@ + + } + else +- s->servername_done = strlen(s->session->tlsext_hostname) == len ++ s->servername_done = s->session->tlsext_hostname ++ && strlen(s->session->tlsext_hostname) == len + && strncmp(s->session->tlsext_hostname, (char *)sdata, len) == 0; + + break; +@@ -765,15 +775,22 @@ + *al = TLS1_AD_DECODE_ERROR; + return 0; + } +- s->session->tlsext_ecpointformatlist_length = 0; +- if (s->session->tlsext_ecpointformatlist != NULL) OPENSSL_free(s->session->tlsext_ecpointformatlist); +- if ((s->session->tlsext_ecpointformatlist = OPENSSL_malloc(ecpointformatlist_length)) == NULL) ++ if (!s->hit) + { +- *al = TLS1_AD_INTERNAL_ERROR; +- return 0; ++ if(s->session->tlsext_ecpointformatlist) ++ { ++ *al = TLS1_AD_DECODE_ERROR; ++ return 0; ++ } ++ s->session->tlsext_ecpointformatlist_length = 0; ++ if ((s->session->tlsext_ecpointformatlist = OPENSSL_malloc(ecpointformatlist_length)) == NULL) ++ { ++ *al = TLS1_AD_INTERNAL_ERROR; ++ return 0; ++ } ++ s->session->tlsext_ecpointformatlist_length = ecpointformatlist_length; ++ memcpy(s->session->tlsext_ecpointformatlist, sdata, ecpointformatlist_length); + } +- s->session->tlsext_ecpointformatlist_length = ecpointformatlist_length; +- memcpy(s->session->tlsext_ecpointformatlist, sdata, ecpointformatlist_length); + #if 0 + fprintf(stderr,"ssl_parse_clienthello_tlsext s->session->tlsext_ecpointformatlist (length=%i) ", s->session->tlsext_ecpointformatlist_length); + sdata = s->session->tlsext_ecpointformatlist; +@@ -794,15 +811,22 @@ + *al = TLS1_AD_DECODE_ERROR; + return 0; + } +- s->session->tlsext_ellipticcurvelist_length = 0; +- if (s->session->tlsext_ellipticcurvelist != NULL) OPENSSL_free(s->session->tlsext_ellipticcurvelist); +- if ((s->session->tlsext_ellipticcurvelist = OPENSSL_malloc(ellipticcurvelist_length)) == NULL) ++ if (!s->hit) + { +- *al = TLS1_AD_INTERNAL_ERROR; +- return 0; ++ if(s->session->tlsext_ellipticcurvelist) ++ { ++ *al = TLS1_AD_DECODE_ERROR; ++ return 0; ++ } ++ s->session->tlsext_ellipticcurvelist_length = 0; ++ if ((s->session->tlsext_ellipticcurvelist = OPENSSL_malloc(ellipticcurvelist_length)) == NULL) ++ { ++ *al = TLS1_AD_INTERNAL_ERROR; ++ return 0; ++ } ++ s->session->tlsext_ellipticcurvelist_length = ellipticcurvelist_length; ++ memcpy(s->session->tlsext_ellipticcurvelist, sdata, ellipticcurvelist_length); + } +- s->session->tlsext_ellipticcurvelist_length = ellipticcurvelist_length; +- memcpy(s->session->tlsext_ellipticcurvelist, sdata, ellipticcurvelist_length); + #if 0 + fprintf(stderr,"ssl_parse_clienthello_tlsext s->session->tlsext_ellipticcurvelist (length=%i) ", s->session->tlsext_ellipticcurvelist_length); + sdata = s->session->tlsext_ellipticcurvelist; diff --git a/ssl/t1_lib.c b/ssl/t1_lib.c index e8bc34c111..eac2deba1e 100644 --- a/ssl/t1_lib.c +++ b/ssl/t1_lib.c @@ -714,14 +714,23 @@ int ssl_parse_clienthello_tlsext(SSL *s, unsigned char **p, unsigned char *d, in switch (servname_type) { case TLSEXT_NAMETYPE_host_name: - if (s->session->tlsext_hostname == NULL) + if (!s->hit) { - if (len > TLSEXT_MAXLEN_host_name || - ((s->session->tlsext_hostname = OPENSSL_malloc(len+1)) == NULL)) + if(s->session->tlsext_hostname) + { + *al = SSL_AD_DECODE_ERROR; + return 0; + } + if (len > TLSEXT_MAXLEN_host_name) { *al = TLS1_AD_UNRECOGNIZED_NAME; return 0; } + if ((s->session->tlsext_hostname = OPENSSL_malloc(len+1)) == NULL) + { + *al = TLS1_AD_INTERNAL_ERROR; + return 0; + } memcpy(s->session->tlsext_hostname, sdata, len); s->session->tlsext_hostname[len]='\0'; if (strlen(s->session->tlsext_hostname) != len) { @@ -734,7 +743,8 @@ int ssl_parse_clienthello_tlsext(SSL *s, unsigned char **p, unsigned char *d, in } else - s->servername_done = strlen(s->session->tlsext_hostname) == len + s->servername_done = s->session->tlsext_hostname + && strlen(s->session->tlsext_hostname) == len && strncmp(s->session->tlsext_hostname, (char *)sdata, len) == 0; break; @@ -765,15 +775,22 @@ int ssl_parse_clienthello_tlsext(SSL *s, unsigned char **p, unsigned char *d, in *al = TLS1_AD_DECODE_ERROR; return 0; } - s->session->tlsext_ecpointformatlist_length = 0; - if (s->session->tlsext_ecpointformatlist != NULL) OPENSSL_free(s->session->tlsext_ecpointformatlist); - if ((s->session->tlsext_ecpointformatlist = OPENSSL_malloc(ecpointformatlist_length)) == NULL) + if (!s->hit) { - *al = TLS1_AD_INTERNAL_ERROR; - return 0; + if(s->session->tlsext_ecpointformatlist) + { + *al = TLS1_AD_DECODE_ERROR; + return 0; + } + s->session->tlsext_ecpointformatlist_length = 0; + if ((s->session->tlsext_ecpointformatlist = OPENSSL_malloc(ecpointformatlist_length)) == NULL) + { + *al = TLS1_AD_INTERNAL_ERROR; + return 0; + } + s->session->tlsext_ecpointformatlist_length = ecpointformatlist_length; + memcpy(s->session->tlsext_ecpointformatlist, sdata, ecpointformatlist_length); } - s->session->tlsext_ecpointformatlist_length = ecpointformatlist_length; - memcpy(s->session->tlsext_ecpointformatlist, sdata, ecpointformatlist_length); #if 0 fprintf(stderr,"ssl_parse_clienthello_tlsext s->session->tlsext_ecpointformatlist (length=%i) ", s->session->tlsext_ecpointformatlist_length); sdata = s->session->tlsext_ecpointformatlist; @@ -794,15 +811,22 @@ int ssl_parse_clienthello_tlsext(SSL *s, unsigned char **p, unsigned char *d, in *al = TLS1_AD_DECODE_ERROR; return 0; } - s->session->tlsext_ellipticcurvelist_length = 0; - if (s->session->tlsext_ellipticcurvelist != NULL) OPENSSL_free(s->session->tlsext_ellipticcurvelist); - if ((s->session->tlsext_ellipticcurvelist = OPENSSL_malloc(ellipticcurvelist_length)) == NULL) + if (!s->hit) { - *al = TLS1_AD_INTERNAL_ERROR; - return 0; + if(s->session->tlsext_ellipticcurvelist) + { + *al = TLS1_AD_DECODE_ERROR; + return 0; + } + s->session->tlsext_ellipticcurvelist_length = 0; + if ((s->session->tlsext_ellipticcurvelist = OPENSSL_malloc(ellipticcurvelist_length)) == NULL) + { + *al = TLS1_AD_INTERNAL_ERROR; + return 0; + } + s->session->tlsext_ellipticcurvelist_length = ellipticcurvelist_length; + memcpy(s->session->tlsext_ellipticcurvelist, sdata, ellipticcurvelist_length); } - s->session->tlsext_ellipticcurvelist_length = ellipticcurvelist_length; - memcpy(s->session->tlsext_ellipticcurvelist, sdata, ellipticcurvelist_length); #if 0 fprintf(stderr,"ssl_parse_clienthello_tlsext s->session->tlsext_ellipticcurvelist (length=%i) ", s->session->tlsext_ellipticcurvelist_length); sdata = s->session->tlsext_ellipticcurvelist;