]> git.ipfire.org Git - thirdparty/suricata.git/commitdiff
decode: set pktlen of decode handler to uint32
authorMaurizio Abba <mabba@lastline.com>
Tue, 16 Jan 2018 16:53:51 +0000 (16:53 +0000)
committerVictor Julien <victor@inliniac.net>
Mon, 6 Aug 2018 09:35:35 +0000 (11:35 +0200)
Change the decode handler signature to increase the size of its decode
handler, from uint16 to uint32. This is necessary to let suricata use
interfaces with mtu > 65535 (ex: lo interface has default size 65536).

It's necessary to change several primitive for Packet manipulation, to
unify the parameter "packet length" whenever we are before IP decoding.

Add tests before calling DecodeIPVX function to avoid a possible
integer overflow over the len parameter.

19 files changed:
src/decode-erspan.c
src/decode-ethernet.c
src/decode-gre.c
src/decode-icmpv4.c
src/decode-icmpv6.c
src/decode-mpls.c
src/decode-null.c
src/decode-ppp.c
src/decode-pppoe.c
src/decode-raw.c
src/decode-sll.c
src/decode-template.c
src/decode-vlan.c
src/decode.c
src/decode.h
src/source-ipfw.c
src/source-nflog.c
src/source-nfq.c
src/source-pcap-file-helper.h

index d4df6462062057b768e19c6002d187568336b2e6..53f43fa24044a55307f700385fce3d3dea136332 100644 (file)
@@ -43,7 +43,7 @@
  * \brief Function to decode ERSPAN packets
  */
 
