From cfad1812508dd8e1baf9c99514c89bda5ab1cd10 Mon Sep 17 00:00:00 2001 From: Andres Amaya Garcia Date: Wed, 18 Jan 2017 13:56:58 +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 2e25e1ca9..545893fb6 100644 --- a/ChangeLog +++ b/ChangeLog @@ -9,6 +9,12 @@ Bugfix * Fix unused variable/function compilation warnings in pem.c and x509_csr.c that are reported when building mbed TLS with a config.h that does not define POLARSSL_PEM_PARSE_C. #562 + * 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 1.3.18 branch 2016-10-17 diff --git a/library/cipher.c b/library/cipher.c index b69d33106..7ea25cfc2 100644 --- a/library/cipher.c +++ b/library/cipher.c @@ -315,9 +315,9 @@ int cipher_update( cipher_context_t *ctx, const unsigned char *input, * If there is not enough data for a full block, cache it. */ if( ( ctx->operation == POLARSSL_DECRYPT && - ilen + ctx->unprocessed_len <= cipher_get_block_size( ctx ) ) || + ilen <= cipher_get_block_size( ctx ) - ctx->unprocessed_len ) || ( ctx->operation == POLARSSL_ENCRYPT && - ilen + ctx->unprocessed_len < cipher_get_block_size( ctx ) ) ) + ilen < 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 24adff08f..7b315e888 100644 --- a/library/ctr_drbg.c +++ b/library/ctr_drbg.c @@ -277,7 +277,8 @@ int ctr_drbg_reseed( ctr_drbg_context *ctx, unsigned char seed[CTR_DRBG_MAX_SEED_INPUT]; size_t seedlen = 0; - if( ctx->entropy_len + len > CTR_DRBG_MAX_SEED_INPUT ) + if( ctx->entropy_len > CTR_DRBG_MAX_SEED_INPUT || + len > CTR_DRBG_MAX_SEED_INPUT - ctx->entropy_len ) return( POLARSSL_ERR_CTR_DRBG_INPUT_TOO_BIG ); memset( seed, 0, CTR_DRBG_MAX_SEED_INPUT ); diff --git a/library/md2.c b/library/md2.c index 110cd95bc..2ac7eba61 100644 --- a/library/md2.c +++ b/library/md2.c @@ -155,7 +155,7 @@ void md2_update( md2_context *ctx, const unsigned char *input, size_t ilen ) while( ilen > 0 ) { - if( ctx->left + ilen > 16 ) + if( ilen > 16 - ctx->left ) fill = 16 - ctx->left; else fill = ilen;