From eeb8c17e0fe214a63c56c99e44ba1f3eee7dca6d Mon Sep 17 00:00:00 2001 From: Jason Ish Date: Mon, 28 Feb 2022 16:48:34 -0600 Subject: [PATCH] dns: don't parse a full request during probe if not enough data If there is more data than a header, but not enough for a complete DNS message, the hostname parser could return an error causing the probe to fail on valid DNS messages. So only parse the complete message if we have enough input data. This is reliable for TCP as DNS messages are prefixed, but for UDP its just going to be the size of the input buffer presented to the parser, so incomplete could still happen. Ticket #5034 (cherry picked from commit 27679a12aa4e03e960112f387640419d29780e5a) --- rust/src/dns/dns.rs | 18 ++++++++++++++++-- 1 file changed, 16 insertions(+), 2 deletions(-) diff --git a/rust/src/dns/dns.rs b/rust/src/dns/dns.rs index 6c6ccd5ed7..7f30ec8c6b 100644 --- a/rust/src/dns/dns.rs +++ b/rust/src/dns/dns.rs @@ -713,9 +713,23 @@ fn probe_header_validity(header: DNSHeader, rlen: usize) -> (bool, bool, bool) { } /// Probe input to see if it looks like DNS. +/// +/// Returns a tuple of booleans: (is_dns, is_request, incomplete) fn probe(input: &[u8], dlen: usize) -> (bool, bool, bool) { - let i2 = if input.len() <= dlen { input } else { &input[..dlen] }; - match parser::dns_parse_request(i2) { + // Trim input to dlen if larger. + let input = if input.len() <= dlen { input } else { &input[..dlen] }; + + // If input is less than dlen then we know we don't have enough data to + // parse a complete message, so perform header validation only. + if input.len() < dlen { + if let Ok((_, header)) = parser::dns_parse_header(input) { + return probe_header_validity(header, dlen); + } else { + return (false, false, false); + } + } + + match parser::dns_parse_request(input) { Ok((_, request)) => { return probe_header_validity(request.header, dlen); }, -- 2.47.2