Program may not exit (#1669)
Cap max executed instructions, report number of executed instructions
This commit is contained in:
parent
aca2f9666d
commit
38ee5c4dfb
|
@ -13,7 +13,7 @@ elf = "0.0.10"
|
|||
env_logger = "0.5.12"
|
||||
libc = "0.2.43"
|
||||
log = "0.4.2"
|
||||
rbpf = "0.1.0"
|
||||
solana_rbpf = "0.1.2"
|
||||
serde = "1.0.27"
|
||||
serde_derive = "1.0.27"
|
||||
solana-sdk = { path = "../../../sdk", version = "0.11.0" }
|
||||
|
|
|
@ -1,4 +1,4 @@
|
|||
use rbpf::ebpf;
|
||||
use solana_rbpf::ebpf;
|
||||
use std::io::{Error, ErrorKind};
|
||||
|
||||
fn reject<S: AsRef<str>>(msg: S) -> Result<(), Error> {
|
||||
|
|
|
@ -5,11 +5,12 @@ extern crate byteorder;
|
|||
extern crate env_logger;
|
||||
#[macro_use]
|
||||
extern crate log;
|
||||
extern crate rbpf;
|
||||
extern crate solana_rbpf;
|
||||
extern crate solana_sdk;
|
||||
|
||||
use bincode::deserialize;
|
||||
use byteorder::{ByteOrder, LittleEndian, WriteBytesExt};
|
||||
use solana_rbpf::{helpers, EbpfVmRaw};
|
||||
use solana_sdk::account::KeyedAccount;
|
||||
use solana_sdk::loader_instruction::LoaderInstruction;
|
||||
use solana_sdk::pubkey::Pubkey;
|
||||
|
@ -52,11 +53,12 @@ pub fn helper_printf(arg1: u64, arg2: u64, arg3: u64, arg4: u64, arg5: u64) -> u
|
|||
+ size_arg(arg5)
|
||||
}
|
||||
|
||||
fn create_vm(prog: &[u8]) -> Result<rbpf::EbpfVmRaw, Error> {
|
||||
let mut vm = rbpf::EbpfVmRaw::new(None)?;
|
||||
fn create_vm(prog: &[u8]) -> Result<EbpfVmRaw, Error> {
|
||||
let mut vm = EbpfVmRaw::new(None)?;
|
||||
vm.set_verifier(bpf_verifier::check)?;
|
||||
vm.set_max_instruction_count(36000)?; // 36000 is a wag, need to tune
|
||||
vm.set_program(&prog)?;
|
||||
vm.register_helper(rbpf::helpers::BPF_TRACE_PRINTK_IDX, helper_printf)?;
|
||||
vm.register_helper(helpers::BPF_TRACE_PRINTK_IDX, helper_printf)?;
|
||||
Ok(vm)
|
||||
}
|
||||
|
||||
|
@ -107,9 +109,9 @@ pub extern "C" fn process(keyed_accounts: &mut [KeyedAccount], tx_data: &[u8]) -
|
|||
|
||||
if keyed_accounts[0].account.executable {
|
||||
let prog = keyed_accounts[0].account.userdata.clone();
|
||||
trace!("Call BPF, {} Instructions", prog.len() / 8);
|
||||
trace!("Call BPF, {} instructions", prog.len() / 8);
|
||||
//dump_program(keyed_accounts[0].key, &prog);
|
||||
let vm = match create_vm(&prog) {
|
||||
let mut vm = match create_vm(&prog) {
|
||||
Ok(vm) => vm,
|
||||
Err(e) => {
|
||||
warn!("create_vm failed: {}", e);
|
||||
|
@ -127,6 +129,10 @@ pub extern "C" fn process(keyed_accounts: &mut [KeyedAccount], tx_data: &[u8]) -
|
|||
}
|
||||
}
|
||||
deserialize_parameters(&mut keyed_accounts[1..], &v);
|
||||
trace!(
|
||||
"BPF program executed {} instructions",
|
||||
vm.get_last_instruction_count()
|
||||
);
|
||||
} else if let Ok(instruction) = deserialize(tx_data) {
|
||||
match instruction {
|
||||
LoaderInstruction::Write { offset, bytes } => {
|
||||
|
@ -153,3 +159,28 @@ pub extern "C" fn process(keyed_accounts: &mut [KeyedAccount], tx_data: &[u8]) -
|
|||
}
|
||||
true
|
||||
}
|
||||
|
||||
#[cfg(test)]
|
||||
mod tests {
|
||||
use super::*;
|
||||
#[test]
|
||||
#[should_panic(expected = "Error: Execution exceeded maximum number of instructions")]
|
||||
fn test_non_terminating_program() {
|
||||
#[rustfmt::skip]
|
||||
let prog = &[
|
||||
0xb7, 0x06, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, // r6 = 0
|
||||
0xb7, 0x01, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, // r1 = 0
|
||||
0xb7, 0x02, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, // r2 = 0
|
||||
0xb7, 0x03, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, // r3 = 0
|
||||
0xb7, 0x04, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, // r4 = 0
|
||||
0xbf, 0x65, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, // r5 = r6
|
||||
0x85, 0x00, 0x00, 0x00, 0x06, 0x00, 0x00, 0x00, // call 6
|
||||
0x07, 0x06, 0x00, 0x00, 0x01, 0x00, 0x00, 0x00, // r6 + 1
|
||||
0x05, 0x00, 0xf8, 0xff, 0x00, 0x00, 0x00, 0x00, // goto -8
|
||||
0x95, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, // exit
|
||||
];
|
||||
let input = &mut [0x00];
|
||||
let mut vm = create_vm(prog).unwrap();
|
||||
vm.execute_program(input).unwrap();
|
||||
}
|
||||
}
|
||||
|
|
Loading…
Reference in New Issue