Skip to content

Commit

Permalink
fix missing UAF for pointing to const (BurtonQin#58)
Browse files Browse the repository at this point in the history
  • Loading branch information
BurtonQin committed Sep 11, 2024
1 parent 774ee22 commit 944af9e
Showing 1 changed file with 59 additions and 54 deletions.
113 changes: 59 additions & 54 deletions src/analysis/pointsto/mod.rs
Original file line number Diff line number Diff line change
Expand Up @@ -20,7 +20,6 @@ use rustc_middle::mir::{
Body, ConstOperand, Local, Location, Operand, Place, PlaceElem, PlaceRef, ProjectionElem,
Rvalue, Statement, StatementKind, Terminator, TerminatorKind,
};
use rustc_middle::ty::ConstKind;

use rustc_middle::mir::Const;
use rustc_middle::ty::{Instance, TyCtxt, TyKind};
Expand Down Expand Up @@ -159,8 +158,8 @@ impl<'a, 'tcx> Andersen<'a, 'tcx> {
pub enum ConstraintNode<'tcx> {
Alloc(PlaceRef<'tcx>),
Place(PlaceRef<'tcx>),
Constant(ConstKind<'tcx>),
ConstantDeref(ConstKind<'tcx>),
Constant(Const<'tcx>),
ConstantDeref(Const<'tcx>),
}

/// The assignments in MIR with default `mir-opt-level` (level 1) are simplified
Expand Down Expand Up @@ -189,11 +188,12 @@ enum ConstraintEdge {
AliasCopy, // Special: y=Arc::clone(x) or y=ptr::read(x)
}

#[derive(Debug)]
enum AccessPattern<'tcx> {
Ref(PlaceRef<'tcx>),
Indirect(PlaceRef<'tcx>),
Direct(PlaceRef<'tcx>),
Constant(ConstKind<'tcx>),
Constant(Const<'tcx>),
}

#[derive(Default)]
Expand Down Expand Up @@ -225,7 +225,7 @@ impl<'tcx> ConstraintGraph<'tcx> {
self.graph.add_edge(rhs, lhs, ConstraintEdge::Address);
}

fn add_constant(&mut self, constant: ConstKind<'tcx>) {
fn add_constant(&mut self, constant: Const<'tcx>) {
let lhs = ConstraintNode::Constant(constant);
let rhs = ConstraintNode::ConstantDeref(constant);
let lhs = self.get_or_insert_node(lhs);
Expand All @@ -252,7 +252,7 @@ impl<'tcx> ConstraintGraph<'tcx> {
self.graph.add_edge(rhs, lhs, ConstraintEdge::Copy);
}

fn add_copy_constant(&mut self, lhs: PlaceRef<'tcx>, rhs: ConstKind<'tcx>) {
fn add_copy_constant(&mut self, lhs: PlaceRef<'tcx>, rhs: Const<'tcx>) {
let lhs = ConstraintNode::Place(lhs);
let rhs = ConstraintNode::Constant(rhs);
let lhs = self.get_or_insert_node(lhs);
Expand All @@ -276,7 +276,7 @@ impl<'tcx> ConstraintGraph<'tcx> {
self.graph.add_edge(rhs, lhs, ConstraintEdge::Store);
}

fn add_store_constant(&mut self, lhs: PlaceRef<'tcx>, rhs: ConstKind<'tcx>) {
fn add_store_constant(&mut self, lhs: PlaceRef<'tcx>, rhs: Const<'tcx>) {
let lhs = ConstraintNode::Place(lhs);
let rhs = ConstraintNode::Constant(rhs);
let lhs = self.get_or_insert_node(lhs);
Expand Down Expand Up @@ -430,33 +430,36 @@ impl<'a, 'tcx> ConstraintGraphCollector<'a, 'tcx> {

fn process_assignment(&mut self, place: &Place<'tcx>, rvalue: &Rvalue<'tcx>) {
let lhs_pattern = Self::process_place(place.as_ref());
let rhs_pattern = Self::process_rvalue(rvalue);
match (lhs_pattern, rhs_pattern) {
// a = &b
(AccessPattern::Direct(lhs), Some(AccessPattern::Ref(rhs))) => {
self.graph.add_address(lhs, rhs);
}
// a = b
(AccessPattern::Direct(lhs), Some(AccessPattern::Direct(rhs))) => {
self.graph.add_copy(lhs, rhs);
}
// a = Constant
(AccessPattern::Direct(lhs), Some(AccessPattern::Constant(rhs))) => {
self.graph.add_copy_constant(lhs, rhs);
}
// a = *b
(AccessPattern::Direct(lhs), Some(AccessPattern::Indirect(rhs))) => {
self.graph.add_load(lhs, rhs);
}
// *a = b
(AccessPattern::Indirect(lhs), Some(AccessPattern::Direct(rhs))) => {
self.graph.add_store(lhs, rhs);
}
// *a = Constant
(AccessPattern::Indirect(lhs), Some(AccessPattern::Constant(rhs))) => {
self.graph.add_store_constant(lhs, rhs);
let rhs_patterns = Self::process_rvalue(rvalue);

for rhs_pattern in rhs_patterns.into_iter() {
match (&lhs_pattern, rhs_pattern) {
// a = &b
(AccessPattern::Direct(lhs), Some(AccessPattern::Ref(rhs))) => {
self.graph.add_address(*lhs, rhs);
}
// a = b
(AccessPattern::Direct(lhs), Some(AccessPattern::Direct(rhs))) => {
self.graph.add_copy(*lhs, rhs);
}
// a = Constant
(AccessPattern::Direct(lhs), Some(AccessPattern::Constant(rhs))) => {
self.graph.add_copy_constant(*lhs, rhs);
}
// a = *b
(AccessPattern::Direct(lhs), Some(AccessPattern::Indirect(rhs))) => {
self.graph.add_load(*lhs, rhs);
}
// *a = b
(AccessPattern::Indirect(lhs), Some(AccessPattern::Direct(rhs))) => {
self.graph.add_store(*lhs, rhs);
}
// *a = Constant
(AccessPattern::Indirect(lhs), Some(AccessPattern::Constant(rhs))) => {
self.graph.add_store_constant(*lhs, rhs);
}
_ => {}
}
_ => {}
}
}

Expand All @@ -473,38 +476,40 @@ impl<'a, 'tcx> ConstraintGraphCollector<'a, 'tcx> {
}
}

fn process_rvalue(rvalue: &Rvalue<'tcx>) -> Option<AccessPattern<'tcx>> {
fn process_operand(operand: &Operand<'tcx>) -> Option<AccessPattern<'tcx>> {
match operand {
Operand::Move(place) | Operand::Copy(place) => {
Some(AccessPattern::Direct(place.as_ref()))
}
Operand::Constant(box ConstOperand {
span: _,
user_ty: _,
const_,
}) => Some(AccessPattern::Constant(*const_)),
}
}

fn process_rvalue(rvalue: &Rvalue<'tcx>) -> Vec<Option<AccessPattern<'tcx>>> {
match rvalue {
Rvalue::Use(operand) | Rvalue::Repeat(operand, _) | Rvalue::Cast(_, operand, _) => {
match operand {
Operand::Move(place) | Operand::Copy(place) => {
Some(AccessPattern::Direct(place.as_ref()))
}
Operand::Constant(box ConstOperand {
span: _,
user_ty: _,
const_,
}) => {
if let Const::Ty(const_) = *const_ {
Some(AccessPattern::Constant(const_.kind()))
} else {
None
}
}
}
vec![Self::process_operand(operand)]
}
// Regard `p = &*q` as `p = q`
Rvalue::Ref(_, _, place) | Rvalue::AddressOf(_, place) => match place.as_ref() {
PlaceRef {
local: l,
projection: [ProjectionElem::Deref, ref remain @ ..],
} => Some(AccessPattern::Direct(PlaceRef {
} => vec![Some(AccessPattern::Direct(PlaceRef {
local: l,
projection: remain,
})),
_ => Some(AccessPattern::Ref(place.as_ref())),
}))],
_ => vec![Some(AccessPattern::Ref(place.as_ref()))],
},
_ => None,
Rvalue::Aggregate(_, fields) => {
let fields = fields.iter().map(Self::process_operand).collect::<Vec<_>>();
fields
}
_ => vec![],
}
}

Expand Down

0 comments on commit 944af9e

Please sign in to comment.