Skip to content

Commit

Permalink
Merge pull request #78 from DiuDiu777/senryx
Browse files Browse the repository at this point in the history
Modify analysis result format in senryx
  • Loading branch information
hxuhack authored Dec 2, 2024
2 parents 4f706f5 + 57c3a64 commit d7e8018
Show file tree
Hide file tree
Showing 5 changed files with 189 additions and 69 deletions.
38 changes: 26 additions & 12 deletions rap/src/analysis/senryx.rs
Original file line number Diff line number Diff line change
Expand Up @@ -9,7 +9,7 @@ use crate::analysis::unsafety_isolation::{
};
use rustc_hir::def_id::DefId;
use rustc_middle::ty::TyCtxt;
use visitor::BodyVisitor;
use visitor::{BodyVisitor, CheckResult};

pub struct SenryxCheck<'tcx> {
pub tcx: TyCtxt<'tcx>,
Expand Down Expand Up @@ -40,22 +40,20 @@ impl<'tcx> SenryxCheck<'tcx> {
}

pub fn check_soundness(&self, def_id: DefId) {
self.pre_handle_type(def_id);
println!(
"Find unsound safe api, def_id: {:?}, location: {:?}, ",
def_id, def_id
);
let check_results = self.body_visit_and_check(def_id);
if check_results.len() > 0 {
Self::show_check_results(def_id, check_results);
}
}

pub fn annotate_safety(&self, def_id: DefId) {
self.pre_handle_type(def_id);
println!(
"Annotate unsafe api, def_id: {:?}, location: {:?}, ",
def_id, def_id
);
let check_results = self.body_visit_and_check(def_id);
if check_results.len() > 0 {
Self::show_check_results(def_id, check_results);
}
}

pub fn pre_handle_type(&self, def_id: DefId) {
pub fn body_visit_and_check(&self, def_id: DefId) -> Vec<CheckResult> {
let mut uig_checker = UnsafetyIsolationCheck::new(self.tcx);
let func_type = uig_checker.get_type(def_id);
let mut body_visitor = BodyVisitor::new(self.tcx, def_id, 0);
Expand All @@ -74,5 +72,21 @@ impl<'tcx> SenryxCheck<'tcx> {
} else {
body_visitor.path_forward_check();
}
return body_visitor.check_results;
}

pub fn show_check_results(def_id: DefId, check_results: Vec<CheckResult>) {
println!("--------In {:?}---------", def_id);
for check_result in check_results {
println!(
" Unsafe api {:?}: {} passed, {} failed!",
check_result.func_name,
check_result.passed_contracts.len(),
check_result.failed_contracts.len()
);
for failed_contract in check_result.failed_contracts {
println!(" Contract failed: {:?}", failed_contract);
}
}
}
}
8 changes: 4 additions & 4 deletions rap/src/analysis/senryx/contracts/checker.rs
Original file line number Diff line number Diff line change
Expand Up @@ -25,10 +25,10 @@ impl<T> SliceFromRawPartsChecker<T> {
map.insert(
0,
vec![
Contract::StateCheck {
op: Op::GE,
state: StateType::AllocatedState(AllocatedState::Alloc),
},
// Contract::StateCheck {
// op: Op::GE,
// state: StateType::AllocatedState(AllocatedState::Alloc),
// },
Contract::StateCheck {
op: Op::GT,
state: StateType::AlignState(AlignState::Unaligned),
Expand Down
32 changes: 23 additions & 9 deletions rap/src/analysis/senryx/matcher.rs
Original file line number Diff line number Diff line change
@@ -1,18 +1,23 @@
use rustc_middle::mir::Operand;
use rustc_span::source_map::Spanned;
use rustc_span::Span;

use super::contracts::{
abstract_state::AbstractState,
checker::{Checker, SliceFromRawPartsChecker},
contract::check_contract,
use super::{
contracts::{
abstract_state::AbstractState,
checker::{Checker, SliceFromRawPartsChecker},
contract::check_contract,
},
visitor::CheckResult,
};

pub fn match_unsafe_api_and_check_contracts<T>(
func_name: &str,
args: &Box<[Spanned<Operand>]>,
abstate: &AbstractState,
span: Span,
_ty: T,
) {
) -> Option<CheckResult> {
let base_func_name = func_name.split::<&str>("<").next().unwrap_or(func_name);
// println!("base name ---- {:?}",base_func_name);
let checker: Option<Box<dyn Checker>> = match base_func_name {
Expand All @@ -23,11 +28,19 @@ pub fn match_unsafe_api_and_check_contracts<T>(
};

if let Some(c) = checker {
process_checker(&*c, args, abstate);
return Some(process_checker(&*c, args, abstate, base_func_name, span));
}
None
}

fn process_checker(checker: &dyn Checker, args: &Box<[Spanned<Operand>]>, abstate: &AbstractState) {
fn process_checker(
checker: &dyn Checker,
args: &Box<[Spanned<Operand>]>,
abstate: &AbstractState,
func_name: &str,
span: Span,
) -> CheckResult {
let mut check_result = CheckResult::new(func_name, span);
for (idx, contracts_vec) in checker.variable_contracts().iter() {
for contract in contracts_vec {
let arg_place = get_arg_place(&args[*idx].node);
Expand All @@ -36,13 +49,14 @@ fn process_checker(checker: &dyn Checker, args: &Box<[Spanned<Operand>]>, abstat
}
if let Some(abstate_item) = abstate.state_map.get(&arg_place) {
if !check_contract(*contract, &abstate_item.clone().unwrap()) {
println!("Contract failed! ---- {:?}", contract);
check_result.failed_contracts.push((*idx, *contract));
} else {
println!("Contract passed! ---- {:?}", contract);
check_result.passed_contracts.push((*idx, *contract));
}
}
}
}
check_result
}

pub fn get_arg_place(arg: &Operand) -> usize {
Expand Down
Loading

0 comments on commit d7e8018

Please sign in to comment.