Skip to content

Commit

Permalink
feat: improved data flow analysis with move semantics
Browse files Browse the repository at this point in the history
  • Loading branch information
0xCCF4 committed Jul 27, 2024
1 parent 44c0334 commit 0337dea
Show file tree
Hide file tree
Showing 9 changed files with 445 additions and 155 deletions.
1 change: 1 addition & 0 deletions untrusted_value_taint_checker/Cargo.toml
Original file line number Diff line number Diff line change
Expand Up @@ -14,6 +14,7 @@ tempfile = "3.10.1"
serde = { version = "1.0.204", features = ["derive"] }
semver = "1.0.23"
petgraph = "0.6.5"
itertools = "0.13.0"
#owo-colors = { version = "4", features = ["supports-colors"] }
#cargo_metadata = "0.18.1"
#bpaf = { version = "0.9.12", features = ["bpaf_derive", "autocomplete"] }
Expand Down
54 changes: 54 additions & 0 deletions untrusted_value_taint_checker/sample/src/main.rs
Original file line number Diff line number Diff line change
Expand Up @@ -20,6 +20,60 @@ fn fails() {
println!("{:?}", insecure_env)

Check failure on line 20 in untrusted_value_taint_checker/sample/src/main.rs

View workflow job for this annotation

GitHub Actions / Style and docs

consider adding a `;` to the last statement for consistent formatting

Check failure on line 20 in untrusted_value_taint_checker/sample/src/main.rs

View workflow job for this annotation

GitHub Actions / Style and docs

variables can be used directly in the `format!` string

Check failure on line 20 in untrusted_value_taint_checker/sample/src/main.rs

View workflow job for this annotation

GitHub Actions / Style and docs --no-default-features

consider adding a `;` to the last statement for consistent formatting

Check failure on line 20 in untrusted_value_taint_checker/sample/src/main.rs

View workflow job for this annotation

GitHub Actions / Style and docs --no-default-features

variables can be used directly in the `format!` string

Check failure on line 20 in untrusted_value_taint_checker/sample/src/main.rs

View workflow job for this annotation

GitHub Actions / Style and docs --features derive_harden_sanitize

consider adding a `;` to the last statement for consistent formatting

Check failure on line 20 in untrusted_value_taint_checker/sample/src/main.rs

View workflow job for this annotation

GitHub Actions / Style and docs --features derive_harden_sanitize

variables can be used directly in the `format!` string
}

#[no_mangle]
fn complicated_nonsense_function(mut arg: String) -> String {

Check failure on line 24 in untrusted_value_taint_checker/sample/src/main.rs

View workflow job for this annotation

GitHub Actions / Style and docs

`#[no_mangle]` set on a function with the default (`Rust`) ABI

Check failure on line 24 in untrusted_value_taint_checker/sample/src/main.rs

View workflow job for this annotation

GitHub Actions / Style and docs --no-default-features

`#[no_mangle]` set on a function with the default (`Rust`) ABI

Check failure on line 24 in untrusted_value_taint_checker/sample/src/main.rs

View workflow job for this annotation

GitHub Actions / Style and docs --features derive_harden_sanitize

`#[no_mangle]` set on a function with the default (`Rust`) ABI
// dont mind the horrible code, used to check the data flow algorithm ;)

let count = arg.chars().filter(|c| *c == '.').count();

loop {
for i in 0..arg.len() {
if let Some(index) = arg.find(".") {

Check failure on line 31 in untrusted_value_taint_checker/sample/src/main.rs

View workflow job for this annotation

GitHub Actions / Style and docs

single-character string constant used as pattern

Check failure on line 31 in untrusted_value_taint_checker/sample/src/main.rs

View workflow job for this annotation

GitHub Actions / Style and docs --no-default-features

single-character string constant used as pattern

Check failure on line 31 in untrusted_value_taint_checker/sample/src/main.rs

View workflow job for this annotation

GitHub Actions / Style and docs --features derive_harden_sanitize

single-character string constant used as pattern
arg.remove(index);
arg.push('+');
}
let ith = arg.chars().nth(i).unwrap();
if ith == '#' {
return arg.to_lowercase();
} else if ith == '-' {
arg = arg.to_uppercase();
} else if ith == '_' {
arg = arg.to_lowercase();
}
}
if !arg.contains(".") {

Check failure on line 44 in untrusted_value_taint_checker/sample/src/main.rs

View workflow job for this annotation

GitHub Actions / Style and docs

single-character string constant used as pattern

Check failure on line 44 in untrusted_value_taint_checker/sample/src/main.rs

View workflow job for this annotation

GitHub Actions / Style and docs --no-default-features

single-character string constant used as pattern

Check failure on line 44 in untrusted_value_taint_checker/sample/src/main.rs

View workflow job for this annotation

GitHub Actions / Style and docs --features derive_harden_sanitize

single-character string constant used as pattern
break;
}
}

arg.repeat(count)
}

