Skip to content

Commit a329050

Browse files
author
Robert Marsh
authored
Merge pull request #1806 from jbj/localExprFlow
C++: Add localExprFlow and localExprTaint
2 parents ef7984d + 8ee87fd commit a329050

File tree

12 files changed

+50
-17
lines changed

12 files changed

+50
-17
lines changed

change-notes/1.23/analysis-cpp.md

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -28,3 +28,6 @@ The following changes in version 1.23 affect C/C++ analysis in all applications.
2828
picture of the partial flow paths from a given source. The feature is
2929
disabled by default and can be enabled for individual configurations by
3030
overriding `int explorationLimit()`.
31+
* There is now a `DataFlow::localExprFlow` predicate and a
32+
`TaintTracking::localExprTaint` predicate to make it easy to use the most
33+
common case of local data flow and taint: from one `Expr` to another.

cpp/ql/src/Critical/NewDelete.qll

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -47,7 +47,7 @@ predicate allocExprOrIndirect(Expr alloc, string kind) {
4747
or
4848
exists(Expr e |
4949
allocExprOrIndirect(e, kind) and
50-
DataFlow::localFlow(DataFlow::exprNode(e), DataFlow::exprNode(rtn.getExpr()))
50+
DataFlow::localExprFlow(e, rtn.getExpr())
5151
)
5252
)
5353
)

