From 5969481085c461961c812a1ffc925f6ea108b2fe Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Alexander=20Mei=C3=9Fner?= Date: Fri, 3 Jun 2022 15:18:12 +0200 Subject: [PATCH] Refactor: Use verifier in tests (#341) * Use the verifier in most tests. * Adjusts test_nested_vm_syscall() as ldabsb instructions are deprecated. --- examples/disassemble.rs | 3 ++- examples/to_json.rs | 3 ++- src/assembler.rs | 4 ++-- src/elf.rs | 10 +++++++--- src/vm.rs | 16 ++++++++-------- tests/assembler.rs | 3 ++- tests/ubpf_execution.rs | 23 +++++++++++------------ 7 files changed, 34 insertions(+), 28 deletions(-) diff --git a/examples/disassemble.rs b/examples/disassemble.rs index 5283d3e9a..b39922153 100644 --- a/examples/disassemble.rs +++ b/examples/disassemble.rs @@ -9,6 +9,7 @@ use solana_rbpf::{ elf::Executable, static_analysis::Analysis, user_error::UserError, + verifier::check, vm::{Config, SyscallRegistry, TestInstructionMeter}, }; use std::collections::BTreeMap; @@ -33,7 +34,7 @@ fn main() { ]; let executable = Executable::::from_text_bytes( &program, - None, + Some(check), Config::default(), SyscallRegistry::default(), BTreeMap::default(), diff --git a/examples/to_json.rs b/examples/to_json.rs index 05ede611f..badf88611 100644 --- a/examples/to_json.rs +++ b/examples/to_json.rs @@ -16,6 +16,7 @@ use solana_rbpf::{ elf::Executable, static_analysis::Analysis, user_error::UserError, + verifier::check, vm::{Config, SyscallRegistry, TestInstructionMeter}, }; use std::collections::BTreeMap; @@ -31,7 +32,7 @@ use std::collections::BTreeMap; fn to_json(program: &[u8]) -> String { let executable = Executable::::from_text_bytes( &program, - None, + Some(check), Config::default(), SyscallRegistry::default(), BTreeMap::default(), diff --git a/src/assembler.rs b/src/assembler.rs index 0ebe970f9..70622cf01 100644 --- a/src/assembler.rs +++ b/src/assembler.rs @@ -186,7 +186,7 @@ fn insn(opc: u8, dst: i64, src: i64, off: i64, imm: i64) -> Result /// # Examples /// /// ``` -/// use solana_rbpf::{assembler::assemble, user_error::UserError, vm::{Config, TestInstructionMeter, SyscallRegistry}}; +/// use solana_rbpf::{assembler::assemble, user_error::UserError, vm::{Config, TestInstructionMeter, SyscallRegistry}, verifier::check}; /// let executable = assemble::( /// "add64 r1, 0x605 /// mov64 r2, 0x32 @@ -194,7 +194,7 @@ fn insn(opc: u8, dst: i64, src: i64, off: i64, imm: i64) -> Result /// be16 r0 /// neg64 r2 /// exit", -/// None, +/// Some(check), /// Config::default(), /// SyscallRegistry::default(), /// ).unwrap(); diff --git a/src/elf.rs b/src/elf.rs index 760ea50d0..2ded30d81 100644 --- a/src/elf.rs +++ b/src/elf.rs @@ -2086,9 +2086,13 @@ mod test { let mut elf_bytes = Vec::new(); file.read_to_end(&mut elf_bytes) .expect("failed to read elf file"); - let mut executable = - ElfExecutable::from_elf(&elf_bytes, None, Config::default(), syscall_registry()) - .expect("validation failed"); + let mut executable = ElfExecutable::from_elf( + &elf_bytes, + Some(crate::verifier::check), + Config::default(), + syscall_registry(), + ) + .expect("validation failed"); { Executable::jit_compile(&mut executable).unwrap(); } diff --git a/src/vm.rs b/src/vm.rs index 0f4202e7d..c9041e937 100644 --- a/src/vm.rs +++ b/src/vm.rs @@ -437,7 +437,7 @@ impl Tracer { /// # Examples /// /// ``` -/// use solana_rbpf::{ebpf, elf::{Executable, register_bpf_function}, memory_region::MemoryRegion, vm::{Config, EbpfVm, TestInstructionMeter, SyscallRegistry}, user_error::UserError}; +/// use solana_rbpf::{ebpf, elf::{Executable, register_bpf_function}, memory_region::MemoryRegion, vm::{Config, EbpfVm, TestInstructionMeter, SyscallRegistry}, verifier::check, user_error::UserError}; /// /// let prog = &[ /// 0x95, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00 // exit @@ -451,7 +451,7 @@ impl Tracer { /// let mut bpf_functions = std::collections::BTreeMap::new(); /// let syscall_registry = SyscallRegistry::default(); /// register_bpf_function(&config, &mut bpf_functions, &syscall_registry, 0, "entrypoint").unwrap(); -/// let mut executable = Executable::::from_text_bytes(prog, None, config, syscall_registry, bpf_functions).unwrap(); +/// let mut executable = Executable::::from_text_bytes(prog, Some(check), config, syscall_registry, bpf_functions).unwrap(); /// let mem_region = MemoryRegion::new_writable(mem, ebpf::MM_INPUT_START); /// let mut vm = EbpfVm::::new(&executable, &mut [], vec![mem_region]).unwrap(); /// @@ -478,7 +478,7 @@ impl<'a, E: UserDefinedError, I: InstructionMeter> EbpfVm<'a, E, I> { /// # Examples /// /// ``` - /// use solana_rbpf::{ebpf, elf::{Executable, register_bpf_function}, vm::{Config, EbpfVm, TestInstructionMeter, SyscallRegistry}, user_error::UserError}; + /// use solana_rbpf::{ebpf, elf::{Executable, register_bpf_function}, vm::{Config, EbpfVm, TestInstructionMeter, SyscallRegistry}, verifier::check, user_error::UserError}; /// /// let prog = &[ /// 0x95, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00 // exit @@ -489,7 +489,7 @@ impl<'a, E: UserDefinedError, I: InstructionMeter> EbpfVm<'a, E, I> { /// let mut bpf_functions = std::collections::BTreeMap::new(); /// let syscall_registry = SyscallRegistry::default(); /// register_bpf_function(&config, &mut bpf_functions, &syscall_registry, 0, "entrypoint").unwrap(); - /// let mut executable = Executable::::from_text_bytes(prog, None, config, syscall_registry, bpf_functions).unwrap(); + /// let mut executable = Executable::::from_text_bytes(prog, Some(check), config, syscall_registry, bpf_functions).unwrap(); /// let mut vm = EbpfVm::::new(&executable, &mut [], Vec::new()).unwrap(); /// ``` pub fn new( @@ -554,7 +554,7 @@ impl<'a, E: UserDefinedError, I: InstructionMeter> EbpfVm<'a, E, I> { /// # Examples /// /// ``` - /// use solana_rbpf::{ebpf, elf::{Executable, register_bpf_function}, vm::{Config, EbpfVm, SyscallObject, SyscallRegistry, TestInstructionMeter}, syscalls::BpfTracePrintf, user_error::UserError}; + /// use solana_rbpf::{ebpf, elf::{Executable, register_bpf_function}, vm::{Config, EbpfVm, SyscallObject, SyscallRegistry, TestInstructionMeter}, verifier::check, syscalls::BpfTracePrintf, user_error::UserError}; /// /// // This program was compiled with clang, from a C program containing the following single /// // instruction: `return bpf_trace_printk("foo %c %c %c\n", 10, 1, 2, 3);` @@ -580,7 +580,7 @@ impl<'a, E: UserDefinedError, I: InstructionMeter> EbpfVm<'a, E, I> { /// let config = Config::default(); /// let mut bpf_functions = std::collections::BTreeMap::new(); /// register_bpf_function(&config, &mut bpf_functions, &syscall_registry, 0, "entrypoint").unwrap(); - /// let mut executable = Executable::::from_text_bytes(prog, None, config, syscall_registry, bpf_functions).unwrap(); + /// let mut executable = Executable::::from_text_bytes(prog, Some(check), config, syscall_registry, bpf_functions).unwrap(); /// let mut vm = EbpfVm::::new(&executable, &mut [], Vec::new()).unwrap(); /// // Bind a context object instance to the previously registered syscall /// vm.bind_syscall_context_objects(0); @@ -632,7 +632,7 @@ impl<'a, E: UserDefinedError, I: InstructionMeter> EbpfVm<'a, E, I> { /// # Examples /// /// ``` - /// use solana_rbpf::{ebpf, elf::{Executable, register_bpf_function}, memory_region::MemoryRegion, vm::{Config, EbpfVm, TestInstructionMeter, SyscallRegistry}, user_error::UserError}; + /// use solana_rbpf::{ebpf, elf::{Executable, register_bpf_function}, memory_region::MemoryRegion, vm::{Config, EbpfVm, TestInstructionMeter, SyscallRegistry}, verifier::check, user_error::UserError}; /// /// let prog = &[ /// 0x95, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00 // exit @@ -646,7 +646,7 @@ impl<'a, E: UserDefinedError, I: InstructionMeter> EbpfVm<'a, E, I> { /// let mut bpf_functions = std::collections::BTreeMap::new(); /// let syscall_registry = SyscallRegistry::default(); /// register_bpf_function(&config, &mut bpf_functions, &syscall_registry, 0, "entrypoint").unwrap(); - /// let mut executable = Executable::::from_text_bytes(prog, None, config, syscall_registry, bpf_functions).unwrap(); + /// let mut executable = Executable::::from_text_bytes(prog, Some(check), config, syscall_registry, bpf_functions).unwrap(); /// let mem_region = MemoryRegion::new_writable(mem, ebpf::MM_INPUT_START); /// let mut vm = EbpfVm::::new(&executable, &mut [], vec![mem_region]).unwrap(); /// diff --git a/tests/assembler.rs b/tests/assembler.rs index d7dd4f242..1ad63c499 100644 --- a/tests/assembler.rs +++ b/tests/assembler.rs @@ -12,6 +12,7 @@ use solana_rbpf::{ assembler::assemble, ebpf, user_error::UserError, + verifier::check, vm::{Config, SyscallRegistry, TestInstructionMeter}, }; use test_utils::{TCP_SACK_ASM, TCP_SACK_BIN}; @@ -577,7 +578,7 @@ fn test_large_immediate() { fn test_tcp_sack() { let executable = assemble::( TCP_SACK_ASM, - None, + Some(check), Config::default(), SyscallRegistry::default(), ) diff --git a/tests/ubpf_execution.rs b/tests/ubpf_execution.rs index cea5a3681..e536c2d35 100644 --- a/tests/ubpf_execution.rs +++ b/tests/ubpf_execution.rs @@ -22,6 +22,7 @@ use solana_rbpf::{ memory_region::{AccessType, MemoryMapping, MemoryRegion}, syscalls::{self, BpfSyscallContext, Result}, user_error::UserError, + verifier::check, vm::{Config, EbpfVm, SyscallObject, SyscallRegistry, TestInstructionMeter}, }; use std::{collections::BTreeMap, fs::File, io::Read}; @@ -99,7 +100,7 @@ macro_rules! test_interpreter_and_jit_asm { { let mut syscall_registry = SyscallRegistry::default(); $(test_interpreter_and_jit!(register, syscall_registry, $location => $syscall_init; $syscall_function);)* - let mut executable = assemble($source, Some(solana_rbpf::verifier::check), $config, syscall_registry).unwrap(); + let mut executable = assemble($source, Some(check), $config, syscall_registry).unwrap(); test_interpreter_and_jit!(executable, $mem, $syscall_context, $check, $expected_instruction_count); } }; @@ -125,7 +126,7 @@ macro_rules! test_interpreter_and_jit_elf { { let mut syscall_registry = SyscallRegistry::default(); $(test_interpreter_and_jit!(register, syscall_registry, $location => $syscall_init; $syscall_function);)* - let mut executable = Executable::::from_elf(&elf, Some(solana_rbpf::verifier::check), $config, syscall_registry).unwrap(); + let mut executable = Executable::::from_elf(&elf, Some(check), $config, syscall_registry).unwrap(); test_interpreter_and_jit!(executable, $mem, $syscall_context, $check, $expected_instruction_count); } }; @@ -2890,7 +2891,7 @@ fn test_err_mem_access_out_of_bound() { #[allow(unused_mut)] let mut executable = Executable::::from_text_bytes( &prog, - None, + Some(check), config, syscall_registry, bpf_functions, @@ -3411,13 +3412,11 @@ impl SyscallObject for NestedVmSyscall { let mem = [depth as u8 - 1, throw as u8]; let mut executable = assemble::( " - ldabsb 0 - mov64 r1, r0 - ldabsb 1 - mov64 r2, r0 + ldxb r2, [r1+1] + ldxb r1, [r1] syscall NestedVmSyscall exit", - None, + Some(check), Config::default(), syscall_registry, ) @@ -3432,7 +3431,7 @@ impl SyscallObject for NestedVmSyscall { true } }, - if throw == 0 { 6 } else { 5 } + if throw == 0 { 4 } else { 3 } ); } else { *result = if throw == 0 { @@ -3555,7 +3554,7 @@ fn test_custom_entrypoint() { #[allow(unused_mut)] let mut executable = Executable::::from_elf( &elf, - None, + Some(check), config, syscall_registry, ) @@ -3982,7 +3981,7 @@ fn test_err_unresolved_elf() { ..Config::default() }; assert!( - matches!(Executable::::from_elf(&elf, None, config, syscall_registry), Err(EbpfError::ElfError(ElfError::UnresolvedSymbol(symbol, pc, offset))) if symbol == "log_64" && pc == 550 && offset == 4168) + matches!(Executable::::from_elf(&elf, Some(check), config, syscall_registry), Err(EbpfError::ElfError(ElfError::UnresolvedSymbol(symbol, pc, offset))) if symbol == "log_64" && pc == 550 && offset == 4168) ); } @@ -4383,7 +4382,7 @@ fn execute_generated_program(prog: &[u8]) -> bool { .unwrap(); let executable = Executable::::from_text_bytes( prog, - Some(solana_rbpf::verifier::check), + Some(check), config, syscall_registry, bpf_functions,