From ef1329e4afb44ed55a0124b0c820d15e816b4fc4 Mon Sep 17 00:00:00 2001 From: Andres Amaya Garcia Date: Tue, 17 Jan 2017 23:24:02 +0000 Subject: [PATCH] Fix integer overflows in buffer bound checks Fix potential integer overflows in the following functions: * mbedtls_md2_update() to be bypassed and cause * mbedtls_cipher_update() * mbedtls_ctr_drbg_reseed() This overflows would mainly be exploitable in 32-bit systems and could cause buffer bound checks to be bypassed. --- ChangeLog | 6 ++++++ library/cipher.c | 4 ++-- library/ctr_drbg.c | 3 ++- library/md2.c | 2 +- 4 files changed, 11 insertions(+), 4 deletions(-) diff --git a/ChangeLog b/ChangeLog index 4bde6e4f2..5856f416a 100644 --- a/ChangeLog +++ b/ChangeLog @@ -6,6 +6,12 @@ Bugfix * Fixed multiple buffer overreads in mbedtls_pem_read_buffer() when parsing the input string in PEM format to extract the different components. Found by Eyal Itkin. + * Fixed potential arithmetic overflow in mbedtls_ctr_drbg_reseed() that could + cause buffer bound checks to be bypassed. Found by Eyal Itkin. + * Fixed potential arithmetic overflows in mbedtls_cipher_update() that could + cause buffer bound checks to be bypassed. Found by Eyal Itkin. + * Fixed potential arithmetic overflow in mbedtls_md2_update() that could + cause buffer bound checks to be bypassed. Found by Eyal Itkin. = mbed TLS 2.1.6 branch released 2016-10-17 diff --git a/library/cipher.c b/library/cipher.c index ccc068503..1523b07da 100644 --- a/library/cipher.c +++ b/library/cipher.c @@ -300,9 +300,9 @@ int mbedtls_cipher_update( mbedtls_cipher_context_t *ctx, const unsigned char *i * If there is not enough data for a full block, cache it. */ if( ( ctx->operation == MBEDTLS_DECRYPT && - ilen + ctx->unprocessed_len <= mbedtls_cipher_get_block_size( ctx ) ) || + ilen <= mbedtls_cipher_get_block_size( ctx ) - ctx->unprocessed_len ) || ( ctx->operation == MBEDTLS_ENCRYPT && - ilen + ctx->unprocessed_len < mbedtls_cipher_get_block_size( ctx ) ) ) + ilen < mbedtls_cipher_get_block_size( ctx ) - ctx->unprocessed_len ) ) { memcpy( &( ctx->unprocessed_data[ctx->unprocessed_len] ), input, ilen ); diff --git a/library/ctr_drbg.c b/library/ctr_drbg.c index aefddfa1d..646196eb1 100644 --- a/library/ctr_drbg.c +++ b/library/ctr_drbg.c @@ -290,7 +290,8 @@ int mbedtls_ctr_drbg_reseed( mbedtls_ctr_drbg_context *ctx, unsigned char seed[MBEDTLS_CTR_DRBG_MAX_SEED_INPUT]; size_t seedlen = 0; - if( ctx->entropy_len + len > MBEDTLS_CTR_DRBG_MAX_SEED_INPUT ) + if( ctx->entropy_len > MBEDTLS_CTR_DRBG_MAX_SEED_INPUT || + len > MBEDTLS_CTR_DRBG_MAX_SEED_INPUT - ctx->entropy_len ) return( MBEDTLS_ERR_CTR_DRBG_INPUT_TOO_BIG ); memset( seed, 0, MBEDTLS_CTR_DRBG_MAX_SEED_INPUT ); diff --git a/library/md2.c b/library/md2.c index 897670131..95cbcce65 100644 --- a/library/md2.c +++ b/library/md2.c @@ -158,7 +158,7 @@ void mbedtls_md2_update( mbedtls_md2_context *ctx, const unsigned char *input, s while( ilen > 0 ) { - if( ctx->left + ilen > 16 ) + if( ilen > 16 - ctx->left ) fill = 16 - ctx->left; else fill = ilen;