C++: move interprocedural iterator flow to taint

This commit is contained in:
Robert Marsh
2020-09-16 12:34:52 -07:00
parent 5f2cafc4f5
commit fa0e27b2de
4 changed files with 29 additions and 13 deletions

View File

@@ -303,7 +303,7 @@ private class VariablePartialDefinitionNode extends PartialDefinitionNode {
override Node getPreUpdateNode() { pd.definesExpressions(_, result.asExpr()) }
}
private class IteratorPartialDefinitionNode extends PartialDefinitionNode {
class IteratorPartialDefinitionNode extends PartialDefinitionNode {
override IteratorPartialDefinition pd;
override Node getPreUpdateNode() { pd.definesExpressions(_, result.asExpr()) }
@@ -546,10 +546,10 @@ predicate simpleLocalFlowStep(Node nodeFrom, Node nodeTo) {
or
// In `f(&x->a)`, this step provides the flow from post-`&` to post-`x->a`,
// from which there is field flow to `x` via reverse read.
exists(PartialDefinition def, Expr inner, Expr outer |
exists(VariablePartialDefinition def, Expr inner, Expr outer |
def.definesExpressions(inner, outer) and
inner = nodeTo.(InnerPartialDefinitionNode).getPreUpdateNode().asExpr() and
outer = nodeFrom.(PartialDefinitionNode).getPreUpdateNode().asExpr()
outer = nodeFrom.(VariablePartialDefinitionNode).getPreUpdateNode().asExpr()
)
or
// Reverse flow: data that flows from the post-update node of a reference

View File

@@ -109,7 +109,7 @@ class FlowVar extends TFlowVar {
* ```
*/
private module PartialDefinitions {
abstract class PartialDefinition extends Expr {
class PartialDefinition extends Expr {
ControlFlowNode node;
PartialDefinition() {
@@ -216,8 +216,7 @@ private module PartialDefinitions {
VariablePartialDefinition() {
exists(Expr convertedInner |
valueToUpdate(convertedInner, this.getFullyConverted(), node) and
innerDefinedExpr = convertedInner.getUnconverted() and
not this instanceof Conversion
innerDefinedExpr = convertedInner.getUnconverted()
)
}
@@ -249,11 +248,16 @@ private module PartialDefinitions {
/**
* A partial definition that's a definition by reference.
*/
class DefinitionByReference extends PartialDefinition {
class DefinitionByReference extends VariablePartialDefinition {
DefinitionByReference() { exists(Call c | this = c.getAnArgument() or this = c.getQualifier()) }
}
}
predicate quickTest(PartialDefinition pd) {
pd instanceof DefinitionByReference and
pd instanceof IteratorPartialDefinition
}
import PartialDefinitions
private import FlowVar_internal

View File

@@ -31,6 +31,11 @@ predicate localTaintStep(DataFlow::Node src, DataFlow::Node sink) {
*/
predicate defaultAdditionalTaintStep(DataFlow::Node src, DataFlow::Node sink) {
localAdditionalTaintStep(src, sink)
or
exists(FunctionCall call, int i |
sink.(DataFlow::IteratorPartialDefinitionNode).getPartialDefinition().definesExpressions(_, call.getArgument(i)) and
src.(DataFlow::RefParameterFinalValueNode).getParameter() = call.getTarget().getParameter(i)
)
}
/**
@@ -258,9 +263,9 @@ private predicate exprToPartialDefinitionStep(Expr exprIn, Expr exprOut) {
}
private predicate iteratorDereference(Call c) {
c.getTarget() instanceof IteratorArrayMemberOperator
or
c.getTarget() instanceof IteratorPointerDereferenceMemberOperator
or
c.getTarget() instanceof IteratorPointerDereferenceOperator
c.getTarget() instanceof IteratorArrayMemberOperator
or
c.getTarget() instanceof IteratorPointerDereferenceMemberOperator
or
c.getTarget() instanceof IteratorPointerDereferenceOperator
}

View File

@@ -331,7 +331,7 @@ void taint_vector_output_iterator(std::vector<int>::iterator iter) {
}
void test_vector_output_iterator(int b) {
std::vector<int> v1(10), v2(10), v3(10), v4(10), v5(10), v6(10), v7(10), v8(10);
std::vector<int> v1(10), v2(10), v3(10), v4(10), v5(10), v6(10), v7(10), v8(10), v9(10);
std::vector<int>::iterator i1 = v1.begin();
*i1 = source();
@@ -379,4 +379,11 @@ void test_vector_output_iterator(int b) {
sink(v8); // tainted [NOT DETECTED by IR]
*i8 = 1;
sink(v8);
std::vector<int>::iterator i9 = v9.begin();
*i9 = source();
taint_vector_output_iterator(i9);
sink(v9);
}