Skip to content

Commit

Permalink
feat: fix and port to rarity after rebase (#20)
Browse files Browse the repository at this point in the history
  • Loading branch information
mstarzinger committed Mar 7, 2021
1 parent d1cf9b4 commit 27cb6fe
Show file tree
Hide file tree
Showing 2 changed files with 93 additions and 7 deletions.
98 changes: 92 additions & 6 deletions src/rarity.rs
Original file line number Diff line number Diff line change
Expand Up @@ -577,7 +577,7 @@ impl Engine {

fn execute(&mut self, instruction: Instruction) -> Result<Option<Bug>, EngineError> {
match instruction {
Instruction::Ecall(_) => self.execute_ecall(),
Instruction::Ecall(_) => self.execute_ecall(instruction),
Instruction::Lui(utype) => self.execute_lui(utype),
Instruction::Addi(itype) => self.execute_itype(instruction, itype, u64::wrapping_add),
Instruction::Add(rtype) => self.execute_rtype(instruction, rtype, u64::wrapping_add),
Expand Down Expand Up @@ -672,6 +672,34 @@ impl Engine {
}
}

fn check_for_valid_memory_range(
&mut self,
instruction: &str,
address: u64,
size: u64,
) -> Result<Option<Bug>, EngineError> {
if !self.is_in_vaddr_range(address) || !self.is_in_vaddr_range(address + size) {
trace!(
"{}: buffer {:#x} - {:#x} out of virtual address range (0x0 - {:#x}) => computing reachability",
instruction,
address,
address + size,
self.state.memory.len() * 8,
);

self.is_running = false;

Ok(Some(Bug::AccessToOutOfRangeAddress {
info: RarityBugInfo {
witness: self.concrete_inputs.clone(),
pc: self.state.pc,
},
}))
} else {
Ok(None)
}
}

fn execute_lui(&mut self, utype: UType) -> Result<Option<Bug>, EngineError> {
let immediate = u64::from(utype.imm()) << 12;

Expand Down Expand Up @@ -765,7 +793,7 @@ impl Engine {
_ => {
let bug = self.check_for_uninitialized_memory(instruction, lhs, rhs)?;

trace!("could not find input assignment => exeting this context");
trace!("could not find input assignment => exiting this context");

self.is_running = false;

Expand Down Expand Up @@ -834,8 +862,9 @@ impl Engine {

trace!("read: fd={} buffer={:#x} size={}", 0, buffer, size,);

if !self.is_in_vaddr_range(buffer) || !self.is_in_vaddr_range(buffer + size) {
return not_supported("read syscall failed to");
let bug = self.check_for_valid_memory_range("read", buffer, size)?;
if bug.is_some() {
return Ok(bug);
}

let size_of_u64 = size_of::<u64>() as u64;
Expand Down Expand Up @@ -894,6 +923,60 @@ impl Engine {
Ok(None)
}

fn execute_write(&mut self, instruction: Instruction) -> Result<Option<Bug>, EngineError> {
if !matches!(self.state.regs[Register::A0 as usize], Value::Concrete(1)) {
return not_supported("can not handle other fd than stdout in write syscall");
}

let buffer = if let Value::Concrete(b) = self.state.regs[Register::A1 as usize] {
b
} else {
return not_supported(
"can not handle symbolic or uninitialized buffer address in write syscall",
);
};

let size = if let Value::Concrete(s) = self.state.regs[Register::A2 as usize] {
s
} else {
return not_supported("can not handle symbolic or uinitialized size in write syscall");
};

trace!("write: fd={} buffer={:#x} size={}", 1, buffer, size,);

let bug = self.check_for_valid_memory_range("write", buffer, size)?;
if bug.is_some() {
return Ok(bug);
}

let size_of_u64 = size_of::<u64>() as u64;
let start = buffer / size_of_u64;
let bytes_to_read = size + buffer % size_of_u64;
let words_to_read = (bytes_to_read + size_of_u64 - 1) / size_of_u64;

for word_count in 0..words_to_read {
if self.state.memory[(start + word_count) as usize] == Value::Uninitialized {
trace!(
"write: access to uninitialized memory at {:#x} => computing reachability",
(start + word_count) * size_of_u64,
);

return Ok(Some(Bug::AccessToUnitializedMemory {
info: RarityBugInfo {
witness: self.concrete_inputs.clone(),
pc: self.state.pc,
},
instruction,
operands: vec![],
}));
}
}

self.state.regs[Register::A0 as usize] = Value::Concrete(size);

Ok(None)
}

fn execute_beq(&mut self, btype: BType) -> Result<Option<Bug>, EngineError> {
let lhs = self.state.regs[btype.rs1() as usize];
let rhs = self.state.regs[btype.rs2() as usize];
Expand Down Expand Up @@ -922,7 +1005,7 @@ impl Engine {

let result = self.check_for_uninitialized_memory(Instruction::Beq(btype), v1, v2);

trace!("access to uninitialized memory => exeting this context");
trace!("access to uninitialized memory => exiting this context");

result
}
Expand Down Expand Up @@ -956,7 +1039,7 @@ impl Engine {
}
}

fn execute_ecall(&mut self) -> Result<Option<Bug>, EngineError> {
fn execute_ecall(&mut self, instruction: Instruction) -> Result<Option<Bug>, EngineError> {
trace!("[{:#010x}] ecall", self.state.pc);

let result = match self.state.regs[Register::A7 as usize] {
Expand All @@ -966,6 +1049,9 @@ impl Engine {
Value::Concrete(syscall_id) if syscall_id == (SyscallId::Read as u64) => {
self.execute_read()
}
Value::Concrete(syscall_id) if syscall_id == (SyscallId::Write as u64) => {
self.execute_write(instruction)
}
Value::Concrete(syscall_id) if syscall_id == (SyscallId::Exit as u64) => {
self.execute_exit()
}
Expand Down
2 changes: 1 addition & 1 deletion tests/engine.rs
Original file line number Diff line number Diff line change
Expand Up @@ -15,7 +15,7 @@ use std::{
};
use utils::{compile_riscu, init, with_temp_dir};

const TEST_FILES: [&str; 18] = [
const TEST_FILES: [&str; 19] = [
"arithmetic.c",
"echo-line.c",
"if-else.c", // needs timeout
Expand Down

0 comments on commit 27cb6fe

Please sign in to comment.