Skip to content

Commit

Permalink
Refactor - Moves config flags into executable capabilities (#473)
Browse files Browse the repository at this point in the history
* Adds Config::enable_sbpf_v1 and Config::enable_sbpf_v2.

* Adds ExecutableCapabilities.

* Removes Config::enable_sdiv.

* Removes Config::reject_rodata_stack_overlap.

* Removes Config::enable_elf_vaddr.

* Removes Config::dynamic_stack_frames.

* Removes Config::static_syscalls.

* Removes test_static_syscall_disabled().

* Renames ExecutableCapabilities => SBPFVersion.
  • Loading branch information
Lichtso committed Jun 27, 2023
1 parent f91d598 commit 0881f8a
Show file tree
Hide file tree
Showing 26 changed files with 489 additions and 255 deletions.
13 changes: 8 additions & 5 deletions benches/memory_mapping.rs
Original file line number Diff line number Diff line change
Expand Up @@ -12,6 +12,7 @@ extern crate test;

use rand::{rngs::SmallRng, Rng, SeedableRng};
use solana_rbpf::{
elf::SBPFVersion,
memory_region::{
AccessType, AlignedMemoryMapping, MemoryRegion, MemoryState, UnalignedMemoryMapping,
},
Expand Down Expand Up @@ -71,7 +72,8 @@ macro_rules! bench_gapped_randomized_access_with_1024_entries {
MemoryState::Readable,
)];
let config = Config::default();
let memory_mapping = $mem::new(memory_regions, &config).unwrap();
let memory_mapping =
$mem::new(memory_regions, &config, &SBPFVersion::V2).unwrap();
let mut prng = new_prng!();
bencher.iter(|| {
assert!(memory_mapping
Expand Down Expand Up @@ -110,7 +112,7 @@ macro_rules! bench_randomized_access_with_0001_entry {
let content = vec![0; 1024 * 2];
let memory_regions = vec![MemoryRegion::new_readonly(&content[..], 0x100000000)];
let config = Config::default();
let memory_mapping = $mem::new(memory_regions, &config).unwrap();
let memory_mapping = $mem::new(memory_regions, &config, &SBPFVersion::V2).unwrap();
let mut prng = new_prng!();
bencher.iter(|| {
let _ = memory_mapping.map(
Expand Down Expand Up @@ -145,7 +147,7 @@ macro_rules! bench_randomized_access_with_n_entries {
let (memory_regions, end_address) =
generate_memory_regions($n, MemoryState::Readable, Some(&mut prng));
let config = Config::default();
let memory_mapping = $mem::new(memory_regions, &config).unwrap();
let memory_mapping = $mem::new(memory_regions, &config, &SBPFVersion::V2).unwrap();
bencher.iter(|| {
let _ = memory_mapping.map(
AccessType::Load,
Expand Down Expand Up @@ -195,7 +197,7 @@ macro_rules! bench_randomized_mapping_with_n_entries {
let (memory_regions, _end_address) =
generate_memory_regions($n, MemoryState::Readable, Some(&mut prng));
let config = Config::default();
let memory_mapping = $mem::new(memory_regions, &config).unwrap();
let memory_mapping = $mem::new(memory_regions, &config, &SBPFVersion::V2).unwrap();
bencher.iter(|| {
let _ = memory_mapping.map(AccessType::Load, 0x100000000, 1, 0);
});
Expand Down Expand Up @@ -244,7 +246,7 @@ macro_rules! bench_mapping_with_n_entries {
let (memory_regions, _end_address) =
generate_memory_regions($n, MemoryState::Readable, None);
let config = Config::default();
let memory_mapping = $mem::new(memory_regions, &config).unwrap();
let memory_mapping = $mem::new(memory_regions, &config, &SBPFVersion::V2).unwrap();
bencher.iter(|| {
let _ = memory_mapping.map(AccessType::Load, 0x100000000, 1, 0);
});
Expand Down Expand Up @@ -302,6 +304,7 @@ fn do_bench_mapping_operation(bencher: &mut Bencher, op: MemoryOperation, vm_add
MemoryRegion::new_writable(&mut mem2, 0x100000000 + 8),
],
&config,
&SBPFVersion::V2,
)
.unwrap();

Expand Down
8 changes: 4 additions & 4 deletions benches/vm_execution.rs
Original file line number Diff line number Diff line change
Expand Up @@ -171,7 +171,7 @@ fn bench_jit_vs_interpreter_address_translation_stack_fixed(bencher: &mut Benche
bencher,
ADDRESS_TRANSLATION_STACK_CODE,
Config {
dynamic_stack_frames: false,
enable_sbpf_v2: false,
..Config::default()
},
524289,
Expand All @@ -186,7 +186,7 @@ fn bench_jit_vs_interpreter_address_translation_stack_dynamic(bencher: &mut Benc
bencher,
ADDRESS_TRANSLATION_STACK_CODE,
Config {
dynamic_stack_frames: true,
enable_sbpf_v2: true,
..Config::default()
},
524289,
Expand Down Expand Up @@ -233,7 +233,7 @@ fn bench_jit_vs_interpreter_call_depth_fixed(bencher: &mut Bencher) {
call function_foo
exit",
Config {
dynamic_stack_frames: false,
enable_sbpf_v2: false,
..Config::default()
},
137218,
Expand Down Expand Up @@ -264,7 +264,7 @@ fn bench_jit_vs_interpreter_call_depth_dynamic(bencher: &mut Bencher) {
add r11, 4
exit",
Config {
dynamic_stack_frames: true,
enable_sbpf_v2: true,
..Config::default()
},
176130,
Expand Down
13 changes: 7 additions & 6 deletions cli/src/main.rs
Original file line number Diff line number Diff line change
Expand Up @@ -12,13 +12,13 @@ use solana_rbpf::{
use std::{fs::File, io::Read, path::Path, sync::Arc};

fn main() {
let matches = App::new("Solana RBPF CLI")
let matches = App::new("Solana BPF CLI")
.version(crate_version!())
.author("Solana Maintainers <maintainers@solana.foundation>")
.about("CLI to test and analyze eBPF programs")
.about("CLI to test and analyze Solana BPF programs")
.arg(
Arg::new("assembler")
.about("Assemble and load eBPF executable")
.about("Assemble and load Solana BPF executable")
.short('a')
.long("asm")
.value_name("FILE")
Expand All @@ -27,7 +27,7 @@ fn main() {
)
.arg(
Arg::new("elf")
.about("Load ELF as eBPF executable")
.about("Load ELF as Solana BPF executable")
.short('e')
.long("elf")
.value_name("FILE")
Expand Down Expand Up @@ -139,6 +139,7 @@ fn main() {
.unwrap(),
);
let config = verified_executable.get_config();
let sbpf_version = verified_executable.get_sbpf_version();
let mut stack = AlignedMemory::<{ ebpf::HOST_ALIGN }>::zero_filled(config.stack_size());
let stack_len = stack.len();
let mut heap = AlignedMemory::<{ ebpf::HOST_ALIGN }>::zero_filled(
Expand All @@ -153,7 +154,7 @@ fn main() {
MemoryRegion::new_writable_gapped(
stack.as_slice_mut(),
ebpf::MM_STACK_START,
if !config.dynamic_stack_frames && config.enable_stack_frame_gaps {
if !sbpf_version.dynamic_stack_frames() && config.enable_stack_frame_gaps {
config.stack_frame_size as u64
} else {
0
Expand All @@ -163,7 +164,7 @@ fn main() {
MemoryRegion::new_writable(&mut mem, ebpf::MM_INPUT_START),
];

let memory_mapping = MemoryMapping::new(regions, config).unwrap();
let memory_mapping = MemoryMapping::new(regions, config, sbpf_version).unwrap();

let mut vm = EbpfVm::new(
&verified_executable,
Expand Down
3 changes: 2 additions & 1 deletion examples/disassemble.rs
Original file line number Diff line number Diff line change
Expand Up @@ -6,7 +6,7 @@

extern crate solana_rbpf;
use solana_rbpf::{
elf::Executable,
elf::{Executable, SBPFVersion},
static_analysis::Analysis,
verifier::TautologyVerifier,
vm::{BuiltinProgram, FunctionRegistry, TestContextObject},
Expand Down Expand Up @@ -35,6 +35,7 @@ fn main() {
let executable = Executable::<TautologyVerifier, TestContextObject>::from_text_bytes(
program,
loader,
SBPFVersion::V2,
FunctionRegistry::default(),
)
.unwrap();
Expand Down
3 changes: 2 additions & 1 deletion examples/to_json.rs
Original file line number Diff line number Diff line change
Expand Up @@ -12,7 +12,7 @@ use std::path::PathBuf;

extern crate solana_rbpf;
use solana_rbpf::{
elf::Executable,
elf::{Executable, SBPFVersion},
static_analysis::Analysis,
verifier::TautologyVerifier,
vm::{BuiltinProgram, FunctionRegistry, TestContextObject},
Expand All @@ -31,6 +31,7 @@ fn to_json(program: &[u8]) -> String {
let executable = Executable::<TautologyVerifier, TestContextObject>::from_text_bytes(
program,
Arc::new(BuiltinProgram::default()),
SBPFVersion::V2,
FunctionRegistry::default(),
)
.unwrap();
Expand Down
8 changes: 0 additions & 8 deletions fuzz/fuzz_targets/common.rs
Original file line number Diff line number Diff line change
Expand Up @@ -14,8 +14,6 @@ pub struct ConfigTemplate {
sanitize_user_provided_values: bool,
encrypt_environment_registers: bool,
reject_callx_r10: bool,
dynamic_stack_frames: bool,
enable_sdiv: bool,
optimize_rodata: bool,
}

Expand All @@ -31,8 +29,6 @@ impl<'a> Arbitrary<'a> for ConfigTemplate {
sanitize_user_provided_values: bools & (1 << 3) != 0,
encrypt_environment_registers: bools & (1 << 4) != 0,
reject_callx_r10: bools & (1 << 6) != 0,
dynamic_stack_frames: bools & (1 << 7) != 0,
enable_sdiv: bools & (1 << 8) != 0,
optimize_rodata: bools & (1 << 9) != 0,
})
}
Expand All @@ -57,8 +53,6 @@ impl From<ConfigTemplate> for Config {
sanitize_user_provided_values,
encrypt_environment_registers,
reject_callx_r10,
dynamic_stack_frames,
enable_sdiv,
optimize_rodata,
} => Config {
max_call_depth,
Expand All @@ -74,8 +68,6 @@ impl From<ConfigTemplate> for Config {
0
},
reject_callx_r10,
dynamic_stack_frames,
enable_sdiv,
optimize_rodata,
..Default::default()
},
Expand Down
5 changes: 3 additions & 2 deletions fuzz/fuzz_targets/dumb.rs
Original file line number Diff line number Diff line change
Expand Up @@ -6,7 +6,7 @@ use libfuzzer_sys::fuzz_target;

use solana_rbpf::{
ebpf,
elf::Executable,
elf::{Executable, SBPFVersion},
memory_region::MemoryRegion,
verifier::{RequisiteVerifier, TautologyVerifier, Verifier},
vm::{BuiltinProgram, FunctionRegistry, TestContextObject},
Expand All @@ -28,14 +28,15 @@ fuzz_target!(|data: DumbFuzzData| {
let prog = data.prog;
let config = data.template.into();
let function_registry = FunctionRegistry::default();
if RequisiteVerifier::verify(&prog, &config, &function_registry).is_err() {
if RequisiteVerifier::verify(&prog, &config, &SBPFVersion::V2, &function_registry).is_err() {
// verify please
return;
}
let mut mem = data.mem;
let executable = Executable::<TautologyVerifier, TestContextObject>::from_text_bytes(
&prog,
std::sync::Arc::new(BuiltinProgram::new_loader(config)),
SBPFVersion::V2,
function_registry,
)
.unwrap();
Expand Down
5 changes: 3 additions & 2 deletions fuzz/fuzz_targets/smart.rs
Original file line number Diff line number Diff line change
Expand Up @@ -7,7 +7,7 @@ use libfuzzer_sys::fuzz_target;
use grammar_aware::*;
use solana_rbpf::{
ebpf,
elf::Executable,
elf::{Executable, SBPFVersion},
insn_builder::{Arch, IntoBytes},
memory_region::MemoryRegion,
verifier::{RequisiteVerifier, TautologyVerifier, Verifier},
Expand All @@ -32,14 +32,15 @@ fuzz_target!(|data: FuzzData| {
let prog = make_program(&data.prog, data.arch);
let config = data.template.into();
let function_registry = FunctionRegistry::default();
if RequisiteVerifier::verify(prog.into_bytes(), &config, &function_registry).is_err() {
if RequisiteVerifier::verify(prog.into_bytes(), &config, &SBPFVersion::V2, &function_registry).is_err() {
// verify please
return;
}
let mut mem = data.mem;
let executable = Executable::<TautologyVerifier, TestContextObject>::from_text_bytes(
prog.into_bytes(),
std::sync::Arc::new(BuiltinProgram::new_loader(config)),
SBPFVersion::V2,
function_registry,
)
.unwrap();
Expand Down
5 changes: 3 additions & 2 deletions fuzz/fuzz_targets/smart_jit_diff.rs
Original file line number Diff line number Diff line change
Expand Up @@ -5,7 +5,7 @@ use libfuzzer_sys::fuzz_target;
use grammar_aware::*;
use solana_rbpf::{
ebpf,
elf::Executable,
elf::{Executable, SBPFVersion},
insn_builder::{Arch, Instruction, IntoBytes},
memory_region::MemoryRegion,
verifier::{RequisiteVerifier, TautologyVerifier, Verifier},
Expand Down Expand Up @@ -39,7 +39,7 @@ fuzz_target!(|data: FuzzData| {
.push();
let config = data.template.into();
let function_registry = FunctionRegistry::default();
if RequisiteVerifier::verify(prog.into_bytes(), &config, &function_registry).is_err() {
if RequisiteVerifier::verify(prog.into_bytes(), &config, &SBPFVersion::V2, &function_registry).is_err() {
// verify please
return;
}
Expand All @@ -48,6 +48,7 @@ fuzz_target!(|data: FuzzData| {
let mut executable = Executable::<TautologyVerifier, TestContextObject>::from_text_bytes(
prog.into_bytes(),
std::sync::Arc::new(BuiltinProgram::new_loader(config)),
SBPFVersion::V2,
function_registry,
)
.unwrap();
Expand Down
5 changes: 3 additions & 2 deletions fuzz/fuzz_targets/smarter_jit_diff.rs
Original file line number Diff line number Diff line change
Expand Up @@ -5,7 +5,7 @@ use libfuzzer_sys::fuzz_target;
use semantic_aware::*;
use solana_rbpf::{
ebpf,
elf::Executable,
elf::{Executable, SBPFVersion},
insn_builder::IntoBytes,
memory_region::MemoryRegion,
static_analysis::Analysis,
Expand Down Expand Up @@ -38,7 +38,7 @@ fuzz_target!(|data: FuzzData| {
let prog = make_program(&data.prog);
let config = data.template.into();
let function_registry = FunctionRegistry::default();
if RequisiteVerifier::verify(prog.into_bytes(), &config, &function_registry).is_err() {
if RequisiteVerifier::verify(prog.into_bytes(), &config, &SBPFVersion::V2, &function_registry).is_err() {
// verify please
return;
}
Expand All @@ -47,6 +47,7 @@ fuzz_target!(|data: FuzzData| {
let mut executable = Executable::<TautologyVerifier, TestContextObject>::from_text_bytes(
prog.into_bytes(),
std::sync::Arc::new(BuiltinProgram::new_loader(config)),
SBPFVersion::V2,
function_registry,
)
.unwrap();
Expand Down
3 changes: 2 additions & 1 deletion fuzz/fuzz_targets/verify_semantic_aware.rs
Original file line number Diff line number Diff line change
Expand Up @@ -4,6 +4,7 @@ use libfuzzer_sys::fuzz_target;

use semantic_aware::*;
use solana_rbpf::{
elf::SBPFVersion,
insn_builder::IntoBytes,
verifier::{RequisiteVerifier, Verifier},
vm::FunctionRegistry,
Expand All @@ -24,5 +25,5 @@ fuzz_target!(|data: FuzzData| {
let prog = make_program(&data.prog);
let config = data.template.into();
let function_registry = FunctionRegistry::default();
RequisiteVerifier::verify(prog.into_bytes(), &config, &function_registry).unwrap();
RequisiteVerifier::verify(prog.into_bytes(), &config, &SBPFVersion::V2, &function_registry).unwrap();
});
18 changes: 15 additions & 3 deletions src/assembler.rs
Original file line number Diff line number Diff line change
Expand Up @@ -18,7 +18,7 @@ use crate::{
Statement,
},
ebpf::{self, Insn},
elf::{register_internal_function, Executable},
elf::{register_internal_function, Executable, SBPFVersion},
verifier::TautologyVerifier,
vm::{BuiltinProgram, ContextObject, FunctionRegistry},
};
Expand Down Expand Up @@ -218,6 +218,11 @@ pub fn assemble<C: ContextObject>(
src: &str,
loader: Arc<BuiltinProgram<C>>,
) -> Result<Executable<TautologyVerifier, C>, String> {
let sbpf_version = if loader.get_config().enable_sbpf_v2 {
SBPFVersion::V2
} else {
SBPFVersion::V1
};
fn resolve_label(
insn_ptr: usize,
labels: &HashMap<&str, usize>,
Expand All @@ -242,6 +247,7 @@ pub fn assemble<C: ContextObject>(
register_internal_function(
&mut function_registry,
&loader,
&SBPFVersion::V2,
insn_ptr,
name.as_bytes(),
)
Expand Down Expand Up @@ -295,6 +301,7 @@ pub fn assemble<C: ContextObject>(
register_internal_function(
&mut function_registry,
&loader,
&SBPFVersion::V2,
target_pc as usize,
label.as_bytes(),
)
Expand Down Expand Up @@ -358,6 +365,11 @@ pub fn assemble<C: ContextObject>(
.iter()
.flat_map(|insn| insn.to_vec())
.collect::<Vec<_>>();
Executable::<TautologyVerifier, C>::from_text_bytes(&program, loader, function_registry)
.map_err(|err| format!("Executable constructor {err:?}"))
Executable::<TautologyVerifier, C>::from_text_bytes(
&program,
loader,
sbpf_version,
function_registry,
)
.map_err(|err| format!("Executable constructor {err:?}"))
}
Loading

0 comments on commit 0881f8a

Please sign in to comment.