1 |
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 |
2 |
--- openssl-fips-0.9.8e/crypto/asn1/a_d2i_fp.c.biobuf 2005-05-09 02:27:32.000000000 +0200 |
3 |
+++ openssl-fips-0.9.8e/crypto/asn1/a_d2i_fp.c 2012-04-23 15:07:40.813957295 +0200 |
4 |
@@ -57,6 +57,7 @@ |
5 |
*/ |
6 |
|
7 |
#include <stdio.h> |
8 |
+#include <limits.h> |
9 |
#include "cryptlib.h" |
10 |
#include <openssl/buffer.h> |
11 |
#include <openssl/asn1_mac.h> |
12 |
@@ -143,17 +144,11 @@ static int asn1_d2i_read_bio(BIO *in, BU |
13 |
BUF_MEM *b; |
14 |
unsigned char *p; |
15 |
int i; |
16 |
- int ret=-1; |
17 |
ASN1_const_CTX c; |
18 |
- int want=HEADER_SIZE; |
19 |
+ size_t want=HEADER_SIZE; |
20 |
int eos=0; |
21 |
-#if defined(__GNUC__) && defined(__ia64) |
22 |
- /* pathetic compiler bug in all known versions as of Nov. 2002 */ |
23 |
- long off=0; |
24 |
-#else |
25 |
- int off=0; |
26 |
-#endif |
27 |
- int len=0; |
28 |
+ size_t off=0; |
29 |
+ size_t len=0; |
30 |
|
31 |
b=BUF_MEM_new(); |
32 |
if (b == NULL) |
33 |
@@ -169,7 +164,7 @@ static int asn1_d2i_read_bio(BIO *in, BU |
34 |
{ |
35 |
want-=(len-off); |
36 |
|
37 |
- if (!BUF_MEM_grow_clean(b,len+want)) |
38 |
+ if (len + want < len || !BUF_MEM_grow_clean(b,len+want)) |
39 |
{ |
40 |
ASN1err(ASN1_F_ASN1_D2I_READ_BIO,ERR_R_MALLOC_FAILURE); |
41 |
goto err; |
42 |
@@ -181,7 +176,14 @@ static int asn1_d2i_read_bio(BIO *in, BU |
43 |
goto err; |
44 |
} |
45 |
if (i > 0) |
46 |
+ { |
47 |
+ if (len+i < len) |
48 |
+ { |
49 |
+ ASN1err(ASN1_F_ASN1_D2I_READ_BIO,ASN1_R_TOO_LONG); |
50 |
+ goto err; |
51 |
+ } |
52 |
len+=i; |
53 |
+ } |
54 |
} |
55 |
/* else data already loaded */ |
56 |
|
57 |
@@ -206,6 +208,11 @@ static int asn1_d2i_read_bio(BIO *in, BU |
58 |
{ |
59 |
/* no data body so go round again */ |
60 |
eos++; |
61 |
+ if (eos < 0) |
62 |
+ { |
63 |
+ ASN1err(ASN1_F_ASN1_D2I_READ_BIO,ASN1_R_HEADER_TOO_LONG); |
64 |
+ goto err; |
65 |
+ } |
66 |
want=HEADER_SIZE; |
67 |
} |
68 |
else if (eos && (c.slen == 0) && (c.tag == V_ASN1_EOC)) |
69 |
@@ -220,10 +227,16 @@ static int asn1_d2i_read_bio(BIO *in, BU |
70 |
else |
71 |
{ |
72 |
/* suck in c.slen bytes of data */ |
73 |
- want=(int)c.slen; |
74 |
+ want=c.slen; |
75 |
if (want > (len-off)) |
76 |
{ |
77 |
want-=(len-off); |
78 |
+ if (want > INT_MAX /* BIO_read takes an int length */ || |
79 |
+ len+want < len) |
80 |
+ { |
81 |
+ ASN1err(ASN1_F_ASN1_D2I_READ_BIO,ASN1_R_TOO_LONG); |
82 |
+ goto err; |
83 |
+ } |
84 |
if (!BUF_MEM_grow_clean(b,len+want)) |
85 |
{ |
86 |
ASN1err(ASN1_F_ASN1_D2I_READ_BIO,ERR_R_MALLOC_FAILURE); |
87 |
@@ -238,11 +251,18 @@ static int asn1_d2i_read_bio(BIO *in, BU |
88 |
ASN1_R_NOT_ENOUGH_DATA); |
89 |
goto err; |
90 |
} |
91 |
+ /* This can't overflow because |
92 |
+ * |len+want| didn't overflow. */ |
93 |
len+=i; |
94 |
- want -= i; |
95 |
+ want-=i; |
96 |
} |
97 |
} |
98 |
- off+=(int)c.slen; |
99 |
+ if (off + c.slen < off) |
100 |
+ { |
101 |
+ ASN1err(ASN1_F_ASN1_D2I_READ_BIO,ASN1_R_TOO_LONG); |
102 |
+ goto err; |
103 |
+ } |
104 |
+ off+=c.slen; |
105 |
if (eos <= 0) |
106 |
{ |
107 |
break; |
108 |
@@ -252,9 +272,15 @@ static int asn1_d2i_read_bio(BIO *in, BU |
109 |
} |
110 |
} |
111 |
|
112 |
+ if (off > INT_MAX) |
113 |
+ { |
114 |
+ ASN1err(ASN1_F_ASN1_D2I_READ_BIO,ASN1_R_TOO_LONG); |
115 |
+ goto err; |
116 |
+ } |
117 |
+ |
118 |
*pb = b; |
119 |
return off; |
120 |
err: |
121 |
if (b != NULL) BUF_MEM_free(b); |
122 |
- return(ret); |
123 |
+ return -1; |
124 |
} |
125 |
diff -up openssl-fips-0.9.8e/crypto/buffer/buffer.c.biobuf openssl-fips-0.9.8e/crypto/buffer/buffer.c |
126 |
--- openssl-fips-0.9.8e/crypto/buffer/buffer.c.biobuf 2007-03-22 01:37:55.000000000 +0100 |
127 |
+++ openssl-fips-0.9.8e/crypto/buffer/buffer.c 2012-04-23 16:01:56.083684024 +0200 |
128 |
@@ -60,6 +60,11 @@ |
129 |
#include "cryptlib.h" |
130 |
#include <openssl/buffer.h> |
131 |
|
132 |
+/* LIMIT_BEFORE_EXPANSION is the maximum n such that (n+3)/3*4 < 2**31. That |
133 |
+ * function is applied in several functions in this file and this limit ensures |
134 |
+ * that the result fits in an int. */ |
135 |
+#define LIMIT_BEFORE_EXPANSION 0x5ffffffc |
136 |
+ |
137 |
BUF_MEM *BUF_MEM_new(void) |
138 |
{ |
139 |
BUF_MEM *ret; |
140 |
@@ -94,6 +99,11 @@ int BUF_MEM_grow(BUF_MEM *str, int len) |
141 |
char *ret; |
142 |
unsigned int n; |
143 |
|
144 |
+ if (len < 0) |
145 |
+ { |
146 |
+ BUFerr(BUF_F_BUF_MEM_GROW,ERR_R_MALLOC_FAILURE); |
147 |
+ return 0; |
148 |
+ } |
149 |
if (str->length >= len) |
150 |
{ |
151 |
str->length=len; |
152 |
@@ -105,6 +115,12 @@ int BUF_MEM_grow(BUF_MEM *str, int len) |
153 |
str->length=len; |
154 |
return(len); |
155 |
} |
156 |
+ /* This limit is sufficient to ensure (len+3)/3*4 < 2**31 */ |
157 |
+ if (len > LIMIT_BEFORE_EXPANSION) |
158 |
+ { |
159 |
+ BUFerr(BUF_F_BUF_MEM_GROW,ERR_R_MALLOC_FAILURE); |
160 |
+ return 0; |
161 |
+ } |
162 |
n=(len+3)/3*4; |
163 |
if (str->data == NULL) |
164 |
ret=OPENSSL_malloc(n); |
165 |
@@ -130,6 +146,11 @@ int BUF_MEM_grow_clean(BUF_MEM *str, int |
166 |
char *ret; |
167 |
unsigned int n; |
168 |
|
169 |
+ if (len < 0) |
170 |
+ { |
171 |
+ BUFerr(BUF_F_BUF_MEM_GROW_CLEAN,ERR_R_MALLOC_FAILURE); |
172 |
+ return 0; |
173 |
+ } |
174 |
if (str->length >= len) |
175 |
{ |
176 |
memset(&str->data[len],0,str->length-len); |
177 |
@@ -142,6 +163,12 @@ int BUF_MEM_grow_clean(BUF_MEM *str, int |
178 |
str->length=len; |
179 |
return(len); |
180 |
} |
181 |
+ /* This limit is sufficient to ensure (len+3)/3*4 < 2**31 */ |
182 |
+ if (len > LIMIT_BEFORE_EXPANSION) |
183 |
+ { |
184 |
+ BUFerr(BUF_F_BUF_MEM_GROW_CLEAN,ERR_R_MALLOC_FAILURE); |
185 |
+ return 0; |
186 |
+ } |
187 |
n=(len+3)/3*4; |
188 |
if (str->data == NULL) |
189 |
ret=OPENSSL_malloc(n); |
190 |
diff -up openssl-fips-0.9.8e/crypto/mem.c.biobuf openssl-fips-0.9.8e/crypto/mem.c |
191 |
--- openssl-fips-0.9.8e/crypto/mem.c.biobuf 2007-03-22 01:37:46.000000000 +0100 |
192 |
+++ openssl-fips-0.9.8e/crypto/mem.c 2012-04-23 15:07:40.814957317 +0200 |
193 |
@@ -372,6 +372,10 @@ void *CRYPTO_realloc_clean(void *str, in |
194 |
|
195 |
if (num <= 0) return NULL; |
196 |
|
197 |
+ /* We don't support shrinking the buffer. Note the memcpy that copies |
198 |
+ * |old_len| bytes to the new buffer, below. */ |
199 |
+ if (num < old_len) return NULL; |
200 |
+ |
201 |
if (realloc_debug_func != NULL) |
202 |
realloc_debug_func(str, NULL, num, file, line, 0); |
203 |
ret=malloc_ex_func(num,file,line); |