From: Mats Klepsland Date: Fri, 11 Mar 2016 11:55:38 +0000 (+0100) Subject: app-layer-ssl: fix memleak X-Git-Tag: suricata-3.0.1RC1~24 X-Git-Url: http://git.ipfire.org/cgi-bin/gitweb.cgi?a=commitdiff_plain;h=7602f650b1ba3a7e043d80e7ac8dd1df5469b5ea;p=thirdparty%2Fsuricata.git app-layer-ssl: fix memleak Avoid that the SNI extension code is executed twice sometimes, causing memory leaks. --- diff --git a/src/app-layer-ssl.c b/src/app-layer-ssl.c index 5650509b4a..8bb2e6b1d3 100644 --- a/src/app-layer-ssl.c +++ b/src/app-layer-ssl.c @@ -65,6 +65,9 @@ SCEnumCharMap tls_decoder_event_table[ ] = { { "INVALID_HEARTBEAT_MESSAGE", TLS_DECODER_EVENT_INVALID_HEARTBEAT }, { "OVERFLOW_HEARTBEAT_MESSAGE", TLS_DECODER_EVENT_OVERFLOW_HEARTBEAT }, { "DATALEAK_HEARTBEAT_MISMATCH", TLS_DECODER_EVENT_DATALEAK_HEARTBEAT_MISMATCH }, + { "MULTIPLE_SNI_EXTENSIONS", TLS_DECODER_EVENT_MULTIPLE_SNI_EXTENSIONS }, + { "INVALID_SNI_TYPE", TLS_DECODER_EVENT_INVALID_SNI_TYPE }, + { "INVALID_SNI_LENGTH", TLS_DECODER_EVENT_INVALID_SNI_LENGTH }, /* Certificates decoding messages */ { "INVALID_CERTIFICATE", TLS_DECODER_EVENT_INVALID_CERTIFICATE }, { "CERTIFICATE_MISSING_ELEMENT", TLS_DECODER_EVENT_CERTIFICATE_MISSING_ELEMENT }, @@ -205,8 +208,31 @@ static int SSLv3ParseHandshakeType(SSLState *ssl_state, uint8_t *input, switch (ext_type) { case SSL_EXTENSION_SNI: { - /* skip sni_list_length and sni_type */ - input += 3; + /* there must not be more than one extension of the same + type (RFC5246 section 7.4.1.4) */ + if (ssl_state->curr_connp->sni) { + SCLogDebug("Multiple SNI extensions"); + AppLayerDecoderEventsSetEvent(ssl_state->f, + TLS_DECODER_EVENT_MULTIPLE_SNI_EXTENSIONS); + return -1; + } + + /* skip sni_list_length */ + input += 2; + + if (!(HAS_SPACE(1))) + goto end; + + uint8_t sni_type = *(input++); + + /* currently the only type allowed is host_name + (RFC6066 section 3) */ + if (sni_type != SSL_SNI_TYPE_HOST_NAME) { + SCLogDebug("Unknown SNI type"); + AppLayerDecoderEventsSetEvent(ssl_state->f, + TLS_DECODER_EVENT_INVALID_SNI_TYPE); + return -1; + } if (!(HAS_SPACE(2))) goto end; @@ -217,6 +243,16 @@ static int SSLv3ParseHandshakeType(SSLState *ssl_state, uint8_t *input, if (!(HAS_SPACE(sni_len))) goto end; + /* host_name contains the fully qualified domain name, + and should therefore be limited by the maximum domain + name length */ + if (sni_len > 255) { + SCLogDebug("SNI length >255"); + AppLayerDecoderEventsSetEvent(ssl_state->f, + TLS_DECODER_EVENT_INVALID_SNI_LENGTH); + return -1; + } + size_t sni_strlen = sni_len + 1; ssl_state->curr_connp->sni = SCMalloc(sni_strlen); diff --git a/src/app-layer-ssl.h b/src/app-layer-ssl.h index e6274249b9..b38035254e 100644 --- a/src/app-layer-ssl.h +++ b/src/app-layer-ssl.h @@ -40,6 +40,9 @@ enum { TLS_DECODER_EVENT_INVALID_HEARTBEAT, TLS_DECODER_EVENT_OVERFLOW_HEARTBEAT, TLS_DECODER_EVENT_DATALEAK_HEARTBEAT_MISMATCH, + TLS_DECODER_EVENT_MULTIPLE_SNI_EXTENSIONS, + TLS_DECODER_EVENT_INVALID_SNI_TYPE, + TLS_DECODER_EVENT_INVALID_SNI_LENGTH, /* Certificates decoding messages */ TLS_DECODER_EVENT_INVALID_CERTIFICATE, TLS_DECODER_EVENT_CERTIFICATE_MISSING_ELEMENT, @@ -89,6 +92,9 @@ enum { /* extensions */ #define SSL_EXTENSION_SNI 0x0000 +/* SNI types */ +#define SSL_SNI_TYPE_HOST_NAME 0 + /* SSL versions. We'll use a unified format for all, with the top byte * holding the major version and the lower byte the minor version */ enum {