equal
deleted
inserted
replaced
|
1 Source: |
|
2 Internal |
|
3 |
|
4 Info: |
|
5 http://cve.mitre.org/cgi-bin/cvename.cgi?name=CVE-2012-1569 |
|
6 The asn1_get_length_der function in decoding.c in GNU Libtasn1 before 2.12, as |
|
7 used in GnuTLS before 3.0.16 and other products, does not properly handle |
|
8 certain large length values, which allows remote attackers to cause a denial |
|
9 of service (heap memory corruption and application crash) or possibly have |
|
10 unspecified other impact via a crafted ASN.1 structure. |
|
11 |
|
12 Status: |
|
13 Need to determine if this patch has been sent upstream. |
|
14 |
|
15 --- libtasn1-2.8/lib/decoding.c.orig 2012-04-06 12:19:39.986443804 +0800 |
|
16 +++ libtasn1-2.8/lib/decoding.c 2012-04-06 12:38:38.607157322 +0800 |
|
17 @@ -55,12 +55,14 @@ |
|
18 * Extract a length field from DER data. |
|
19 * |
|
20 * Returns: Return the decoded length value, or -1 on indefinite |
|
21 - * length, or -2 when the value was too big. |
|
22 + * length, or -2 when the value was too big to fit in a int, or -4 |
|
23 + * when the decoed length value plus @len would exceed @der_len. |
|
24 + |
|
25 **/ |
|
26 signed long |
|
27 asn1_get_length_der (const unsigned char *der, int der_len, int *len) |
|
28 { |
|
29 - unsigned long ans; |
|
30 + int ans; |
|
31 int k, punt; |
|
32 |
|
33 *len = 0; |
|
34 @@ -83,7 +85,7 @@ |
|
35 ans = 0; |
|
36 while (punt <= k && punt < der_len) |
|
37 { |
|
38 - unsigned long last = ans; |
|
39 + int last = ans; |
|
40 |
|
41 ans = ans * 256 + der[punt++]; |
|
42 if (ans < last) |
|
43 @@ -93,10 +95,13 @@ |
|
44 } |
|
45 else |
|
46 { /* indefinite length method */ |
|
47 - ans = -1; |
|
48 + *len = punt; |
|
49 + return -1; |
|
50 } |
|
51 |
|
52 *len = punt; |
|
53 + if (ans + *len < ans || ans + *len > der_len) |
|
54 + return -4; |
|
55 return ans; |
|
56 } |
|
57 } |