]> git.ipfire.org Git - thirdparty/suricata.git/commitdiff
rust/ftp: validate port components in passive reponse
authorJason Ish <ish@unx.ca>
Tue, 26 Mar 2019 22:24:34 +0000 (16:24 -0600)
committerVictor Julien <victor@inliniac.net>
Tue, 30 Apr 2019 09:12:28 +0000 (11:12 +0200)
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

rust/src/ftp/mod.rs

index 58cdff92e9f98a28f0e1ad3206ead615afcdca7e..958a77a5b89bb9ca3a8f2790cd52b86a93325f2a 100644 (file)
@@ -46,9 +46,9 @@ named!(pub ftp_pasv_response<u16>,
             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());
+    }
+}