From: Philippe Antoine Date: Fri, 23 Sep 2022 09:01:03 +0000 (+0200) Subject: dcerpc: fix integer underflow X-Git-Tag: suricata-7.0.0-rc1~331 X-Git-Url: http://git.ipfire.org/cgi-bin/gitweb.cgi?a=commitdiff_plain;h=29f40c9e074834bfc87fb1d9c424e584c6869d04;p=thirdparty%2Fsuricata.git dcerpc: fix integer underflow as input.len() can be 65536, it cannot be directly cast to u16 Ticket: #5557 --- diff --git a/rust/src/dcerpc/dcerpc.rs b/rust/src/dcerpc/dcerpc.rs index 40609bda9f..90bee6d20a 100644 --- a/rust/src/dcerpc/dcerpc.rs +++ b/rust/src/dcerpc/dcerpc.rs @@ -759,7 +759,7 @@ impl DCERPCState { } } - pub fn handle_stub_data(&mut self, input: &[u8], input_len: u16, dir: Direction) -> u16 { + pub fn handle_stub_data(&mut self, input: &[u8], input_len: usize, dir: Direction) -> u16 { let retval; let hdrpfcflags = self.get_hdr_pfcflags().unwrap_or(0); let padleft = self.padleft; @@ -837,19 +837,20 @@ impl DCERPCState { /// Return value: /// * Success: Number of bytes successfully parsed. /// * Failure: -1 in case fragment length defined by header mismatches the data. - pub fn handle_common_stub(&mut self, input: &[u8], bytes_consumed: u16, dir: Direction) -> i32 { + pub fn handle_common_stub(&mut self, input: &[u8], bytes_consumed: usize, dir: Direction) -> i32 { let fraglen = self.get_hdr_fraglen().unwrap_or(0); - if fraglen < bytes_consumed + DCERPC_HDR_LEN { + if (fraglen as usize) < bytes_consumed + (DCERPC_HDR_LEN as usize) { return -1; } - self.padleft = fraglen - DCERPC_HDR_LEN - bytes_consumed; - let mut input_left = input.len() as u16 - bytes_consumed; + // Above check makes sure padleft stays in u16 limits + self.padleft = fraglen - DCERPC_HDR_LEN - bytes_consumed as u16; + let mut input_left = input.len() - bytes_consumed; let mut parsed = bytes_consumed as i32; while input_left > 0 && parsed < fraglen as i32 { let retval = self.handle_stub_data(&input[parsed as usize..], input_left, dir); - if retval > 0 && retval <= input_left { + if retval > 0 && retval as usize <= input_left { parsed += retval as i32; - input_left -= retval; + input_left -= >::into(retval); } else if input_left > 0 { SCLogDebug!( "Error parsing DCERPC {} stub data", @@ -891,7 +892,7 @@ impl DCERPCState { } let parsed = self.handle_common_stub( input, - (input.len() - leftover_input.len()) as u16, + input.len() - leftover_input.len(), Direction::ToServer, ); parsed @@ -1091,12 +1092,13 @@ impl DCERPCState { } fn evaluate_stub_params( - input: &[u8], input_len: u16, hdrflags: u8, lenleft: u16, + input: &[u8], input_len: usize, hdrflags: u8, lenleft: u16, stub_data_buffer: &mut Vec,stub_data_buffer_reset: &mut bool, ) -> u16 { let fragtype = hdrflags & (PFC_FIRST_FRAG | PFC_LAST_FRAG); - let stub_len: u16 = cmp::min(lenleft, input_len); + // min of usize and u16 is a valid u16 + let stub_len: u16 = cmp::min(lenleft as usize, input_len) as u16; if stub_len == 0 { return 0; }