]> git.ipfire.org Git - thirdparty/suricata.git/commitdiff
app-layer-ssl: fix memleak
authorMats Klepsland <mats.klepsland@gmail.com>
Fri, 11 Mar 2016 11:55:38 +0000 (12:55 +0100)
committerVictor Julien <victor@inliniac.net>
Tue, 15 Mar 2016 09:09:33 +0000 (10:09 +0100)
Avoid that the SNI extension code is executed twice sometimes, causing
memory leaks.

src/app-layer-ssl.c
src/app-layer-ssl.h

index 5650509b4a627a7e69281f53971c6dfe6dbed9bc..8bb2e6b1d3bae8717d044bddc0dd14928f6f4c47 100644 (file)
@@ -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);
 
index e6274249b9e436ef823b91fa0ce4e94937db080e..b38035254ee962faff102d9a4d9c04536300015c 100644 (file)
@@ -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 {