cpp/ql/src/Critical/OverflowStatic.ql

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -95,7 +95,7 @@ class CallWithBufferSize extends FunctionCall {
9595

9696
int statedSizeValue() {
9797
exists(Expr statedSizeSrc |
98-
DataFlow::localFlow(DataFlow::exprNode(statedSizeSrc), DataFlow::exprNode(statedSizeExpr())) and
98+
DataFlow::localExprFlow(statedSizeSrc, statedSizeExpr()) and
9999
result = statedSizeSrc.getValue().toInt()
100100
)
101101
}

cpp/ql/src/Likely Bugs/Conversion/LossyFunctionResultCast.ql

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -55,7 +55,7 @@ predicate whiteListWrapped(FunctionCall fc) {
5555
whitelistPow(fc) or
5656
exists(Expr e, ReturnStmt rs |
5757
whiteListWrapped(e) and
58-
DataFlow::localFlow(DataFlow::exprNode(e), DataFlow::exprNode(rs.getExpr())) and
58+
DataFlow::localExprFlow(e, rs.getExpr()) and
5959
fc.getTarget() = rs.getEnclosingFunction()
6060
)
6161
}

cpp/ql/src/Likely Bugs/Likely Typos/UsingStrcpyAsBoolean.ql

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -23,7 +23,7 @@ predicate isBoolean(Expr e1) {
2323
}
2424

2525
predicate isStringCopyCastedAsBoolean(FunctionCall func, Expr expr1, string msg) {
26-
DataFlow::localFlow(DataFlow::exprNode(func), DataFlow::exprNode(expr1)) and
26+
DataFlow::localExprFlow(func, expr1) and
2727
isBoolean(expr1.getConversion*()) and
2828
func.getTarget() instanceof StrcpyFunction and
2929
msg = "Return value of " + func.getTarget().getName() + " used as a Boolean."

cpp/ql/src/Security/CWE/CWE-131/NoSpaceForZeroTerminator.ql

Lines changed: 3 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -36,12 +36,10 @@ class MallocCall extends FunctionCall
3636

3737
predicate terminationProblem(MallocCall malloc, string msg) {
3838
malloc.getAllocatedSize() instanceof StrlenCall and
39-
not exists(DataFlow::Node def, DataFlow::Node use, FunctionCall fc, MemcpyFunction memcpy, int ix |
40-
DataFlow::localFlow(def, use) and
41-
def.asExpr() = malloc and
39+
not exists(FunctionCall fc, MemcpyFunction memcpy, int ix |
40+
DataFlow::localExprFlow(malloc, fc.getArgument(ix)) and
4241
fc.getTarget() = memcpy and
43-
memcpy.hasArrayOutput(ix) and
44-
use.asExpr() = fc.getArgument(ix)
42+
memcpy.hasArrayOutput(ix)
4543
) and
4644
msg = "This allocation does not include space to null-terminate the string."
4745
}

cpp/ql/src/semmle/code/cpp/dataflow/DataFlow.qll

Lines changed: 4 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -11,8 +11,10 @@
1111
*
1212
* To use global (interprocedural) data flow, extend the class
1313
* `DataFlow::Configuration` as documented on that class. To use local
14-
* (intraprocedural) data flow, invoke `DataFlow::localFlow` or
15-
* `DataFlow::LocalFlowStep` with arguments of type `DataFlow::Node`.
14+
* (intraprocedural) data flow between expressions, call
15+
* `DataFlow::localExprFlow`. For more general cases of local data flow, call
16+
* `DataFlow::localFlow` or `DataFlow::localFlowStep` with arguments of type
17+
* `DataFlow::Node`.
1618
*/
1719
import cpp
1820

cpp/ql/src/semmle/code/cpp/dataflow/TaintTracking.qll

Lines changed: 7 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -6,6 +6,13 @@
66
* the information from the source is preserved at the sink. For example, taint
77
* propagates from `x` to `x + 100`, but it does not propagate from `x` to `x >
88
* 100` since we consider a single bit of information to be too little.
9+
*
10+
* To use global (interprocedural) taint tracking, extend the class
11+
* `TaintTracking::Configuration` as documented on that class. To use local
12+
* (intraprocedural) taint tracking between expressions, call
13+
* `TaintTracking::localExprTaint`. For more general cases of local taint
14+
* tracking, call `TaintTracking::localTaint` or
15+
* `TaintTracking::localTaintStep` with arguments of type `DataFlow::Node`.
916
*/
1017
import semmle.code.cpp.dataflow.DataFlow
1118
import semmle.code.cpp.dataflow.DataFlow2

cpp/ql/src/semmle/code/cpp/dataflow/TaintTracking2.qll

Lines changed: 9 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -1,11 +1,14 @@
11
/**
2-
* Provides classes for performing local (intra-procedural) and
3-
* global (inter-procedural) taint-tracking analyses.
2+
* Provides a `TaintTracking2` module, which is a copy of the `TaintTracking`
3+
* module. Use this class when data-flow configurations or taint-tracking
4+
* configurations must depend on each other. Two classes extending
5+
* `DataFlow::Configuration` should never depend on each other, but one of them
6+
* should instead depend on a `DataFlow2::Configuration`, a
7+
* `DataFlow3::Configuration`, or a `DataFlow4::Configuration`. The
8+
* `TaintTracking::Configuration` class extends `DataFlow::Configuration`, and
9+
* `TaintTracking2::Configuration` extends `DataFlow2::Configuration`.
410
*
5-
* We define _taint propagation_ informally to mean that a substantial part of
6-
* the information from the source is preserved at the sink. For example, taint
7-
* propagates from `x` to `x + 100`, but it does not propagate from `x` to `x >
8-
* 100` since we consider a single bit of information to be too little.
11+
* See `semmle.code.cpp.dataflow.TaintTracking` for the full documentation.
912
*/
1013
module TaintTracking2 {
1114
import semmle.code.cpp.dataflow.internal.tainttracking2.TaintTrackingImpl

cpp/ql/src/semmle/code/cpp/dataflow/internal/DataFlowUtil.qll

Lines changed: 6 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -496,6 +496,12 @@ predicate simpleLocalFlowStep(Node nodeFrom, Node nodeTo) {
496496
*/
497497
predicate localFlow(Node source, Node sink) { localFlowStep*(source, sink) }
498498

499+
/**
500+
* Holds if data can flow from `e1` to `e2` in zero or more
501+
* local (intra-procedural) steps.
502+
*/
503+
predicate localExprFlow(Expr e1, Expr e2) { localFlow(exprNode(e1), exprNode(e2)) }
504+
499505
/**
500506
* Holds if the initial value of `v`, if it is a source, flows to `var`.
501507
*/

0 commit comments

Comments
 (0)