Fix heap-buffer overread in ALPN ext parsing

This commit is contained in:
Manuel Pégourié-Gonnard 2018-01-09 10:43:43 +01:00
parent 3366d373f8
commit 239987fd31
2 changed files with 28 additions and 17 deletions

View file

@ -38,6 +38,9 @@ Security
corrupt 6 bytes on the peer's heap, potentially leading to crash or corrupt 6 bytes on the peer's heap, potentially leading to crash or
remote code execution. This can be triggered remotely from either remote code execution. This can be triggered remotely from either
side in both TLS and DTLS. side in both TLS and DTLS.
* Fix a potential heap buffer overread in ALPN extension parsing
(server-side). Could result in application crash, but only if an ALPN
name larger than 16 bytes had been configured on the server.
Features Features
* Allow comments in test data files. * Allow comments in test data files.

View file

@ -603,33 +603,41 @@ static int ssl_parse_alpn_ext( mbedtls_ssl_context *ssl,
} }
/* /*
* Use our order of preference * Validate peer's list (lengths)
*/ */
start = buf + 2; start = buf + 2;
end = buf + len; end = buf + len;
for( theirs = start; theirs != end; theirs += cur_len )
{
cur_len = *theirs++;
/* Current identifier must fit in list */
if( cur_len > (size_t)( end - theirs ) )
{
mbedtls_ssl_send_alert_message( ssl, MBEDTLS_SSL_ALERT_LEVEL_FATAL,
MBEDTLS_SSL_ALERT_MSG_DECODE_ERROR );
return( MBEDTLS_ERR_SSL_BAD_HS_CLIENT_HELLO );
}
/* Empty strings MUST NOT be included */
if( cur_len == 0 )
{
mbedtls_ssl_send_alert_message( ssl, MBEDTLS_SSL_ALERT_LEVEL_FATAL,
MBEDTLS_SSL_ALERT_MSG_ILLEGAL_PARAMETER );
return( MBEDTLS_ERR_SSL_BAD_HS_CLIENT_HELLO );
}
}
/*
* Use our order of preference
*/
for( ours = ssl->conf->alpn_list; *ours != NULL; ours++ ) for( ours = ssl->conf->alpn_list; *ours != NULL; ours++ )
{ {
ours_len = strlen( *ours ); ours_len = strlen( *ours );
for( theirs = start; theirs != end; theirs += cur_len ) for( theirs = start; theirs != end; theirs += cur_len )
{ {
/* If the list is well formed, we should get equality first */
if( theirs > end )
{
mbedtls_ssl_send_alert_message( ssl, MBEDTLS_SSL_ALERT_LEVEL_FATAL,
MBEDTLS_SSL_ALERT_MSG_ILLEGAL_PARAMETER );
return( MBEDTLS_ERR_SSL_BAD_HS_CLIENT_HELLO );
}
cur_len = *theirs++; cur_len = *theirs++;
/* Empty strings MUST NOT be included */
if( cur_len == 0 )
{
mbedtls_ssl_send_alert_message( ssl, MBEDTLS_SSL_ALERT_LEVEL_FATAL,
MBEDTLS_SSL_ALERT_MSG_ILLEGAL_PARAMETER );
return( MBEDTLS_ERR_SSL_BAD_HS_CLIENT_HELLO );
}
if( cur_len == ours_len && if( cur_len == ours_len &&
memcmp( theirs, *ours, cur_len ) == 0 ) memcmp( theirs, *ours, cur_len ) == 0 )
{ {