diff options
Diffstat (limited to 'src')
| -rw-r--r-- | src/lib/libcrypto/asn1/a_d2i_fp.c | 54 | ||||
| -rw-r--r-- | src/lib/libcrypto/buffer/buffer.c | 17 | ||||
| -rw-r--r-- | src/lib/libcrypto/mem.c | 4 | ||||
| -rw-r--r-- | src/lib/libssl/src/crypto/asn1/a_d2i_fp.c | 54 | ||||
| -rw-r--r-- | src/lib/libssl/src/crypto/buffer/buffer.c | 17 | ||||
| -rw-r--r-- | src/lib/libssl/src/crypto/mem.c | 4 |
6 files changed, 122 insertions, 28 deletions
diff --git a/src/lib/libcrypto/asn1/a_d2i_fp.c b/src/lib/libcrypto/asn1/a_d2i_fp.c index ece40bc4c0..52b2ebdb63 100644 --- a/src/lib/libcrypto/asn1/a_d2i_fp.c +++ b/src/lib/libcrypto/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; |
| 257 | err: | 283 | err: |
| 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/libcrypto/buffer/buffer.c b/src/lib/libcrypto/buffer/buffer.c index 620ea8d536..bc803ab6c8 100644 --- a/src/lib/libcrypto/buffer/buffer.c +++ b/src/lib/libcrypto/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 | |||
| 63 | BUF_MEM *BUF_MEM_new(void) | 68 | BUF_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/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; |
| 257 | err: | 283 | err: |
| 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 | |||
| 63 | BUF_MEM *BUF_MEM_new(void) | 68 | BUF_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); |
