From 19e91292e84cb7e4367e9b2987df9a1c059d0c48 Mon Sep 17 00:00:00 2001 From: ronwellman Date: Fri, 24 Jul 2020 09:26:09 -0400 Subject: [PATCH] Validate option_len in EDNS packets. --- src/analyzer/protocol/dns/DNS.cc | 15 ++++++++++++--- 1 file changed, 12 insertions(+), 3 deletions(-) diff --git a/src/analyzer/protocol/dns/DNS.cc b/src/analyzer/protocol/dns/DNS.cc index de75652d6e..bd704667f4 100644 --- a/src/analyzer/protocol/dns/DNS.cc +++ b/src/analyzer/protocol/dns/DNS.cc @@ -712,7 +712,11 @@ bool DNS_Interpreter::ParseRR_EDNS(DNS_MsgInfo* msg, while ( len > 0 ) { uint16_t option_code = ExtractShort(data, len); - int option_len = ExtractShort(data, len); + uint16_t option_len = ExtractShort(data, len); + // check for invalid option length + if ( (option_len > len) || (0 == option_len) ) { + break; + } len -= option_len; // TODO: Implement additional option codes @@ -720,9 +724,14 @@ bool DNS_Interpreter::ParseRR_EDNS(DNS_MsgInfo* msg, { case TYPE_ECS: { + // must be 4 bytes + variable number of octets for address + if ( option_len <= 4 ) { + break; + } + EDNS_ECS opt{}; - uint16_t ecs_family = ExtractShort(data, option_len); - uint16_t source_scope = ExtractShort(data, option_len); + uint16_t ecs_family = ExtractShort(data, (int&)option_len); + uint16_t source_scope = ExtractShort(data, (int&)option_len); opt.ecs_src_pfx_len = (source_scope >> 8) & 0xff; opt.ecs_scp_pfx_len = source_scope & 0xff;