Blame SOURCES/openssl-fips-0.9.8e-cve-2012-2110.patch

c4366c
diff -up openssl-fips-0.9.8e/crypto/asn1/a_d2i_fp.c.biobuf openssl-fips-0.9.8e/crypto/asn1/a_d2i_fp.c
c4366c
--- openssl-fips-0.9.8e/crypto/asn1/a_d2i_fp.c.biobuf	2005-05-09 02:27:32.000000000 +0200
c4366c
+++ openssl-fips-0.9.8e/crypto/asn1/a_d2i_fp.c	2012-04-23 15:07:40.813957295 +0200
c4366c
@@ -57,6 +57,7 @@
c4366c
  */
c4366c
 
c4366c
 #include <stdio.h>
c4366c
+#include <limits.h>
c4366c
 #include "cryptlib.h"
c4366c
 #include <openssl/buffer.h>
c4366c
 #include <openssl/asn1_mac.h>
c4366c
@@ -143,17 +144,11 @@ static int asn1_d2i_read_bio(BIO *in, BU
c4366c
 	BUF_MEM *b;
c4366c
 	unsigned char *p;
c4366c
 	int i;
c4366c
-	int ret=-1;
c4366c
 	ASN1_const_CTX c;
c4366c
-	int want=HEADER_SIZE;
c4366c
+	size_t want=HEADER_SIZE;
c4366c
 	int eos=0;
c4366c
-#if defined(__GNUC__) && defined(__ia64)
c4366c
-	/* pathetic compiler bug in all known versions as of Nov. 2002 */
c4366c
-	long off=0;
c4366c
-#else
c4366c
-	int off=0;
c4366c
-#endif
c4366c
-	int len=0;
c4366c
+	size_t off=0;
c4366c
+	size_t len=0;
c4366c
 
c4366c
 	b=BUF_MEM_new();
c4366c
 	if (b == NULL)
c4366c
@@ -169,7 +164,7 @@ static int asn1_d2i_read_bio(BIO *in, BU
c4366c
 			{
c4366c
 			want-=(len-off);
c4366c
 
c4366c
-			if (!BUF_MEM_grow_clean(b,len+want))
c4366c
+			if (len + want < len || !BUF_MEM_grow_clean(b,len+want))
c4366c
 				{
c4366c
 				ASN1err(ASN1_F_ASN1_D2I_READ_BIO,ERR_R_MALLOC_FAILURE);
c4366c
 				goto err;
c4366c
@@ -181,7 +176,14 @@ static int asn1_d2i_read_bio(BIO *in, BU
c4366c
 				goto err;
c4366c
 				}
c4366c
 			if (i > 0)
c4366c
+				{
c4366c
+				if (len+i < len)
c4366c
+					{
c4366c
+					ASN1err(ASN1_F_ASN1_D2I_READ_BIO,ASN1_R_TOO_LONG);
c4366c
+					goto err;
c4366c
+					}
c4366c
 				len+=i;
c4366c
+				}
c4366c
 			}
c4366c
 		/* else data already loaded */
c4366c
 
c4366c
@@ -206,6 +208,11 @@ static int asn1_d2i_read_bio(BIO *in, BU
c4366c
 			{
c4366c
 			/* no data body so go round again */
c4366c
 			eos++;
c4366c
+			if (eos < 0)
c4366c
+				{
c4366c
+				ASN1err(ASN1_F_ASN1_D2I_READ_BIO,ASN1_R_HEADER_TOO_LONG);
c4366c
+				goto err;
c4366c
+				}
c4366c
 			want=HEADER_SIZE;
c4366c
 			}
c4366c
 		else if (eos && (c.slen == 0) && (c.tag == V_ASN1_EOC))
c4366c
@@ -220,10 +227,16 @@ static int asn1_d2i_read_bio(BIO *in, BU
c4366c
 		else 
c4366c
 			{
c4366c
 			/* suck in c.slen bytes of data */
c4366c
-			want=(int)c.slen;
c4366c
+			want=c.slen;
c4366c
 			if (want > (len-off))
c4366c
 				{
c4366c
 				want-=(len-off);
c4366c
+				if (want > INT_MAX /* BIO_read takes an int length */ ||
c4366c
+					len+want < len)
c4366c
+						{
c4366c
+						ASN1err(ASN1_F_ASN1_D2I_READ_BIO,ASN1_R_TOO_LONG);
c4366c
+						goto err;
c4366c
+						}
c4366c
 				if (!BUF_MEM_grow_clean(b,len+want))
c4366c
 					{
c4366c
 					ASN1err(ASN1_F_ASN1_D2I_READ_BIO,ERR_R_MALLOC_FAILURE);
c4366c
@@ -238,11 +251,18 @@ static int asn1_d2i_read_bio(BIO *in, BU
c4366c
 						    ASN1_R_NOT_ENOUGH_DATA);
c4366c
 						goto err;
c4366c
 						}
c4366c
+					/* This can't overflow because
c4366c
+					 * |len+want| didn't overflow. */
c4366c
 					len+=i;
c4366c
-					want -= i;
c4366c
+					want-=i;
c4366c
 					}
c4366c
 				}
c4366c
-			off+=(int)c.slen;
c4366c
+			if (off + c.slen < off)
c4366c
+				{
c4366c
+				ASN1err(ASN1_F_ASN1_D2I_READ_BIO,ASN1_R_TOO_LONG);
c4366c
+				goto err;
c4366c
+				}
c4366c
+			off+=c.slen;
c4366c
 			if (eos <= 0)
c4366c
 				{
c4366c
 				break;
c4366c
@@ -252,9 +272,15 @@ static int asn1_d2i_read_bio(BIO *in, BU
c4366c
 			}
c4366c
 		}
c4366c
 
c4366c
+	if (off > INT_MAX)
c4366c
+		{
c4366c
+		ASN1err(ASN1_F_ASN1_D2I_READ_BIO,ASN1_R_TOO_LONG);
c4366c
+		goto err;
c4366c
+		}
c4366c
+
c4366c
 	*pb = b;
c4366c
 	return off;
c4366c
 err:
c4366c
 	if (b != NULL) BUF_MEM_free(b);
c4366c
-	return(ret);
c4366c
+	return -1;
c4366c
 	}
c4366c
diff -up openssl-fips-0.9.8e/crypto/buffer/buffer.c.biobuf openssl-fips-0.9.8e/crypto/buffer/buffer.c
c4366c
--- openssl-fips-0.9.8e/crypto/buffer/buffer.c.biobuf	2007-03-22 01:37:55.000000000 +0100
c4366c
+++ openssl-fips-0.9.8e/crypto/buffer/buffer.c	2012-04-23 16:01:56.083684024 +0200
c4366c
@@ -60,6 +60,11 @@
c4366c
 #include "cryptlib.h"
c4366c
 #include <openssl/buffer.h>
c4366c
 
c4366c
+/* LIMIT_BEFORE_EXPANSION is the maximum n such that (n+3)/3*4 < 2**31. That
c4366c
+ * function is applied in several functions in this file and this limit ensures
c4366c
+ * that the result fits in an int. */
c4366c
+#define LIMIT_BEFORE_EXPANSION 0x5ffffffc
c4366c
+
c4366c
 BUF_MEM *BUF_MEM_new(void)
c4366c
 	{
c4366c
 	BUF_MEM *ret;
c4366c
@@ -94,6 +99,11 @@ int BUF_MEM_grow(BUF_MEM *str, int len)
c4366c
 	char *ret;
c4366c
 	unsigned int n;
c4366c
 
c4366c
+	if (len < 0)
c4366c
+		{
c4366c
+		BUFerr(BUF_F_BUF_MEM_GROW,ERR_R_MALLOC_FAILURE);
c4366c
+		return 0;
c4366c
+		}
c4366c
 	if (str->length >= len)
c4366c
 		{
c4366c
 		str->length=len;
c4366c
@@ -105,6 +115,12 @@ int BUF_MEM_grow(BUF_MEM *str, int len)
c4366c
 		str->length=len;
c4366c
 		return(len);
c4366c
 		}
c4366c
+	/* This limit is sufficient to ensure (len+3)/3*4 < 2**31 */
c4366c
+	if (len > LIMIT_BEFORE_EXPANSION)
c4366c
+		{
c4366c
+		BUFerr(BUF_F_BUF_MEM_GROW,ERR_R_MALLOC_FAILURE);
c4366c
+		return 0;
c4366c
+		}
c4366c
 	n=(len+3)/3*4;
c4366c
 	if (str->data == NULL)
c4366c
 		ret=OPENSSL_malloc(n);
c4366c
@@ -130,6 +146,11 @@ int BUF_MEM_grow_clean(BUF_MEM *str, int
c4366c
 	char *ret;
c4366c
 	unsigned int n;
c4366c
 
c4366c
+	if (len < 0)
c4366c
+		{
c4366c
+		BUFerr(BUF_F_BUF_MEM_GROW_CLEAN,ERR_R_MALLOC_FAILURE);
c4366c
+		return 0;
c4366c
+		}
c4366c
 	if (str->length >= len)
c4366c
 		{
c4366c
 		memset(&str->data[len],0,str->length-len);
c4366c
@@ -142,6 +163,12 @@ int BUF_MEM_grow_clean(BUF_MEM *str, int
c4366c
 		str->length=len;
c4366c
 		return(len);
c4366c
 		}
c4366c
+	/* This limit is sufficient to ensure (len+3)/3*4 < 2**31 */
c4366c
+	if (len > LIMIT_BEFORE_EXPANSION)
c4366c
+		{
c4366c
+		BUFerr(BUF_F_BUF_MEM_GROW_CLEAN,ERR_R_MALLOC_FAILURE);
c4366c
+		return 0;
c4366c
+		}
c4366c
 	n=(len+3)/3*4;
c4366c
 	if (str->data == NULL)
c4366c
 		ret=OPENSSL_malloc(n);
c4366c
diff -up openssl-fips-0.9.8e/crypto/mem.c.biobuf openssl-fips-0.9.8e/crypto/mem.c
c4366c
--- openssl-fips-0.9.8e/crypto/mem.c.biobuf	2007-03-22 01:37:46.000000000 +0100
c4366c
+++ openssl-fips-0.9.8e/crypto/mem.c	2012-04-23 15:07:40.814957317 +0200
c4366c
@@ -372,6 +372,10 @@ void *CRYPTO_realloc_clean(void *str, in
c4366c
 
c4366c
 	if (num <= 0) return NULL;
c4366c
 
c4366c
+	/* We don't support shrinking the buffer. Note the memcpy that copies
c4366c
+	 * |old_len| bytes to the new buffer, below. */
c4366c
+	if (num < old_len) return NULL;
c4366c
+
c4366c
 	if (realloc_debug_func != NULL)
c4366c
 		realloc_debug_func(str, NULL, num, file, line, 0);
c4366c
 	ret=malloc_ex_func(num,file,line);