-int DecodeERSPAN(ThreadVars *tv, DecodeThreadVars *dtv, Packet *p, uint8_t *pkt, uint16_t len, PacketQueue *pq)
+int DecodeERSPAN(ThreadVars *tv, DecodeThreadVars *dtv, Packet *p, uint8_t *pkt, uint32_t len, PacketQueue *pq)
 {
     StatsIncr(tv, dtv->counter_erspan);
 
index 6bdcff7414bcab8d4e0944a11719fd31f14dc1ea..3b55f31be876c2181c3f6464873e990624dff911 100644 (file)
@@ -39,7 +39,7 @@
 #include "util-debug.h"
 
 int DecodeEthernet(ThreadVars *tv, DecodeThreadVars *dtv, Packet *p,
-                   uint8_t *pkt, uint16_t len, PacketQueue *pq)
+                   uint8_t *pkt, uint32_t len, PacketQueue *pq)
 {
     StatsIncr(tv, dtv->counter_eth);
 
@@ -48,6 +48,10 @@ int DecodeEthernet(ThreadVars *tv, DecodeThreadVars *dtv, Packet *p,
         return TM_ECODE_FAILED;
     }
 
+    if (unlikely(len > ETHERNET_HEADER_LEN + USHRT_MAX)) {
+        return TM_ECODE_FAILED;
+    }
+
     p->ethh = (EthernetHdr *)pkt;
     if (unlikely(p->ethh == NULL))
         return TM_ECODE_FAILED;
index 7c7bc80490e405ca25c579f3d23d63c469f57306..2429cb660cfae22e9166c011223e3013e2bf5d59 100644 (file)
@@ -43,9 +43,9 @@
  * \brief Function to decode GRE packets
  */
 
-int DecodeGRE(ThreadVars *tv, DecodeThreadVars *dtv, Packet *p, uint8_t *pkt, uint16_t len, PacketQueue *pq)
+int DecodeGRE(ThreadVars *tv, DecodeThreadVars *dtv, Packet *p, uint8_t *pkt, uint32_t len, PacketQueue *pq)
 {
-    uint16_t header_len = GRE_HDR_LEN;
+    uint32_t header_len = GRE_HDR_LEN;
     GRESreHdr *gsre = NULL;
 
     StatsIncr(tv, dtv->counter_gre);
index 2e567b7557d3c50fb3e5aa9f325928942b1ff54f..00bc27630845ff440258ab7a17445211536a0791 100644 (file)
@@ -152,7 +152,7 @@ static int DecodePartialIPV4(Packet* p, uint8_t* partial_packet, uint16_t len)
 /** DecodeICMPV4
  *  \brief Main ICMPv4 decoding function
  */
-int DecodeICMPV4(ThreadVars *tv, DecodeThreadVars *dtv, Packet *p, uint8_t *pkt, uint16_t len, PacketQueue *pq)
+int DecodeICMPV4(ThreadVars *tv, DecodeThreadVars *dtv, Packet *p, uint8_t *pkt, uint32_t len, PacketQueue *pq)
 {
     StatsIncr(tv, dtv->counter_icmpv4);
 
@@ -205,8 +205,12 @@ int DecodeICMPV4(ThreadVars *tv, DecodeThreadVars *dtv, Packet *p, uint8_t *pkt,
                 ENGINE_SET_EVENT(p,ICMPV4_UNKNOWN_CODE);
             } else {
                 // parse IP header plus 64 bytes
-                if (len >= ICMPV4_HEADER_PKT_OFFSET)
+                if (len >= ICMPV4_HEADER_PKT_OFFSET) {
+                    if (unlikely(len > ICMPV4_HEADER_PKT_OFFSET + USHRT_MAX)) {
+                        return TM_ECODE_FAILED;
+                    }
                     DecodePartialIPV4( p, (uint8_t*) (pkt + ICMPV4_HEADER_PKT_OFFSET), len - ICMPV4_HEADER_PKT_OFFSET  );
+                }
             }
             break;
 
@@ -215,8 +219,12 @@ int DecodeICMPV4(ThreadVars *tv, DecodeThreadVars *dtv, Packet *p, uint8_t *pkt,
                 ENGINE_SET_EVENT(p,ICMPV4_UNKNOWN_CODE);
             } else {
                 // parse IP header plus 64 bytes
-                if (len > ICMPV4_HEADER_PKT_OFFSET)
+                if (len > ICMPV4_HEADER_PKT_OFFSET) {
+                    if (unlikely(len > ICMPV4_HEADER_PKT_OFFSET + USHRT_MAX)) {
+                        return TM_ECODE_FAILED;
+                    }
                     DecodePartialIPV4( p, (uint8_t*) (pkt + ICMPV4_HEADER_PKT_OFFSET), len - ICMPV4_HEADER_PKT_OFFSET );
+                }
             }
             break;
 
@@ -233,8 +241,12 @@ int DecodeICMPV4(ThreadVars *tv, DecodeThreadVars *dtv, Packet *p, uint8_t *pkt,
                 ENGINE_SET_EVENT(p,ICMPV4_UNKNOWN_CODE);
             } else {
                 // parse IP header plus 64 bytes
-                if (len > ICMPV4_HEADER_PKT_OFFSET)
+                if (len > ICMPV4_HEADER_PKT_OFFSET) {
+                    if (unlikely(len > ICMPV4_HEADER_PKT_OFFSET + USHRT_MAX)) {
+                        return TM_ECODE_FAILED;
+                    }
                     DecodePartialIPV4( p, (uint8_t*) (pkt + ICMPV4_HEADER_PKT_OFFSET), len - ICMPV4_HEADER_PKT_OFFSET );
+                }
             }
             break;
 
@@ -243,8 +255,12 @@ int DecodeICMPV4(ThreadVars *tv, DecodeThreadVars *dtv, Packet *p, uint8_t *pkt,
                 ENGINE_SET_EVENT(p,ICMPV4_UNKNOWN_CODE);
             } else {
                 // parse IP header plus 64 bytes
-                if (len > ICMPV4_HEADER_PKT_OFFSET)
+                if (len > ICMPV4_HEADER_PKT_OFFSET) {
+                    if (unlikely(len > ICMPV4_HEADER_PKT_OFFSET + USHRT_MAX)) {
+                        return TM_ECODE_FAILED;
+                    }
                     DecodePartialIPV4( p, (uint8_t*) (pkt + ICMPV4_HEADER_PKT_OFFSET), len - ICMPV4_HEADER_PKT_OFFSET );
+                }
             }
             break;
 
index d035e133b0f3cbc82922cce5d45a83954dd3e821..a6c713eb3090a9e45361659a4a47d70290dc1628 100644 (file)
@@ -187,7 +187,7 @@ int ICMPv6GetCounterpart(uint8_t type)
  * \retval void No return value
  */
 int DecodeICMPV6(ThreadVars *tv, DecodeThreadVars *dtv, Packet *p,
-                  uint8_t *pkt, uint16_t len, PacketQueue *pq)
+                  uint8_t *pkt, uint32_t len, PacketQueue *pq)
 {
     int full_hdr = 0;
     StatsIncr(tv, dtv->counter_icmpv6);
@@ -220,6 +220,9 @@ int DecodeICMPV6(ThreadVars *tv, DecodeThreadVars *dtv, Packet *p,
             if (ICMPV6_GET_CODE(p) > ICMP6_DST_UNREACH_REJECTROUTE) {
                 ENGINE_SET_EVENT(p, ICMPV6_UNKNOWN_CODE);
             } else {
+                if (unlikely(len > ICMPV6_HEADER_LEN + USHRT_MAX)) {
+                    return TM_ECODE_FAILED;
+                }
                 DecodePartialIPV6(p, (uint8_t*) (pkt + ICMPV6_HEADER_LEN),
                                   len - ICMPV6_HEADER_LEN );
                 full_hdr = 1;
@@ -232,6 +235,9 @@ int DecodeICMPV6(ThreadVars *tv, DecodeThreadVars *dtv, Packet *p,
             if (ICMPV6_GET_CODE(p) != 0) {
                 ENGINE_SET_EVENT(p, ICMPV6_UNKNOWN_CODE);
             } else {
+                if (unlikely(len > ICMPV6_HEADER_LEN + USHRT_MAX)) {
+                    return TM_ECODE_FAILED;
+                }
                 p->icmpv6vars.mtu = ICMPV6_GET_MTU(p);
                 DecodePartialIPV6(p, (uint8_t*) (pkt + ICMPV6_HEADER_LEN),
                                   len - ICMPV6_HEADER_LEN );
@@ -245,6 +251,9 @@ int DecodeICMPV6(ThreadVars *tv, DecodeThreadVars *dtv, Packet *p,
             if (ICMPV6_GET_CODE(p) > ICMP6_TIME_EXCEED_REASSEMBLY) {
                 ENGINE_SET_EVENT(p, ICMPV6_UNKNOWN_CODE);
             } else {
+                if (unlikely(len > ICMPV6_HEADER_LEN + USHRT_MAX)) {
+                    return TM_ECODE_FAILED;
+                }
                 DecodePartialIPV6(p, (uint8_t*) (pkt + ICMPV6_HEADER_LEN),
                                   len - ICMPV6_HEADER_LEN );
                 full_hdr = 1;
@@ -257,6 +266,9 @@ int DecodeICMPV6(ThreadVars *tv, DecodeThreadVars *dtv, Packet *p,
             if (ICMPV6_GET_CODE(p) > ICMP6_PARAMPROB_OPTION) {
                 ENGINE_SET_EVENT(p, ICMPV6_UNKNOWN_CODE);
             } else {
+                if (unlikely(len > ICMPV6_HEADER_LEN + USHRT_MAX)) {
+                    return TM_ECODE_FAILED;
+                }
                 p->icmpv6vars.error_ptr= ICMPV6_GET_ERROR_PTR(p);
                 DecodePartialIPV6(p, (uint8_t*) (pkt + ICMPV6_HEADER_LEN),
                                   len - ICMPV6_HEADER_LEN );
index 9694a341f4061a6eb3f6ccaae103bb946ce051fc..53d7ec18820ef0708b31d820a9f61543c675dfe5 100644 (file)
@@ -45,7 +45,7 @@
 #define MPLS_PROTO_IPV6         6
 
 int DecodeMPLS(ThreadVars *tv, DecodeThreadVars *dtv, Packet *p, uint8_t *pkt,
-    uint16_t len, PacketQueue *pq)
+    uint32_t len, PacketQueue *pq)
 {
     uint32_t shim;
     int label;
@@ -65,6 +65,9 @@ int DecodeMPLS(ThreadVars *tv, DecodeThreadVars *dtv, Packet *p, uint8_t *pkt,
 
     label = MPLS_LABEL(shim);
     if (label == MPLS_LABEL_IPV4) {
+        if (len > USHRT_MAX) {
+            return TM_ECODE_FAILED;
+        }
         return DecodeIPV4(tv, dtv, p, pkt, len, pq);
     }
     else if (label == MPLS_LABEL_ROUTER_ALERT) {
@@ -72,6 +75,9 @@ int DecodeMPLS(ThreadVars *tv, DecodeThreadVars *dtv, Packet *p, uint8_t *pkt,
         event = MPLS_BAD_LABEL_ROUTER_ALERT;
     }
     else if (label == MPLS_LABEL_IPV6) {
+        if (len > USHRT_MAX) {
+            return TM_ECODE_FAILED;
+        }
         return DecodeIPV6(tv, dtv, p, pkt, len, pq);
     }
     else if (label == MPLS_LABEL_NULL) {
@@ -89,9 +95,15 @@ int DecodeMPLS(ThreadVars *tv, DecodeThreadVars *dtv, Packet *p, uint8_t *pkt,
     /* Best guess at inner packet. */
     switch (pkt[0] >> 4) {
     case MPLS_PROTO_IPV4:
+        if (len > USHRT_MAX) {
+            return TM_ECODE_FAILED;
+        }
         DecodeIPV4(tv, dtv, p, pkt, len, pq);
         break;
     case MPLS_PROTO_IPV6:
+        if (len > USHRT_MAX) {
+            return TM_ECODE_FAILED;
+        }
         DecodeIPV6(tv, dtv, p, pkt, len, pq);
         break;
     case MPLS_PROTO_ETHERNET_PW:
index b3bcb0667c2176cd23219fe1b4e02385469c482f..1a98d002747c43db7a2546a8b5831e580ad6723c 100644 (file)
@@ -45,7 +45,7 @@
 
 #define HDR_SIZE 4
 
-int DecodeNull(ThreadVars *tv, DecodeThreadVars *dtv, Packet *p, uint8_t *pkt, uint16_t len, PacketQueue *pq)
+int DecodeNull(ThreadVars *tv, DecodeThreadVars *dtv, Packet *p, uint8_t *pkt, uint32_t len, PacketQueue *pq)
 {
     StatsIncr(tv, dtv->counter_null);
 
@@ -54,6 +54,10 @@ int DecodeNull(ThreadVars *tv, DecodeThreadVars *dtv, Packet *p, uint8_t *pkt, u
         return TM_ECODE_FAILED;
     }
 
+    if (unlikely(GET_PKT_LEN(p) > HDR_SIZE + USHRT_MAX)) {
+        return TM_ECODE_FAILED;
+    }
+
     uint32_t type = *((uint32_t *)pkt);
     switch(type) {
         case AF_INET:
index d5aae6bb7827b003181a4fbeb501ffe787f77590..f9eae736df9d0f4a97251c4d1b906a5a51a12480 100644 (file)
@@ -40,7 +40,7 @@
 #include "util-unittest.h"
 #include "util-debug.h"
 
-int DecodePPP(ThreadVars *tv, DecodeThreadVars *dtv, Packet *p, uint8_t *pkt, uint16_t len, PacketQueue *pq)
+int DecodePPP(ThreadVars *tv, DecodeThreadVars *dtv, Packet *p, uint8_t *pkt, uint32_t len, PacketQueue *pq)
 {
     StatsIncr(tv, dtv->counter_ppp);
 
@@ -53,7 +53,7 @@ int DecodePPP(ThreadVars *tv, DecodeThreadVars *dtv, Packet *p, uint8_t *pkt, ui
     if (unlikely(p->ppph == NULL))
         return TM_ECODE_FAILED;
 
-    SCLogDebug("p %p pkt %p PPP protocol %04x Len: %" PRId32 "",
+    SCLogDebug("p %p pkt %p PPP protocol %04x Len: %" PRIu32 "",
         p, pkt, SCNtohs(p->ppph->protocol), len);
 
     switch (SCNtohs(p->ppph->protocol))
@@ -65,6 +65,10 @@ int DecodePPP(ThreadVars *tv, DecodeThreadVars *dtv, Packet *p, uint8_t *pkt, ui
                 return TM_ECODE_FAILED;
             }
 
+            if (unlikely(len > PPP_HEADER_LEN + USHRT_MAX)) {
+                return TM_ECODE_FAILED;
+            }
+
             if (likely(IPV4_GET_RAW_VER((IPV4Hdr *)(pkt + PPP_HEADER_LEN)) == 4)) {
                 return DecodeIPV4(tv, dtv, p, pkt + PPP_HEADER_LEN, len - PPP_HEADER_LEN, pq);
             } else
@@ -77,6 +81,9 @@ int DecodePPP(ThreadVars *tv, DecodeThreadVars *dtv, Packet *p, uint8_t *pkt, ui
                 p->ppph = NULL;
                 return TM_ECODE_FAILED;
             }
+            if (unlikely(len > PPP_HEADER_LEN + USHRT_MAX)) {
+                return TM_ECODE_FAILED;
+            }
 
             return DecodeIPV4(tv, dtv, p, pkt + PPP_HEADER_LEN, len - PPP_HEADER_LEN, pq);
 
@@ -87,6 +94,9 @@ int DecodePPP(ThreadVars *tv, DecodeThreadVars *dtv, Packet *p, uint8_t *pkt, ui
                 p->ppph = NULL;
                 return TM_ECODE_FAILED;
             }
+            if (unlikely(len > PPP_HEADER_LEN + USHRT_MAX)) {
+                return TM_ECODE_FAILED;
+            }
 
             return DecodeIPV6(tv, dtv, p, pkt + PPP_HEADER_LEN, len - PPP_HEADER_LEN, pq);
 
index 7d5aeb19490466533f7196668fc4e97515aa5635..0551a5141dd0737311881d9ff5dbd83a91c52605 100644 (file)
@@ -47,7 +47,7 @@
 /**
  * \brief Main decoding function for PPPOE Discovery packets
  */
-int DecodePPPOEDiscovery(ThreadVars *tv, DecodeThreadVars *dtv, Packet *p, uint8_t *pkt, uint16_t len, PacketQueue *pq)
+int DecodePPPOEDiscovery(ThreadVars *tv, DecodeThreadVars *dtv, Packet *p, uint8_t *pkt, uint32_t len, PacketQueue *pq)
 {
     StatsIncr(tv, dtv->counter_pppoe);
 
@@ -81,13 +81,13 @@ int DecodePPPOEDiscovery(ThreadVars *tv, DecodeThreadVars *dtv, Packet *p, uint8
 
     /* parse any tags we have in the packet */
 
-    uint16_t tag_length = 0;
+    uint32_t tag_length = 0;
     PPPOEDiscoveryTag* pppoedt = (PPPOEDiscoveryTag*) (p->pppoedh +  PPPOE_DISCOVERY_HEADER_MIN_LEN);
 
-    uint16_t pppoe_length = SCNtohs(p->pppoedh->pppoe_length);
-    uint16_t packet_length = len - PPPOE_DISCOVERY_HEADER_MIN_LEN ;
+    uint32_t pppoe_length = SCNtohs(p->pppoedh->pppoe_length);
+    uint32_t packet_length = len - PPPOE_DISCOVERY_HEADER_MIN_LEN ;
 
-    SCLogDebug("pppoe_length %"PRIu16", packet_length %"PRIu16"",
+    SCLogDebug("pppoe_length %"PRIu32", packet_length %"PRIu32"",
         pppoe_length, packet_length);
 
     if (pppoe_length > packet_length) {
@@ -103,7 +103,7 @@ int DecodePPPOEDiscovery(ThreadVars *tv, DecodeThreadVars *dtv, Packet *p, uint8
 #endif
         tag_length = SCNtohs(pppoedt->pppoe_tag_length);
 
-        SCLogDebug ("PPPoE Tag type %x, length %u", tag_type, tag_length);
+        SCLogDebug ("PPPoE Tag type %x, length %"PRIu32, tag_type, tag_length);
 
         if (pppoe_length >= (4 + tag_length)) {
             pppoe_length -= (4 + tag_length);
@@ -126,7 +126,7 @@ int DecodePPPOEDiscovery(ThreadVars *tv, DecodeThreadVars *dtv, Packet *p, uint8
 /**
  * \brief Main decoding function for PPPOE Session packets
  */
-int DecodePPPOESession(ThreadVars *tv, DecodeThreadVars *dtv, Packet *p, uint8_t *pkt, uint16_t len, PacketQueue *pq)
+int DecodePPPOESession(ThreadVars *tv, DecodeThreadVars *dtv, Packet *p, uint8_t *pkt, uint32_t len, PacketQueue *pq)
 {
     StatsIncr(tv, dtv->counter_pppoe);
 
@@ -186,6 +186,9 @@ int DecodePPPOESession(ThreadVars *tv, DecodeThreadVars *dtv, Packet *p, uint8_t
                     ENGINE_SET_INVALID_EVENT(p, PPPVJU_PKT_TOO_SMALL);
                     return TM_ECODE_OK;
                 }
+                if (unlikely(len > PPPOE_SESSION_HEADER_LEN + USHRT_MAX)) {
+                    return TM_ECODE_FAILED;
+                }
 
                 if(IPV4_GET_RAW_VER((IPV4Hdr *)(pkt + PPPOE_SESSION_HEADER_LEN)) == 4) {
                     DecodeIPV4(tv, dtv, p, pkt + PPPOE_SESSION_HEADER_LEN, len - PPPOE_SESSION_HEADER_LEN, pq );
@@ -197,6 +200,9 @@ int DecodePPPOESession(ThreadVars *tv, DecodeThreadVars *dtv, Packet *p, uint8_t
                     ENGINE_SET_INVALID_EVENT(p, PPPIPV4_PKT_TOO_SMALL);
                     return TM_ECODE_OK;
                 }
+                if (unlikely(len > PPPOE_SESSION_HEADER_LEN + USHRT_MAX)) {
+                    return TM_ECODE_FAILED;
+                }
 
                 DecodeIPV4(tv, dtv, p, pkt + PPPOE_SESSION_HEADER_LEN, len - PPPOE_SESSION_HEADER_LEN, pq );
                 break;
@@ -207,6 +213,9 @@ int DecodePPPOESession(ThreadVars *tv, DecodeThreadVars *dtv, Packet *p, uint8_t
                     ENGINE_SET_INVALID_EVENT(p, PPPIPV6_PKT_TOO_SMALL);
                     return TM_ECODE_OK;
                 }
+                if (unlikely(len > PPPOE_SESSION_HEADER_LEN + USHRT_MAX)) {
+                    return TM_ECODE_FAILED;
+                }
 
                 DecodeIPV6(tv, dtv, p, pkt + PPPOE_SESSION_HEADER_LEN, len - PPPOE_SESSION_HEADER_LEN, pq );
                 break;
index d174ab3766173004f48dad5bc7e0543a112e0bbc..f5ad077044ddb03899ff21c8ffd5ef8821f40c06 100644 (file)
@@ -43,7 +43,7 @@
 #include "host.h"
 
 
-int DecodeRaw(ThreadVars *tv, DecodeThreadVars *dtv, Packet *p, uint8_t *pkt, uint16_t len, PacketQueue *pq)
+int DecodeRaw(ThreadVars *tv, DecodeThreadVars *dtv, Packet *p, uint8_t *pkt, uint32_t len, PacketQueue *pq)
 {
     StatsIncr(tv, dtv->counter_raw);
 
@@ -53,10 +53,18 @@ int DecodeRaw(ThreadVars *tv, DecodeThreadVars *dtv, Packet *p, uint8_t *pkt, ui
         return TM_ECODE_FAILED;
     }
 
+
+
     if (IP_GET_RAW_VER(pkt) == 4) {
+        if (unlikely(GET_PKT_LEN(p) > USHRT_MAX)) {
+            return TM_ECODE_FAILED;
+        }
         SCLogDebug("IPV4 Packet");
         DecodeIPV4(tv, dtv, p, GET_PKT_DATA(p), GET_PKT_LEN(p), pq);
     } else if (IP_GET_RAW_VER(pkt) == 6) {
+        if (unlikely(GET_PKT_LEN(p) > USHRT_MAX)) {
+            return TM_ECODE_FAILED;
+        }
         SCLogDebug("IPV6 Packet");
         DecodeIPV6(tv, dtv, p, GET_PKT_DATA(p), GET_PKT_LEN(p), pq);
     } else {
index d9730de2d2cb79713240b9e021b789573e946849..c9360bfdb2bca114f9167144c65090b3000c5f40 100644 (file)
@@ -36,7 +36,7 @@
 #include "decode-events.h"
 #include "util-debug.h"
 
-int DecodeSll(ThreadVars *tv, DecodeThreadVars *dtv, Packet *p, uint8_t *pkt, uint16_t len, PacketQueue *pq)
+int DecodeSll(ThreadVars *tv, DecodeThreadVars *dtv, Packet *p, uint8_t *pkt, uint32_t len, PacketQueue *pq)
 {
     StatsIncr(tv, dtv->counter_sll);
 
@@ -53,10 +53,16 @@ int DecodeSll(ThreadVars *tv, DecodeThreadVars *dtv, Packet *p, uint8_t *pkt, ui
 
     switch (SCNtohs(sllh->sll_protocol)) {
         case ETHERNET_TYPE_IP:
+            if (unlikely(len > SLL_HEADER_LEN + USHRT_MAX)) {
+                return TM_ECODE_FAILED;
+            }
             DecodeIPV4(tv, dtv, p, pkt + SLL_HEADER_LEN,
                        len - SLL_HEADER_LEN, pq);
             break;
         case ETHERNET_TYPE_IPV6:
+            if (unlikely(len > SLL_HEADER_LEN + USHRT_MAX)) {
+                return TM_ECODE_FAILED;
+            }
             DecodeIPV6(tv, dtv, p, pkt + SLL_HEADER_LEN,
                        len - SLL_HEADER_LEN, pq);
             break;
index 2673a2cdff567285df540572dd111f283583b4ba..be7acfe1b1bbc462cae418796306ab2ad4535deb 100644 (file)
@@ -50,7 +50,7 @@
  */
 
 int DecodeTEMPLATE(ThreadVars *tv, DecodeThreadVars *dtv, Packet *p,
-                   const uint8_t *pkt, uint16_t len, PacketQueue *pq)
+                   const uint8_t *pkt, uint32_t len, PacketQueue *pq)
 {
     /* TODO add counter for your type of packet to DecodeThreadVars,
      * and register it in DecodeRegisterPerfCounters */
index e9478da2559a064e27f5c453ef085eeb05af562e..78e257eb3aa100211809a5a6d5ab2dcd7a583fba 100644 (file)
@@ -59,7 +59,7 @@ static int DecodeIEEE8021ah(ThreadVars *tv, DecodeThreadVars *dtv, Packet *p,
  * \param pq pointer to the packet queue
  *
  */
-int DecodeVLAN(ThreadVars *tv, DecodeThreadVars *dtv, Packet *p, uint8_t *pkt, uint16_t len, PacketQueue *pq)
+int DecodeVLAN(ThreadVars *tv, DecodeThreadVars *dtv, Packet *p, uint8_t *pkt, uint32_t len, PacketQueue *pq)
 {
     uint32_t proto;
 
@@ -83,7 +83,7 @@ int DecodeVLAN(ThreadVars *tv, DecodeThreadVars *dtv, Packet *p, uint8_t *pkt, u
 
     proto = GET_VLAN_PROTO(p->vlanh[p->vlan_idx]);
 
-    SCLogDebug("p %p pkt %p VLAN protocol %04x VLAN PRI %d VLAN CFI %d VLAN ID %d Len: %" PRId32 "",
+    SCLogDebug("p %p pkt %p VLAN protocol %04x VLAN PRI %d VLAN CFI %d VLAN ID %d Len: %" PRIu32 "",
             p, pkt, proto, GET_VLAN_PRIORITY(p->vlanh[p->vlan_idx]),
             GET_VLAN_CFI(p->vlanh[p->vlan_idx]), GET_VLAN_ID(p->vlanh[p->vlan_idx]), len);
 
@@ -95,10 +95,17 @@ int DecodeVLAN(ThreadVars *tv, DecodeThreadVars *dtv, Packet *p, uint8_t *pkt, u
 
     switch (proto)   {
         case ETHERNET_TYPE_IP:
+            if (unlikely(len > VLAN_HEADER_LEN + USHRT_MAX)) {
+                return TM_ECODE_FAILED;
+            }
+
             DecodeIPV4(tv, dtv, p, pkt + VLAN_HEADER_LEN,
                        len - VLAN_HEADER_LEN, pq);
             break;
         case ETHERNET_TYPE_IPV6:
+            if (unlikely(len > VLAN_HEADER_LEN + USHRT_MAX)) {
+                return TM_ECODE_FAILED;
+            }
             DecodeIPV6(tv, dtv, p, pkt + VLAN_HEADER_LEN,
                        len - VLAN_HEADER_LEN, pq);
             break;
index e9e2f38be6b0cb8a1aa8c207208321f096aaa974..3f89e6029067d8c88905c04741195fa0d7449701 100644 (file)
@@ -68,7 +68,7 @@
 #include "output-flow.h"
 
 int DecodeTunnel(ThreadVars *tv, DecodeThreadVars *dtv, Packet *p,
-        uint8_t *pkt, uint16_t len, PacketQueue *pq, enum DecodeTunnelProto proto)
+        uint8_t *pkt, uint32_t len, PacketQueue *pq, enum DecodeTunnelProto proto)
 {
     switch (proto) {
         case DECODE_TUNNEL_PPP:
@@ -203,7 +203,7 @@ inline int PacketCallocExtPkt(Packet *p, int datalen)
  *  \param Pointer to the data to copy
  *  \param Length of the data to copy
  */
-inline int PacketCopyDataOffset(Packet *p, int offset, uint8_t *data, int datalen)
+inline int PacketCopyDataOffset(Packet *p, uint32_t offset, uint8_t *data, uint32_t datalen)
 {
     if (unlikely(offset + datalen > MAX_PAYLOAD_SIZE)) {
         /* too big */
@@ -212,7 +212,11 @@ inline int PacketCopyDataOffset(Packet *p, int offset, uint8_t *data, int datale
 
     /* Do we have already an packet with allocated data */
     if (! p->ext_pkt) {
-        if (offset + datalen <= (int)default_packet_size) {
+        uint32_t newsize = offset + datalen;
+        // check overflow
+        if (newsize < offset)
+            return -1;
+        if (newsize <= default_packet_size) {
             /* data will fit in memory allocated with packet */
             memcpy(GET_PKT_DIRECT_DATA(p) + offset, data, datalen);
         } else {
@@ -240,7 +244,7 @@ inline int PacketCopyDataOffset(Packet *p, int offset, uint8_t *data, int datale
  *  \param Pointer to the data to copy
  *  \param Length of the data to copy
  */
-inline int PacketCopyData(Packet *p, uint8_t *pktdata, int pktlen)
+inline int PacketCopyData(Packet *p, uint8_t *pktdata, uint32_t pktlen)
 {
     SET_PKT_LEN(p, (size_t)pktlen);
     return PacketCopyDataOffset(p, 0, pktdata, pktlen);
@@ -257,7 +261,7 @@ inline int PacketCopyData(Packet *p, uint8_t *pktdata, int pktlen)
  *  \retval p the pseudo packet or NULL if out of memory
  */
 Packet *PacketTunnelPktSetup(ThreadVars *tv, DecodeThreadVars *dtv, Packet *parent,
-                             uint8_t *pkt, uint16_t len, enum DecodeTunnelProto proto,
+                             uint8_t *pkt, uint32_t len, enum DecodeTunnelProto proto,
                              PacketQueue *pq)
 {
     int ret;
@@ -326,7 +330,7 @@ Packet *PacketTunnelPktSetup(ThreadVars *tv, DecodeThreadVars *dtv, Packet *pare
  *
  *  \retval p the pseudo packet or NULL if out of memory
  */
-Packet *PacketDefragPktSetup(Packet *parent, uint8_t *pkt, uint16_t len, uint8_t proto)
+Packet *PacketDefragPktSetup(Packet *parent, uint8_t *pkt, uint32_t len, uint8_t proto)
 {
     SCEnter();
 
@@ -537,7 +541,7 @@ void DecodeThreadVarsFree(ThreadVars *tv, DecodeThreadVars *dtv)
  *  \param Pointer to the data
  *  \param Length of the data
  */
-inline int PacketSetData(Packet *p, uint8_t *pktdata, int pktlen)
+inline int PacketSetData(Packet *p, uint8_t *pktdata, uint32_t pktlen)
 {
     SET_PKT_LEN(p, (size_t)pktlen);
     if (unlikely(!pktdata)) {
index 64b0103e94172ee67b4ebd0dee72f7d6d31bc620..8f05fd23fa6ce69b2ddf5ab9c27aea8048cab20d 100644 (file)
@@ -908,8 +908,8 @@ enum DecodeTunnelProto {
 };
 
 Packet *PacketTunnelPktSetup(ThreadVars *tv, DecodeThreadVars *dtv, Packet *parent,
-                             uint8_t *pkt, uint16_t len, enum DecodeTunnelProto proto, PacketQueue *pq);
-Packet *PacketDefragPktSetup(Packet *parent, uint8_t *pkt, uint16_t len, uint8_t proto);
+                             uint8_t *pkt, uint32_t len, enum DecodeTunnelProto proto, PacketQueue *pq);
+Packet *PacketDefragPktSetup(Packet *parent, uint8_t *pkt, uint32_t len, uint8_t proto);
 void PacketDefragPktSetupParent(Packet *parent);
 void DecodeRegisterPerfCounters(DecodeThreadVars *, ThreadVars *);
 Packet *PacketGetFromQueueOrAlloc(void);
@@ -918,9 +918,9 @@ void PacketDecodeFinalize(ThreadVars *tv, DecodeThreadVars *dtv, Packet *p);
 void PacketFree(Packet *p);
 void PacketFreeOrRelease(Packet *p);
 int PacketCallocExtPkt(Packet *p, int datalen);
-int PacketCopyData(Packet *p, uint8_t *pktdata, int pktlen);
-int PacketSetData(Packet *p, uint8_t *pktdata, int pktlen);
-int PacketCopyDataOffset(Packet *p, int offset, uint8_t *data, int datalen);
+int PacketCopyData(Packet *p, uint8_t *pktdata, uint32_t pktlen);
+int PacketSetData(Packet *p, uint8_t *pktdata, uint32_t pktlen);
+int PacketCopyDataOffset(Packet *p, uint32_t offset, uint8_t *data, uint32_t datalen);
 const char *PktSrcToString(enum PktSrcEnum pkt_src);
 void PacketBypassCallback(Packet *p);
 
@@ -930,26 +930,26 @@ void DecodeUpdatePacketCounters(ThreadVars *tv,
                                 const DecodeThreadVars *dtv, const Packet *p);
 
 /* decoder functions */
-int DecodeEthernet(ThreadVars *, DecodeThreadVars *, Packet *, uint8_t *, uint16_t, PacketQueue *);
-int DecodeSll(ThreadVars *, DecodeThreadVars *, Packet *, uint8_t *, uint16_t, PacketQueue *);
-int DecodePPP(ThreadVars *, DecodeThreadVars *, Packet *, uint8_t *, uint16_t, PacketQueue *);
-int DecodePPPOESession(ThreadVars *, DecodeThreadVars *, Packet *, uint8_t *, uint16_t, PacketQueue *);
-int DecodePPPOEDiscovery(ThreadVars *, DecodeThreadVars *, Packet *, uint8_t *, uint16_t, PacketQueue *);
-int DecodeTunnel(ThreadVars *, DecodeThreadVars *, Packet *, uint8_t *, uint16_t, PacketQueue *, enum DecodeTunnelProto) __attribute__ ((warn_unused_result));
-int DecodeNull(ThreadVars *, DecodeThreadVars *, Packet *, uint8_t *, uint16_t, PacketQueue *);
-int DecodeRaw(ThreadVars *, DecodeThreadVars *, Packet *, uint8_t *, uint16_t, PacketQueue *);
+int DecodeEthernet(ThreadVars *, DecodeThreadVars *, Packet *, uint8_t *, uint32_t, PacketQueue *);
+int DecodeSll(ThreadVars *, DecodeThreadVars *, Packet *, uint8_t *, uint32_t, PacketQueue *);
+int DecodePPP(ThreadVars *, DecodeThreadVars *, Packet *, uint8_t *, uint32_t, PacketQueue *);
+int DecodePPPOESession(ThreadVars *, DecodeThreadVars *, Packet *, uint8_t *, uint32_t, PacketQueue *);
+int DecodePPPOEDiscovery(ThreadVars *, DecodeThreadVars *, Packet *, uint8_t *, uint32_t, PacketQueue *);
+int DecodeTunnel(ThreadVars *, DecodeThreadVars *, Packet *, uint8_t *, uint32_t, PacketQueue *, enum DecodeTunnelProto) __attribute__ ((warn_unused_result));
+int DecodeNull(ThreadVars *, DecodeThreadVars *, Packet *, uint8_t *, uint32_t, PacketQueue *);
+int DecodeRaw(ThreadVars *, DecodeThreadVars *, Packet *, uint8_t *, uint32_t, PacketQueue *);
 int DecodeIPV4(ThreadVars *, DecodeThreadVars *, Packet *, uint8_t *, uint16_t, PacketQueue *);
 int DecodeIPV6(ThreadVars *, DecodeThreadVars *, Packet *, uint8_t *, uint16_t, PacketQueue *);
-int DecodeICMPV4(ThreadVars *, DecodeThreadVars *, Packet *, uint8_t *, uint16_t, PacketQueue *);
-int DecodeICMPV6(ThreadVars *, DecodeThreadVars *, Packet *, uint8_t *, uint16_t, PacketQueue *);
+int DecodeICMPV4(ThreadVars *, DecodeThreadVars *, Packet *, uint8_t *, uint32_t, PacketQueue *);
+int DecodeICMPV6(ThreadVars *, DecodeThreadVars *, Packet *, uint8_t *, uint32_t, PacketQueue *);
 int DecodeTCP(ThreadVars *, DecodeThreadVars *, Packet *, uint8_t *, uint16_t, PacketQueue *);
 int DecodeUDP(ThreadVars *, DecodeThreadVars *, Packet *, uint8_t *, uint16_t, PacketQueue *);
 int DecodeSCTP(ThreadVars *, DecodeThreadVars *, Packet *, uint8_t *, uint16_t, PacketQueue *);
-int DecodeGRE(ThreadVars *, DecodeThreadVars *, Packet *, uint8_t *, uint16_t, PacketQueue *);
-int DecodeVLAN(ThreadVars *, DecodeThreadVars *, Packet *, uint8_t *, uint16_t, PacketQueue *);
-int DecodeMPLS(ThreadVars *, DecodeThreadVars *, Packet *, uint8_t *, uint16_t, PacketQueue *);
-int DecodeERSPAN(ThreadVars *, DecodeThreadVars *, Packet *, uint8_t *, uint16_t, PacketQueue *);
-int DecodeTEMPLATE(ThreadVars *, DecodeThreadVars *, Packet *, const uint8_t *, uint16_t, PacketQueue *);
+int DecodeGRE(ThreadVars *, DecodeThreadVars *, Packet *, uint8_t *, uint32_t, PacketQueue *);
+int DecodeVLAN(ThreadVars *, DecodeThreadVars *, Packet *, uint8_t *, uint32_t, PacketQueue *);
+int DecodeMPLS(ThreadVars *, DecodeThreadVars *, Packet *, uint8_t *, uint32_t, PacketQueue *);
+int DecodeERSPAN(ThreadVars *, DecodeThreadVars *, Packet *, uint8_t *, uint32_t, PacketQueue *);
+int DecodeTEMPLATE(ThreadVars *, DecodeThreadVars *, Packet *, const uint8_t *, uint32_t, PacketQueue *);
 
 #ifdef UNITTESTS
 void DecodeIPV6FragHeader(Packet *p, uint8_t *pkt,
@@ -961,7 +961,7 @@ void AddressDebugPrint(Address *);
 
 #ifdef AFLFUZZ_DECODER
 typedef int (*DecoderFunc)(ThreadVars *tv, DecodeThreadVars *dtv, Packet *p,
-         uint8_t *pkt, uint16_t len, PacketQueue *pq);
+         uint8_t *pkt, uint32_t len, PacketQueue *pq);
 
 int DecoderParseDataFromFile(char *filename, DecoderFunc Decoder);
 int DecoderParseDataFromFileSerie(char *fileprefix, DecoderFunc Decoder);
index fb89a03cc8b1349a06eb238ed1afeed6a4303e68..008189822857a121e4cd34fc801e93bd230601ac 100644 (file)
@@ -457,10 +457,16 @@ TmEcode DecodeIPFW(ThreadVars *tv, Packet *p, void *data, PacketQueue *pq, Packe
 
     /* Process IP packets */
     if (IPV4_GET_RAW_VER(ip4h) == 4) {
+        if (unlikely(GET_PKT_LEN(p) > USHRT_MAX)) {
+            return TM_ECODE_FAILED;
+        }
         SCLogDebug("DecodeIPFW ip4 processing");
         DecodeIPV4(tv, dtv, p, GET_PKT_DATA(p), GET_PKT_LEN(p), pq);
 
     } else if(IPV6_GET_RAW_VER(ip6h) == 6) {
+        if (unlikely(GET_PKT_LEN(p) > USHRT_MAX)) {
+            return TM_ECODE_FAILED;
+        }
         SCLogDebug("DecodeIPFW ip6 processing");
         DecodeIPV6(tv, dtv, p, GET_PKT_DATA(p), GET_PKT_LEN(p), pq);
 
index b2a9199631f70832f2a06c6c88ad1966cc718ee8..90cbe4ddfba1a57bc26cb44691137226fc9717b0 100644 (file)
@@ -503,9 +503,15 @@ TmEcode DecodeNFLOG(ThreadVars *tv, Packet *p, void *data, PacketQueue *pq, Pack
     DecodeUpdatePacketCounters(tv, dtv, p);
 
     if (IPV4_GET_RAW_VER(ip4h) == 4) {
+        if (unlikely(GET_PKT_LEN(p) > USHRT_MAX)) {
+            return TM_ECODE_FAILED;
+        }
         SCLogDebug("IPv4 packet");
         DecodeIPV4(tv, dtv, p, GET_PKT_DATA(p), GET_PKT_LEN(p), pq);
     } else if(IPV6_GET_RAW_VER(ip6h) == 6) {
+        if (unlikely(GET_PKT_LEN(p) > USHRT_MAX)) {
+            return TM_ECODE_FAILED;
+        }
         SCLogDebug("IPv6 packet");
         DecodeIPV6(tv, dtv, p, GET_PKT_DATA(p), GET_PKT_LEN(p), pq);
     } else {
index f693bccf23ea6564cd7fab462cb6fe04a06e69d3..3680c06e45616f640c22f07c13a4c86f3da59e25 100644 (file)
@@ -1183,9 +1183,15 @@ TmEcode DecodeNFQ(ThreadVars *tv, Packet *p, void *data, PacketQueue *pq, Packet
     DecodeUpdatePacketCounters(tv, dtv, p);
 
     if (IPV4_GET_RAW_VER(ip4h) == 4) {
+        if (unlikely(GET_PKT_LEN(p) > USHRT_MAX)) {
+            return TM_ECODE_FAILED;
+        }
         SCLogDebug("IPv4 packet");
         DecodeIPV4(tv, dtv, p, GET_PKT_DATA(p), GET_PKT_LEN(p), pq);
     } else if(IPV6_GET_RAW_VER(ip6h) == 6) {
+        if (unlikely(GET_PKT_LEN(p) > USHRT_MAX)) {
+            return TM_ECODE_FAILED;
+        }
         SCLogDebug("IPv6 packet");
         DecodeIPV6(tv, dtv, p, GET_PKT_DATA(p), GET_PKT_LEN(p), pq);
     } else {
index e12005b8adf91572113b6a73890ab97c2f9fa833..8852b77a59ba6a54bc7fe23634ea589f78c9eae1 100644 (file)
@@ -76,7 +76,7 @@ typedef struct PcapFileFileVars_
     PcapFileSharedVars *shared;
 } PcapFileFileVars;
 
-typedef int (*Decoder)(ThreadVars *, DecodeThreadVars *, Packet *, uint8_t *, uint16_t, PacketQueue *);
+typedef int (*Decoder)(ThreadVars *, DecodeThreadVars *, Packet *, uint8_t *, uint32_t, PacketQueue *);
 
 /**
  * Dispatch a file for processing, where the information necessary to process that