-/* 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 crate::common::nom7::bits;
use nom7::bits::streaming::take as take_bits;
use nom7::bytes::streaming::take;
-use nom7::combinator::cond;
+use nom7::combinator::{cond, verify};
use nom7::multi::length_data;
-use nom7::number::streaming::be_u32;
+use nom7::number::streaming::{be_u32};
use nom7::sequence::tuple;
use nom7::IResult;
+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>),
fn parse_rpc_request_creds_unix(i: &[u8]) -> IResult<&[u8], RpcRequestCreds> {
let (i, stamp) = be_u32(i)?;
- let (i, machine_name_len) = be_u32(i)?;
+ let (i, machine_name_len) = verify(be_u32, |&size| size < RPC_MAX_MACHINE_SIZE)(i)?;
let (i, machine_name_buf) = take(machine_name_len as usize)(i)?;
let (i, uid) = be_u32(i)?;
let (i, gid) = be_u32(i)?;
// Parse the GSSAPI Integrity envelope to get to the
// data we care about.
pub fn parse_rpc_gssapi_integrity(i: &[u8]) -> IResult<&[u8], RpcGssApiIntegrity> {
- let (i, len) = be_u32(i)?;
+ let (i, len) = verify(be_u32, |&size| size < RPC_MAX_CREDS_SIZE)(i)?;
let (i, seq_num) = be_u32(i)?;
let (i, data) = take(len as usize)(i)?;
let res = RpcGssApiIntegrity { seq_num, data };
let (i, procedure) = be_u32(i)?;
let (i, creds_flavor) = be_u32(i)?;
- let (i, creds_len) = be_u32(i)?;
+ let (i, creds_len) = verify(be_u32, |&size| size < RPC_MAX_CREDS_SIZE)(i)?;
let (i, creds_buf) = take(creds_len as usize)(i)?;
let (_, creds) = match creds_flavor {
1 => parse_rpc_request_creds_unix(creds_buf)?,
};
let (i, verifier_flavor) = be_u32(i)?;
- let (i, verifier_len) = be_u32(i)?;
+ let (i, verifier_len) = verify(be_u32, |&size| size < RPC_MAX_VERIFIER_SIZE)(i)?;
let (i, verifier) = take(verifier_len as usize)(i)?;
let (i, prog_data) = (&[], i);
let (i, reply_state) = be_u32(i)?;
let (i, verifier_flavor) = be_u32(i)?;
- let (i, verifier_len) = be_u32(i)?;
+ let (i, verifier_len) = verify(be_u32, |&size| size < RPC_MAX_VERIFIER_SIZE)(i)?;
let (i, verifier) = cond(verifier_len > 0, take(verifier_len as usize))(i)?;
let (i, accept_state) = be_u32(i)?;
let (i, procedure) = be_u32(i)?;
let (i, creds_flavor) = be_u32(i)?;
- let (i, creds_len) = be_u32(i)?;
+ let (i, creds_len) = verify(be_u32, |&size| size < RPC_MAX_CREDS_SIZE)(i)?;
let (i, creds_buf) = take(creds_len as usize)(i)?;
let (_, creds) = match creds_flavor {
1 => parse_rpc_request_creds_unix(creds_buf)?,
};
let (i, verifier_flavor) = be_u32(i)?;
- let (i, verifier_len) = be_u32(i)?;
+ let (i, verifier_len) = verify(be_u32, |&size| size < RPC_MAX_VERIFIER_SIZE)(i)?;
let (i, verifier) = take(verifier_len as usize)(i)?;
let (i, prog_data) = (&[], i);
let (i, hdr) = parse_rpc_udp_packet_header(i)?;
let (i, verifier_flavor) = be_u32(i)?;
- let (i, verifier_len) = be_u32(i)?;
+ let (i, verifier_len) = verify(be_u32, |&size| size < RPC_MAX_VERIFIER_SIZE)(i)?;
let (i, verifier) = cond(verifier_len > 0, take(verifier_len as usize))(i)?;
let (i, reply_state) = be_u32(i)?;