Bump solana_rbpf to version v0.2.14 (#18869)

* Feature gate for verify_mul64_imm_nonzero as discussed in #17520.
This commit is contained in:
Alexander Meißner
2021-12-13 22:09:18 +01:00
committed by Michael Vines
parent 843f26c2de
commit f9b7e24846
10 changed files with 274 additions and 212 deletions

4
Cargo.lock generated
View File

@ -5887,9 +5887,9 @@ dependencies = [
[[package]] [[package]]
name = "solana_rbpf" name = "solana_rbpf"
version = "0.2.13" version = "0.2.14"
source = "registry+https://github.com/rust-lang/crates.io-index" source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "fc1dced9892c2b0273318ef4d8486112ea7c7a7b8eb563a20e7858ad921b4719" checksum = "e27486ed1c74044866b529076b6aa9ca6fab9ec494d1835439ec84efc5575953"
dependencies = [ dependencies = [
"byteorder", "byteorder",
"combine", "combine",

View File

@ -40,7 +40,7 @@ solana-config-program = { path = "../programs/config", version = "=1.8.11" }
solana-faucet = { path = "../faucet", version = "=1.8.11" } solana-faucet = { path = "../faucet", version = "=1.8.11" }
solana-logger = { path = "../logger", version = "=1.8.11" } solana-logger = { path = "../logger", version = "=1.8.11" }
solana-net-utils = { path = "../net-utils", version = "=1.8.11" } solana-net-utils = { path = "../net-utils", version = "=1.8.11" }
solana_rbpf = "=0.2.13" solana_rbpf = "=0.2.14"
solana-remote-wallet = { path = "../remote-wallet", version = "=1.8.11" } solana-remote-wallet = { path = "../remote-wallet", version = "=1.8.11" }
solana-sdk = { path = "../sdk", version = "=1.8.11" } solana-sdk = { path = "../sdk", version = "=1.8.11" }
solana-transaction-status = { path = "../transaction-status", version = "=1.8.11" } solana-transaction-status = { path = "../transaction-status", version = "=1.8.11" }

View File

@ -1992,9 +1992,10 @@ fn read_and_verify_elf(program_location: &str) -> Result<Vec<u8>, Box<dyn std::e
// Verify the program // Verify the program
<dyn Executable<BpfError, ThisInstructionMeter>>::from_elf( <dyn Executable<BpfError, ThisInstructionMeter>>::from_elf(
&program_data, &program_data,
Some(|x| verifier::check(x)), Some(verifier::check),
Config { Config {
reject_unresolved_syscalls: true, reject_unresolved_syscalls: true,
verify_mul64_imm_nonzero: true, // TODO: Remove me after feature gate
..Config::default() ..Config::default()
}, },
register_syscalls(&mut invoke_context).unwrap(), register_syscalls(&mut invoke_context).unwrap(),

View File

@ -3699,9 +3699,9 @@ dependencies = [
[[package]] [[package]]
name = "solana_rbpf" name = "solana_rbpf"
version = "0.2.13" version = "0.2.14"
source = "registry+https://github.com/rust-lang/crates.io-index" source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "fc1dced9892c2b0273318ef4d8486112ea7c7a7b8eb563a20e7858ad921b4719" checksum = "e27486ed1c74044866b529076b6aa9ca6fab9ec494d1835439ec84efc5575953"
dependencies = [ dependencies = [
"byteorder 1.3.4", "byteorder 1.3.4",
"combine", "combine",

View File

@ -30,7 +30,7 @@ solana-bpf-loader-program = { path = "../bpf_loader", version = "=1.8.11" }
solana-cli-output = { path = "../../cli-output", version = "=1.8.11" } solana-cli-output = { path = "../../cli-output", version = "=1.8.11" }
solana-logger = { path = "../../logger", version = "=1.8.11" } solana-logger = { path = "../../logger", version = "=1.8.11" }
solana-measure = { path = "../../measure", version = "=1.8.11" } solana-measure = { path = "../../measure", version = "=1.8.11" }
solana_rbpf = "=0.2.13" solana_rbpf = "=0.2.14"
solana-runtime = { path = "../../runtime", version = "=1.8.11" } solana-runtime = { path = "../../runtime", version = "=1.8.11" }
solana-sdk = { path = "../../sdk", version = "=1.8.11" } solana-sdk = { path = "../../sdk", version = "=1.8.11" }
solana-transaction-status = { path = "../../transaction-status", version = "=1.8.11" } solana-transaction-status = { path = "../../transaction-status", version = "=1.8.11" }

View File

@ -22,7 +22,7 @@ sha3 = "0.9.1"
solana-measure = { path = "../../measure", version = "=1.8.11" } solana-measure = { path = "../../measure", version = "=1.8.11" }
solana-runtime = { path = "../../runtime", version = "=1.8.11" } solana-runtime = { path = "../../runtime", version = "=1.8.11" }
solana-sdk = { path = "../../sdk", version = "=1.8.11" } solana-sdk = { path = "../../sdk", version = "=1.8.11" }
solana_rbpf = "=0.2.13" solana_rbpf = "=0.2.14"
thiserror = "1.0" thiserror = "1.0"
[dev-dependencies] [dev-dependencies]

View File

@ -16,9 +16,8 @@ use log::{log_enabled, trace, Level::Trace};
use solana_measure::measure::Measure; use solana_measure::measure::Measure;
use solana_rbpf::{ use solana_rbpf::{
aligned_memory::AlignedMemory, aligned_memory::AlignedMemory,
ebpf::{HOST_ALIGN, MM_HEAP_START}, ebpf::HOST_ALIGN,
error::{EbpfError, UserDefinedError}, error::{EbpfError, UserDefinedError},
memory_region::MemoryRegion,
static_analysis::Analysis, static_analysis::Analysis,
verifier::{self, VerifierError}, verifier::{self, VerifierError},
vm::{Config, EbpfVm, Executable, InstructionMeter}, vm::{Config, EbpfVm, Executable, InstructionMeter},
@ -33,7 +32,8 @@ use solana_sdk::{
entrypoint::{HEAP_LENGTH, SUCCESS}, entrypoint::{HEAP_LENGTH, SUCCESS},
feature_set::{ feature_set::{
add_missing_program_error_mappings, close_upgradeable_program_accounts, fix_write_privs, add_missing_program_error_mappings, close_upgradeable_program_accounts, fix_write_privs,
reduce_required_deploy_balance, requestable_heap_size, upgradeable_close_instruction, reduce_required_deploy_balance, requestable_heap_size, stop_verify_mul64_imm_nonzero,
upgradeable_close_instruction,
}, },
ic_logger_msg, ic_msg, ic_logger_msg, ic_msg,
instruction::{AccountMeta, InstructionError}, instruction::{AccountMeta, InstructionError},
@ -86,6 +86,8 @@ pub fn create_executor(
max_call_depth: bpf_compute_budget.max_call_depth, max_call_depth: bpf_compute_budget.max_call_depth,
stack_frame_size: bpf_compute_budget.stack_frame_size, stack_frame_size: bpf_compute_budget.stack_frame_size,
enable_instruction_tracing: log_enabled!(Trace), enable_instruction_tracing: log_enabled!(Trace),
verify_mul64_imm_nonzero: !invoke_context
.is_feature_active(&stop_verify_mul64_imm_nonzero::id()), // TODO: Feature gate and then remove me
..Config::default() ..Config::default()
}; };
let mut executable = { let mut executable = {
@ -101,10 +103,8 @@ pub fn create_executor(
) )
} }
.map_err(|e| map_ebpf_error(invoke_context, e))?; .map_err(|e| map_ebpf_error(invoke_context, e))?;
let (_, elf_bytes) = executable let text_bytes = executable.get_text_bytes().1;
.get_text_bytes() verifier::check(text_bytes, &config)
.map_err(|e| map_ebpf_error(invoke_context, e))?;
verifier::check(elf_bytes)
.map_err(|e| map_ebpf_error(invoke_context, EbpfError::UserError(e.into())))?; .map_err(|e| map_ebpf_error(invoke_context, EbpfError::UserError(e.into())))?;
if use_jit { if use_jit {
if let Err(err) = executable.jit_compile() { if let Err(err) = executable.jit_compile() {
@ -153,18 +153,11 @@ pub fn create_vm<'a>(
invoke_context: &'a mut dyn InvokeContext, invoke_context: &'a mut dyn InvokeContext,
) -> Result<EbpfVm<'a, BpfError, ThisInstructionMeter>, EbpfError<BpfError>> { ) -> Result<EbpfVm<'a, BpfError, ThisInstructionMeter>, EbpfError<BpfError>> {
let bpf_compute_budget = invoke_context.get_bpf_compute_budget(); let bpf_compute_budget = invoke_context.get_bpf_compute_budget();
let heap_size = bpf_compute_budget.heap_size.unwrap_or(HEAP_LENGTH); let mut heap = AlignedMemory::new_with_size(
if invoke_context.is_feature_active(&requestable_heap_size::id()) {
let _ = invoke_context.get_compute_meter().borrow_mut().consume(
(heap_size as u64 / (32 * 1024)).saturating_sub(1) * bpf_compute_budget.heap_cost,
);
}
let heap = AlignedMemory::new_with_size(
bpf_compute_budget.heap_size.unwrap_or(HEAP_LENGTH), bpf_compute_budget.heap_size.unwrap_or(HEAP_LENGTH),
HOST_ALIGN, HOST_ALIGN,
); );
let heap_region = MemoryRegion::new_from_slice(heap.as_slice(), MM_HEAP_START, 0, true); let mut vm = EbpfVm::new(program, heap.as_slice_mut(), parameter_bytes)?;
let mut vm = EbpfVm::new(program, parameter_bytes, &[heap_region])?;
syscalls::bind_syscall_context_objects(loader_id, &mut vm, invoke_context, heap)?; syscalls::bind_syscall_context_objects(loader_id, &mut vm, invoke_context, heap)?;
Ok(vm) Ok(vm)
} }
@ -1065,7 +1058,8 @@ mod tests {
) )
.unwrap(); .unwrap();
let mut vm = let mut vm =
EbpfVm::<BpfError, TestInstructionMeter>::new(program.as_ref(), input, &[]).unwrap(); EbpfVm::<BpfError, TestInstructionMeter>::new(program.as_ref(), &mut [], input)
.unwrap();
let mut instruction_meter = TestInstructionMeter { remaining: 10 }; let mut instruction_meter = TestInstructionMeter { remaining: 10 };
vm.execute_program_interpreted(&mut instruction_meter) vm.execute_program_interpreted(&mut instruction_meter)
.unwrap(); .unwrap();
@ -1077,7 +1071,7 @@ mod tests {
let prog = &[ let prog = &[
0x18, 0x00, 0x00, 0x00, 0x88, 0x77, 0x66, 0x55, // first half of lddw 0x18, 0x00, 0x00, 0x00, 0x88, 0x77, 0x66, 0x55, // first half of lddw
]; ];
verifier::check(prog).unwrap(); verifier::check(prog, &Config::default()).unwrap();
} }
#[test] #[test]

View File

@ -2,7 +2,7 @@ use crate::{alloc, BpfError};
use alloc::Alloc; use alloc::Alloc;
use solana_rbpf::{ use solana_rbpf::{
aligned_memory::AlignedMemory, aligned_memory::AlignedMemory,
ebpf::MM_HEAP_START, ebpf,
error::EbpfError, error::EbpfError,
memory_region::{AccessType, MemoryMapping}, memory_region::{AccessType, MemoryMapping},
question_mark, question_mark,
@ -453,7 +453,7 @@ pub fn bind_syscall_context_objects<'a>(
vm.bind_syscall_context_object( vm.bind_syscall_context_object(
Box::new(SyscallAllocFree { Box::new(SyscallAllocFree {
aligned: *loader_id != bpf_loader_deprecated::id(), aligned: *loader_id != bpf_loader_deprecated::id(),
allocator: BpfAllocator::new(heap, MM_HEAP_START), allocator: BpfAllocator::new(heap, ebpf::MM_HEAP_START),
}), }),
None, None,
)?; )?;
@ -2767,7 +2767,9 @@ mod tests {
macro_rules! assert_access_violation { macro_rules! assert_access_violation {
($result:expr, $va:expr, $len:expr) => { ($result:expr, $va:expr, $len:expr) => {
match $result { match $result {
Err(EbpfError::AccessViolation(_, _, va, len, _)) if $va == va && len == len => (), Err(EbpfError::AccessViolation(_, _, va, len, _)) if $va == va && $len == len => (),
Err(EbpfError::StackAccessViolation(_, _, va, len, _))
if $va == va && $len == len => {}
_ => panic!(), _ => panic!(),
} }
}; };
@ -2781,13 +2783,16 @@ mod tests {
#[test] #[test]
fn test_translate() { fn test_translate() {
const START: u64 = 100; const START: u64 = 0x100000000;
const LENGTH: u64 = 1000; const LENGTH: u64 = 1000;
let data = vec![0u8; LENGTH as usize]; let data = vec![0u8; LENGTH as usize];
let addr = data.as_ptr() as u64; let addr = data.as_ptr() as u64;
let config = Config::default(); let config = Config::default();
let memory_mapping = MemoryMapping::new::<UserError>( let memory_mapping = MemoryMapping::new::<UserError>(
vec![MemoryRegion::new_from_slice(&data, START, 0, false)], vec![
MemoryRegion::default(),
MemoryRegion::new_from_slice(&data, START, 0, false),
],
&config, &config,
) )
.unwrap(); .unwrap();
@ -2827,18 +2832,22 @@ mod tests {
let addr = &pubkey as *const _ as u64; let addr = &pubkey as *const _ as u64;
let config = Config::default(); let config = Config::default();
let memory_mapping = MemoryMapping::new::<UserError>( let memory_mapping = MemoryMapping::new::<UserError>(
vec![MemoryRegion { vec![
host_addr: addr, MemoryRegion::default(),
vm_addr: 100, MemoryRegion {
len: std::mem::size_of::<Pubkey>() as u64, host_addr: addr,
vm_gap_shift: 63, vm_addr: 0x100000000,
is_writable: false, len: std::mem::size_of::<Pubkey>() as u64,
}], vm_gap_shift: 63,
is_writable: false,
},
],
&config, &config,
) )
.unwrap(); .unwrap();
let translated_pubkey = let translated_pubkey =
translate_type::<Pubkey>(&memory_mapping, 100, &bpf_loader::id(), true).unwrap(); translate_type::<Pubkey>(&memory_mapping, 0x100000000, &bpf_loader::id(), true)
.unwrap();
assert_eq!(pubkey, *translated_pubkey); assert_eq!(pubkey, *translated_pubkey);
// Instruction // Instruction
@ -2849,23 +2858,31 @@ mod tests {
); );
let addr = &instruction as *const _ as u64; let addr = &instruction as *const _ as u64;
let mut memory_mapping = MemoryMapping::new::<UserError>( let mut memory_mapping = MemoryMapping::new::<UserError>(
vec![MemoryRegion { vec![
host_addr: addr, MemoryRegion::default(),
vm_addr: 96, MemoryRegion {
len: std::mem::size_of::<Instruction>() as u64, host_addr: addr,
vm_gap_shift: 63, vm_addr: 0x100000000,
is_writable: false, len: std::mem::size_of::<Instruction>() as u64,
}], vm_gap_shift: 63,
is_writable: false,
},
],
&config, &config,
) )
.unwrap(); .unwrap();
let translated_instruction = let translated_instruction =
translate_type::<Instruction>(&memory_mapping, 96, &bpf_loader::id(), true).unwrap(); translate_type::<Instruction>(&memory_mapping, 0x100000000, &bpf_loader::id(), true)
.unwrap();
assert_eq!(instruction, *translated_instruction); assert_eq!(instruction, *translated_instruction);
memory_mapping.resize_region::<BpfError>(0, 1).unwrap(); memory_mapping.resize_region::<BpfError>(1, 1).unwrap();
assert!( assert!(translate_type::<Instruction>(
translate_type::<Instruction>(&memory_mapping, 100, &bpf_loader::id(), true).is_err() &memory_mapping,
); 0x100000000,
&bpf_loader::id(),
true
)
.is_err());
} }
#[test] #[test]
@ -2877,13 +2894,16 @@ mod tests {
let addr = good_data.as_ptr() as *const _ as u64; let addr = good_data.as_ptr() as *const _ as u64;
let config = Config::default(); let config = Config::default();
let memory_mapping = MemoryMapping::new::<UserError>( let memory_mapping = MemoryMapping::new::<UserError>(
vec![MemoryRegion { vec![
host_addr: addr, MemoryRegion::default(),
vm_addr: 100, MemoryRegion {
len: good_data.len() as u64, host_addr: addr,
vm_gap_shift: 63, vm_addr: 0x100000000,
is_writable: false, len: good_data.len() as u64,
}], vm_gap_shift: 63,
is_writable: false,
},
],
&config, &config,
) )
.unwrap(); .unwrap();
@ -2902,19 +2922,22 @@ mod tests {
let mut data = vec![1u8, 2, 3, 4, 5]; let mut data = vec![1u8, 2, 3, 4, 5];
let addr = data.as_ptr() as *const _ as u64; let addr = data.as_ptr() as *const _ as u64;
let memory_mapping = MemoryMapping::new::<UserError>( let memory_mapping = MemoryMapping::new::<UserError>(
vec![MemoryRegion { vec![
host_addr: addr, MemoryRegion::default(),
vm_addr: 100, MemoryRegion {
len: data.len() as u64, host_addr: addr,
vm_gap_shift: 63, vm_addr: 0x100000000,
is_writable: false, len: data.len() as u64,
}], vm_gap_shift: 63,
is_writable: false,
},
],
&config, &config,
) )
.unwrap(); .unwrap();
let translated_data = translate_slice::<u8>( let translated_data = translate_slice::<u8>(
&memory_mapping, &memory_mapping,
100, 0x100000000,
data.len() as u64, data.len() as u64,
&bpf_loader::id(), &bpf_loader::id(),
true, true,
@ -2934,7 +2957,7 @@ mod tests {
assert!(translate_slice::<u8>( assert!(translate_slice::<u8>(
&memory_mapping, &memory_mapping,
100 - 1, 0x100000000 - 1,
data.len() as u64, data.len() as u64,
&bpf_loader::id(), &bpf_loader::id(),
true, true,
@ -2945,19 +2968,22 @@ mod tests {
let mut data = vec![1u64, 2, 3, 4, 5]; let mut data = vec![1u64, 2, 3, 4, 5];
let addr = data.as_ptr() as *const _ as u64; let addr = data.as_ptr() as *const _ as u64;
let memory_mapping = MemoryMapping::new::<UserError>( let memory_mapping = MemoryMapping::new::<UserError>(
vec![MemoryRegion { vec![
host_addr: addr, MemoryRegion::default(),
vm_addr: 96, MemoryRegion {
len: (data.len() * size_of::<u64>()) as u64, host_addr: addr,
vm_gap_shift: 63, vm_addr: 0x100000000,
is_writable: false, len: (data.len() * size_of::<u64>()) as u64,
}], vm_gap_shift: 63,
is_writable: false,
},
],
&config, &config,
) )
.unwrap(); .unwrap();
let translated_data = translate_slice::<u64>( let translated_data = translate_slice::<u64>(
&memory_mapping, &memory_mapping,
96, 0x100000000,
data.len() as u64, data.len() as u64,
&bpf_loader::id(), &bpf_loader::id(),
true, true,
@ -2966,28 +2992,35 @@ mod tests {
assert_eq!(data, translated_data); assert_eq!(data, translated_data);
data[0] = 10; data[0] = 10;
assert_eq!(data, translated_data); assert_eq!(data, translated_data);
assert!( assert!(translate_slice::<u64>(
translate_slice::<u64>(&memory_mapping, 96, u64::MAX, &bpf_loader::id(), true,) &memory_mapping,
.is_err() 0x100000000,
); u64::MAX,
&bpf_loader::id(),
true,
)
.is_err());
// Pubkeys // Pubkeys
let mut data = vec![solana_sdk::pubkey::new_rand(); 5]; let mut data = vec![solana_sdk::pubkey::new_rand(); 5];
let addr = data.as_ptr() as *const _ as u64; let addr = data.as_ptr() as *const _ as u64;
let memory_mapping = MemoryMapping::new::<UserError>( let memory_mapping = MemoryMapping::new::<UserError>(
vec![MemoryRegion { vec![
host_addr: addr, MemoryRegion::default(),
vm_addr: 100, MemoryRegion {
len: (data.len() * std::mem::size_of::<Pubkey>()) as u64, host_addr: addr,
vm_gap_shift: 63, vm_addr: 0x100000000,
is_writable: false, len: (data.len() * std::mem::size_of::<Pubkey>()) as u64,
}], vm_gap_shift: 63,
is_writable: false,
},
],
&config, &config,
) )
.unwrap(); .unwrap();
let translated_data = translate_slice::<Pubkey>( let translated_data = translate_slice::<Pubkey>(
&memory_mapping, &memory_mapping,
100, 0x100000000,
data.len() as u64, data.len() as u64,
&bpf_loader::id(), &bpf_loader::id(),
true, true,
@ -3004,13 +3037,16 @@ mod tests {
let addr = string.as_ptr() as *const _ as u64; let addr = string.as_ptr() as *const _ as u64;
let config = Config::default(); let config = Config::default();
let memory_mapping = MemoryMapping::new::<UserError>( let memory_mapping = MemoryMapping::new::<UserError>(
vec![MemoryRegion { vec![
host_addr: addr, MemoryRegion::default(),
vm_addr: 100, MemoryRegion {
len: string.len() as u64, host_addr: addr,
vm_gap_shift: 63, vm_addr: 0x100000000,
is_writable: false, len: string.len() as u64,
}], vm_gap_shift: 63,
is_writable: false,
},
],
&config, &config,
) )
.unwrap(); .unwrap();
@ -3018,7 +3054,7 @@ mod tests {
42, 42,
translate_string_and_do( translate_string_and_do(
&memory_mapping, &memory_mapping,
100, 0x100000000,
string.len() as u64, string.len() as u64,
&bpf_loader::id(), &bpf_loader::id(),
true, true,
@ -3058,13 +3094,16 @@ mod tests {
let addr = string.as_ptr() as *const _ as u64; let addr = string.as_ptr() as *const _ as u64;
let config = Config::default(); let config = Config::default();
let memory_mapping = MemoryMapping::new::<UserError>( let memory_mapping = MemoryMapping::new::<UserError>(
vec![MemoryRegion { vec![
host_addr: addr, MemoryRegion::default(),
vm_addr: 100, MemoryRegion {
len: string.len() as u64, host_addr: addr,
vm_gap_shift: 63, vm_addr: 0x100000000,
is_writable: false, len: string.len() as u64,
}], vm_gap_shift: 63,
is_writable: false,
},
],
&config, &config,
) )
.unwrap(); .unwrap();
@ -3080,7 +3119,7 @@ mod tests {
}; };
let mut result: Result<u64, EbpfError<BpfError>> = Ok(0); let mut result: Result<u64, EbpfError<BpfError>> = Ok(0);
syscall_panic.call( syscall_panic.call(
100, 0x100000000,
string.len() as u64, string.len() as u64,
42, 42,
84, 84,
@ -3106,7 +3145,7 @@ mod tests {
}; };
let mut result: Result<u64, EbpfError<BpfError>> = Ok(0); let mut result: Result<u64, EbpfError<BpfError>> = Ok(0);
syscall_panic.call( syscall_panic.call(
100, 0x100000000,
string.len() as u64, string.len() as u64,
42, 42,
84, 84,
@ -3135,20 +3174,23 @@ mod tests {
}; };
let config = Config::default(); let config = Config::default();
let memory_mapping = MemoryMapping::new::<UserError>( let memory_mapping = MemoryMapping::new::<UserError>(
vec![MemoryRegion { vec![
host_addr: addr, MemoryRegion::default(),
vm_addr: 100, MemoryRegion {
len: string.len() as u64, host_addr: addr,
vm_gap_shift: 63, vm_addr: 0x100000000,
is_writable: false, len: string.len() as u64,
}], vm_gap_shift: 63,
is_writable: false,
},
],
&config, &config,
) )
.unwrap(); .unwrap();
let mut result: Result<u64, EbpfError<BpfError>> = Ok(0); let mut result: Result<u64, EbpfError<BpfError>> = Ok(0);
syscall_sol_log.call( syscall_sol_log.call(
100, 0x100000000,
string.len() as u64, string.len() as u64,
0, 0,
0, 0,
@ -3162,7 +3204,7 @@ mod tests {
let mut result: Result<u64, EbpfError<BpfError>> = Ok(0); let mut result: Result<u64, EbpfError<BpfError>> = Ok(0);
syscall_sol_log.call( syscall_sol_log.call(
101, // AccessViolation 0x100000001, // AccessViolation
string.len() as u64, string.len() as u64,
0, 0,
0, 0,
@ -3170,10 +3212,10 @@ mod tests {
&memory_mapping, &memory_mapping,
&mut result, &mut result,
); );
assert_access_violation!(result, 101, string.len() as u64); assert_access_violation!(result, 0x100000001, string.len() as u64);
let mut result: Result<u64, EbpfError<BpfError>> = Ok(0); let mut result: Result<u64, EbpfError<BpfError>> = Ok(0);
syscall_sol_log.call( syscall_sol_log.call(
100, 0x100000000,
string.len() as u64 * 2, // AccessViolation string.len() as u64 * 2, // AccessViolation
0, 0,
0, 0,
@ -3181,10 +3223,10 @@ mod tests {
&memory_mapping, &memory_mapping,
&mut result, &mut result,
); );
assert_access_violation!(result, 100, string.len() as u64 * 2); assert_access_violation!(result, 0x100000000, string.len() as u64 * 2);
let mut result: Result<u64, EbpfError<BpfError>> = Ok(0); let mut result: Result<u64, EbpfError<BpfError>> = Ok(0);
syscall_sol_log.call( syscall_sol_log.call(
100, 0x100000000,
string.len() as u64, string.len() as u64,
0, 0,
0, 0,
@ -3206,7 +3248,7 @@ mod tests {
}; };
let mut result: Result<u64, EbpfError<BpfError>> = Ok(0); let mut result: Result<u64, EbpfError<BpfError>> = Ok(0);
syscall_sol_log.call( syscall_sol_log.call(
100, 0x100000000,
string.len() as u64, string.len() as u64,
0, 0,
0, 0,
@ -3217,7 +3259,7 @@ mod tests {
result.unwrap(); result.unwrap();
let mut result: Result<u64, EbpfError<BpfError>> = Ok(0); let mut result: Result<u64, EbpfError<BpfError>> = Ok(0);
syscall_sol_log.call( syscall_sol_log.call(
100, 0x100000000,
string.len() as u64, string.len() as u64,
0, 0,
0, 0,
@ -3277,19 +3319,22 @@ mod tests {
}; };
let config = Config::default(); let config = Config::default();
let memory_mapping = MemoryMapping::new::<UserError>( let memory_mapping = MemoryMapping::new::<UserError>(
vec![MemoryRegion { vec![
host_addr: addr, MemoryRegion::default(),
vm_addr: 100, MemoryRegion {
len: 32, host_addr: addr,
vm_gap_shift: 63, vm_addr: 0x100000000,
is_writable: false, len: 32,
}], vm_gap_shift: 63,
is_writable: false,
},
],
&config, &config,
) )
.unwrap(); .unwrap();
let mut result: Result<u64, EbpfError<BpfError>> = Ok(0); let mut result: Result<u64, EbpfError<BpfError>> = Ok(0);
syscall_sol_pubkey.call(100, 0, 0, 0, 0, &memory_mapping, &mut result); syscall_sol_pubkey.call(0x100000000, 0, 0, 0, 0, &memory_mapping, &mut result);
result.unwrap(); result.unwrap();
assert_eq!(log.borrow().len(), 1); assert_eq!(log.borrow().len(), 1);
assert_eq!( assert_eq!(
@ -3298,7 +3343,7 @@ mod tests {
); );
let mut result: Result<u64, EbpfError<BpfError>> = Ok(0); let mut result: Result<u64, EbpfError<BpfError>> = Ok(0);
syscall_sol_pubkey.call( syscall_sol_pubkey.call(
101, // AccessViolation 0x100000001, // AccessViolation
32, 32,
0, 0,
0, 0,
@ -3306,7 +3351,7 @@ mod tests {
&memory_mapping, &memory_mapping,
&mut result, &mut result,
); );
assert_access_violation!(result, 101, 32); assert_access_violation!(result, 0x100000001, 32);
let mut result: Result<u64, EbpfError<BpfError>> = Ok(0); let mut result: Result<u64, EbpfError<BpfError>> = Ok(0);
syscall_sol_pubkey.call(100, 32, 0, 0, 0, &memory_mapping, &mut result); syscall_sol_pubkey.call(100, 32, 0, 0, 0, &memory_mapping, &mut result);
assert_eq!( assert_eq!(
@ -3324,18 +3369,19 @@ mod tests {
{ {
let heap = AlignedMemory::new_with_size(100, HOST_ALIGN); let heap = AlignedMemory::new_with_size(100, HOST_ALIGN);
let memory_mapping = MemoryMapping::new::<UserError>( let memory_mapping = MemoryMapping::new::<UserError>(
vec![MemoryRegion::new_from_slice( vec![
heap.as_slice(), MemoryRegion::default(),
MM_HEAP_START, MemoryRegion::new_from_slice(&[], ebpf::MM_PROGRAM_START, 0, false),
0, MemoryRegion::new_from_slice(&[], ebpf::MM_STACK_START, 4096, true),
true, MemoryRegion::new_from_slice(heap.as_slice(), ebpf::MM_HEAP_START, 0, true),
)], MemoryRegion::new_from_slice(&[], ebpf::MM_INPUT_START, 0, true),
],
&config, &config,
) )
.unwrap(); .unwrap();
let mut syscall = SyscallAllocFree { let mut syscall = SyscallAllocFree {
aligned: true, aligned: true,
allocator: BpfAllocator::new(heap, MM_HEAP_START), allocator: BpfAllocator::new(heap, ebpf::MM_HEAP_START),
}; };
let mut result: Result<u64, EbpfError<BpfError>> = Ok(0); let mut result: Result<u64, EbpfError<BpfError>> = Ok(0);
syscall.call(100, 0, 0, 0, 0, &memory_mapping, &mut result); syscall.call(100, 0, 0, 0, 0, &memory_mapping, &mut result);
@ -3351,18 +3397,19 @@ mod tests {
{ {
let heap = AlignedMemory::new_with_size(100, HOST_ALIGN); let heap = AlignedMemory::new_with_size(100, HOST_ALIGN);
let memory_mapping = MemoryMapping::new::<UserError>( let memory_mapping = MemoryMapping::new::<UserError>(
vec![MemoryRegion::new_from_slice( vec![
heap.as_slice(), MemoryRegion::default(),
MM_HEAP_START, MemoryRegion::new_from_slice(&[], ebpf::MM_PROGRAM_START, 0, false),
0, MemoryRegion::new_from_slice(&[], ebpf::MM_STACK_START, 4096, true),
true, MemoryRegion::new_from_slice(heap.as_slice(), ebpf::MM_HEAP_START, 0, true),
)], MemoryRegion::new_from_slice(&[], ebpf::MM_INPUT_START, 0, true),
],
&config, &config,
) )
.unwrap(); .unwrap();
let mut syscall = SyscallAllocFree { let mut syscall = SyscallAllocFree {
aligned: false, aligned: false,
allocator: BpfAllocator::new(heap, MM_HEAP_START), allocator: BpfAllocator::new(heap, ebpf::MM_HEAP_START),
}; };
for _ in 0..100 { for _ in 0..100 {
let mut result: Result<u64, EbpfError<BpfError>> = Ok(0); let mut result: Result<u64, EbpfError<BpfError>> = Ok(0);
@ -3377,18 +3424,19 @@ mod tests {
{ {
let heap = AlignedMemory::new_with_size(100, HOST_ALIGN); let heap = AlignedMemory::new_with_size(100, HOST_ALIGN);
let memory_mapping = MemoryMapping::new::<UserError>( let memory_mapping = MemoryMapping::new::<UserError>(
vec![MemoryRegion::new_from_slice( vec![
heap.as_slice(), MemoryRegion::default(),
MM_HEAP_START, MemoryRegion::new_from_slice(&[], ebpf::MM_PROGRAM_START, 0, false),
0, MemoryRegion::new_from_slice(&[], ebpf::MM_STACK_START, 4096, true),
true, MemoryRegion::new_from_slice(heap.as_slice(), ebpf::MM_HEAP_START, 0, true),
)], MemoryRegion::new_from_slice(&[], ebpf::MM_INPUT_START, 0, true),
],
&config, &config,
) )
.unwrap(); .unwrap();
let mut syscall = SyscallAllocFree { let mut syscall = SyscallAllocFree {
aligned: true, aligned: true,
allocator: BpfAllocator::new(heap, MM_HEAP_START), allocator: BpfAllocator::new(heap, ebpf::MM_HEAP_START),
}; };
for _ in 0..12 { for _ in 0..12 {
let mut result: Result<u64, EbpfError<BpfError>> = Ok(0); let mut result: Result<u64, EbpfError<BpfError>> = Ok(0);
@ -3405,18 +3453,19 @@ mod tests {
let heap = AlignedMemory::new_with_size(100, HOST_ALIGN); let heap = AlignedMemory::new_with_size(100, HOST_ALIGN);
let config = Config::default(); let config = Config::default();
let memory_mapping = MemoryMapping::new::<UserError>( let memory_mapping = MemoryMapping::new::<UserError>(
vec![MemoryRegion::new_from_slice( vec![
heap.as_slice(), MemoryRegion::default(),
MM_HEAP_START, MemoryRegion::new_from_slice(&[], ebpf::MM_PROGRAM_START, 0, false),
0, MemoryRegion::new_from_slice(&[], ebpf::MM_STACK_START, 4096, true),
true, MemoryRegion::new_from_slice(heap.as_slice(), ebpf::MM_HEAP_START, 0, true),
)], MemoryRegion::new_from_slice(&[], ebpf::MM_INPUT_START, 0, true),
],
&config, &config,
) )
.unwrap(); .unwrap();
let mut syscall = SyscallAllocFree { let mut syscall = SyscallAllocFree {
aligned: true, aligned: true,
allocator: BpfAllocator::new(heap, MM_HEAP_START), allocator: BpfAllocator::new(heap, ebpf::MM_HEAP_START),
}; };
let mut result: Result<u64, EbpfError<BpfError>> = Ok(0); let mut result: Result<u64, EbpfError<BpfError>> = Ok(0);
syscall.call( syscall.call(
@ -3445,38 +3494,25 @@ mod tests {
let bytes2 = "flurbos"; let bytes2 = "flurbos";
let mock_slice1 = MockSlice { let mock_slice1 = MockSlice {
vm_addr: 4096, vm_addr: 0x300000000,
len: bytes1.len(), len: bytes1.len(),
}; };
let mock_slice2 = MockSlice { let mock_slice2 = MockSlice {
vm_addr: 8192, vm_addr: 0x400000000,
len: bytes2.len(), len: bytes2.len(),
}; };
let bytes_to_hash = [mock_slice1, mock_slice2]; let bytes_to_hash = [mock_slice1, mock_slice2];
let hash_result = [0; HASH_BYTES]; let hash_result = [0; HASH_BYTES];
let ro_len = bytes_to_hash.len() as u64; let ro_len = bytes_to_hash.len() as u64;
let ro_va = 96; let ro_va = 0x100000000;
let rw_va = 192; let rw_va = 0x200000000;
let config = Config::default(); let config = Config::default();
let memory_mapping = MemoryMapping::new::<UserError>( let memory_mapping = MemoryMapping::new::<UserError>(
vec![ vec![
MemoryRegion { MemoryRegion::default(),
host_addr: bytes1.as_ptr() as *const _ as u64,
vm_addr: 4096,
len: bytes1.len() as u64,
vm_gap_shift: 63,
is_writable: false,
},
MemoryRegion {
host_addr: bytes2.as_ptr() as *const _ as u64,
vm_addr: 8192,
len: bytes2.len() as u64,
vm_gap_shift: 63,
is_writable: false,
},
MemoryRegion { MemoryRegion {
host_addr: bytes_to_hash.as_ptr() as *const _ as u64, host_addr: bytes_to_hash.as_ptr() as *const _ as u64,
vm_addr: 96, vm_addr: ro_va,
len: 32, len: 32,
vm_gap_shift: 63, vm_gap_shift: 63,
is_writable: false, is_writable: false,
@ -3488,6 +3524,20 @@ mod tests {
vm_gap_shift: 63, vm_gap_shift: 63,
is_writable: true, is_writable: true,
}, },
MemoryRegion {
host_addr: bytes1.as_ptr() as *const _ as u64,
vm_addr: bytes_to_hash[0].vm_addr,
len: bytes1.len() as u64,
vm_gap_shift: 63,
is_writable: false,
},
MemoryRegion {
host_addr: bytes2.as_ptr() as *const _ as u64,
vm_addr: bytes_to_hash[1].vm_addr,
len: bytes2.len() as u64,
vm_gap_shift: 63,
is_writable: false,
},
], ],
&config, &config,
) )
@ -3520,7 +3570,7 @@ mod tests {
&memory_mapping, &memory_mapping,
&mut result, &mut result,
); );
assert_access_violation!(result, ro_va - 1, ro_len); assert_access_violation!(result, ro_va - 1, 32);
let mut result: Result<u64, EbpfError<BpfError>> = Ok(0); let mut result: Result<u64, EbpfError<BpfError>> = Ok(0);
syscall.call( syscall.call(
ro_va, ro_va,
@ -3531,7 +3581,7 @@ mod tests {
&memory_mapping, &memory_mapping,
&mut result, &mut result,
); );
assert_access_violation!(result, ro_va, ro_len + 1); assert_access_violation!(result, ro_va, 48);
let mut result: Result<u64, EbpfError<BpfError>> = Ok(0); let mut result: Result<u64, EbpfError<BpfError>> = Ok(0);
syscall.call( syscall.call(
ro_va, ro_va,
@ -3559,16 +3609,19 @@ mod tests {
// Test clock sysvar // Test clock sysvar
{ {
let got_clock = Clock::default(); let got_clock = Clock::default();
let got_clock_va = 2048; let got_clock_va = 0x100000000;
let memory_mapping = MemoryMapping::new::<UserError>( let memory_mapping = MemoryMapping::new::<UserError>(
vec![MemoryRegion { vec![
host_addr: &got_clock as *const _ as u64, MemoryRegion::default(),
vm_addr: got_clock_va, MemoryRegion {
len: size_of::<Clock>() as u64, host_addr: &got_clock as *const _ as u64,
vm_gap_shift: 63, vm_addr: got_clock_va,
is_writable: true, len: size_of::<Clock>() as u64,
}], vm_gap_shift: 63,
is_writable: true,
},
],
&config, &config,
) )
.unwrap(); .unwrap();
@ -3601,16 +3654,19 @@ mod tests {
// Test epoch_schedule sysvar // Test epoch_schedule sysvar
{ {
let got_epochschedule = EpochSchedule::default(); let got_epochschedule = EpochSchedule::default();
let got_epochschedule_va = 2048; let got_epochschedule_va = 0x100000000;
let memory_mapping = MemoryMapping::new::<UserError>( let memory_mapping = MemoryMapping::new::<UserError>(
vec![MemoryRegion { vec![
host_addr: &got_epochschedule as *const _ as u64, MemoryRegion::default(),
vm_addr: got_epochschedule_va, MemoryRegion {
len: size_of::<EpochSchedule>() as u64, host_addr: &got_epochschedule as *const _ as u64,
vm_gap_shift: 63, vm_addr: got_epochschedule_va,
is_writable: true, len: size_of::<EpochSchedule>() as u64,
}], vm_gap_shift: 63,
is_writable: true,
},
],
&config, &config,
) )
.unwrap(); .unwrap();
@ -3651,16 +3707,19 @@ mod tests {
// Test fees sysvar // Test fees sysvar
{ {
let got_fees = Fees::default(); let got_fees = Fees::default();
let got_fees_va = 2048; let got_fees_va = 0x100000000;
let memory_mapping = MemoryMapping::new::<UserError>( let memory_mapping = MemoryMapping::new::<UserError>(
vec![MemoryRegion { vec![
host_addr: &got_fees as *const _ as u64, MemoryRegion::default(),
vm_addr: got_fees_va, MemoryRegion {
len: size_of::<Fees>() as u64, host_addr: &got_fees as *const _ as u64,
vm_gap_shift: 63, vm_addr: got_fees_va,
is_writable: true, len: size_of::<Fees>() as u64,
}], vm_gap_shift: 63,
is_writable: true,
},
],
&config, &config,
) )
.unwrap(); .unwrap();
@ -3691,16 +3750,19 @@ mod tests {
// Test rent sysvar // Test rent sysvar
{ {
let got_rent = Rent::default(); let got_rent = Rent::default();
let got_rent_va = 2048; let got_rent_va = 0x100000000;
let memory_mapping = MemoryMapping::new::<UserError>( let memory_mapping = MemoryMapping::new::<UserError>(
vec![MemoryRegion { vec![
host_addr: &got_rent as *const _ as u64, MemoryRegion::default(),
vm_addr: got_rent_va, MemoryRegion {
len: size_of::<Rent>() as u64, host_addr: &got_rent as *const _ as u64,
vm_gap_shift: 63, vm_addr: got_rent_va,
is_writable: true, len: size_of::<Rent>() as u64,
}], vm_gap_shift: 63,
is_writable: true,
},
],
&config, &config,
) )
.unwrap(); .unwrap();

View File

@ -205,8 +205,8 @@ native machine code before execting it in the virtual machine.",
.unwrap(); .unwrap();
if matches.is_present("verify") { if matches.is_present("verify") {
let (_, elf_bytes) = executable.get_text_bytes().unwrap(); let text_bytes = executable.get_text_bytes().1;
check(elf_bytes).unwrap(); check(text_bytes, &config).unwrap();
} }
executable.jit_compile().unwrap(); executable.jit_compile().unwrap();
let analysis = Analysis::from_executable(executable.as_ref()); let analysis = Analysis::from_executable(executable.as_ref());

View File

@ -163,6 +163,10 @@ pub mod libsecp256k1_0_5_upgrade_enabled {
solana_sdk::declare_id!("DhsYfRjxfnh2g7HKJYSzT79r74Afa1wbHkAgHndrA1oy"); solana_sdk::declare_id!("DhsYfRjxfnh2g7HKJYSzT79r74Afa1wbHkAgHndrA1oy");
} }
pub mod stop_verify_mul64_imm_nonzero {
solana_sdk::declare_id!("EHFwHg2vhwUb7ifm7BuY9RMbsyt1rS1rUii7yeDJtGnN");
}
pub mod merge_nonce_error_into_system_error { pub mod merge_nonce_error_into_system_error {
solana_sdk::declare_id!("21AWDosvp3pBamFW91KB35pNoaoZVTM7ess8nr2nt53B"); solana_sdk::declare_id!("21AWDosvp3pBamFW91KB35pNoaoZVTM7ess8nr2nt53B");
} }
@ -292,6 +296,7 @@ lazy_static! {
(neon_evm_compute_budget::id(), "bump neon_evm's compute budget"), (neon_evm_compute_budget::id(), "bump neon_evm's compute budget"),
(rent_for_sysvars::id(), "collect rent from accounts owned by sysvars"), (rent_for_sysvars::id(), "collect rent from accounts owned by sysvars"),
(libsecp256k1_0_5_upgrade_enabled::id(), "upgrade libsecp256k1 to v0.5.0"), (libsecp256k1_0_5_upgrade_enabled::id(), "upgrade libsecp256k1 to v0.5.0"),
(stop_verify_mul64_imm_nonzero::id(), "Sets rbpf vm config verify_mul64_imm_nonzero to false"),
(merge_nonce_error_into_system_error::id(), "merge NonceError into SystemError"), (merge_nonce_error_into_system_error::id(), "merge NonceError into SystemError"),
(spl_token_v2_set_authority_fix::id(), "spl-token set_authority fix"), (spl_token_v2_set_authority_fix::id(), "spl-token set_authority fix"),
(stake_merge_with_unmatched_credits_observed::id(), "allow merging active stakes with unmatched credits_observed #18985"), (stake_merge_with_unmatched_credits_observed::id(), "allow merging active stakes with unmatched credits_observed #18985"),