Skip to content
This repository has been archived by the owner on Jan 22, 2025. It is now read-only.

Sanitize zero lamport accounts in append vecs #9083

Merged
merged 1 commit into from
Mar 29, 2020
Merged
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
43 changes: 39 additions & 4 deletions runtime/src/append_vec.rs
Original file line number Diff line number Diff line change
Expand Up @@ -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
Expand Down Expand Up @@ -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",
));
}

Expand Down Expand Up @@ -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");
Expand All @@ -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]
Expand All @@ -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]
Expand Down Expand Up @@ -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");
}
}