mirror of
https://github.com/zeek/zeek.git
synced 2025-10-13 03:58:20 +00:00
Add some extra length checking when parsing mobile ipv6 packets
Credit to OSS-Fuzz for discovery https://bugs.chromium.org/p/oss-fuzz/issues/detail?id=34263 (Link to details becomes public 30 days after patch release)
This commit is contained in:
parent
2c27f1bf34
commit
54271657a8
4 changed files with 57 additions and 22 deletions
49
src/IP.cc
49
src/IP.cc
|
@ -619,6 +619,12 @@ void IPv6_Hdr_Chain::ProcessRoutingHeader(const struct ip6_rthdr* r, uint16_t le
|
|||
#ifdef ENABLE_MOBILE_IPV6
|
||||
void IPv6_Hdr_Chain::ProcessDstOpts(const struct ip6_dest* d, uint16_t len)
|
||||
{
|
||||
// Skip two bytes to get the beginning of the first option structure. These
|
||||
// two bytes are the protocol for the next header and extension header length,
|
||||
// already known to exist before calling this method. See header format:
|
||||
// https://datatracker.ietf.org/doc/html/rfc8200#section-4.6
|
||||
assert(len >= 2);
|
||||
|
||||
const u_char* data = (const u_char*) d;
|
||||
len -= 2 * sizeof(uint8_t);
|
||||
data += 2* sizeof(uint8_t);
|
||||
|
@ -627,32 +633,43 @@ void IPv6_Hdr_Chain::ProcessDstOpts(const struct ip6_dest* d, uint16_t len)
|
|||
{
|
||||
const struct ip6_opt* opt = (const struct ip6_opt*) data;
|
||||
switch ( opt->ip6o_type ) {
|
||||
case 201: // Home Address Option, Mobile IPv6 RFC 6275 section 6.3
|
||||
case 0:
|
||||
// If option type is zero, it's a Pad0 and can be just a single
|
||||
// byte in width. Skip over it.
|
||||
data += sizeof(uint8_t);
|
||||
len -= sizeof(uint8_t);
|
||||
break;
|
||||
default:
|
||||
{
|
||||
// Double-check that the len can hold the whole option structure.
|
||||
// Otherwise we get a buffer-overflow when we check the option_len.
|
||||
// Also check that it holds everything for the option itself.
|
||||
if ( len < sizeof(struct ip6_opt) ||
|
||||
len < sizeof(struct ip6_opt) + opt->ip6o_len )
|
||||
{
|
||||
reporter->Weird(SrcAddr(), DstAddr(), "bad_ipv6_dest_opt_len");
|
||||
len = 0;
|
||||
break;
|
||||
}
|
||||
|
||||
if ( opt->ip6o_type == 201 ) // Home Address Option, Mobile IPv6 RFC 6275 section 6.3
|
||||
{
|
||||
if ( opt->ip6o_len == sizeof(struct in6_addr) )
|
||||
{
|
||||
if ( opt->ip6o_len == 16 )
|
||||
if ( homeAddr )
|
||||
reporter->Weird(SrcAddr(), DstAddr(), "multiple_home_addr_opts");
|
||||
else
|
||||
homeAddr = new IPAddr(*((const in6_addr*)(data + 2)));
|
||||
homeAddr = new IPAddr(*((const in6_addr*)(data + sizeof(struct ip6_opt))));
|
||||
}
|
||||
else
|
||||
reporter->Weird(SrcAddr(), DstAddr(), "bad_home_addr_len");
|
||||
}
|
||||
break;
|
||||
|
||||
default:
|
||||
data += sizeof(struct ip6_opt) + opt->ip6o_len;
|
||||
len -= sizeof(struct ip6_opt) + opt->ip6o_len;
|
||||
}
|
||||
break;
|
||||
}
|
||||
|
||||
if ( opt->ip6o_type == 0 )
|
||||
{
|
||||
data += sizeof(uint8_t);
|
||||
len -= sizeof(uint8_t);
|
||||
}
|
||||
else
|
||||
{
|
||||
data += 2 * sizeof(uint8_t) + opt->ip6o_len;
|
||||
len -= 2 * sizeof(uint8_t) + opt->ip6o_len;
|
||||
}
|
||||
}
|
||||
}
|
||||
#endif
|
||||
|
|
14
testing/btest/Baseline/core.mobile-ipv6-dst-opts/weird.log
Normal file
14
testing/btest/Baseline/core.mobile-ipv6-dst-opts/weird.log
Normal file
|
@ -0,0 +1,14 @@
|
|||
### 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 - 2001:4f8:4:7:2e0:81ff:fe52:ffff 0 2001:4f8:4:7:2e0:81ff:fe52:9a6b 0 bad_ipv6_dest_opt_len - F zeek -
|
||||
XXXXXXXXXX.XXXXXX - 2001:78:1:32::1 0 2001:4f8:4:7:2e0:81ff:fe52:9a6b 0 multiple_home_addr_opts - F zeek -
|
||||
XXXXXXXXXX.XXXXXX - 2001:78:1:32::1 0 2001:4f8:4:7:2e0:81ff:fe52:9a6b 0 invalid_IP_header_size - F zeek IP
|
||||
XXXXXXXXXX.XXXXXX - 2001:4f8:4:7:2e0:81ff:fe52:ffff 0 2001:4f8:4:7:2e0:81ff:fe52:9a6b 0 bad_home_addr_len - F zeek -
|
||||
#close XXXX-XX-XX-XX-XX-XX
|
BIN
testing/btest/Traces/ipv6-mobility-dst-opts.trace
Executable file
BIN
testing/btest/Traces/ipv6-mobility-dst-opts.trace
Executable file
Binary file not shown.
4
testing/btest/core/mobile-ipv6-dst-opts.test
Normal file
4
testing/btest/core/mobile-ipv6-dst-opts.test
Normal file
|
@ -0,0 +1,4 @@
|
|||
# @TEST-REQUIRES: grep -q "#define ENABLE_MOBILE_IPV6" $BUILD/zeek-config.h
|
||||
#
|
||||
# @TEST-EXEC: zeek -C -r $TRACES/ipv6-mobility-dst-opts.trace
|
||||
# @TEST-EXEC: btest-diff weird.log
|
Loading…
Add table
Add a link
Reference in a new issue