]> git.ipfire.org Git - thirdparty/suricata.git/commitdiff
dns: better error handling when parsing names
authorJason Ish <jason.ish@oisf.net>
Tue, 1 Feb 2022 21:44:43 +0000 (15:44 -0600)
committerShivani Bhardwaj <shivanib134@gmail.com>
Thu, 21 Apr 2022 07:31:56 +0000 (13:01 +0530)
The DNS name parser will error out with an error even if the
error is incomplete. Instead of manually generating errors,
use '?' to let the nom error ripple up the error handling chain.

The reason this wasn't done in the first place is this code
predates the ? operator, or we were not aware of it at the time.

This prevents the case where probing fails when there is enough data to
parse the header, but not enough to complete name parser. In such a case
a parse error is returned (instead of incomplete) resulting in the
payload not being detected as DNS.

Ticket #5034

(cherry picked from commit 0623ada24df1da99c72bb8cd4959b2cb0e64ccc2)

rust/src/dns/parser.rs

index 0f7038dda61475ed7c31d65d9a97c5ad63856acc..d25e0ad233101a98a87afd95a41a91d3b934da25 100644 (file)
@@ -20,7 +20,6 @@
 use nom::IResult;
 use nom::combinator::rest;
 use nom::error::ErrorKind;
-use nom::multi::length_data;
 use nom::number::streaming::{be_u8, be_u16, be_u32};
 use nom;
 use crate::dns::dns::*;
@@ -71,36 +70,21 @@ pub fn dns_parse_name<'a, 'b>(start: &'b [u8],
             pos = &pos[1..];
             break;
         } else if len & 0b1100_0000 == 0 {
-            match length_data(be_u8)(pos) as IResult<&[u8],_> {
-                Ok((rem, label)) => {
-                    if name.len() > 0 {
-                        name.push('.' as u8);
-                    }
-                    name.extend(label);
-                    pos = rem;
-                }
-                _ => {
-                    return Err(nom::Err::Error(
-                        error_position!(pos, ErrorKind::OctDigit)));
-                }
+            let (rem, label) = nom::length_data!(pos, be_u8)?;
+            if name.len() > 0 {
+                name.push('.' as u8);
             }
+            name.extend(label);
+            pos = rem;
         } else if len & 0b1100_0000 == 0b1100_0000 {
-            match be_u16(pos) as IResult<&[u8],_> {
-                Ok((rem, leader)) => {
-                    let offset = usize::from(leader) & 0x3fff;
-                    if offset > message.len() {
-                        return Err(nom::Err::Error(
-                            error_position!(pos, ErrorKind::OctDigit)));
-                    }
-                    pos = &message[offset..];
-                    if pivot == start {
-                        pivot = rem;
-                    }
-                }
-                _ => {
-                    return Err(nom::Err::Error(
-                        error_position!(pos, ErrorKind::OctDigit)));
-                }
+            let (rem, leader) = be_u16(pos)?;
+            let offset = usize::from(leader) & 0x3fff;
+            if offset > message.len() {
+                return Err(nom::Err::Error(error_position!(pos, nom::error::ErrorKind::OctDigit)));
+            }
+            pos = &message[offset..];
+            if pivot == start {
+                pivot = rem;
             }
         } else {
             return Err(nom::Err::Error(