From 0e34f2e02f88d0699a3431f2144ca343f93c986d Mon Sep 17 00:00:00 2001 From: Tim Wojtulewicz Date: Thu, 27 May 2021 16:33:50 -0700 Subject: [PATCH] Fix handling of IP packets with bogus IP header lengths Credit to OSS-Fuzz for discovery https://bugs.chromium.org/p/oss-fuzz/issues/detail?id=34711 (Link to details becomes public 30 days after patch release) --- src/packet_analysis/protocol/ip/IP.cc | 7 +++++++ .../ip-bogus-header-weird.log | 12 ++++++++++++ .../{weird.log => mpls-6in6-broken-wierd.log} | 0 testing/btest/Traces/ip-bogus-header-len.pcap | Bin 0 -> 100 bytes testing/btest/core/ip-broken-header.zeek | 6 +++++- 5 files changed, 24 insertions(+), 1 deletion(-) create mode 100644 testing/btest/Baseline/core.ip-broken-header/ip-bogus-header-weird.log rename testing/btest/Baseline/core.ip-broken-header/{weird.log => mpls-6in6-broken-wierd.log} (100%) create mode 100644 testing/btest/Traces/ip-bogus-header-len.pcap diff --git a/src/packet_analysis/protocol/ip/IP.cc b/src/packet_analysis/protocol/ip/IP.cc index 4d05600e6a..e384397cd4 100644 --- a/src/packet_analysis/protocol/ip/IP.cc +++ b/src/packet_analysis/protocol/ip/IP.cc @@ -235,6 +235,13 @@ bool IPAnalyzer::AnalyzePacket(size_t len, const uint8_t* data, Packet* packet) packet->proto = proto; + // Double check the lengths one more time before forwarding this on. + if ( packet->ip_hdr->TotalLen() < packet->ip_hdr->HdrLen() ) + { + Weird("bogus_IP_header_lengths", packet); + return false; + } + switch ( proto ) { case IPPROTO_NONE: // If the packet is encapsulated in Teredo, then it was a bubble and diff --git a/testing/btest/Baseline/core.ip-broken-header/ip-bogus-header-weird.log b/testing/btest/Baseline/core.ip-broken-header/ip-bogus-header-weird.log new file mode 100644 index 0000000000..d5adac806f --- /dev/null +++ b/testing/btest/Baseline/core.ip-broken-header/ip-bogus-header-weird.log @@ -0,0 +1,12 @@ +### BTest baseline data generated by btest-diff. Do not edit. Use "btest -U/-u" to update. Requires BTest >= 0.63. +#separator \x09 +#set_separator , +#empty_field (empty) +#unset_field - +#path weird +#open XXXX-XX-XX-XX-XX-XX +#fields ts uid id.orig_h id.orig_p id.resp_h id.resp_p name addl notice peer source +#types time string addr port addr port string string bool string string +XXXXXXXXXX.XXXXXX - 118.181.144.194 0 136.255.115.116 0 ip_hdr_len_zero - F zeek IP +XXXXXXXXXX.XXXXXX - 118.181.144.194 0 136.255.115.116 0 bogus_IP_header_lengths - F zeek IP +#close XXXX-XX-XX-XX-XX-XX diff --git a/testing/btest/Baseline/core.ip-broken-header/weird.log b/testing/btest/Baseline/core.ip-broken-header/mpls-6in6-broken-wierd.log similarity index 100% rename from testing/btest/Baseline/core.ip-broken-header/weird.log rename to testing/btest/Baseline/core.ip-broken-header/mpls-6in6-broken-wierd.log diff --git a/testing/btest/Traces/ip-bogus-header-len.pcap b/testing/btest/Traces/ip-bogus-header-len.pcap new file mode 100644 index 0000000000000000000000000000000000000000..27f9057b5e27fa5483ed288aa1d50cfa0a7b7134 GIT binary patch literal 100 zcmca|c+)~A1{MYcU}Rtfa+3D1PcY|aVz2?SK^P2}z$7CFgDW!wgQ^aY2UJ|Pb;6;J Q|HUPVC8_^`A|Q+g0Q2e&tN;K2 literal 0 HcmV?d00001 diff --git a/testing/btest/core/ip-broken-header.zeek b/testing/btest/core/ip-broken-header.zeek index 08c72b06f1..d2c13af76e 100644 --- a/testing/btest/core/ip-broken-header.zeek +++ b/testing/btest/core/ip-broken-header.zeek @@ -2,6 +2,10 @@ # OOB reads in Zeek. It has a number of packets broken in weird ways. # # @TEST-EXEC: gunzip -c $TRACES/trunc/mpls-6in6-broken.pcap.gz | zeek -C -b -r - %INPUT -# @TEST-EXEC: btest-diff weird.log +# @TEST-EXEC: mv weird.log mpls-6in6-broken-wierd.log +# @TEST-EXEC: btest-diff mpls-6in6-broken-wierd.log +# @TEST-EXEC: zeek -C -b -r $TRACES/ip-bogus-header-len.pcap %INPUT +# @TEST-EXEC: mv weird.log ip-bogus-header-weird.log +# @TEST-EXEC: btest-diff ip-bogus-header-weird.log @load base/frameworks/notice/weird