Skip to content

Commit

Permalink
If the account length is zero, no data region is present
Browse files Browse the repository at this point in the history
This only affects unaligned programs, as for aligned programs the resize
area address will match the account region address if the data length is
zero.
  • Loading branch information
seanyoung committed Mar 3, 2025
1 parent 0921d7d commit 52c6d48
Show file tree
Hide file tree
Showing 4 changed files with 36 additions and 6 deletions.
4 changes: 2 additions & 2 deletions programs/bpf_loader/src/syscalls/mem_ops.rs
Original file line number Diff line number Diff line change
Expand Up @@ -530,7 +530,7 @@ impl<'a> Iterator for MemoryChunkIterator<'a> {
account_index = account_index.saturating_add(1);
self.account_index = Some(account_index);
} else {
region_is_account = region.vm_addr == account_addr
region_is_account = (account.original_data_len != 0 && region.vm_addr == account_addr)
// unaligned programs do not have a resize area
|| (self.resize_area && region.vm_addr == resize_addr);
break;
Expand Down Expand Up @@ -604,7 +604,7 @@ impl DoubleEndedIterator for MemoryChunkIterator<'_> {

self.account_index = Some(account_index);
} else {
region_is_account = region.vm_addr == account_addr
region_is_account = (account.original_data_len != 0 && region.vm_addr == account_addr)
// unaligned programs do not have a resize area
|| (self.resize_area && region.vm_addr == resize_addr);
break;
Expand Down
7 changes: 7 additions & 0 deletions programs/sbf/rust/account_mem/src/lib.rs
Original file line number Diff line number Diff line change
Expand Up @@ -60,8 +60,15 @@ pub fn process_instruction(
sol_memset(&mut data[data_len.saturating_sub(2)..], 0, 3);
}
5 => {
// memcmp overlaps begining
#[allow(clippy::manual_memcpy)]
for i in 0..3 {
buf[i] = too_early(2)[i];
}

// memset overlaps begin of account area
sol_memset(too_early(2), 3, 3);
sol_memcpy(too_early(2), &buf, 3);
}
6 => {
// memcpy src overlaps end of account
Expand Down
8 changes: 4 additions & 4 deletions programs/sbf/rust/account_mem_deprecated/src/lib.rs
Original file line number Diff line number Diff line change
Expand Up @@ -14,7 +14,7 @@ pub fn process_instruction(
accounts: &[AccountInfo],
instruction_data: &[u8],
) -> ProgramResult {
let mut buf = [0u8; 2048];
let mut buf = [0u8; 1024];

let account = accounts.last().ok_or(ProgramError::NotEnoughAccountKeys)?;
let data_len = account.try_borrow_data()?.len();
Expand All @@ -25,7 +25,7 @@ pub fn process_instruction(
let mut too_early = |before: usize| -> &mut [u8] {
let data = data.as_mut_ptr().wrapping_sub(before);

unsafe { std::slice::from_raw_parts_mut(data, data_len) }
unsafe { std::slice::from_raw_parts_mut(data, data_len.wrapping_add(100)) }
};

match instruction_data[0] {
Expand All @@ -40,11 +40,11 @@ pub fn process_instruction(
2 => {
// memcmp overlaps begining
#[allow(clippy::manual_memcpy)]
for i in 0..500 {
for i in 0..90 {
buf[i] = too_early(8)[i];
}

sol_memcmp(too_early(8), &buf, 500);
sol_memcmp(too_early(8), &buf, 90);
}
3 => {
// memcmp overlaps begining
Expand Down
23 changes: 23 additions & 0 deletions programs/sbf/tests/programs.rs
Original file line number Diff line number Diff line change
Expand Up @@ -5194,6 +5194,29 @@ fn test_mem_syscalls_overlap_account_begin_or_end() {
assert!(!logs.last().unwrap().ends_with(" failed: InvalidLength"));
}
}

let account = AccountSharedData::new(42, 0, &program_id);
bank.store_account(&account_keypair.pubkey(), &account);

for instr in 0..=15 {
println!("Testing deprecated:{deprecated} direct_mapping:{direct_mapping} instruction:{instr} zero-length account");
let instruction =
Instruction::new_with_bytes(program_id, &[instr, 0], account_metas.clone());

let message = Message::new(&[instruction], Some(&mint_pubkey));
let tx = Transaction::new(&[&mint_keypair], message.clone(), bank.last_blockhash());
let (result, _, logs, _) = process_transaction_and_record_inner(&bank, tx);

if direct_mapping && !deprecated {
// we have a resize area
assert!(
logs.last().unwrap().ends_with(" failed: InvalidLength"),
"{logs:?}"
);
} else if result.is_err() {
assert!(result.is_ok(), "{logs:?}");
}
}
}
}
}

0 comments on commit 52c6d48

Please sign in to comment.