components/libtasn1/patches/libtasn1-02-cve-2012-1569.patch
author Ann Lai <ann.lai@oracle.com>
Thu, 30 Jul 2015 17:45:10 -0700
changeset 4723 4193dfeb0e39
permissions -rw-r--r--
21124729 Move libtasn1 from Desktop to Userland consolidation 21124720 Move libgpg-error from Desktop to Userland consolidation 21124683 Move libgcrypt from Desktop to Userland consolidation

Source:
Internal

Info:
http://cve.mitre.org/cgi-bin/cvename.cgi?name=CVE-2012-1569
The asn1_get_length_der function in decoding.c in GNU Libtasn1 before 2.12, as 
used in GnuTLS before 3.0.16 and other products, does not properly handle 
certain large length values, which allows remote attackers to cause a denial 
of service (heap memory corruption and application crash) or possibly have 
unspecified other impact via a crafted ASN.1 structure. 

Status:
Need to determine if this patch has been sent upstream.

--- libtasn1-2.8/lib/decoding.c.orig	2012-04-06 12:19:39.986443804 +0800
+++ libtasn1-2.8/lib/decoding.c	2012-04-06 12:38:38.607157322 +0800
@@ -55,12 +55,14 @@
  * Extract a length field from DER data.
  *
  * Returns: Return the decoded length value, or -1 on indefinite
- *   length, or -2 when the value was too big.
+ *   length, or -2 when the value was too big to fit in a int, or -4
+ *   when the decoed length value plus @len would exceed @der_len.
+
  **/
 signed long
 asn1_get_length_der (const unsigned char *der, int der_len, int *len)
 {
-  unsigned long ans;
+  int ans;
   int k, punt;
 
   *len = 0;
@@ -83,7 +85,7 @@
 	  ans = 0;
 	  while (punt <= k && punt < der_len)
 	    {
-	      unsigned long last = ans;
+              int last = ans;
 
 	      ans = ans * 256 + der[punt++];
 	      if (ans < last)
@@ -93,10 +95,13 @@
 	}
       else
 	{			/* indefinite length method */
-	  ans = -1;
+           *len = punt;
+           return -1;
 	}
 
       *len = punt;
+      if (ans + *len < ans || ans + *len > der_len)
+       return -4;
       return ans;
     }
 }