Blame SOURCES/openssl-1.0.1e-cve-2014-3508.patch

1b2890
From 03b04ddac162c7b7fa3c57eadccc5a583a00d291 Mon Sep 17 00:00:00 2001
1b2890
From: Emilia Kasper <emilia@openssl.org>
1b2890
Date: Wed, 2 Jul 2014 19:02:33 +0200
1b2890
Subject: [PATCH] Fix OID handling:
1b2890
1b2890
- Upon parsing, reject OIDs with invalid base-128 encoding.
1b2890
- Always NUL-terminate the destination buffer in OBJ_obj2txt printing function.
1b2890
1b2890
CVE-2014-3508
1b2890
1b2890
Reviewed-by: Dr. Stephen Henson <steve@openssl.org>
1b2890
Reviewed-by: Kurt Roeckx <kurt@openssl.org>
1b2890
Reviewed-by: Tim Hudson <tjh@openssl.org>
1b2890
---
1b2890
 crypto/asn1/a_object.c   | 30 +++++++++++++++++++++---------
1b2890
 crypto/objects/obj_dat.c | 16 +++++++++-------
1b2890
 2 files changed, 30 insertions(+), 16 deletions(-)
1b2890
1b2890
diff --git a/crypto/asn1/a_object.c b/crypto/asn1/a_object.c
1b2890
index 3978c91..77b2768 100644
1b2890
--- a/crypto/asn1/a_object.c
1b2890
+++ b/crypto/asn1/a_object.c
1b2890
@@ -283,17 +283,29 @@ err:
1b2890
 	ASN1err(ASN1_F_D2I_ASN1_OBJECT,i);
1b2890
 	return(NULL);
1b2890
 }
1b2890
+
1b2890
 ASN1_OBJECT *c2i_ASN1_OBJECT(ASN1_OBJECT **a, const unsigned char **pp,
1b2890
 	     long len)
1b2890
 	{
1b2890
 	ASN1_OBJECT *ret=NULL;
1b2890
 	const unsigned char *p;
1b2890
 	unsigned char *data;
1b2890
-	int i;
1b2890
-	/* Sanity check OID encoding: can't have leading 0x80 in
1b2890
-	 * subidentifiers, see: X.690 8.19.2
1b2890
+	int i, length;
1b2890
+
1b2890
+	/* Sanity check OID encoding.
1b2890
+	 * Need at least one content octet.
1b2890
+	 * MSB must be clear in the last octet.
1b2890
+	 * can't have leading 0x80 in subidentifiers, see: X.690 8.19.2
1b2890
 	 */
1b2890
-	for (i = 0, p = *pp; i < len; i++, p++)
1b2890
+	if (len <= 0 || len > INT_MAX || pp == NULL || (p = *pp) == NULL ||
1b2890
+	    p[len - 1] & 0x80)
1b2890
+		{
1b2890
+		ASN1err(ASN1_F_C2I_ASN1_OBJECT,ASN1_R_INVALID_OBJECT_ENCODING);
1b2890
+		return NULL;
1b2890
+		}
1b2890
+	/* Now 0 < len <= INT_MAX, so the cast is safe. */
1b2890
+	length = (int)len;
1b2890
+	for (i = 0; i < length; i++, p++)
1b2890
 		{
1b2890
 		if (*p == 0x80 && (!i || !(p[-1] & 0x80)))
1b2890
 			{
1b2890
@@ -316,23 +328,23 @@ ASN1_OBJECT *c2i_ASN1_OBJECT(ASN1_OBJECT **a, const unsigned char **pp,
1b2890
 	data = (unsigned char *)ret->data;
1b2890
 	ret->data = NULL;
1b2890
 	/* once detached we can change it */
1b2890
-	if ((data == NULL) || (ret->length < len))
1b2890
+	if ((data == NULL) || (ret->length < length))
1b2890
 		{
1b2890
 		ret->length=0;
1b2890
 		if (data != NULL) OPENSSL_free(data);
1b2890
-		data=(unsigned char *)OPENSSL_malloc(len ? (int)len : 1);
1b2890
+		data=(unsigned char *)OPENSSL_malloc(length);
1b2890
 		if (data == NULL)
1b2890
 			{ i=ERR_R_MALLOC_FAILURE; goto err; }
1b2890
 		ret->flags|=ASN1_OBJECT_FLAG_DYNAMIC_DATA;
1b2890
 		}
1b2890
-	memcpy(data,p,(int)len);
1b2890
+	memcpy(data,p,length);
1b2890
 	/* reattach data to object, after which it remains const */
1b2890
 	ret->data  =data;
1b2890
-	ret->length=(int)len;
1b2890
+	ret->length=length;
1b2890
 	ret->sn=NULL;
1b2890
 	ret->ln=NULL;
1b2890
 	/* ret->flags=ASN1_OBJECT_FLAG_DYNAMIC; we know it is dynamic */
1b2890
-	p+=len;
1b2890
+	p+=length;
1b2890
 
1b2890
 	if (a != NULL) (*a)=ret;
1b2890
 	*pp=p;
1b2890
diff --git a/crypto/objects/obj_dat.c b/crypto/objects/obj_dat.c
1b2890
index 8a342ba..0b2f442 100644
1b2890
--- a/crypto/objects/obj_dat.c
1b2890
+++ b/crypto/objects/obj_dat.c
1b2890
@@ -471,11 +471,12 @@ int OBJ_obj2txt(char *buf, int buf_len, const ASN1_OBJECT *a, int no_name)
1b2890
 	const unsigned char *p;
1b2890
 	char tbuf[DECIMAL_SIZE(i)+DECIMAL_SIZE(l)+2];
1b2890
 
1b2890
-	if ((a == NULL) || (a->data == NULL)) {
1b2890
-		buf[0]='\0';
1b2890
-		return(0);
1b2890
-	}
1b2890
+	/* Ensure that, at every state, |buf| is NUL-terminated. */
1b2890
+	if (buf && buf_len > 0)
1b2890
+		buf[0] = '\0';
1b2890
 
1b2890
+	if ((a == NULL) || (a->data == NULL))
1b2890
+		return(0);
1b2890
 
1b2890
 	if (!no_name && (nid=OBJ_obj2nid(a)) != NID_undef)
1b2890
 		{
1b2890
@@ -554,9 +555,10 @@ int OBJ_obj2txt(char *buf, int buf_len, const ASN1_OBJECT *a, int no_name)
1b2890
 				i=(int)(l/40);
1b2890
 				l-=(long)(i*40);
1b2890
 				}
1b2890
-			if (buf && (buf_len > 0))
1b2890
+			if (buf && (buf_len > 1))
1b2890
 				{
1b2890
 				*buf++ = i + '0';
1b2890
+				*buf = '\0';
1b2890
 				buf_len--;
1b2890
 				}
1b2890
 			n++;
1b2890
@@ -571,9 +573,10 @@ int OBJ_obj2txt(char *buf, int buf_len, const ASN1_OBJECT *a, int no_name)
1b2890
 			i = strlen(bndec);
1b2890
 			if (buf)
1b2890
 				{
1b2890
-				if (buf_len > 0)
1b2890
+				if (buf_len > 1)
1b2890
 					{
1b2890
 					*buf++ = '.';
1b2890
+					*buf = '\0';
1b2890
 					buf_len--;
1b2890
 					}
1b2890
 				BUF_strlcpy(buf,bndec,buf_len);
1b2890
@@ -807,4 +810,3 @@ err:
1b2890
 	OPENSSL_free(buf);
1b2890
 	return(ok);
1b2890
 	}
1b2890
-
1b2890
-- 
1b2890
1.8.3.1
1b2890