summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authordjm <>2012-04-22 01:39:23 +0000
committerdjm <>2012-04-22 01:39:23 +0000
commit3075bc4e6f1b9e7974c187bfddab4998fe5d999d (patch)
treee5d553520471124ee44fa63fc973f56df1af9dc8
parentd57e27e9b660f0127442966f4b388e83caefeafd (diff)
downloadopenbsd-OPENBSD_5_1.tar.gz
openbsd-OPENBSD_5_1.tar.bz2
openbsd-OPENBSD_5_1.zip
mem.c revision 1.14 date: 2012/04/19 22:57:38; author: djm; state: Exp; lines: +4 -0 cherrypick fix for CVE-2012-2110: libcrypto ASN.1 parsing heap overflow ok miod@ deraadt@ asn1/a_d2i_fp.c revision 1.6 date: 2012/04/19 22:57:38; author: djm; state: Exp; lines: +40 -14 cherrypick fix for CVE-2012-2110: libcrypto ASN.1 parsing heap overflow ok miod@ deraadt@ buffer/buffer.c revision 1.9 date: 2012/04/19 22:57:38; author: djm; state: Exp; lines: +17 -0 cherrypick fix for CVE-2012-2110: libcrypto ASN.1 parsing heap overflow ok miod@ deraadt@
-rw-r--r--src/lib/libcrypto/mem.c4
-rw-r--r--src/lib/libssl/src/crypto/asn1/a_d2i_fp.c54
-rw-r--r--src/lib/libssl/src/crypto/buffer/buffer.c17
-rw-r--r--src/lib/libssl/src/crypto/mem.c4
4 files changed, 65 insertions, 14 deletions
diff --git a/src/lib/libcrypto/mem.c b/src/lib/libcrypto/mem.c
index 8f06d190a1..9ecb8d26b1 100644
--- a/src/lib/libcrypto/mem.c
+++ b/src/lib/libcrypto/mem.c
@@ -362,6 +362,10 @@ void *CRYPTO_realloc_clean(void *str, int old_len, int num, const char *file,
362 362
363 if (num <= 0) return NULL; 363 if (num <= 0) return NULL;
364 364
365 /* We don't support shrinking the buffer. Note the memcpy that copies
366 * |old_len| bytes to the new buffer, below. */
367 if (num < old_len) return NULL;
368
365 if (realloc_debug_func != NULL) 369 if (realloc_debug_func != NULL)
366 realloc_debug_func(str, NULL, num, file, line, 0); 370 realloc_debug_func(str, NULL, num, file, line, 0);
367 ret=malloc_ex_func(num,file,line); 371 ret=malloc_ex_func(num,file,line);
diff --git a/src/lib/libssl/src/crypto/asn1/a_d2i_fp.c b/src/lib/libssl/src/crypto/asn1/a_d2i_fp.c
index ece40bc4c0..52b2ebdb63 100644
--- a/src/lib/libssl/src/crypto/asn1/a_d2i_fp.c
+++ b/src/lib/libssl/src/crypto/asn1/a_d2i_fp.c
@@ -57,6 +57,7 @@
57 */ 57 */
58 58
59#include <stdio.h> 59#include <stdio.h>
60#include <limits.h>
60#include "cryptlib.h" 61#include "cryptlib.h"
61#include <openssl/buffer.h> 62#include <openssl/buffer.h>
62#include <openssl/asn1_mac.h> 63#include <openssl/asn1_mac.h>
@@ -143,17 +144,11 @@ static int asn1_d2i_read_bio(BIO *in, BUF_MEM **pb)
143 BUF_MEM *b; 144 BUF_MEM *b;
144 unsigned char *p; 145 unsigned char *p;
145 int i; 146 int i;
146 int ret=-1;
147 ASN1_const_CTX c; 147 ASN1_const_CTX c;
148 int want=HEADER_SIZE; 148 size_t want=HEADER_SIZE;
149 int eos=0; 149 int eos=0;
150#if defined(__GNUC__) && defined(__ia64) 150 size_t off=0;
151 /* pathetic compiler bug in all known versions as of Nov. 2002 */ 151 size_t len=0;
152 long off=0;
153#else
154 int off=0;
155#endif
156 int len=0;
157 152
158 b=BUF_MEM_new(); 153 b=BUF_MEM_new();
159 if (b == NULL) 154 if (b == NULL)
@@ -169,7 +164,7 @@ static int asn1_d2i_read_bio(BIO *in, BUF_MEM **pb)
169 { 164 {
170 want-=(len-off); 165 want-=(len-off);
171 166
172 if (!BUF_MEM_grow_clean(b,len+want)) 167 if (len + want < len || !BUF_MEM_grow_clean(b,len+want))
173 { 168 {
174 ASN1err(ASN1_F_ASN1_D2I_READ_BIO,ERR_R_MALLOC_FAILURE); 169 ASN1err(ASN1_F_ASN1_D2I_READ_BIO,ERR_R_MALLOC_FAILURE);
175 goto err; 170 goto err;
@@ -181,7 +176,14 @@ static int asn1_d2i_read_bio(BIO *in, BUF_MEM **pb)
181 goto err; 176 goto err;
182 } 177 }
183 if (i > 0) 178 if (i > 0)
179 {
180 if (len+i < len)
181 {
182 ASN1err(ASN1_F_ASN1_D2I_READ_BIO,ASN1_R_TOO_LONG);
183 goto err;
184 }
184 len+=i; 185 len+=i;
186 }
185 } 187 }
186 /* else data already loaded */ 188 /* else data already loaded */
187 189
@@ -206,6 +208,11 @@ static int asn1_d2i_read_bio(BIO *in, BUF_MEM **pb)
206 { 208 {
207 /* no data body so go round again */ 209 /* no data body so go round again */
208 eos++; 210 eos++;
211 if (eos < 0)
212 {
213 ASN1err(ASN1_F_ASN1_D2I_READ_BIO,ASN1_R_HEADER_TOO_LONG);
214 goto err;
215 }
209 want=HEADER_SIZE; 216 want=HEADER_SIZE;
210 } 217 }
211 else if (eos && (c.slen == 0) && (c.tag == V_ASN1_EOC)) 218 else if (eos && (c.slen == 0) && (c.tag == V_ASN1_EOC))
@@ -220,10 +227,16 @@ static int asn1_d2i_read_bio(BIO *in, BUF_MEM **pb)
220 else 227 else
221 { 228 {
222 /* suck in c.slen bytes of data */ 229 /* suck in c.slen bytes of data */
223 want=(int)c.slen; 230 want=c.slen;
224 if (want > (len-off)) 231 if (want > (len-off))
225 { 232 {
226 want-=(len-off); 233 want-=(len-off);
234 if (want > INT_MAX /* BIO_read takes an int length */ ||
235 len+want < len)
236 {
237 ASN1err(ASN1_F_ASN1_D2I_READ_BIO,ASN1_R_TOO_LONG);
238 goto err;
239 }
227 if (!BUF_MEM_grow_clean(b,len+want)) 240 if (!BUF_MEM_grow_clean(b,len+want))
228 { 241 {
229 ASN1err(ASN1_F_ASN1_D2I_READ_BIO,ERR_R_MALLOC_FAILURE); 242 ASN1err(ASN1_F_ASN1_D2I_READ_BIO,ERR_R_MALLOC_FAILURE);
@@ -238,11 +251,18 @@ static int asn1_d2i_read_bio(BIO *in, BUF_MEM **pb)
238 ASN1_R_NOT_ENOUGH_DATA); 251 ASN1_R_NOT_ENOUGH_DATA);
239 goto err; 252 goto err;
240 } 253 }
254 /* This can't overflow because
255 * |len+want| didn't overflow. */
241 len+=i; 256 len+=i;
242 want -= i; 257 want-=i;
243 } 258 }
244 } 259 }
245 off+=(int)c.slen; 260 if (off + c.slen < off)
261 {
262 ASN1err(ASN1_F_ASN1_D2I_READ_BIO,ASN1_R_TOO_LONG);
263 goto err;
264 }
265 off+=c.slen;
246 if (eos <= 0) 266 if (eos <= 0)
247 { 267 {
248 break; 268 break;
@@ -252,9 +272,15 @@ static int asn1_d2i_read_bio(BIO *in, BUF_MEM **pb)
252 } 272 }
253 } 273 }
254 274
275 if (off > INT_MAX)
276 {
277 ASN1err(ASN1_F_ASN1_D2I_READ_BIO,ASN1_R_TOO_LONG);
278 goto err;
279 }
280
255 *pb = b; 281 *pb = b;
256 return off; 282 return off;
257err: 283err:
258 if (b != NULL) BUF_MEM_free(b); 284 if (b != NULL) BUF_MEM_free(b);
259 return(ret); 285 return -1;
260 } 286 }
diff --git a/src/lib/libssl/src/crypto/buffer/buffer.c b/src/lib/libssl/src/crypto/buffer/buffer.c
index 620ea8d536..bc803ab6c8 100644
--- a/src/lib/libssl/src/crypto/buffer/buffer.c
+++ b/src/lib/libssl/src/crypto/buffer/buffer.c
@@ -60,6 +60,11 @@
60#include "cryptlib.h" 60#include "cryptlib.h"
61#include <openssl/buffer.h> 61#include <openssl/buffer.h>
62 62
63/* LIMIT_BEFORE_EXPANSION is the maximum n such that (n+3)/3*4 < 2**31. That
64 * function is applied in several functions in this file and this limit ensures
65 * that the result fits in an int. */
66#define LIMIT_BEFORE_EXPANSION 0x5ffffffc
67
63BUF_MEM *BUF_MEM_new(void) 68BUF_MEM *BUF_MEM_new(void)
64 { 69 {
65 BUF_MEM *ret; 70 BUF_MEM *ret;
@@ -105,6 +110,12 @@ int BUF_MEM_grow(BUF_MEM *str, size_t len)
105 str->length=len; 110 str->length=len;
106 return(len); 111 return(len);
107 } 112 }
113 /* This limit is sufficient to ensure (len+3)/3*4 < 2**31 */
114 if (len > LIMIT_BEFORE_EXPANSION)
115 {
116 BUFerr(BUF_F_BUF_MEM_GROW,ERR_R_MALLOC_FAILURE);
117 return 0;
118 }
108 n=(len+3)/3*4; 119 n=(len+3)/3*4;
109 if (str->data == NULL) 120 if (str->data == NULL)
110 ret=OPENSSL_malloc(n); 121 ret=OPENSSL_malloc(n);
@@ -142,6 +153,12 @@ int BUF_MEM_grow_clean(BUF_MEM *str, size_t len)
142 str->length=len; 153 str->length=len;
143 return(len); 154 return(len);
144 } 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 }
145 n=(len+3)/3*4; 162 n=(len+3)/3*4;
146 if (str->data == NULL) 163 if (str->data == NULL)
147 ret=OPENSSL_malloc(n); 164 ret=OPENSSL_malloc(n);
diff --git a/src/lib/libssl/src/crypto/mem.c b/src/lib/libssl/src/crypto/mem.c
index 8f06d190a1..9ecb8d26b1 100644
--- a/src/lib/libssl/src/crypto/mem.c
+++ b/src/lib/libssl/src/crypto/mem.c
@@ -362,6 +362,10 @@ void *CRYPTO_realloc_clean(void *str, int old_len, int num, const char *file,
362 362
363 if (num <= 0) return NULL; 363 if (num <= 0) return NULL;
364 364
365 /* We don't support shrinking the buffer. Note the memcpy that copies
366 * |old_len| bytes to the new buffer, below. */
367 if (num < old_len) return NULL;
368
365 if (realloc_debug_func != NULL) 369 if (realloc_debug_func != NULL)
366 realloc_debug_func(str, NULL, num, file, line, 0); 370 realloc_debug_func(str, NULL, num, file, line, 0);
367 ret=malloc_ex_func(num,file,line); 371 ret=malloc_ex_func(num,file,line);