limits pre-allocation size when deserializing shreds (#24921)
Though current Shred struct is not vulnerable to this, adding with_limit causes pre-allocation size to be limited to prevent against memory exhaustion attacks: https://github.com/bincode-org/bincode/blob/2d3f42034/readme.md
This commit is contained in:
parent
59177f0f39
commit
9587c8537f
|
@ -59,7 +59,7 @@ use {
|
||||||
num_enum::{IntoPrimitive, TryFromPrimitive},
|
num_enum::{IntoPrimitive, TryFromPrimitive},
|
||||||
serde::{Deserialize, Serialize},
|
serde::{Deserialize, Serialize},
|
||||||
solana_entry::entry::{create_ticks, Entry},
|
solana_entry::entry::{create_ticks, Entry},
|
||||||
solana_perf::packet::{limited_deserialize, Packet},
|
solana_perf::packet::{deserialize_from_with_limit, limited_deserialize, Packet},
|
||||||
solana_sdk::{
|
solana_sdk::{
|
||||||
clock::Slot,
|
clock::Slot,
|
||||||
hash::{hashv, Hash},
|
hash::{hashv, Hash},
|
||||||
|
@ -290,16 +290,16 @@ impl Shred {
|
||||||
|
|
||||||
pub fn new_from_serialized_shred(mut payload: Vec<u8>) -> Result<Self, Error> {
|
pub fn new_from_serialized_shred(mut payload: Vec<u8>) -> Result<Self, Error> {
|
||||||
let mut cursor = Cursor::new(&payload[..]);
|
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 {
|
let (data_header, coding_header) = match common_header.shred_type {
|
||||||
ShredType::Code => {
|
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
|
// see: https://github.com/solana-labs/solana/pull/10109
|
||||||
payload.truncate(SHRED_PAYLOAD_SIZE);
|
payload.truncate(SHRED_PAYLOAD_SIZE);
|
||||||
(DataShredHeader::default(), coding_header)
|
(DataShredHeader::default(), coding_header)
|
||||||
}
|
}
|
||||||
ShredType::Data => {
|
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
|
// see: https://github.com/solana-labs/solana/pull/16602
|
||||||
payload.resize(SHRED_PAYLOAD_SIZE, 0u8);
|
payload.resize(SHRED_PAYLOAD_SIZE, 0u8);
|
||||||
(data_header, CodingShredHeader::default())
|
(data_header, CodingShredHeader::default())
|
||||||
|
|
|
@ -3,8 +3,8 @@ pub use solana_sdk::packet::{Meta, Packet, PacketFlags, PACKET_DATA_SIZE};
|
||||||
use {
|
use {
|
||||||
crate::{cuda_runtime::PinnedVec, recycler::Recycler},
|
crate::{cuda_runtime::PinnedVec, recycler::Recycler},
|
||||||
bincode::config::Options,
|
bincode::config::Options,
|
||||||
serde::Serialize,
|
serde::{de::DeserializeOwned, Serialize},
|
||||||
std::net::SocketAddr,
|
std::{io::Read, net::SocketAddr},
|
||||||
};
|
};
|
||||||
|
|
||||||
pub const NUM_PACKETS: usize = 1024 * 8;
|
pub const NUM_PACKETS: usize = 1024 * 8;
|
||||||
|
@ -137,6 +137,20 @@ where
|
||||||
.deserialize_from(data)
|
.deserialize_from(data)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
pub fn deserialize_from_with_limit<R, T>(reader: R) -> bincode::Result<T>
|
||||||
|
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)]
|
#[cfg(test)]
|
||||||
mod tests {
|
mod tests {
|
||||||
use {
|
use {
|
||||||
|
|
Loading…
Reference in New Issue