#[no_mangle]
fn nested_function(mut input: usize) -> usize {

Check failure on line 53 in untrusted_value_taint_checker/sample/src/main.rs

View workflow job for this annotation

GitHub Actions / Style and docs

`#[no_mangle]` set on a function with the default (`Rust`) ABI

Check failure on line 53 in untrusted_value_taint_checker/sample/src/main.rs

View workflow job for this annotation

GitHub Actions / Style and docs --no-default-features

`#[no_mangle]` set on a function with the default (`Rust`) ABI

Check failure on line 53 in untrusted_value_taint_checker/sample/src/main.rs

View workflow job for this annotation

GitHub Actions / Style and docs --features derive_harden_sanitize

`#[no_mangle]` set on a function with the default (`Rust`) ABI
#[no_mangle]
fn inner_function(unsafe_arg: &mut usize) {
*unsafe_arg = 10;
}

inner_function(&mut input);

input
}

struct ABC {
value: i32,
}
#[no_mangle]
fn test_rename(q: ABC) -> ABC {
let mut x = q;

Check failure on line 69 in untrusted_value_taint_checker/sample/src/main.rs

View workflow job for this annotation

GitHub Actions / Build and test --features derive_harden_sanitize: ubuntu-latest, nightly

variable does not need to be mutable

Check failure on line 69 in untrusted_value_taint_checker/sample/src/main.rs

View workflow job for this annotation

GitHub Actions / Build and test --features derive_harden_sanitize: ubuntu-latest, stable

variable does not need to be mutable

Check failure on line 69 in untrusted_value_taint_checker/sample/src/main.rs

View workflow job for this annotation

GitHub Actions / Build and test --no-default-features: ubuntu-latest, nightly

variable does not need to be mutable

Check failure on line 69 in untrusted_value_taint_checker/sample/src/main.rs

View workflow job for this annotation

GitHub Actions / Build and test : ubuntu-latest, stable

variable does not need to be mutable

Check failure on line 69 in untrusted_value_taint_checker/sample/src/main.rs

View workflow job for this annotation

GitHub Actions / Style and docs

variable does not need to be mutable

Check failure on line 69 in untrusted_value_taint_checker/sample/src/main.rs

View workflow job for this annotation

GitHub Actions / Style and docs --no-default-features

variable does not need to be mutable

Check failure on line 69 in untrusted_value_taint_checker/sample/src/main.rs

View workflow job for this annotation

GitHub Actions / Style and docs --features derive_harden_sanitize

variable does not need to be mutable
let mut y = x;
y.value = 10;
let z = y;

z
}

fn main() {
works();
fails();
Expand Down
29 changes: 17 additions & 12 deletions untrusted_value_taint_checker/src/analysis/callbacks.rs
Original file line number Diff line number Diff line change
@@ -1,12 +1,15 @@
use std::path::PathBuf;

use petgraph::dot::{Config, Dot};
use crate::analysis::taint_source::TaintSource;
use petgraph::dot::Dot;
use rustc_driver::Compilation;
use rustc_middle::{mir::{visit::Visitor as VisitorMir}, ty::{TyCtxt}};
use rustc_middle::{mir::visit::Visitor as VisitorMir, ty::TyCtxt};
use tracing::{event, span, Level};
use crate::analysis::taint_source::TaintSource;

use super::{hir::crate_function_finder::{CrateFunctionFinder, FunctionInfo}, mir::data_flow::DataFlowTaintTracker};
use super::{
hir::crate_function_finder::{CrateFunctionFinder, FunctionInfo},
mir::data_flow::DataFlowTaintTracker,
};

pub struct TaintCompilerCallbacks<'tsrc> {
pub package_name: String,
Expand Down Expand Up @@ -66,18 +69,20 @@ pub fn mir_analysis(tcx: TyCtxt, callback_data: &mut TaintCompilerCallbacks) {
);
}

for function in &functions {
let body = tcx.optimized_mir(function.local_def_id);
let mut tracker = DataFlowTaintTracker::new(tcx, body);
for function in &functions {
if callback_data.package_name == "sample"
|| callback_data.package_name.starts_with("untrusted_value")
{
let body = tcx.optimized_mir(function.local_def_id);
let mut tracker = DataFlowTaintTracker::new(tcx, body);

println!("{}", function.function_name);
tracker.visit_body(body);
println!("\n\n\n");
if callback_data.package_name == "sample" || callback_data.package_name.starts_with("untrusted_value") {
println!("{}", function.function_name);
tracker.visit_body(body);
println!("\n\n\n");
let dir_path = PathBuf::from("/tmp/taint/").join(&callback_data.package_name);
std::fs::create_dir_all(&dir_path).expect("Failed to create directory");
let dot_file = dir_path.join(&function.function_name).with_extension("dot");
let dot = Dot::with_config(&tracker.data_dependency_graph, &[Config::EdgeNoLabel]);
let dot = Dot::with_config(&tracker.data_dependency_graph, &[]);
std::fs::write(&dot_file, format!("{:?}", dot)).expect("Failed to write dot file");
let pdf_file = dot_file.with_extension("pdf");
std::process::Command::new("dot")
Expand Down
Original file line number Diff line number Diff line change
@@ -1,6 +1,5 @@
use rustc_middle::ty;
use rustc_hir::intravisit::Visitor as HirVisitor;

use rustc_middle::ty;

pub struct FunctionInfo {
pub function_name: String,
Expand Down
Loading

0 comments on commit 0337dea

Please sign in to comment.