Fix potential overflow in base64_encode

This commit is contained in:
Manuel Pégourié-Gonnard 2015-09-30 16:30:28 +02:00
parent 5aff029f9d
commit 48ec2c7b5e
3 changed files with 12 additions and 5 deletions

View file

@ -18,6 +18,9 @@ Security
* Fix potential double-free if ssl_set_psk() is called repeatedly on * Fix potential double-free if ssl_set_psk() is called repeatedly on
the same ssl_context object and some memory allocations fail. the same ssl_context object and some memory allocations fail.
Found by Guido Vranken. Can not be forced remotely. Found by Guido Vranken. Can not be forced remotely.
* Fix possible heap buffer overflow in base64_encode() when the input
buffer is 512MB or larger on 32-bit platforms.
Found by Guido Vranken. Not trigerrable remotely in TLS.
= mbed TLS 1.3.13 reladsed 2015-09-17 = mbed TLS 1.3.13 reladsed 2015-09-17

View file

@ -25,6 +25,7 @@
#define POLARSSL_BASE64_H #define POLARSSL_BASE64_H
#include <stddef.h> #include <stddef.h>
#include <limits.h>
#define POLARSSL_ERR_BASE64_BUFFER_TOO_SMALL -0x002A /**< Output buffer too small. */ #define POLARSSL_ERR_BASE64_BUFFER_TOO_SMALL -0x002A /**< Output buffer too small. */
#define POLARSSL_ERR_BASE64_INVALID_CHARACTER -0x002C /**< Invalid character in input. */ #define POLARSSL_ERR_BASE64_INVALID_CHARACTER -0x002C /**< Invalid character in input. */
@ -44,6 +45,8 @@ extern "C" {
* \return 0 if successful, or POLARSSL_ERR_BASE64_BUFFER_TOO_SMALL. * \return 0 if successful, or POLARSSL_ERR_BASE64_BUFFER_TOO_SMALL.
* *dlen is always updated to reflect the amount * *dlen is always updated to reflect the amount
* of data that has (or would have) been written. * of data that has (or would have) been written.
* If that length cannot be represented, then no data is
* written to the buffer and *olen is set to SIZE_T_MAX.
* *
* \note Call this function with *dlen = 0 to obtain the * \note Call this function with *dlen = 0 to obtain the
* required buffer size in *dlen * required buffer size in *dlen

View file

@ -91,15 +91,16 @@ int base64_encode( unsigned char *dst, size_t *dlen,
return( 0 ); return( 0 );
} }
n = ( slen << 3 ) / 6; n = slen / 3 + ( slen % 3 != 0 );
switch( ( slen << 3 ) - ( n * 6 ) ) if( n > ( SIZE_T_MAX - 1 ) / 4 )
{ {
case 2: n += 3; break; *dlen = SIZE_T_MAX;
case 4: n += 2; break; return( POLARSSL_ERR_BASE64_BUFFER_TOO_SMALL );
default: break;
} }
n *= 4;
if( *dlen < n + 1 ) if( *dlen < n + 1 )
{ {
*dlen = n + 1; *dlen = n + 1;