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.
This commit is contained in:
Andres Amaya Garcia 2017-01-17 23:04:22 +00:00 committed by Simon Butcher
parent 1afbac17c5
commit 74ad1c1b22
5 changed files with 17 additions and 5 deletions

View file

@ -1,6 +1,6 @@
mbed TLS ChangeLog (Sorted per branch, date) mbed TLS ChangeLog (Sorted per branch, date)
= mbed TLS x.x.x branch released xxxx-xx-xx = mbed TLS 2.x.x branch released xxxx-xx-xx
Bugfix Bugfix
* Fix the redefinition of macro ssl_set_bio to an undefined symbol * Fix the redefinition of macro ssl_set_bio to an undefined symbol
@ -14,6 +14,12 @@ Bugfix
in RFC 6347 Section 4.3.1. This could cause the execution of the in RFC 6347 Section 4.3.1. This could cause the execution of the
renegotiation routines at unexpected times when the protocol is DTLS. Found renegotiation routines at unexpected times when the protocol is DTLS. Found
by wariua. #687 by wariua. #687
* 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.4.1 branch released 2016-12-13 = mbed TLS 2.4.1 branch released 2016-12-13

View file

@ -326,9 +326,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 there is not enough data for a full block, cache it.
*/ */
if( ( ctx->operation == MBEDTLS_DECRYPT && if( ( ctx->operation == MBEDTLS_DECRYPT &&
ilen + ctx->unprocessed_len <= block_size ) || ilen <= block_size - ctx->unprocessed_len ) ||
( ctx->operation == MBEDTLS_ENCRYPT && ( ctx->operation == MBEDTLS_ENCRYPT &&
ilen + ctx->unprocessed_len < block_size ) ) ilen < block_size - ctx->unprocessed_len ) )
{ {
memcpy( &( ctx->unprocessed_data[ctx->unprocessed_len] ), input, memcpy( &( ctx->unprocessed_data[ctx->unprocessed_len] ), input,
ilen ); ilen );

View file

@ -290,7 +290,8 @@ int mbedtls_ctr_drbg_reseed( mbedtls_ctr_drbg_context *ctx,
unsigned char seed[MBEDTLS_CTR_DRBG_MAX_SEED_INPUT]; unsigned char seed[MBEDTLS_CTR_DRBG_MAX_SEED_INPUT];
size_t seedlen = 0; 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 ); return( MBEDTLS_ERR_CTR_DRBG_INPUT_TOO_BIG );
memset( seed, 0, MBEDTLS_CTR_DRBG_MAX_SEED_INPUT ); memset( seed, 0, MBEDTLS_CTR_DRBG_MAX_SEED_INPUT );

View file

@ -158,7 +158,7 @@ void mbedtls_md2_update( mbedtls_md2_context *ctx, const unsigned char *input, s
while( ilen > 0 ) while( ilen > 0 )
{ {
if( ctx->left + ilen > 16 ) if( ilen > 16 - ctx->left )
fill = 16 - ctx->left; fill = 16 - ctx->left;
else else
fill = ilen; fill = ilen;

View file

@ -39,6 +39,11 @@ void ctr_drbg_special_behaviours( )
TEST_ASSERT( mbedtls_ctr_drbg_reseed( &ctx, additional, TEST_ASSERT( mbedtls_ctr_drbg_reseed( &ctx, additional,
MBEDTLS_CTR_DRBG_MAX_SEED_INPUT + 1 ) == MBEDTLS_CTR_DRBG_MAX_SEED_INPUT + 1 ) ==
MBEDTLS_ERR_CTR_DRBG_INPUT_TOO_BIG ); MBEDTLS_ERR_CTR_DRBG_INPUT_TOO_BIG );
mbedtls_ctr_drbg_set_entropy_len( &ctx, ~0 );
TEST_ASSERT( mbedtls_ctr_drbg_reseed( &ctx, additional,
MBEDTLS_CTR_DRBG_MAX_SEED_INPUT ) ==
MBEDTLS_ERR_CTR_DRBG_INPUT_TOO_BIG );
exit: exit:
mbedtls_ctr_drbg_free( &ctx ); mbedtls_ctr_drbg_free( &ctx );
} }