From 7f67d3677765d7ec2d5c1e0b115da73550f4e583 Mon Sep 17 00:00:00 2001 From: Trent Nelson Date: Mon, 5 Oct 2020 21:21:33 -0600 Subject: [PATCH] RPC: Check encoded transaction size before decoding --- core/src/rpc.rs | 16 ++++++++++++++++ 1 file changed, 16 insertions(+) diff --git a/core/src/rpc.rs b/core/src/rpc.rs index e98673b129..0f79beacc1 100644 --- a/core/src/rpc.rs +++ b/core/src/rpc.rs @@ -2599,7 +2599,16 @@ impl RpcSol for RpcSolImpl { } } +const WORST_CASE_BASE58_TX: usize = 1683; // Golden, bump if PACKET_DATA_SIZE changes fn deserialize_bs58_transaction(bs58_transaction: String) -> Result<(Vec, Transaction)> { + if bs58_transaction.len() > WORST_CASE_BASE58_TX { + return Err(Error::invalid_params(format!( + "encoded transaction too large: {} bytes (max: encoded/raw {}/{})", + bs58_transaction.len(), + WORST_CASE_BASE58_TX, + PACKET_DATA_SIZE, + ))); + } let wire_transaction = bs58::decode(bs58_transaction) .into_vec() .map_err(|e| Error::invalid_params(format!("{:?}", e)))?; @@ -5776,4 +5785,11 @@ pub mod tests { let slot: Slot = serde_json::from_value(json["result"].clone()).unwrap(); assert_eq!(slot, 3); } + + #[test] + fn test_worst_case_encoded_tx_goldens() { + let ff_tx = vec![0xffu8; PACKET_DATA_SIZE]; + let tx58 = bs58::encode(ff_tx).into_string(); + assert_eq!(tx58.len(), WORST_CASE_BASE58_TX); + } }