Skip to content

Commit

Permalink
Fix zero-len slice translations (#12642) (#12656)
Browse files Browse the repository at this point in the history
(cherry picked from commit d0aa8a6)

Co-authored-by: Jack May <[email protected]>
  • Loading branch information
mergify[bot] and jackcmay authored Oct 3, 2020
1 parent ffa0ee6 commit efcb5cd
Show file tree
Hide file tree
Showing 6 changed files with 48 additions and 0 deletions.
12 changes: 12 additions & 0 deletions programs/bpf/c/src/invoke/invoke.c
Original file line number Diff line number Diff line change
Expand Up @@ -115,6 +115,18 @@ extern uint64_t entrypoint(const uint8_t *input) {
sol_invoke(&instruction, accounts, SOL_ARRAY_SIZE(accounts)));
}

sol_log("Test no instruction data");
{
SolAccountMeta arguments[] = {{accounts[ARGUMENT_INDEX].key, true, true}};
uint8_t data[] = {};
const SolInstruction instruction = {accounts[INVOKED_PROGRAM_INDEX].key,
arguments, SOL_ARRAY_SIZE(arguments),
data, SOL_ARRAY_SIZE(data)};

sol_assert(SUCCESS ==
sol_invoke(&instruction, accounts, SOL_ARRAY_SIZE(accounts)));
}

sol_log("Test return error");
{
SolAccountMeta arguments[] = {{accounts[ARGUMENT_INDEX].key, true, true}};
Expand Down
4 changes: 4 additions & 0 deletions programs/bpf/c/src/invoked/invoked.c
Original file line number Diff line number Diff line change
Expand Up @@ -12,6 +12,10 @@ extern uint64_t entrypoint(const uint8_t *input) {
return ERROR_INVALID_ARGUMENT;
}

if (params.data_len == 0) {
return SUCCESS;
}

switch (params.data[0]) {
case TEST_VERIFY_TRANSLATIONS: {
sol_log("verify data translations");
Expand Down
10 changes: 10 additions & 0 deletions programs/bpf/rust/invoke/src/lib.rs
Original file line number Diff line number Diff line change
Expand Up @@ -117,6 +117,16 @@ fn process_instruction(
invoke(&instruction, accounts)?;
}

info!("Test no instruction data");
{
let instruction = create_instruction(
*accounts[INVOKED_PROGRAM_INDEX].key,
&[(accounts[ARGUMENT_INDEX].key, true, true)],
vec![],
);
invoke(&instruction, accounts)?;
}

info!("Test return error");
{
let instruction = create_instruction(
Expand Down
4 changes: 4 additions & 0 deletions programs/bpf/rust/invoked/src/lib.rs
Original file line number Diff line number Diff line change
Expand Up @@ -21,6 +21,10 @@ fn process_instruction(
) -> ProgramResult {
info!("Invoked program");

if instruction_data.is_empty() {
return Ok(());
}

match instruction_data[0] {
TEST_VERIFY_TRANSLATIONS => {
info!("verify data translations");
Expand Down
1 change: 1 addition & 0 deletions programs/bpf/tests/programs.rs
Original file line number Diff line number Diff line change
Expand Up @@ -534,6 +534,7 @@ fn test_program_bpf_invoke() {
invoked_program_id.clone(),
invoked_program_id.clone(),
invoked_program_id.clone(),
invoked_program_id.clone(),
]
);

Expand Down
17 changes: 17 additions & 0 deletions programs/bpf_loader/src/syscalls.rs
Original file line number Diff line number Diff line change
Expand Up @@ -213,6 +213,8 @@ macro_rules! translate_slice_mut {
&& ($vm_addr as u64 as *mut $t).align_offset(align_of::<$t>()) != 0
{
Err(SyscallError::UnalignedPointer.into())
} else if $len == 0 {
Ok(unsafe { from_raw_parts_mut(0x1 as *mut $t, $len as usize) })
} else {
match translate_addr::<BPFError>(
$vm_addr as u64,
Expand Down Expand Up @@ -1179,6 +1181,21 @@ mod tests {

#[test]
fn test_translate_slice() {
// zero len
let good_data = vec![1u8, 2, 3, 4, 5];
let data: Vec<u8> = vec![];
assert_eq!(0x1 as *const u8, data.as_ptr());
let addr = good_data.as_ptr() as *const _ as u64;
let regions = vec![MemoryRegion {
addr_host: addr,
addr_vm: 100,
len: good_data.len() as u64,
}];
let translated_data =
translate_slice!(u8, data.as_ptr(), data.len(), &regions, &bpf_loader::id()).unwrap();
assert_eq!(data, translated_data);
assert_eq!(0, translated_data.len());

// u8
let mut data = vec![1u8, 2, 3, 4, 5];
let addr = data.as_ptr() as *const _ as u64;
Expand Down

0 comments on commit efcb5cd

Please sign in to comment.