]> git.ipfire.org Git - thirdparty/suricata.git/commitdiff
ipv6: decoder event on invalid length
authorPhilippe Antoine <contact@catenacyber.fr>
Mon, 19 Jul 2021 15:31:32 +0000 (17:31 +0200)
committerJason Ish <jason.ish@oisf.net>
Fri, 10 Sep 2021 15:44:50 +0000 (09:44 -0600)
From RFC 2460, section 4.5,
each fragment, except the last one, must have a length
which is a multiple of 8

(cherry picked from commit ca760e305cd74933b685b1bd5be795b24a7d94a7)

rules/decoder-events.rules
src/decode-events.c
src/decode-events.h
src/decode-ipv6.c

index 515e93325df53f421b6c1d1af84f994c4d467bce..362bd62e4a9bb086800237640d71311a51164397 100644 (file)
@@ -104,6 +104,7 @@ alert pkthdr any any -> any any (msg:"SURICATA FRAG IPv4 Packet size too large";
 alert pkthdr any any -> any any (msg:"SURICATA FRAG IPv4 Fragmentation overlap"; decode-event:ipv4.frag_overlap; classtype:protocol-command-decode; sid:2200070; rev:2;)
 alert pkthdr any any -> any any (msg:"SURICATA FRAG IPv6 Packet size too large"; decode-event:ipv6.frag_pkt_too_large; classtype:protocol-command-decode; sid:2200071; rev:3;)
 alert pkthdr any any -> any any (msg:"SURICATA FRAG IPv6 Fragmentation overlap"; decode-event:ipv6.frag_overlap; classtype:protocol-command-decode; sid:2200072; rev:2;)
+alert pkthdr any any -> any any (msg:"SURICATA FRAG IPv6 Fragment invalid length"; decode-event:ipv6.frag_invalid_length; classtype:protocol-command-decode; sid:2200119; rev:1;)
 
 # checksum rules
 alert ip any any -> any any (msg:"SURICATA IPv4 invalid checksum"; ipv4-csum:invalid; classtype:protocol-command-decode; sid:2200073; rev:2;)
@@ -145,4 +146,4 @@ alert pkthdr any any -> any any (msg:"SURICATA DCE packet too small"; decode-eve
 
 alert pkthdr any any -> any any (msg:"SURICATA packet with too many layers"; decode-event:too_many_layers; classtype:protocol-command-decode; sid:2200116; rev:1;)
 
-# next sid is 2200117
+# next sid is 2200120
index a900bc3b15890e1e9ce5ff2ef75dfe8eeb4c1ad7..0a9cfab9627b53a02c440e975b2ae1e117524595 100644 (file)
@@ -153,10 +153,26 @@ const struct DecodeEvents_ DEvents[] = {
     { "decoder.sctp.pkt_too_small", SCTP_PKT_TOO_SMALL, },
 
     /* Fragmentation reasembly events. */
-    { "decoder.ipv4.frag_pkt_too_large", IPV4_FRAG_PKT_TOO_LARGE, },
-    { "decoder.ipv6.frag_pkt_too_large", IPV6_FRAG_PKT_TOO_LARGE, },
-    { "decoder.ipv4.frag_overlap", IPV4_FRAG_OVERLAP, },
-    { "decoder.ipv6.frag_overlap", IPV6_FRAG_OVERLAP, },
+    {
+            "decoder.ipv4.frag_pkt_too_large",
+            IPV4_FRAG_PKT_TOO_LARGE,
+    },
+    {
+            "decoder.ipv6.frag_pkt_too_large",
+            IPV6_FRAG_PKT_TOO_LARGE,
+    },
+    {
+            "decoder.ipv4.frag_overlap",
+            IPV4_FRAG_OVERLAP,
+    },
+    {
+            "decoder.ipv6.frag_overlap",
+            IPV6_FRAG_OVERLAP,
+    },
+    {
+            "decoder.ipv6.frag_invalid_length",
+            IPV6_FRAG_INVALID_LENGTH,
+    },
     /* Fragment ignored due to internal error */
     { "decoder.ipv4.frag_ignored", IPV4_FRAG_IGNORED, },
     { "decoder.ipv6.frag_ignored", IPV6_FRAG_IGNORED, },
index 088453315ba99e721b42905d18674df0e4d88a1a..329860ffcea79d90bcb201aed2d6373f9f12e7ae 100644 (file)
@@ -162,6 +162,7 @@ enum {
     IPV6_FRAG_PKT_TOO_LARGE,
     IPV4_FRAG_OVERLAP,
     IPV6_FRAG_OVERLAP,
+    IPV6_FRAG_INVALID_LENGTH,
 
     /* Fragment ignored due to internal error */
     IPV4_FRAG_IGNORED,
index 8ddce2e10a1e771716772909d945f9047f1d7570..0f1243aab87681f0e70c59c7aae6a4b72e91a39e 100644 (file)
@@ -459,6 +459,12 @@ DecodeIPV6ExtHdrs(ThreadVars *tv, DecodeThreadVars *dtv, Packet *p,
                     plen -= hdrextlen;
                     break;
                 }
+                if (p->ip6eh.fh_more_frags_set != 0 && plen % 8 != 0) {
+                    // cf https://datatracker.ietf.org/doc/html/rfc2460#section-4.5
+                    // each, except possibly the last ("rightmost") one,
+                    // being an integer multiple of 8 octets long.
+                    ENGINE_SET_EVENT(p, IPV6_FRAG_INVALID_LENGTH);
+                }
 
                 /* the rest is parsed upon reassembly */
                 p->flags |= PKT_IS_FRAGMENT;