terra: Check that bytes32 fits into 20 bytes before truncating (#1458)

This commit is contained in:
Csongor Kiss 2022-08-23 21:13:30 +02:00 committed by GitHub
parent fd540c91b4
commit ca43f8629a
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
3 changed files with 62 additions and 24 deletions

View File

@ -679,12 +679,7 @@ fn handle_complete_transfer_with_payload(
}
}
fn submit_vaa(
deps: DepsMut,
env: Env,
info: MessageInfo,
data: &Binary,
) -> StdResult<Response> {
fn submit_vaa(deps: DepsMut, env: Env, info: MessageInfo, data: &Binary) -> StdResult<Response> {
let state = config_read(deps.storage).load()?;
let vaa = parse_vaa(deps.as_ref(), env.block.time.seconds(), data)?;
@ -793,17 +788,31 @@ fn handle_complete_transfer(
relayer_address: &HumanAddr,
) -> StdResult<Response> {
let transfer_info = TransferInfo::deserialize(&data)?;
if transfer_info.token_address.as_slice()[0] == 1 && transfer_info.token_chain == CHAIN_ID {
handle_complete_transfer_token_native(
deps,
env,
info,
emitter_chain,
emitter_address,
transfer_type,
data,
relayer_address,
)
let marker_byte = transfer_info.token_address.as_slice()[0];
if transfer_info.token_chain == CHAIN_ID {
match marker_byte {
1 => handle_complete_transfer_token_native(
deps,
env,
info,
emitter_chain,
emitter_address,
transfer_type,
data,
relayer_address,
),
0 => handle_complete_transfer_token(
deps,
env,
info,
emitter_chain,
emitter_address,
transfer_type,
data,
relayer_address,
),
b => Err(StdError::generic_err(format!("Unknown marker byte: {}", b))),
}
} else {
handle_complete_transfer_token(
deps,

View File

@ -44,6 +44,9 @@ impl ByteUtils for &[u8] {
}
fn get_address(&self, index: usize) -> CanonicalAddr {
// 32 bytes are reserved for addresses, but only the last 20 bytes are taken by the actual address
if self.get_u128_be(index) >> 32 != 0 {
panic!("invalid Terra address");
}
CanonicalAddr::from(&self[index + 32 - 20..index + 32])
}
fn get_bytes32(&self, index: usize) -> &[u8] {

View File

@ -1,6 +1,7 @@
use cosmwasm_std::StdResult;
use cosmwasm_std::{StdResult, CanonicalAddr};
use crate::state::{GuardianAddress, GuardianSetInfo, ParsedVAA};
use crate::byte_utils::ByteUtils;
#[test]
fn quardian_set_quorum() {
@ -55,10 +56,10 @@ fn deserialize_round_1() -> StdResult<()> {
let nonce = 5u32;
assert_eq!(parsed.nonce, nonce, "parsed.nonce != expected");
let len_signers = 1u8;
assert_eq!(parsed.len_signers, len_signers, "parsed.len_signers != expected");
let emitter_chain = 2u16;
assert_eq!(parsed.emitter_chain, emitter_chain, "parsed.emitter_chain != expected");
@ -112,17 +113,17 @@ fn deserialize_round_2() -> StdResult<()> {
let nonce = 0u32;
assert_eq!(parsed.nonce, nonce, "parsed.nonce != expected");
let len_signers = 1u8;
assert_eq!(parsed.len_signers, len_signers, "parsed.len_signers != expected");
let emitter_chain = 1u16;
assert_eq!(parsed.emitter_chain, emitter_chain, "parsed.emitter_chain != expected");
let emitter_address = "000000000000000000000000000000000000000000000000000000000000ffff";
let emitter_address = hex::decode(emitter_address).unwrap();
assert_eq!(parsed.emitter_address, emitter_address, "parsed.emitter_address != expected");
let sequence = 0u64;
assert_eq!(parsed.sequence, sequence, "parsed.sequence != expected");
@ -159,4 +160,29 @@ fn deserialize_round_2() -> StdResult<()> {
assert_eq!(parsed.hash, hash, "parsed.hash != expected");
Ok(())
}
}
#[test]
fn get_address_test() -> StdResult<()> {
let zeros_32: &[u8] = &[0;32];
let zeros_20: &[u8] = &[0;20];
assert_eq!(zeros_32.get_address(0), CanonicalAddr::from(zeros_20));
Ok(())
}
#[test]
#[should_panic]
fn get_address_test_panic() -> () {
// panics because of junk in first 12 bytes
let ones_32: &[u8] = &[1;32];
ones_32.get_address(0);
}
#[test]
#[should_panic]
fn get_address_test_panic_2() -> () {
// panics because not enough bytes (need at least 32)
let short_address: &[u8] = &[0;31];
short_address.get_address(0);
}