diff --git a/sdk/program/src/message.rs b/sdk/program/src/message.rs index 3dd9cd52baf04e..14b26f24b30ff9 100644 --- a/sdk/program/src/message.rs +++ b/sdk/program/src/message.rs @@ -404,7 +404,10 @@ impl Message { data: &[u8], ) -> Result { let mut current = 0; - let _num_instructions = read_u16(&mut current, &data)?; + let num_instructions = read_u16(&mut current, &data)?; + if index >= num_instructions as usize { + return Err(SanitizeError::IndexOutOfBounds); + } // index into the instruction byte-offset table. current += index * 2; @@ -862,6 +865,25 @@ mod tests { } } + #[test] + fn test_decompile_instructions_out_of_bounds() { + solana_logger::setup(); + let program_id0 = Pubkey::new_unique(); + let id0 = Pubkey::new_unique(); + let id1 = Pubkey::new_unique(); + let instructions = vec![ + Instruction::new_with_bincode(program_id0, &0, vec![AccountMeta::new(id0, false)]), + Instruction::new_with_bincode(program_id0, &0, vec![AccountMeta::new(id1, true)]), + ]; + + let message = Message::new(&instructions, Some(&id1)); + let serialized = message.serialize_instructions(); + assert_eq!( + Message::deserialize_instruction(instructions.len(), &serialized).unwrap_err(), + SanitizeError::IndexOutOfBounds, + ); + } + #[test] fn test_program_ids() { let key0 = Pubkey::new_unique();