From 8c989da68342918f1717c60aa60fdfab7d1e676e Mon Sep 17 00:00:00 2001 From: Jack May Date: Fri, 2 Oct 2020 00:33:37 -0700 Subject: [PATCH] Fix zero-len slice translations --- programs/bpf/rust/invoke/src/lib.rs | 10 ++++++++ programs/bpf/rust/invoked/src/lib.rs | 4 ++++ programs/bpf_loader/src/syscalls.rs | 36 +++++++++++++++++++++------- 3 files changed, 41 insertions(+), 9 deletions(-) diff --git a/programs/bpf/rust/invoke/src/lib.rs b/programs/bpf/rust/invoke/src/lib.rs index feee567c8c..b29212eeb4 100644 --- a/programs/bpf/rust/invoke/src/lib.rs +++ b/programs/bpf/rust/invoke/src/lib.rs @@ -83,6 +83,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( diff --git a/programs/bpf/rust/invoked/src/lib.rs b/programs/bpf/rust/invoked/src/lib.rs index b976697a88..6226d9ea98 100644 --- a/programs/bpf/rust/invoked/src/lib.rs +++ b/programs/bpf/rust/invoked/src/lib.rs @@ -26,6 +26,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"); diff --git a/programs/bpf_loader/src/syscalls.rs b/programs/bpf_loader/src/syscalls.rs index 38f78e9ae2..4810b58340 100644 --- a/programs/bpf_loader/src/syscalls.rs +++ b/programs/bpf_loader/src/syscalls.rs @@ -169,15 +169,19 @@ macro_rules! translate_type { #[macro_export] macro_rules! translate_slice_mut { ($t:ty, $vm_addr:expr, $len: expr, $regions:expr) => { - match translate_addr::( - $vm_addr as u64, - $len as usize * size_of::<$t>(), - file!(), - line!() as usize - ELF_INSN_DUMP_OFFSET + 1, - $regions, - ) { - Ok(value) => Ok(unsafe { from_raw_parts_mut(value as *mut $t, $len as usize) }), - Err(e) => Err(e), + if $len == 0 { + Ok(unsafe { from_raw_parts_mut(0x1 as *mut $t, $len as usize) }) + } else { + match translate_addr::( + $vm_addr as u64, + $len as usize * size_of::<$t>(), + file!(), + line!() as usize - ELF_INSN_DUMP_OFFSET + 1, + $regions, + ) { + Ok(value) => Ok(unsafe { from_raw_parts_mut(value as *mut $t, $len as usize) }), + Err(e) => Err(e), + } } }; } @@ -935,6 +939,20 @@ mod tests { #[test] fn test_translate_slice() { + // zero len + let good_data = vec![1u8, 2, 3, 4, 5]; + let data: Vec = 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(), ®ions).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;