diff options
author | Dr. Stephen Henson <steve@openssl.org> | 2012-04-19 16:19:56 +0000 |
---|---|---|
committer | Dr. Stephen Henson <steve@openssl.org> | 2012-04-19 16:19:56 +0000 |
commit | d9a9d10f4f8d4ed051f2488a90b012dceb7ec885 (patch) | |
tree | dabb138053661e7c2c25d1d5bef7221ef0d5ab04 /crypto/buffer/buffer.c | |
parent | 0d2baadfb4dbd36fa323f3ae57ad309744713572 (diff) |
Check for potentially exploitable overflows in asn1_d2i_read_bio
BUF_mem_grow and BUF_mem_grow_clean. Refuse attempts to shrink buffer
in CRYPTO_realloc_clean.
Thanks to Tavis Ormandy, Google Security Team, for discovering this
issue and to Adam Langley <agl@chromium.org> for fixing it. (CVE-2012-2110)
Diffstat (limited to 'crypto/buffer/buffer.c')
-rw-r--r-- | crypto/buffer/buffer.c | 17 |
1 files changed, 17 insertions, 0 deletions
diff --git a/crypto/buffer/buffer.c b/crypto/buffer/buffer.c index f4b358bbbd..52e65dfdfc 100644 --- a/crypto/buffer/buffer.c +++ b/crypto/buffer/buffer.c @@ -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 @@ int BUF_MEM_grow(BUF_MEM *str, size_t len) 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 @@ int BUF_MEM_grow_clean(BUF_MEM *str, size_t len) 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); |