File openssl-CVE-2016-2177.patch of Package openssl.4105

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-1.0.1i/ssl/s3_srvr.c
===================================================================
--- openssl-1.0.1i.orig/ssl/s3_srvr.c	2016-08-08 16:49:55.399925661 +0200
+++ openssl-1.0.1i/ssl/s3_srvr.c	2016-08-08 16:49:56.387941032 +0200
@@ -1080,7 +1080,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;
@@ -1147,7 +1147,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-1.0.1i/ssl/t1_lib.c
===================================================================
--- openssl-1.0.1i.orig/ssl/t1_lib.c	2016-08-08 16:49:55.399925661 +0200
+++ openssl-1.0.1i/ssl/t1_lib.c	2016-08-08 17:09:11.541935618 +0200
@@ -937,11 +937,13 @@ static void ssl_check_for_safari(SSL *s,
 		0x02, 0x03,  /* SHA-1/ECDSA */
 	};
 
-	if (data >= (d+n-2))
+	const unsigned char *limit = d + n;
+
+	if (limit - data <= 2)
 		return;
 	data += 2;
 
-	if (data > (d+n-4))
+	if (limit - data < 4)
 		return;
 	n2s(data,type);
 	n2s(data,size);
@@ -949,7 +951,7 @@ static void ssl_check_for_safari(SSL *s,
 	if (type != TLSEXT_TYPE_server_name)
 		return;
 
-	if (data+size > d+n)
+	if (d+n-data < size)
 		return;
 	data += size;
 
@@ -958,7 +960,7 @@ static void ssl_check_for_safari(SSL *s,
 		const size_t len1 = sizeof(kSafariExtensionsBlock);
 		const size_t len2 = sizeof(kSafariTLS12ExtensionsBlock);
 
-		if (data + len1 + len2 != d+n)
+		if (limit - data != (int)(len1 + len2))
 			return;
 		if (memcmp(data, kSafariExtensionsBlock, len1) != 0)
 			return;
@@ -969,7 +971,7 @@ static void ssl_check_for_safari(SSL *s,
 		{
 		const size_t len = sizeof(kSafariExtensionsBlock);
 
-		if (data + len != d+n)
+		if (limit - data != (int)(len))
 			return;
 		if (memcmp(data, kSafariExtensionsBlock, len) != 0)
 			return;
@@ -987,6 +989,7 @@ int ssl_parse_clienthello_tlsext(SSL *s,
 	unsigned char *data = *p;
 	int renegotiate_seen = 0;
 	int sigalg_seen = 0;
+	const unsigned char *limit = d + n;
 
 	s->servername_done = 0;
 	s->tlsext_status_type = -1;
@@ -1004,20 +1007,24 @@ int ssl_parse_clienthello_tlsext(SSL *s,
 		ssl_check_for_safari(s, data, d, n);
 #endif /* !OPENSSL_NO_EC */
 
-	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 0
 		fprintf(stderr,"Received extension type %d size %d\n",type,size);
 #endif
@@ -1478,6 +1485,9 @@ int ssl_parse_clienthello_tlsext(SSL *s,
 		}
 
 	return 1;
+err:
+	*al = SSL_AD_DECODE_ERROR;
+	return 0;
 	}
 
 #ifndef OPENSSL_NO_NEXTPROTONEG
@@ -1518,22 +1528,22 @@ int ssl_parse_serverhello_tlsext(SSL *s,
 	                       SSL_TLSEXT_HB_DONT_SEND_REQUESTS);
 #endif
 
-	if (data >= (d+n-2))
+	if ((d + n) - data <= 2)
 		goto ri_check;
 
 	n2s(data,length);
-	if (data+length != d+n)
+	if ((d + n) - data != length)
 		{
 		*al = SSL_AD_DECODE_ERROR;
 		return 0;
 		}
 
-	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)
@@ -2220,30 +2230,32 @@ int tls1_process_ticket(SSL *s, unsigned
 	if (s->version == DTLS1_VERSION || s->version == DTLS1_BAD_VER)
 		{
 		i = *(p++);
-		p+= i;
-		if (p >= limit)
+		if (limit - p <= i)
 			return -1;
+		p += i;
 		}
 	/* 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 0;
 	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 0;
 		if (type == TLSEXT_TYPE_session_ticket)
 			{
openSUSE Build Service is sponsored by