fix CVE-2010-3864

This commit is contained in:
Dr. Stephen Henson 2010-11-17 17:36:29 +00:00
parent 975c6efbe4
commit 6e21ce592e
2 changed files with 50 additions and 18 deletions

View File

@ -40,6 +40,10 @@
Changes between 1.0.0a and 1.0.0b [xx XXX xxxx] Changes between 1.0.0a and 1.0.0b [xx XXX xxxx]
*) Fix extension code to avoid race conditions which can result in a buffer
overrun vulnerability: resumed sessions must not be modified as they can
be shared by multiple threads. CVE-2010-3864
*) Fix WIN32 build system to correctly link an ENGINE directory into *) Fix WIN32 build system to correctly link an ENGINE directory into
a DLL. a DLL.
[Steve Henson] [Steve Henson]
@ -893,6 +897,10 @@
Changes between 0.9.8o and 0.9.8p [xx XXX xxxx] Changes between 0.9.8o and 0.9.8p [xx XXX xxxx]
*) Fix extension code to avoid race conditions which can result in a buffer
overrun vulnerability: resumed sessions must not be modified as they can
be shared by multiple threads. CVE-2010-3864
*) Fix for double free bug in ssl/s3_clnt.c CVE-2010-2939 *) Fix for double free bug in ssl/s3_clnt.c CVE-2010-2939
[Steve Henson] [Steve Henson]

View File

@ -714,14 +714,23 @@ int ssl_parse_clienthello_tlsext(SSL *s, unsigned char **p, unsigned char *d, in
switch (servname_type) switch (servname_type)
{ {
case TLSEXT_NAMETYPE_host_name: case TLSEXT_NAMETYPE_host_name:
if (s->session->tlsext_hostname == NULL) if (!s->hit)
{ {
if (len > TLSEXT_MAXLEN_host_name || if(s->session->tlsext_hostname)
((s->session->tlsext_hostname = OPENSSL_malloc(len+1)) == NULL)) {
*al = SSL_AD_DECODE_ERROR;
return 0;
}
if (len > TLSEXT_MAXLEN_host_name)
{ {
*al = TLS1_AD_UNRECOGNIZED_NAME; *al = TLS1_AD_UNRECOGNIZED_NAME;
return 0; 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); memcpy(s->session->tlsext_hostname, sdata, len);
s->session->tlsext_hostname[len]='\0'; s->session->tlsext_hostname[len]='\0';
if (strlen(s->session->tlsext_hostname) != len) { 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 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; && strncmp(s->session->tlsext_hostname, (char *)sdata, len) == 0;
break; break;
@ -765,15 +775,22 @@ int ssl_parse_clienthello_tlsext(SSL *s, unsigned char **p, unsigned char *d, in
*al = TLS1_AD_DECODE_ERROR; *al = TLS1_AD_DECODE_ERROR;
return 0; return 0;
} }
s->session->tlsext_ecpointformatlist_length = 0; if (!s->hit)
if (s->session->tlsext_ecpointformatlist != NULL) OPENSSL_free(s->session->tlsext_ecpointformatlist);
if ((s->session->tlsext_ecpointformatlist = OPENSSL_malloc(ecpointformatlist_length)) == NULL)
{ {
*al = TLS1_AD_INTERNAL_ERROR; if(s->session->tlsext_ecpointformatlist)
return 0; {
OPENSSL_free(s->session->tlsext_ecpointformatlist);
s->session->tlsext_ecpointformatlist = NULL;
}
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 #if 0
fprintf(stderr,"ssl_parse_clienthello_tlsext s->session->tlsext_ecpointformatlist (length=%i) ", s->session->tlsext_ecpointformatlist_length); fprintf(stderr,"ssl_parse_clienthello_tlsext s->session->tlsext_ecpointformatlist (length=%i) ", s->session->tlsext_ecpointformatlist_length);
sdata = s->session->tlsext_ecpointformatlist; 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; *al = TLS1_AD_DECODE_ERROR;
return 0; return 0;
} }
s->session->tlsext_ellipticcurvelist_length = 0; if (!s->hit)
if (s->session->tlsext_ellipticcurvelist != NULL) OPENSSL_free(s->session->tlsext_ellipticcurvelist);
if ((s->session->tlsext_ellipticcurvelist = OPENSSL_malloc(ellipticcurvelist_length)) == NULL)
{ {
*al = TLS1_AD_INTERNAL_ERROR; if(s->session->tlsext_ellipticcurvelist)
return 0; {
*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 #if 0
fprintf(stderr,"ssl_parse_clienthello_tlsext s->session->tlsext_ellipticcurvelist (length=%i) ", s->session->tlsext_ellipticcurvelist_length); fprintf(stderr,"ssl_parse_clienthello_tlsext s->session->tlsext_ellipticcurvelist (length=%i) ", s->session->tlsext_ellipticcurvelist_length);
sdata = s->session->tlsext_ellipticcurvelist; sdata = s->session->tlsext_ellipticcurvelist;