From: Jason Ish Date: Tue, 26 Mar 2019 22:24:34 +0000 (-0600) Subject: rust/ftp: validate port components in passive reponse X-Git-Tag: suricata-5.0.0-beta1~5 X-Git-Url: http://git.ipfire.org/cgi-bin/gitweb.cgi?a=commitdiff_plain;h=9d75fdc6eafcbbc47b6cff5d54cc8bf86237585e;p=thirdparty%2Fsuricata.git rust/ftp: validate port components in passive reponse Make sure they are valid 8 bit integers before combining the two parts into a u16 to prevent an overflow of the u16 return value. Add unit tests to check parsing of invalid ports. Redmine issue: https://redmine.openinfosecfoundation.org/issues/2904 --- diff --git a/rust/src/ftp/mod.rs b/rust/src/ftp/mod.rs index 58cdff92e9..958a77a5b8 100644 --- a/rust/src/ftp/mod.rs +++ b/rust/src/ftp/mod.rs @@ -46,9 +46,9 @@ named!(pub ftp_pasv_response, take_until_and_consume!("(") >> digit >> tag!(",") >> digit >> tag!(",") >> digit >> tag!(",") >> digit >> tag!(",") >> - part1: getu16 >> + part1: verify!(getu16, |v| v <= std::u8::MAX as u16) >> tag!(",") >> - part2: getu16 >> + part2: verify!(getu16, |v| v <= std::u8::MAX as u16) >> alt! (tag!(").") | tag!(")")) >> ( part1 * 256 + part2 @@ -108,3 +108,24 @@ pub extern "C" fn rs_ftp_epsv_response(input: *const libc::uint8_t, len: libc::u } return 0; } + +#[cfg(test)] +mod test { + use super::*; + + #[test] + fn test_pasv_response_valid() { + let port = ftp_pasv_response("227 Entering Passive Mode (212,27,32,66,221,243).".as_bytes()); + assert_eq!(port, Ok((&b""[..], 56819))); + } + + // A port that is too large for a u16. + #[test] + fn test_pasv_response_too_large() { + let port = ftp_pasv_response("227 Entering Passive Mode (212,27,32,66,257,243).".as_bytes()); + assert!(port.is_err()); + + let port = ftp_pasv_response("227 Entering Passive Mode (212,27,32,66,255,65535).".as_bytes()); + assert!(port.is_err()); + } +}