File openssl-CVE-2016-2177.patch of Package compat-openssl098.16428
commit 6f35f6deb5ca7daebe289f86477e061ce3ee5f46
Author: Matt Caswell <matt@openssl.org>
Date: Thu May 5 11:10:26 2016 +0100
Avoid some undefined pointer arithmetic
A common idiom in the codebase is:
if (p + len > limit)
{
return; /* Too long */
}
Where "p" points to some malloc'd data of SIZE bytes and
limit == p + SIZE
"len" here could be from some externally supplied data (e.g. from a TLS
message).
The rules of C pointer arithmetic are such that "p + len" is only well
defined where len <= SIZE. Therefore the above idiom is actually
undefined behaviour.
For example this could cause problems if some malloc implementation
provides an address for "p" such that "p + len" actually overflows for
values of len that are too big and therefore p + len < limit!
Issue reported by Guido Vranken.
CVE-2016-2177
Reviewed-by: Rich Salz <rsalz@openssl.org>
Index: openssl-0.9.8j/ssl/s3_srvr.c
===================================================================
--- openssl-0.9.8j.orig/ssl/s3_srvr.c 2016-08-18 10:51:53.086597242 +0200
+++ openssl-0.9.8j/ssl/s3_srvr.c 2016-08-18 10:51:53.282600243 +0200
@@ -885,7 +885,7 @@ int ssl3_get_client_hello(SSL *s)
SSLerr(SSL_F_SSL3_GET_CLIENT_HELLO,SSL_R_NO_CIPHERS_SPECIFIED);
goto f_err;
}
- if ((p+i) >= (d+n))
+ if ((d+n) - p <= i)
{
/* not enough data */
al=SSL_AD_DECODE_ERROR;
@@ -952,7 +952,7 @@ int ssl3_get_client_hello(SSL *s)
/* compression */
i= *(p++);
- if ((p+i) > (d+n))
+ if ((d + n) - p < i)
{
/* not enough data */
al=SSL_AD_DECODE_ERROR;
Index: openssl-0.9.8j/ssl/t1_lib.c
===================================================================
--- openssl-0.9.8j.orig/ssl/t1_lib.c 2016-08-18 10:51:52.738591916 +0200
+++ openssl-0.9.8j/ssl/t1_lib.c 2016-08-18 10:55:50.486229089 +0200
@@ -351,24 +351,28 @@ int ssl_parse_clienthello_tlsext(SSL *s,
unsigned short len;
unsigned char *data = *p;
int renegotiate_seen = 0;
+ const unsigned char *limit = d + n;
s->servername_done = 0;
s->tlsext_status_type = -1;
- if (data >= (d+n-2))
+ if (data == limit)
goto ri_check;
+ if (limit - data < 2)
+ goto err;
+
n2s(data,len);
- if (data > (d+n-len))
- goto ri_check;
+ if (limit - data != len)
+ goto err;
- while (data <= (d+n-4))
+ while (limit - data >= 4)
{
n2s(data,type);
n2s(data,size);
- if (data+size > (d+n))
- goto ri_check;
+ if (limit - data < size)
+ goto err;
if (s->tlsext_debug_cb)
s->tlsext_debug_cb(s, 0, type, data, size,
@@ -611,6 +615,9 @@ int ssl_parse_clienthello_tlsext(SSL *s,
}
return 1;
+err:
+ *al = SSL_AD_DECODE_ERROR;
+ return 0;
}
int ssl_parse_serverhello_tlsext(SSL *s, unsigned char **p, unsigned char *d, int n, int *al)
@@ -623,17 +630,17 @@ int ssl_parse_serverhello_tlsext(SSL *s,
int tlsext_servername = 0;
int renegotiate_seen = 0;
- if (data >= (d+n-2))
+ if ((d + n) - data <= 2)
goto ri_check;
n2s(data,len);
- while(data <= (d+n-4))
+ while((d + n) - data >= 4)
{
n2s(data,type);
n2s(data,size);
- if (data+size > (d+n))
+ if ((d + n) - data < size)
goto ri_check;
if (s->tlsext_debug_cb)
@@ -731,6 +738,9 @@ int ssl_parse_serverhello_tlsext(SSL *s,
}
return 1;
+err:
+ *al = SSL_AD_DECODE_ERROR;
+ return 0;
}
int ssl_check_clienthello_tlsext(SSL *s)
@@ -871,24 +881,26 @@ int tls1_process_ticket(SSL *s, unsigned
return -1;
/* Skip past cipher list */
n2s(p, i);
- p+= i;
- if (p >= limit)
+ if (limit - p <= i)
return -1;
+ p += i;
+
/* Skip past compression algorithm list */
i = *(p++);
- p += i;
- if (p > limit)
+ if (limit - p < i)
return -1;
+ p += i;
+
/* Now at start of extensions */
- if ((p + 2) >= limit)
+ if (limit - p <= 2)
return 1;
n2s(p, i);
- while ((p + 4) <= limit)
+ while (limit - p >= 4)
{
unsigned short type, size;
n2s(p, type);
n2s(p, size);
- if (p + size > limit)
+ if (limit - p < size)
return 1;
if (type == TLSEXT_TYPE_session_ticket)
{