diff --git a/ledger/src/shred.rs b/ledger/src/shred.rs index 1b923eec3..ec354929a 100644 --- a/ledger/src/shred.rs +++ b/ledger/src/shred.rs @@ -59,7 +59,7 @@ use { num_enum::{IntoPrimitive, TryFromPrimitive}, serde::{Deserialize, Serialize}, solana_entry::entry::{create_ticks, Entry}, - solana_perf::packet::{limited_deserialize, Packet}, + solana_perf::packet::{deserialize_from_with_limit, limited_deserialize, Packet}, solana_sdk::{ clock::Slot, hash::{hashv, Hash}, @@ -290,16 +290,16 @@ impl Shred { pub fn new_from_serialized_shred(mut payload: Vec) -> Result { let mut cursor = Cursor::new(&payload[..]); - let common_header: ShredCommonHeader = bincode::deserialize_from(&mut cursor)?; + let common_header: ShredCommonHeader = deserialize_from_with_limit(&mut cursor)?; let (data_header, coding_header) = match common_header.shred_type { ShredType::Code => { - let coding_header = bincode::deserialize_from(&mut cursor)?; + let coding_header = deserialize_from_with_limit(&mut cursor)?; // see: https://github.com/solana-labs/solana/pull/10109 payload.truncate(SHRED_PAYLOAD_SIZE); (DataShredHeader::default(), coding_header) } ShredType::Data => { - let data_header = bincode::deserialize_from(&mut cursor)?; + let data_header = deserialize_from_with_limit(&mut cursor)?; // see: https://github.com/solana-labs/solana/pull/16602 payload.resize(SHRED_PAYLOAD_SIZE, 0u8); (data_header, CodingShredHeader::default()) diff --git a/perf/src/packet.rs b/perf/src/packet.rs index b4cea63ee..0b5adbfc3 100644 --- a/perf/src/packet.rs +++ b/perf/src/packet.rs @@ -3,8 +3,8 @@ pub use solana_sdk::packet::{Meta, Packet, PacketFlags, PACKET_DATA_SIZE}; use { crate::{cuda_runtime::PinnedVec, recycler::Recycler}, bincode::config::Options, - serde::Serialize, - std::net::SocketAddr, + serde::{de::DeserializeOwned, Serialize}, + std::{io::Read, net::SocketAddr}, }; pub const NUM_PACKETS: usize = 1024 * 8; @@ -137,6 +137,20 @@ where .deserialize_from(data) } +pub fn deserialize_from_with_limit(reader: R) -> bincode::Result +where + R: Read, + T: DeserializeOwned, +{ + // with_limit causes pre-allocation size to be limited + // to prevent against memory exhaustion attacks. + bincode::options() + .with_limit(PACKET_DATA_SIZE as u64) + .with_fixint_encoding() + .allow_trailing_bytes() + .deserialize_from(reader) +} + #[cfg(test)] mod tests { use {