]> git.ipfire.org Git - thirdparty/suricata.git/commitdiff
dns: don't parse a full request during probe if not enough data
authorJason Ish <jason.ish@oisf.net>
Mon, 28 Feb 2022 22:48:34 +0000 (16:48 -0600)
committerVictor Julien <vjulien@oisf.net>
Tue, 19 Apr 2022 21:56:01 +0000 (23:56 +0200)
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

rust/src/dns/dns.rs

index 072cbf981feb42ed3a95b4f250e1d28d1a2e3403..485127e04eb190e43c815f58ccc91735942e9307 100644 (file)
@@ -598,9 +598,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);
         },