]> git.ipfire.org Git - thirdparty/suricata.git/commitdiff
range: checks that end is after start for HTTP2 6492/head
authorPhilippe Antoine <contact@catenacyber.fr>
Tue, 19 Oct 2021 10:38:49 +0000 (12:38 +0200)
committerPhilippe Antoine <contact@catenacyber.fr>
Tue, 19 Oct 2021 21:10:29 +0000 (23:10 +0200)
As was done only for HTTP1 in previous commit

The verification part stays separated from the parsing part,
as we want to keep on logging invalid ranges values.

rust/src/http2/http2.rs
rust/src/http2/range.rs

index 99a8d16a1c47a76df26b5ef7a1851e34ae4f1a99..3cbbf1d2b310b5618e3d2fd322d65ea76dd73a6e 100644 (file)
@@ -221,7 +221,7 @@ impl HTTP2Transaction {
                     STREAM_TOCLIENT,
                     "content-range",
                 ) {
-                    match range::http2_parse_content_range(&value) {
+                    match range::http2_parse_check_content_range(&value) {
                         Ok((_, v)) => {
                             range::http2_range_open(self, &v, flow, sfcm, flags, decompressed);
                             if over && self.file_range != std::ptr::null_mut() {
index 55338209051b418a68465d600f5f01ee5e0f8c07..08f3b5bec59c68c9a8b1aa4a98186a184362c700 100644 (file)
@@ -23,6 +23,8 @@ use crate::filecontainer::FileContainer;
 use crate::http2::http2::HTTP2Transaction;
 
 use nom::character::complete::digit1;
+use nom::error::ErrorKind;
+use nom::Err;
 use nom::IResult;
 use std::os::raw::c_uchar;
 use std::str::FromStr;
@@ -68,7 +70,7 @@ pub fn http2_parse_content_range_def<'a>(input: &'a [u8]) -> IResult<&'a [u8], H
     ));
 }
 
-pub fn http2_parse_content_range<'a>(input: &'a [u8]) -> IResult<&'a [u8], HTTPContentRange> {
+fn http2_parse_content_range<'a>(input: &'a [u8]) -> IResult<&'a [u8], HTTPContentRange> {
     let (i2, _) = take_while!(input, |c| c == b' ')?;
     let (i2, _) = take_till!(i2, |c| c == b' ')?;
     let (i2, _) = take_while!(i2, |c| c == b' ')?;
@@ -78,6 +80,14 @@ pub fn http2_parse_content_range<'a>(input: &'a [u8]) -> IResult<&'a [u8], HTTPC
     );
 }
 
+pub fn http2_parse_check_content_range<'a>(input: &'a [u8]) -> IResult<&'a [u8], HTTPContentRange> {
+    let (rem, v) = http2_parse_content_range(input)?;
+    if v.start > v.end {
+        return Err(Err::Error((rem, ErrorKind::Verify)));
+    }
+    return Ok((rem, v));
+}
+
 #[no_mangle]
 pub unsafe extern "C" fn rs_http_parse_content_range(
     cr: &mut HTTPContentRange, buffer: *const u8, buffer_len: u32,
@@ -127,6 +137,13 @@ pub fn http2_range_open(
     tx: &mut HTTP2Transaction, v: &HTTPContentRange, flow: *const Flow,
     cfg: &'static SuricataFileContext, flags: u16, data: &[u8],
 ) {
+    if v.end <= 0 || v.size <= 0 {
+        // skipped for incomplete range information
+        return;
+    } else if v.end == v.size - 1 && v.start == 0 {
+        // whole file in one range
+        return;
+    }
     if let Ok((key, index)) = http2_range_key_get(tx) {
         let name = &key[index..];
         tx.file_range = unsafe {