Sanitize zero lamport accounts in append vecs (#9083)

This commit is contained in:
Ryo Onodera 2020-03-29 15:45:45 +09:00 committed by GitHub
parent 2ed3e2160d
commit 729cc4e04f
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
1 changed files with 39 additions and 4 deletions

View File

@ -80,10 +80,19 @@ impl<'a> StoredAccount<'a> {
}
fn sanitize(&self) -> bool {
self.sanitize_executable() && self.sanitize_lamports()
}
fn sanitize_executable(&self) -> bool {
// Sanitize executable to ensure higher 7-bits are cleared correctly.
self.ref_executable_byte() & !1 == 0
}
fn sanitize_lamports(&self) -> bool {
// Sanitize 0 lamports to ensure to be same as Account::default()
self.account_meta.lamports != 0 || self.clone_account() == Account::default()
}
fn ref_executable_byte(&self) -> &u8 {
// Use extra references to avoid value silently clamped to 1 (=true) and 0 (=false)
// Yes, this really happens; see test_set_file_crafted_executable
@ -258,7 +267,7 @@ impl AppendVec {
if !self.sanitize_layout_and_length() {
return Err(std::io::Error::new(
std::io::ErrorKind::Other,
"incorrect layout/length",
"incorrect layout/length/data",
));
}
@ -686,6 +695,32 @@ pub mod tests {
);
}
#[test]
fn test_set_file_crafted_zero_lamport_account() {
let file = get_append_vec_path("test_append");
let path = &file.path;
let mut av = AppendVec::new(&path, true, 1024 * 1024);
let pubkey = Pubkey::new_rand();
let owner = Pubkey::default();
let data_len = 3 as u64;
let mut account = Account::new(0, data_len as usize, &owner);
account.data = b"abc".to_vec();
let stored_meta = StoredMeta {
write_version: 0,
pubkey,
data_len,
};
let account_with_meta = (stored_meta, account);
let index = av.append_account_test(&account_with_meta).unwrap();
assert_eq!(av.get_account_test(index).unwrap(), account_with_meta);
av.flush().unwrap();
av.file_size = 0;
let result = av.set_file(path);
assert_matches!(result, Err(ref message) if message.to_string() == *"incorrect layout/length/data");
}
#[test]
fn test_set_file_crafted_data_len() {
let file = get_append_vec_path("test_set_file_crafted_data_len");
@ -709,7 +744,7 @@ pub mod tests {
av.flush().unwrap();
av.file_size = 0;
let result = av.set_file(path);
assert_matches!(result, Err(ref message) if message.to_string() == *"incorrect layout/length");
assert_matches!(result, Err(ref message) if message.to_string() == *"incorrect layout/length/data");
}
#[test]
@ -733,7 +768,7 @@ pub mod tests {
av.flush().unwrap();
av.file_size = 0;
let result = av.set_file(path);
assert_matches!(result, Err(ref message) if message.to_string() == *"incorrect layout/length");
assert_matches!(result, Err(ref message) if message.to_string() == *"incorrect layout/length/data");
}
#[test]
@ -786,6 +821,6 @@ pub mod tests {
av.flush().unwrap();
av.file_size = 0;
let result = av.set_file(path);
assert_matches!(result, Err(ref message) if message.to_string() == *"incorrect layout/length");
assert_matches!(result, Err(ref message) if message.to_string() == *"incorrect layout/length/data");
}
}