range: checks that end is after start for HTTP2

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.
pull/6492/head
Philippe Antoine 4 years ago
parent 07370ed5c0
commit 5bd065cb3c

@ -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() {

@ -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 {

Loading…
Cancel
Save