diff --git a/ChangeLog b/ChangeLog index 7df5fa39a..3078c58e2 100644 --- a/ChangeLog +++ b/ChangeLog @@ -30,6 +30,10 @@ Bugfix * Memory leak in benchmark application * Fixed x509_crt_parse_path() bug on Windows platforms +Security + * Possible remotely-triggered out-of-bounds memory access fixed (found by + TrustInSoft) + = PolarSSL 1.3.2 released on 2013-11-04 Features * PK tests added to test framework diff --git a/include/polarssl/ssl.h b/include/polarssl/ssl.h index 4b0c5f8bb..7e668f93b 100644 --- a/include/polarssl/ssl.h +++ b/include/polarssl/ssl.h @@ -237,8 +237,8 @@ #endif /* !POLARSSL_CONFIG_OPTIONS */ /* - * Allow an extra 512 bytes for the record header - * and encryption overhead (counter + MAC + padding) + * Allow an extra 301 bytes for the record header + * and encryption overhead: counter (8) + header (5) + MAC (32) + padding (256) * and allow for a maximum of 1024 of compression expansion if * enabled. */ @@ -248,9 +248,9 @@ #define SSL_COMPRESSION_ADD 0 #endif -#define SSL_BUFFER_LEN (SSL_MAX_CONTENT_LEN + SSL_COMPRESSION_ADD + 512) +#define SSL_BUFFER_LEN (SSL_MAX_CONTENT_LEN + SSL_COMPRESSION_ADD + 301) -#define SSL_EMPTY_RENEGOTIATION_INFO 0xFF /**< renegotiation info ext */ +#define SSL_EMPTY_RENEGOTIATION_INFO 0xFF /**< renegotiation info ext */ /* * Supported Signature and Hash algorithms (For TLS 1.2) diff --git a/library/ssl_tls.c b/library/ssl_tls.c index 75ba9075a..6ea282180 100644 --- a/library/ssl_tls.c +++ b/library/ssl_tls.c @@ -1610,6 +1610,21 @@ static int ssl_decrypt_buf( ssl_context *ssl ) size_t pad_count = 0, real_count = 1; size_t padding_idx = ssl->in_msglen - padlen - 1; + /* + * Padding is guaranteed to be incorrect if: + * 1. padlen - 1 > ssl->in_msglen + * + * 2. ssl->in_msglen + padlen > + * SSL_MAX_CONTENT_LEN + 256 (max padding) + * + * In both cases we reset padding_idx to a safe value (0) to + * prevent out-of-buffer reads. + */ + correct &= ( ssl->in_msglen >= padlen - 1 ); + correct &= ( ssl->in_msglen + padlen <= SSL_MAX_CONTENT_LEN + 256 ); + + padding_idx *= correct; + for( i = 1; i <= 256; i++ ) { real_count &= ( i <= padlen );