| --- openssl/crypto/asn1/a_d2i_fp.c 2011-02-01 06:46:34.000000000 -0800 |
| +++ openssl/crypto/asn1/a_d2i_fp.c 2012-04-02 10:54:56.000000000 -0700 |
| @@ -57,6 +57,7 @@ |
| */ |
| |
| #include <stdio.h> |
| +#include <limits.h> |
| #include "cryptlib.h" |
| #include <openssl/buffer.h> |
| #include <openssl/asn1_mac.h> |
| @@ -143,17 +144,11 @@ |
| BUF_MEM *b; |
| unsigned char *p; |
| int i; |
| - int ret=-1; |
| ASN1_const_CTX c; |
| - int want=HEADER_SIZE; |
| + size_t want=HEADER_SIZE; |
| int eos=0; |
| -#if defined(__GNUC__) && defined(__ia64) |
| - /* pathetic compiler bug in all known versions as of Nov. 2002 */ |
| - long off=0; |
| -#else |
| - int off=0; |
| -#endif |
| - int len=0; |
| + size_t off=0; |
| + size_t len=0; |
| |
| b=BUF_MEM_new(); |
| if (b == NULL) |
| @@ -169,7 +164,7 @@ |
| { |
| want-=(len-off); |
| |
| - if (!BUF_MEM_grow_clean(b,len+want)) |
| + if (len+want < len || !BUF_MEM_grow_clean(b,len+want)) |
| { |
| ASN1err(ASN1_F_ASN1_D2I_READ_BIO,ERR_R_MALLOC_FAILURE); |
| goto err; |
| @@ -181,7 +176,14 @@ |
| goto err; |
| } |
| if (i > 0) |
| + { |
| + if (len+i < len) |
| + { |
| + ASN1err(ASN1_F_ASN1_D2I_READ_BIO,ASN1_R_TOO_LONG); |
| + goto err; |
| + } |
| len+=i; |
| + } |
| } |
| /* else data already loaded */ |
| |
| @@ -206,6 +208,11 @@ |
| { |
| /* no data body so go round again */ |
| eos++; |
| + if (eos < 0) |
| + { |
| + ASN1err(ASN1_F_ASN1_D2I_READ_BIO,ASN1_R_HEADER_TOO_LONG); |
| + goto err; |
| + } |
| want=HEADER_SIZE; |
| } |
| else if (eos && (c.slen == 0) && (c.tag == V_ASN1_EOC)) |
| @@ -220,10 +227,16 @@ |
| else |
| { |
| /* suck in c.slen bytes of data */ |
| - want=(int)c.slen; |
| + want=c.slen; |
| if (want > (len-off)) |
| { |
| want-=(len-off); |
| + if (want > INT_MAX /* BIO_read takes an int length */ || |
| + len+want < len) |
| + { |
| + ASN1err(ASN1_F_ASN1_D2I_READ_BIO,ASN1_R_TOO_LONG); |
| + goto err; |
| + } |
| if (!BUF_MEM_grow_clean(b,len+want)) |
| { |
| ASN1err(ASN1_F_ASN1_D2I_READ_BIO,ERR_R_MALLOC_FAILURE); |
| @@ -238,11 +251,18 @@ |
| ASN1_R_NOT_ENOUGH_DATA); |
| goto err; |
| } |
| + /* This can't overflow because |
| + * |len+want| didn't overflow. */ |
| len+=i; |
| - want -= i; |
| + want-=i; |
| } |
| } |
| - off+=(int)c.slen; |
| + if (off + c.slen < off) |
| + { |
| + ASN1err(ASN1_F_ASN1_D2I_READ_BIO,ASN1_R_TOO_LONG); |
| + goto err; |
| + } |
| + off+=c.slen; |
| if (eos <= 0) |
| { |
| break; |
| @@ -252,9 +272,14 @@ |
| } |
| } |
| |
| + if (off > INT_MAX) |
| + { |
| + ASN1err(ASN1_F_ASN1_D2I_READ_BIO,ASN1_R_TOO_LONG); |
| + goto err; |
| + } |
| *pb = b; |
| return off; |
| err: |
| if (b != NULL) BUF_MEM_free(b); |
| - return(ret); |
| + return -1; |
| } |
| --- openssl/crypto/buffer/buffer.c 2011-02-01 06:46:34.000000000 -0800 |
| +++ openssl/crypto/buffer/buffer.c 2012-04-02 10:54:56.000000000 -0700 |
| @@ -60,6 +60,11 @@ |
| #include "cryptlib.h" |
| #include <openssl/buffer.h> |
| |
| +/* LIMIT_BEFORE_EXPANSION is the maximum n such that (n+3)/3*4 < 2**31. That |
| + * function is applied in several functions in this file and this limit ensures |
| + * that the result fits in an int. */ |
| +#define LIMIT_BEFORE_EXPANSION 0x5ffffffc |
| + |
| BUF_MEM *BUF_MEM_new(void) |
| { |
| BUF_MEM *ret; |
| @@ -105,6 +110,12 @@ |
| str->length=len; |
| return(len); |
| } |
| + /* This limit is sufficient to ensure (len+3)/3*4 < 2**31 */ |
| + if (len > LIMIT_BEFORE_EXPANSION) |
| + { |
| + BUFerr(BUF_F_BUF_MEM_GROW,ERR_R_MALLOC_FAILURE); |
| + return 0; |
| + } |
| n=(len+3)/3*4; |
| if (str->data == NULL) |
| ret=OPENSSL_malloc(n); |
| @@ -142,6 +153,12 @@ |
| str->length=len; |
| return(len); |
| } |
| + /* This limit is sufficient to ensure (len+3)/3*4 < 2**31 */ |
| + if (len > LIMIT_BEFORE_EXPANSION) |
| + { |
| + BUFerr(BUF_F_BUF_MEM_GROW,ERR_R_MALLOC_FAILURE); |
| + return 0; |
| + } |
| n=(len+3)/3*4; |
| if (str->data == NULL) |
| ret=OPENSSL_malloc(n); |
| --- openssl/crypto/mem.c 2011-02-02 16:53:02.000000000 -0800 |
| +++ openssl/crypto/mem.c 2012-04-02 10:54:56.000000000 -0700 |
| @@ -334,6 +334,10 @@ |
| |
| if (num <= 0) return NULL; |
| |
| + /* We don't support shrinking the buffer. Note the memcpy that copies |
| + * |old_len| bytes to the new buffer, below. */ |
| + if (num < old_len) return NULL; |
| + |
| if (realloc_debug_func != NULL) |
| realloc_debug_func(str, NULL, num, file, line, 0); |
| ret=malloc_ex_func(num,file,line); |