mirror of
https://github.com/github/codeql.git
synced 2025-12-16 16:53:25 +01:00
Merge pull request #2063 from jbj/dataflow-ref-parameter
C++: Data flow through reference parameters
This commit is contained in:
@@ -32,6 +32,7 @@ The following changes in version 1.23 affect C/C++ analysis in all applications.
|
||||
picture of the partial flow paths from a given source. The feature is
|
||||
disabled by default and can be enabled for individual configurations by
|
||||
overriding `int explorationLimit()`.
|
||||
* The data-flow library now supports flow out of C++ reference parameters.
|
||||
* The data-flow library now allows flow through the address-of operator (`&`).
|
||||
* The `DataFlow::DefinitionByReferenceNode` class now considers `f(x)` to be a
|
||||
definition of `x` when `x` is a variable of pointer type. It no longer
|
||||
|
||||
@@ -51,7 +51,9 @@ class ArgumentNode extends Node {
|
||||
DataFlowCall getCall() { this.argumentOf(result, _) }
|
||||
}
|
||||
|
||||
private newtype TReturnKind = TNormalReturnKind()
|
||||
private newtype TReturnKind =
|
||||
TNormalReturnKind() or
|
||||
TRefReturnKind(int i) { exists(Parameter parameter | i = parameter.getIndex()) }
|
||||
|
||||
/**
|
||||
* A return kind. A return kind describes how a value can be returned
|
||||
@@ -59,23 +61,54 @@ private newtype TReturnKind = TNormalReturnKind()
|
||||
*/
|
||||
class ReturnKind extends TReturnKind {
|
||||
/** Gets a textual representation of this return kind. */
|
||||
string toString() { result = "return" }
|
||||
string toString() {
|
||||
this instanceof TNormalReturnKind and
|
||||
result = "return"
|
||||
or
|
||||
this instanceof TRefReturnKind and
|
||||
result = "ref"
|
||||
}
|
||||
}
|
||||
|
||||
/** A data flow node that occurs as the result of a `ReturnStmt`. */
|
||||
class ReturnNode extends ExprNode {
|
||||
ReturnNode() { exists(ReturnStmt ret | this.getExpr() = ret.getExpr()) }
|
||||
/** A data flow node that represents a returned value in the called function. */
|
||||
abstract class ReturnNode extends Node {
|
||||
/** Gets the kind of this returned value. */
|
||||
abstract ReturnKind getKind();
|
||||
}
|
||||
|
||||
/** A `ReturnNode` that occurs as the result of a `ReturnStmt`. */
|
||||
private class NormalReturnNode extends ReturnNode, ExprNode {
|
||||
NormalReturnNode() { exists(ReturnStmt ret | this.getExpr() = ret.getExpr()) }
|
||||
|
||||
/** Gets the kind of this returned value. */
|
||||
ReturnKind getKind() { result = TNormalReturnKind() }
|
||||
override ReturnKind getKind() { result = TNormalReturnKind() }
|
||||
}
|
||||
|
||||
/** A data flow node that represents the output of a call. */
|
||||
class OutNode extends ExprNode {
|
||||
OutNode() { this.getExpr() instanceof Call }
|
||||
/**
|
||||
* A `ReturnNode` that occurs as a result of a definition of a reference
|
||||
* parameter reaching the end of a function body.
|
||||
*/
|
||||
private class RefReturnNode extends ReturnNode, RefParameterFinalValueNode {
|
||||
/** Gets the kind of this returned value. */
|
||||
override ReturnKind getKind() { result = TRefReturnKind(this.getParameter().getIndex()) }
|
||||
}
|
||||
|
||||
/** A data flow node that represents the output of a call at the call site. */
|
||||
abstract class OutNode extends Node {
|
||||
/** Gets the underlying call. */
|
||||
abstract DataFlowCall getCall();
|
||||
}
|
||||
|
||||
private class ExprOutNode extends OutNode, ExprNode {
|
||||
ExprOutNode() { this.getExpr() instanceof Call }
|
||||
|
||||
/** Gets the underlying call. */
|
||||
DataFlowCall getCall() { result = this.getExpr() }
|
||||
override DataFlowCall getCall() { result = this.getExpr() }
|
||||
}
|
||||
|
||||
private class RefOutNode extends OutNode, DefinitionByReferenceNode {
|
||||
/** Gets the underlying call. */
|
||||
override DataFlowCall getCall() { result = this.getArgument().getParent() }
|
||||
}
|
||||
|
||||
/**
|
||||
@@ -85,6 +118,11 @@ class OutNode extends ExprNode {
|
||||
OutNode getAnOutNode(DataFlowCall call, ReturnKind kind) {
|
||||
result = call.getNode() and
|
||||
kind = TNormalReturnKind()
|
||||
or
|
||||
exists(int i |
|
||||
result.asDefiningArgument() = call.getArgument(i) and
|
||||
kind = TRefReturnKind(i)
|
||||
)
|
||||
}
|
||||
|
||||
/**
|
||||
|
||||
@@ -25,7 +25,8 @@ private newtype TNode =
|
||||
not c.getTarget().getParameter(i).getUnderlyingType().(PointerType).getBaseType().isConst()
|
||||
)
|
||||
} or
|
||||
TUninitializedNode(LocalVariable v) { not v.hasInitializer() }
|
||||
TUninitializedNode(LocalVariable v) { not v.hasInitializer() } or
|
||||
TRefParameterFinalValueNode(Parameter p) { exists(FlowVar var | var.reachesRefParameter(p)) }
|
||||
|
||||
/**
|
||||
* A node in a data flow graph.
|
||||
@@ -248,6 +249,23 @@ class UninitializedNode extends Node, TUninitializedNode {
|
||||
LocalVariable getLocalVariable() { result = v }
|
||||
}
|
||||
|
||||
/** INTERNAL: do not use. The final value of a non-const ref parameter. */
|
||||
class RefParameterFinalValueNode extends Node, TRefParameterFinalValueNode {
|
||||
Parameter p;
|
||||
|
||||
RefParameterFinalValueNode() { this = TRefParameterFinalValueNode(p) }
|
||||
|
||||
override Function getFunction() { result = p.getFunction() }
|
||||
|
||||
override Type getType() { result = p.getType() }
|
||||
|
||||
override string toString() { result = p.toString() }
|
||||
|
||||
override Location getLocation() { result = p.getLocation() }
|
||||
|
||||
Parameter getParameter() { result = p }
|
||||
}
|
||||
|
||||
/**
|
||||
* A node associated with an object after an operation that might have
|
||||
* changed its state.
|
||||
@@ -490,7 +508,7 @@ predicate simpleLocalFlowStep(Node nodeFrom, Node nodeTo) {
|
||||
or
|
||||
var.definedPartiallyAt(nodeFrom.asPartialDefinition())
|
||||
) and
|
||||
varToExprStep(var, nodeTo.asExpr())
|
||||
varToNodeStep(var, nodeTo)
|
||||
)
|
||||
or
|
||||
// Expr -> DefinitionByReferenceNode
|
||||
@@ -533,9 +551,13 @@ private predicate exprToVarStep(Expr assignedExpr, FlowVar var) {
|
||||
}
|
||||
|
||||
/**
|
||||
* Holds if the expression `e` is an access of the variable `var`.
|
||||
* Holds if the node `n` is an access of the variable `var`.
|
||||
*/
|
||||
private predicate varToExprStep(FlowVar var, Expr e) { e = var.getAnAccess() }
|
||||
private predicate varToNodeStep(FlowVar var, Node n) {
|
||||
n.asExpr() = var.getAnAccess()
|
||||
or
|
||||
var.reachesRefParameter(n.(RefParameterFinalValueNode).getParameter())
|
||||
}
|
||||
|
||||
/**
|
||||
* Holds if data flows from `fromExpr` to `toExpr` directly, in the case
|
||||
|
||||
@@ -62,9 +62,20 @@ class FlowVar extends TFlowVar {
|
||||
cached
|
||||
abstract predicate definedByReference(Expr arg);
|
||||
|
||||
/**
|
||||
* Holds if this `FlowVar` is a `PartialDefinition` whose defined expression
|
||||
* is `e`.
|
||||
*/
|
||||
cached
|
||||
abstract predicate definedPartiallyAt(Expr e);
|
||||
|
||||
/**
|
||||
* Holds if this `FlowVar` is a definition of a reference parameter `p` that
|
||||
* persists until the function returns.
|
||||
*/
|
||||
cached
|
||||
abstract predicate reachesRefParameter(Parameter p);
|
||||
|
||||
/**
|
||||
* Holds if this `FlowVar` corresponds to the initial value of `v`. The following
|
||||
* is an exhaustive list of cases where this may happen.
|
||||
@@ -338,6 +349,9 @@ module FlowVar_internal {
|
||||
param = v
|
||||
}
|
||||
|
||||
// `fullySupportedSsaVariable` excludes reference types
|
||||
override predicate reachesRefParameter(Parameter p) { none() }
|
||||
|
||||
/**
|
||||
* Holds if this `SsaVar` corresponds to a non-phi definition. Users of this
|
||||
* library will never directly use an `SsaVar` that comes from a phi node,
|
||||
@@ -387,6 +401,13 @@ module FlowVar_internal {
|
||||
sbb = v.(Parameter).getFunction().getEntryPoint()
|
||||
}
|
||||
|
||||
override predicate reachesRefParameter(Parameter p) {
|
||||
parameterIsNonConstReference(p) and
|
||||
p = v and
|
||||
// This definition reaches the exit node of the function CFG
|
||||
getAReachedBlockVarSBB(this).getANode() = p.getFunction()
|
||||
}
|
||||
|
||||
override predicate definedByInitialValue(LocalScopeVariable lsv) {
|
||||
blockVarDefinedByVariable(sbb, lsv) and
|
||||
lsv = v
|
||||
@@ -588,12 +609,23 @@ module FlowVar_internal {
|
||||
private predicate variableLiveInSBB(SubBasicBlock sbb, Variable v) {
|
||||
variableAccessInSBB(v, sbb, _)
|
||||
or
|
||||
// Non-const reference parameters are live at the end of the function
|
||||
parameterIsNonConstReference(v) and
|
||||
sbb.contains(v.(Parameter).getFunction())
|
||||
or
|
||||
exists(SubBasicBlock succ | succ = sbb.getASuccessor() |
|
||||
variableLiveInSBB(succ, v) and
|
||||
not variableNotLiveBefore(succ, v)
|
||||
)
|
||||
}
|
||||
|
||||
predicate parameterIsNonConstReference(Parameter p) {
|
||||
exists(ReferenceType refType |
|
||||
refType = p.getUnderlyingType() and
|
||||
not refType.getBaseType().isConst()
|
||||
)
|
||||
}
|
||||
|
||||
/**
|
||||
* Holds if liveness of `v` should stop propagating backwards from `sbb`.
|
||||
*/
|
||||
|
||||
@@ -43,5 +43,5 @@ void test_lambdas()
|
||||
c = source();
|
||||
};
|
||||
e(t, u, w);
|
||||
sink(w); // flow from source() [NOT DETECTED]
|
||||
sink(w); // flow from source()
|
||||
}
|
||||
|
||||
134
cpp/ql/test/library-tests/dataflow/dataflow-tests/ref.cpp
Normal file
134
cpp/ql/test/library-tests/dataflow/dataflow-tests/ref.cpp
Normal file
@@ -0,0 +1,134 @@
|
||||
int source();
|
||||
|
||||
template<typename T>
|
||||
void sink(T);
|
||||
|
||||
extern int arbitrary;
|
||||
|
||||
namespace withoutFields {
|
||||
template<typename T>
|
||||
void assign(T &lhs, T rhs) {
|
||||
lhs = rhs;
|
||||
}
|
||||
|
||||
template<typename T>
|
||||
void assignWrapper(T &lhs, T rhs) {
|
||||
assign(lhs, rhs);
|
||||
}
|
||||
|
||||
void notAssign(int &lhs, int rhs) {
|
||||
lhs = rhs;
|
||||
if (arbitrary) {
|
||||
lhs = 1;
|
||||
} else {
|
||||
lhs = 2;
|
||||
}
|
||||
}
|
||||
|
||||
void sourceToParam(int &out) {
|
||||
out = source();
|
||||
if (arbitrary) {
|
||||
out = 1;
|
||||
}
|
||||
}
|
||||
|
||||
void sourceToParamWrapper(int &out) {
|
||||
if (arbitrary) {
|
||||
sourceToParam(out);
|
||||
} else {
|
||||
out = 1;
|
||||
}
|
||||
}
|
||||
|
||||
void notSource(int &out) {
|
||||
out = source();
|
||||
if (arbitrary) {
|
||||
out = 1;
|
||||
} else {
|
||||
out = 2;
|
||||
}
|
||||
}
|
||||
|
||||
void testRefs() {
|
||||
int x1, x2, x3, x4;
|
||||
|
||||
assignWrapper(x1, source());
|
||||
sink(x1); // flow [FALSE POSITIVE from uninitialized]
|
||||
|
||||
notAssign(x2, source());
|
||||
sink(x2); // no flow [FALSE POSITIVE from uninitialized]
|
||||
|
||||
sourceToParamWrapper(x3);
|
||||
sink(x3); // flow [FALSE POSITIVE from uninitialized]
|
||||
|
||||
notSource(x4);
|
||||
sink(x4); // no flow [FALSE POSITIVE from uninitialized]
|
||||
}
|
||||
}
|
||||
|
||||
namespace withFields {
|
||||
struct Int {
|
||||
int val;
|
||||
};
|
||||
|
||||
void assign(Int &lhs, int rhs) {
|
||||
lhs.val = rhs;
|
||||
}
|
||||
|
||||
void assignWrapper(Int &lhs, int rhs) {
|
||||
assign(lhs, rhs);
|
||||
}
|
||||
|
||||
void notAssign(Int &lhs, int rhs) {
|
||||
lhs.val = rhs;
|
||||
// Field flow ignores that the field is subsequently overwritten, leading
|
||||
// to false flow here.
|
||||
if (arbitrary) {
|
||||
lhs.val = 1;
|
||||
} else {
|
||||
lhs.val = 2;
|
||||
}
|
||||
}
|
||||
|
||||
void sourceToParam(Int &out) {
|
||||
out.val = source();
|
||||
if (arbitrary) {
|
||||
out.val = 1;
|
||||
}
|
||||
}
|
||||
|
||||
void sourceToParamWrapper(Int &out) {
|
||||
if (arbitrary) {
|
||||
sourceToParam(out);
|
||||
} else {
|
||||
out.val = 1;
|
||||
}
|
||||
}
|
||||
|
||||
void notSource(Int &out) {
|
||||
out.val = source();
|
||||
// Field flow ignores that the field is subsequently overwritten, leading
|
||||
// to false flow here.
|
||||
if (arbitrary) {
|
||||
out.val = 1;
|
||||
} else {
|
||||
out.val = 2;
|
||||
}
|
||||
}
|
||||
|
||||
void testRefs() {
|
||||
Int x1, x2, x3, x4;
|
||||
|
||||
assignWrapper(x1, source());
|
||||
sink(x1.val); // flow
|
||||
|
||||
notAssign(x2, source());
|
||||
sink(x2.val); // no flow [FALSE POSITIVE]
|
||||
|
||||
sourceToParamWrapper(x3);
|
||||
sink(x3.val); // flow
|
||||
|
||||
notSource(x4);
|
||||
sink(x4.val); // no flow [FALSE POSITIVE]
|
||||
}
|
||||
}
|
||||
@@ -11,6 +11,17 @@
|
||||
| lambdas.cpp:29:3:29:6 | t | lambdas.cpp:8:10:8:15 | call to source |
|
||||
| lambdas.cpp:35:8:35:8 | a | lambdas.cpp:8:10:8:15 | call to source |
|
||||
| lambdas.cpp:41:8:41:8 | a | lambdas.cpp:8:10:8:15 | call to source |
|
||||
| lambdas.cpp:46:7:46:7 | w | lambdas.cpp:43:7:43:12 | call to source |
|
||||
| ref.cpp:56:10:56:11 | x1 | ref.cpp:53:9:53:10 | x1 |
|
||||
| ref.cpp:56:10:56:11 | x1 | ref.cpp:55:23:55:28 | call to source |
|
||||
| ref.cpp:59:10:59:11 | x2 | ref.cpp:53:13:53:14 | x2 |
|
||||
| ref.cpp:62:10:62:11 | x3 | ref.cpp:29:11:29:16 | call to source |
|
||||
| ref.cpp:62:10:62:11 | x3 | ref.cpp:53:17:53:18 | x3 |
|
||||
| ref.cpp:65:10:65:11 | x4 | ref.cpp:53:21:53:22 | x4 |
|
||||
| ref.cpp:123:13:123:15 | val | ref.cpp:122:23:122:28 | call to source |
|
||||
| ref.cpp:126:13:126:15 | val | ref.cpp:125:19:125:24 | call to source |
|
||||
| ref.cpp:129:13:129:15 | val | ref.cpp:94:15:94:20 | call to source |
|
||||
| ref.cpp:132:13:132:15 | val | ref.cpp:109:15:109:20 | call to source |
|
||||
| test.cpp:7:8:7:9 | t1 | test.cpp:6:12:6:17 | call to source |
|
||||
| test.cpp:9:8:9:9 | t1 | test.cpp:6:12:6:17 | call to source |
|
||||
| test.cpp:10:8:10:9 | t2 | test.cpp:6:12:6:17 | call to source |
|
||||
|
||||
@@ -8,6 +8,17 @@
|
||||
| lambdas.cpp:8:10:8:15 | lambdas.cpp:29:3:29:6 | AST only |
|
||||
| lambdas.cpp:8:10:8:15 | lambdas.cpp:35:8:35:8 | AST only |
|
||||
| lambdas.cpp:8:10:8:15 | lambdas.cpp:41:8:41:8 | AST only |
|
||||
| lambdas.cpp:43:7:43:12 | lambdas.cpp:46:7:46:7 | AST only |
|
||||
| ref.cpp:29:11:29:16 | ref.cpp:62:10:62:11 | AST only |
|
||||
| ref.cpp:53:9:53:10 | ref.cpp:56:10:56:11 | AST only |
|
||||
| ref.cpp:53:13:53:14 | ref.cpp:59:10:59:11 | AST only |
|
||||
| ref.cpp:53:17:53:18 | ref.cpp:62:10:62:11 | AST only |
|
||||
| ref.cpp:53:21:53:22 | ref.cpp:65:10:65:11 | AST only |
|
||||
| ref.cpp:55:23:55:28 | ref.cpp:56:10:56:11 | AST only |
|
||||
| ref.cpp:94:15:94:20 | ref.cpp:129:13:129:15 | AST only |
|
||||
| ref.cpp:109:15:109:20 | ref.cpp:132:13:132:15 | AST only |
|
||||
| ref.cpp:122:23:122:28 | ref.cpp:123:13:123:15 | AST only |
|
||||
| ref.cpp:125:19:125:24 | ref.cpp:126:13:126:15 | AST only |
|
||||
| test.cpp:89:28:89:34 | test.cpp:92:8:92:14 | IR only |
|
||||
| test.cpp:100:13:100:18 | test.cpp:103:10:103:12 | AST only |
|
||||
| test.cpp:109:9:109:14 | test.cpp:110:10:110:12 | IR only |
|
||||
|
||||
@@ -1,3 +1,19 @@
|
||||
| ref.cpp:53:9:53:10 | x1 | ref.cpp:55:19:55:20 | x1 |
|
||||
| ref.cpp:53:9:53:10 | x1 | ref.cpp:56:10:56:11 | x1 |
|
||||
| ref.cpp:53:13:53:14 | x2 | ref.cpp:58:15:58:16 | x2 |
|
||||
| ref.cpp:53:13:53:14 | x2 | ref.cpp:59:10:59:11 | x2 |
|
||||
| ref.cpp:53:17:53:18 | x3 | ref.cpp:61:26:61:27 | x3 |
|
||||
| ref.cpp:53:17:53:18 | x3 | ref.cpp:62:10:62:11 | x3 |
|
||||
| ref.cpp:53:21:53:22 | x4 | ref.cpp:64:15:64:16 | x4 |
|
||||
| ref.cpp:53:21:53:22 | x4 | ref.cpp:65:10:65:11 | x4 |
|
||||
| ref.cpp:120:9:120:10 | x1 | ref.cpp:122:19:122:20 | x1 |
|
||||
| ref.cpp:120:9:120:10 | x1 | ref.cpp:123:10:123:11 | x1 |
|
||||
| ref.cpp:120:13:120:14 | x2 | ref.cpp:125:15:125:16 | x2 |
|
||||
| ref.cpp:120:13:120:14 | x2 | ref.cpp:126:10:126:11 | x2 |
|
||||
| ref.cpp:120:17:120:18 | x3 | ref.cpp:128:26:128:27 | x3 |
|
||||
| ref.cpp:120:17:120:18 | x3 | ref.cpp:129:10:129:11 | x3 |
|
||||
| ref.cpp:120:21:120:22 | x4 | ref.cpp:131:15:131:16 | x4 |
|
||||
| ref.cpp:120:21:120:22 | x4 | ref.cpp:132:10:132:11 | x4 |
|
||||
| test.cpp:75:7:75:8 | u1 | test.cpp:76:8:76:9 | u1 |
|
||||
| test.cpp:83:7:83:8 | u2 | test.cpp:84:13:84:14 | u2 |
|
||||
| test.cpp:83:7:83:8 | u2 | test.cpp:85:8:85:9 | u2 |
|
||||
|
||||
@@ -125,6 +125,8 @@ edges
|
||||
| aliasing.cpp:9:3:9:3 | s [post update] [m1] | aliasing.cpp:25:17:25:19 | ref arg & ... [m1] |
|
||||
| aliasing.cpp:9:3:9:22 | ... = ... | aliasing.cpp:9:3:9:3 | s [post update] [m1] |
|
||||
| aliasing.cpp:9:11:9:20 | call to user_input | aliasing.cpp:9:3:9:22 | ... = ... |
|
||||
| aliasing.cpp:12:25:12:25 | s [m1] | aliasing.cpp:26:19:26:20 | ref arg s2 [m1] |
|
||||
| aliasing.cpp:13:3:13:3 | s [post update] [m1] | aliasing.cpp:12:25:12:25 | s [m1] |
|
||||
| aliasing.cpp:13:3:13:3 | s [post update] [m1] | aliasing.cpp:26:19:26:20 | ref arg s2 [m1] |
|
||||
| aliasing.cpp:13:3:13:21 | ... = ... | aliasing.cpp:13:3:13:3 | s [post update] [m1] |
|
||||
| aliasing.cpp:13:10:13:19 | call to user_input | aliasing.cpp:13:3:13:21 | ... = ... |
|
||||
@@ -379,6 +381,7 @@ nodes
|
||||
| aliasing.cpp:9:3:9:3 | s [post update] [m1] | semmle.label | s [post update] [m1] |
|
||||
| aliasing.cpp:9:3:9:22 | ... = ... | semmle.label | ... = ... |
|
||||
| aliasing.cpp:9:11:9:20 | call to user_input | semmle.label | call to user_input |
|
||||
| aliasing.cpp:12:25:12:25 | s [m1] | semmle.label | s [m1] |
|
||||
| aliasing.cpp:13:3:13:3 | s [post update] [m1] | semmle.label | s [post update] [m1] |
|
||||
| aliasing.cpp:13:3:13:21 | ... = ... | semmle.label | ... = ... |
|
||||
| aliasing.cpp:13:10:13:19 | call to user_input | semmle.label | call to user_input |
|
||||
|
||||
@@ -1,3 +1,8 @@
|
||||
| file://:0:0:0:0 | p#0 | file://:0:0:0:0 | p#0 | |
|
||||
| file://:0:0:0:0 | p#0 | file://:0:0:0:0 | p#0 | |
|
||||
| file://:0:0:0:0 | p#0 | file://:0:0:0:0 | p#0 | |
|
||||
| file://:0:0:0:0 | p#0 | file://:0:0:0:0 | p#0 | |
|
||||
| file://:0:0:0:0 | p#0 | file://:0:0:0:0 | p#0 | |
|
||||
| taint.cpp:4:27:4:33 | source1 | taint.cpp:6:13:6:19 | source1 | |
|
||||
| taint.cpp:4:40:4:45 | clean1 | taint.cpp:5:8:5:13 | clean1 | |
|
||||
| taint.cpp:4:40:4:45 | clean1 | taint.cpp:6:3:6:8 | clean1 | |
|
||||
@@ -223,8 +228,11 @@
|
||||
| taint.cpp:249:18:249:18 | a | taint.cpp:250:8:250:8 | a | |
|
||||
| taint.cpp:249:25:249:25 | b | taint.cpp:251:8:251:8 | b | |
|
||||
| taint.cpp:255:11:259:2 | [...](...){...} | taint.cpp:260:2:260:2 | e | |
|
||||
| taint.cpp:255:19:255:19 | a | taint.cpp:255:19:255:19 | a | |
|
||||
| taint.cpp:255:19:255:19 | a | taint.cpp:256:8:256:8 | a | |
|
||||
| taint.cpp:255:27:255:27 | b | taint.cpp:255:27:255:27 | b | |
|
||||
| taint.cpp:255:27:255:27 | b | taint.cpp:257:8:257:8 | b | |
|
||||
| taint.cpp:258:7:258:12 | call to source | taint.cpp:255:35:255:35 | c | |
|
||||
| taint.cpp:258:7:258:12 | call to source | taint.cpp:258:3:258:14 | ... = ... | |
|
||||
| taint.cpp:260:10:260:10 | ref arg w | taint.cpp:261:7:261:7 | w | |
|
||||
| taint.cpp:266:12:266:12 | x | taint.cpp:268:9:268:9 | x | |
|
||||
@@ -246,9 +254,12 @@
|
||||
| taint.cpp:286:6:286:7 | call to id | taint.cpp:291:7:291:7 | y | |
|
||||
| taint.cpp:287:6:287:7 | call to id | taint.cpp:287:2:287:10 | ... = ... | |
|
||||
| taint.cpp:287:6:287:7 | call to id | taint.cpp:292:7:292:7 | z | |
|
||||
| taint.cpp:297:29:297:29 | b | taint.cpp:297:29:297:29 | b | |
|
||||
| taint.cpp:297:29:297:29 | b | taint.cpp:299:6:299:6 | b | |
|
||||
| taint.cpp:299:6:299:6 | b | taint.cpp:297:21:297:21 | a | |
|
||||
| taint.cpp:299:6:299:6 | b | taint.cpp:299:2:299:6 | ... = ... | |
|
||||
| taint.cpp:302:28:302:28 | b | taint.cpp:304:6:304:6 | b | |
|
||||
| taint.cpp:304:6:304:6 | b | taint.cpp:302:21:302:21 | a | |
|
||||
| taint.cpp:304:6:304:6 | b | taint.cpp:304:2:304:6 | ... = ... | |
|
||||
| taint.cpp:307:21:307:21 | a | taint.cpp:309:3:309:3 | a | |
|
||||
| taint.cpp:307:28:307:28 | b | taint.cpp:309:7:309:7 | b | |
|
||||
@@ -265,9 +276,11 @@
|
||||
| taint.cpp:320:23:320:23 | a | taint.cpp:322:6:322:6 | a | |
|
||||
| taint.cpp:320:31:320:31 | b | taint.cpp:323:6:323:6 | b | |
|
||||
| taint.cpp:322:6:322:6 | a | taint.cpp:322:6:322:10 | ... + ... | TAINT |
|
||||
| taint.cpp:322:6:322:10 | ... + ... | taint.cpp:320:23:320:23 | a | |
|
||||
| taint.cpp:322:6:322:10 | ... + ... | taint.cpp:322:2:322:10 | ... = ... | |
|
||||
| taint.cpp:322:10:322:10 | 1 | taint.cpp:322:6:322:10 | ... + ... | TAINT |
|
||||
| taint.cpp:323:6:323:6 | b | taint.cpp:323:6:323:10 | ... + ... | TAINT |
|
||||
| taint.cpp:323:6:323:10 | ... + ... | taint.cpp:320:31:320:31 | b | |
|
||||
| taint.cpp:323:6:323:10 | ... + ... | taint.cpp:323:2:323:10 | ... = ... | |
|
||||
| taint.cpp:323:10:323:10 | 1 | taint.cpp:323:6:323:10 | ... + ... | TAINT |
|
||||
| taint.cpp:330:6:330:11 | call to source | taint.cpp:330:2:330:13 | ... = ... | |
|
||||
|
||||
@@ -258,7 +258,7 @@ void test_lambdas()
|
||||
c = source();
|
||||
};
|
||||
e(t, u, w);
|
||||
sink(w); // tainted [NOT DETECTED]
|
||||
sink(w); // tainted
|
||||
}
|
||||
|
||||
// --- taint through return value ---
|
||||
@@ -348,8 +348,8 @@ void test_outparams()
|
||||
myNotAssign(e, t);
|
||||
|
||||
sink(t); // tainted
|
||||
sink(a); // tainted [NOT DETECTED]
|
||||
sink(b); // tainted [NOT DETECTED]
|
||||
sink(a); // tainted
|
||||
sink(b); // tainted
|
||||
sink(c); // tainted [NOT DETECTED]
|
||||
sink(d); // tainted [NOT DETECTED]
|
||||
sink(e);
|
||||
|
||||
@@ -28,9 +28,12 @@
|
||||
| taint.cpp:244:3:244:6 | t | taint.cpp:223:10:223:15 | call to source |
|
||||
| taint.cpp:250:8:250:8 | a | taint.cpp:223:10:223:15 | call to source |
|
||||
| taint.cpp:256:8:256:8 | a | taint.cpp:223:10:223:15 | call to source |
|
||||
| taint.cpp:261:7:261:7 | w | taint.cpp:258:7:258:12 | call to source |
|
||||
| taint.cpp:280:7:280:7 | t | taint.cpp:275:6:275:11 | call to source |
|
||||
| taint.cpp:289:7:289:7 | t | taint.cpp:275:6:275:11 | call to source |
|
||||
| taint.cpp:290:7:290:7 | x | taint.cpp:275:6:275:11 | call to source |
|
||||
| taint.cpp:291:7:291:7 | y | taint.cpp:275:6:275:11 | call to source |
|
||||
| taint.cpp:337:7:337:7 | t | taint.cpp:330:6:330:11 | call to source |
|
||||
| taint.cpp:350:7:350:7 | t | taint.cpp:330:6:330:11 | call to source |
|
||||
| taint.cpp:351:7:351:7 | a | taint.cpp:330:6:330:11 | call to source |
|
||||
| taint.cpp:352:7:352:7 | b | taint.cpp:330:6:330:11 | call to source |
|
||||
|
||||
@@ -21,4 +21,7 @@
|
||||
| taint.cpp:244:3:244:6 | taint.cpp:223:10:223:15 | AST only |
|
||||
| taint.cpp:250:8:250:8 | taint.cpp:223:10:223:15 | AST only |
|
||||
| taint.cpp:256:8:256:8 | taint.cpp:223:10:223:15 | AST only |
|
||||
| taint.cpp:261:7:261:7 | taint.cpp:258:7:258:12 | AST only |
|
||||
| taint.cpp:350:7:350:7 | taint.cpp:330:6:330:11 | AST only |
|
||||
| taint.cpp:351:7:351:7 | taint.cpp:330:6:330:11 | AST only |
|
||||
| taint.cpp:352:7:352:7 | taint.cpp:330:6:330:11 | AST only |
|
||||
|
||||
Reference in New Issue
Block a user