From: Victor Julien Date: Wed, 16 Dec 2015 09:50:50 +0000 (+0100) Subject: icmpv4: harden embedded packet handling X-Git-Tag: suricata-3.0RC3~11 X-Git-Url: http://git.ipfire.org/cgi-bin/gitweb.cgi?a=commitdiff_plain;h=ed1cc1ee2af993d9be68c91d03b7823644e3273d;p=thirdparty%2Fsuricata.git icmpv4: harden embedded packet handling --- diff --git a/src/decode-icmpv4.c b/src/decode-icmpv4.c index 5af012ce9a..45b213f670 100644 --- a/src/decode-icmpv4.c +++ b/src/decode-icmpv4.c @@ -47,13 +47,13 @@ /** * Note, this is the IP header, plus a bit of the original packet, not the whole thing! */ -void DecodePartialIPV4( Packet* p, uint8_t* partial_packet, uint16_t len ) +int DecodePartialIPV4( Packet* p, uint8_t* partial_packet, uint16_t len ) { /** Check the sizes, the header must fit at least */ if (len < IPV4_HEADER_LEN) { SCLogDebug("DecodePartialIPV4: ICMPV4_IPV4_TRUNC_PKT"); ENGINE_SET_INVALID_EVENT(p, ICMPV4_IPV4_TRUNC_PKT); - return; + return -1; } IPV4Hdr *icmp4_ip4h = (IPV4Hdr*)partial_packet; @@ -64,7 +64,7 @@ void DecodePartialIPV4( Packet* p, uint8_t* partial_packet, uint16_t len ) SCLogDebug("DecodePartialIPV4: ICMPv4 contains Unknown IPV4 version " "ICMPV4_IPV4_UNKNOWN_VER"); ENGINE_SET_INVALID_EVENT(p, ICMPV4_IPV4_UNKNOWN_VER); - return; + return -1; } /** We need to fill icmpv4vars */ @@ -125,12 +125,14 @@ void DecodePartialIPV4( Packet* p, uint8_t* partial_packet, uint16_t len ) break; case IPPROTO_ICMP: - p->icmpv4vars.emb_icmpv4h = (ICMPV4Hdr*)(partial_packet + IPV4_HEADER_LEN); - p->icmpv4vars.emb_sport = 0; - p->icmpv4vars.emb_dport = 0; - p->icmpv4vars.emb_ip4_proto = IPPROTO_ICMP; + if (len >= IPV4_HEADER_LEN + ICMPV4_HEADER_LEN ) { + p->icmpv4vars.emb_icmpv4h = (ICMPV4Hdr*)(partial_packet + IPV4_HEADER_LEN); + p->icmpv4vars.emb_sport = 0; + p->icmpv4vars.emb_dport = 0; + p->icmpv4vars.emb_ip4_proto = IPPROTO_ICMP; - SCLogDebug("DecodePartialIPV4: ICMPV4->IPV4->ICMP header"); + SCLogDebug("DecodePartialIPV4: ICMPV4->IPV4->ICMP header"); + } break; } @@ -144,8 +146,7 @@ void DecodePartialIPV4( Packet* p, uint8_t* partial_packet, uint16_t len ) IPV4_GET_RAW_IPPROTO(icmp4_ip4h), IPV4_GET_RAW_IPID(icmp4_ip4h)); #endif - return; - + return 0; } /** DecodeICMPV4 @@ -188,11 +189,13 @@ int DecodeICMPV4(ThreadVars *tv, DecodeThreadVars *dtv, Packet *p, uint8_t *pkt, } else { /* parse IP header plus 64 bytes */ if (len > ICMPV4_HEADER_PKT_OFFSET) { - DecodePartialIPV4( p, (uint8_t *)(pkt + ICMPV4_HEADER_PKT_OFFSET), len - ICMPV4_HEADER_PKT_OFFSET ); - - /* ICMP ICMP_DEST_UNREACH influence TCP/UDP flows */ - if (ICMPV4_DEST_UNREACH_IS_VALID(p)) { - FlowHandlePacket(tv, dtv, p); + if (DecodePartialIPV4(p, (uint8_t *)(pkt + ICMPV4_HEADER_PKT_OFFSET), + len - ICMPV4_HEADER_PKT_OFFSET ) == 0) + { + /* ICMP ICMP_DEST_UNREACH influence TCP/UDP flows */ + if (ICMPV4_DEST_UNREACH_IS_VALID(p)) { + FlowHandlePacket(tv, dtv, p); + } } } }