]> git.ipfire.org Git - thirdparty/suricata.git/commitdiff
nfs/rpc: enforce length field limits
authorVictor Julien <vjulien@oisf.net>
Sat, 19 Feb 2022 07:42:35 +0000 (08:42 +0100)
committerJason Ish <jason.ish@oisf.net>
Tue, 15 Mar 2022 18:05:56 +0000 (12:05 -0600)
Limits based on the Linux kernel limits. Then multiplied a few times
to allow for other implementations to have higher limits.

(cherry picked from commit fe76ab1803bea02f47f691b5944ba319a3bc0300)

rust/src/nfs/rpc_records.rs

index 723c73e55d1e1710f2c73e0c3d880dc2f1358d8c..8565d998e3a647081f6a09ec449213be86be411a 100644 (file)
@@ -1,4 +1,4 @@
-/* Copyright (C) 2017-2018 Open Information Security Foundation
+/* Copyright (C) 2017-2022 Open Information Security Foundation
  *
  * You can copy, redistribute or modify this Program under the terms of
  * the GNU General Public License version 2 as published by the Free
 
 use nom::{be_u32, rest};
 
+pub const RPC_MAX_MACHINE_SIZE: u32 = 256; // Linux kernel defines 64.
+pub const RPC_MAX_CREDS_SIZE: u32 = 4096; // Linux kernel defines 400.
+pub const RPC_MAX_VERIFIER_SIZE: u32 = 4096; // Linux kernel defines 400.
+
 #[derive(Debug,PartialEq)]
 pub enum RpcRequestCreds<'a> {
     Unix(RpcRequestCredsUnix<'a>),
@@ -44,7 +48,7 @@ pub struct RpcRequestCredsUnix<'a> {
 named!(parse_rpc_request_creds_unix<RpcRequestCreds>,
     do_parse!(
         stamp: be_u32
-    >>  machine_name_len: be_u32
+    >>  machine_name_len: verify!(be_u32, |size| size < RPC_MAX_MACHINE_SIZE)
     >>  machine_name_buf: take!(machine_name_len)
     >>  uid: be_u32
     >>  gid: be_u32
@@ -102,7 +106,7 @@ pub struct RpcGssApiIntegrity<'a> {
 // data we care about.
 named!(pub parse_rpc_gssapi_integrity<RpcGssApiIntegrity>,
     do_parse!(
-        len: be_u32
+        len: verify!(be_u32, |size| size < RPC_MAX_CREDS_SIZE)
     >>  seq_num: be_u32
     >>  data: take!(len)
     >> (RpcGssApiIntegrity {
@@ -209,14 +213,14 @@ named!(pub parse_rpc<RpcPacket>,
        >> procedure: be_u32
 
        >> creds_flavor: be_u32
-       >> creds_len: be_u32
+       >> creds_len: verify!(be_u32, |size| size < RPC_MAX_CREDS_SIZE)
        >> creds: flat_map!(take!(creds_len), switch!(value!(creds_flavor),
             1 => call!(parse_rpc_request_creds_unix)    |
             6 => call!(parse_rpc_request_creds_gssapi)  |
             _ => call!(parse_rpc_request_creds_unknown) ))
 
        >> verifier_flavor: be_u32
-       >> verifier_len: be_u32
+       >> verifier_len: verify!(be_u32, |size| size < RPC_MAX_VERIFIER_SIZE)
        >> verifier: take!(verifier_len as usize)
 
        >> pl: rest
@@ -250,7 +254,7 @@ named!(pub parse_rpc_reply<RpcReplyPacket>,
        >> reply_state: be_u32
 
        >> verifier_flavor: be_u32
-       >> verifier_len: be_u32
+       >> verifier_len: verify!(be_u32, |size| size < RPC_MAX_VERIFIER_SIZE)
        >> verifier: cond!(verifier_len > 0, take!(verifier_len as usize))
 
        >> accept_state: be_u32
@@ -281,7 +285,6 @@ named!(pub parse_rpc_udp_packet_header<RpcPacketHeader>,
             RpcPacketHeader {
                 frag_is_last:false,
                 frag_len:0,
-
                 xid:xid,
                 msgtype:msgtype,
             }
@@ -298,14 +301,14 @@ named!(pub parse_rpc_udp_request<RpcPacket>,
        >> procedure: be_u32
 
        >> creds_flavor: be_u32
-       >> creds_len: be_u32
+       >> creds_len: verify!(be_u32, |size| size < RPC_MAX_CREDS_SIZE)
        >> creds: flat_map!(take!(creds_len), switch!(value!(creds_flavor),
             1 => call!(parse_rpc_request_creds_unix)    |
             6 => call!(parse_rpc_request_creds_gssapi)  |
             _ => call!(parse_rpc_request_creds_unknown) ))
 
        >> verifier_flavor: be_u32
-       >> verifier_len: be_u32
+       >> verifier_len: verify!(be_u32, |size| size < RPC_MAX_VERIFIER_SIZE)
        >> verifier: take!(verifier_len as usize)
 
        >> pl: rest
@@ -336,7 +339,7 @@ named!(pub parse_rpc_udp_reply<RpcReplyPacket>,
        hdr: parse_rpc_udp_packet_header
 
        >> verifier_flavor: be_u32
-       >> verifier_len: be_u32
+       >> verifier_len: verify!(be_u32, |size| size < RPC_MAX_VERIFIER_SIZE)
        >> verifier: cond!(verifier_len > 0, take!(verifier_len as usize))
 
        >> reply_state: be_u32