From: Victor Julien Date: Sat, 19 Feb 2022 07:42:35 +0000 (+0100) Subject: nfs/rpc: enforce length field limits X-Git-Tag: suricata-5.0.9~59 X-Git-Url: http://git.ipfire.org/cgi-bin/gitweb.cgi?a=commitdiff_plain;h=432af6d5ede43db785d3f0ace12f346e5361d719;p=thirdparty%2Fsuricata.git nfs/rpc: enforce length field limits 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) --- diff --git a/rust/src/nfs/rpc_records.rs b/rust/src/nfs/rpc_records.rs index 723c73e55d..8565d998e3 100644 --- a/rust/src/nfs/rpc_records.rs +++ b/rust/src/nfs/rpc_records.rs @@ -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 @@ -19,6 +19,10 @@ 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, 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, 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, >> 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, >> 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 { frag_is_last:false, frag_len:0, - xid:xid, msgtype:msgtype, } @@ -298,14 +301,14 @@ named!(pub parse_rpc_udp_request, >> 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, 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