Fix potential overflow in base64_encode

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

View file

@ -15,6 +15,9 @@ Security
on crafted PEM input data. Found an fix provided by Guid Vranken. on crafted PEM input data. Found an fix provided by Guid Vranken.
Not triggerable remotely in TLS. Triggerable remotely if you accept PEM Not triggerable remotely in TLS. Triggerable remotely if you accept PEM
data from an untrusted source. data from an untrusted source.
* 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.
= Version 1.2.16 released 2015-09-17 = Version 1.2.16 released 2015-09-17

View file

@ -25,6 +25,7 @@
#define POLARSSL_BASE64_H #define POLARSSL_BASE64_H
#include <string.h> #include <string.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 *dlen 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

@ -77,15 +77,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;