Thanks to visit codestin.com
Credit goes to github.com

Skip to content

Commit cc854dd

Browse files
committed
Merge branch 'master' of github.com:Semmle/ql into attribute
2 parents cb3551b + cf24c9f commit cc854dd

214 files changed

Lines changed: 13079 additions & 4043 deletions

File tree

Some content is hidden

Large Commits have some content hidden by default. Use the searchbox below for content that may be hidden.

change-notes/1.22/analysis-cpp.md

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -25,6 +25,8 @@
2525
- The predicate `Variable.getAnAssignedValue()` now reports assignments to fields resulting from aggregate initialization (` = {...}`).
2626
- The predicate `TypeMention.toString()` has been simplified to always return the string "`type mention`". This may improve performance when using `Element.toString()` or its descendants.
2727
- The `semmle.code.cpp.security.TaintTracking` library now considers a pointer difference calculation as blocking taint flow.
28+
- The second copy of the interprocedural `TaintTracking` library has been renamed from `TaintTracking::Configuration2` to `TaintTracking2::Configuration`, and the old name is now deprecated. Import `semmle.code.cpp.dataflow.TaintTracking2` to access the new name.
2829
- Fixed the `LocalScopeVariableReachability.qll` library's handling of loops with an entry condition is both always true upon first entry, and where there is more than one control flow path through the loop condition. This change increases the accuracy of the `LocalScopeVariableReachability.qll` library and queries which depend on it.
2930
- The `semmle.code.cpp.models` library now models data flow through `std::swap`.
3031
- There is a new `Variable.isThreadLocal()` predicate. It can be used to tell whether a variable is `thread_local`.
32+
- Recursion through the `DataFlow` library is now always a compile error. Such recursion has been deprecated since release 1.16. If one `DataFlow::Configuration` needs to depend on the results of another, switch one of them to use one of the `DataFlow2` through `DataFlow4` libraries.

change-notes/1.22/analysis-csharp.md

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -41,5 +41,6 @@
4141
- The new predicate `ConstructedGeneric.getAnnotatedTypeArgument()` gets the annotated type of a type argument
4242
- The new predicate `TypeParameterConstraints.getAnAnnotatedTypeConstraint()` gets a type constraint with type annotations
4343
* The new class `SuppressNullableWarningExpr` models suppress-nullable-warning expressions such as `x!`
44+
* The data-flow library (and taint-tracking library) now supports flow through fields. All existing configurations will have field-flow enabled by default, but it can be disabled by adding `override int fieldFlowBranchLimit() { result = 0 }` to the configuration class. Field assignments, `this.Foo = x`, object initializers, `new C() { Foo = x }`, and field initializers `int Foo = 0` are supported.
4445

4546
## Changes to autobuilder

change-notes/1.22/analysis-java.md

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -16,4 +16,4 @@
1616
removes false positives that arose from paths through impossible `toString()`
1717
calls.
1818
* The library `VCS.qll` and all queries that imported it have been removed.
19-
19+
* The second copy of the interprocedural `TaintTracking` library has been renamed from `TaintTracking::Configuration2` to `TaintTracking2::Configuration`, and the old name is now deprecated. Import `semmle.code.java.dataflow.TaintTracking2` to access the new name.

config/identical-files.json

Lines changed: 11 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -25,6 +25,17 @@
2525
"cpp/ql/src/semmle/code/cpp/ir/dataflow/internal/DataFlowImplCommon.qll",
2626
"csharp/ql/src/semmle/code/csharp/dataflow/internal/DataFlowImplCommon.qll"
2727
],
28+
"TaintTracking::Configuration Java/C++/C#": [
29+
"cpp/ql/src/semmle/code/cpp/dataflow/internal/tainttracking1/TaintTrackingImpl.qll",
30+
"cpp/ql/src/semmle/code/cpp/dataflow/internal/tainttracking2/TaintTrackingImpl.qll",
31+
"csharp/ql/src/semmle/code/csharp/dataflow/internal/tainttracking1/TaintTrackingImpl.qll",
32+
"csharp/ql/src/semmle/code/csharp/dataflow/internal/tainttracking2/TaintTrackingImpl.qll",
33+
"csharp/ql/src/semmle/code/csharp/dataflow/internal/tainttracking3/TaintTrackingImpl.qll",
34+
"csharp/ql/src/semmle/code/csharp/dataflow/internal/tainttracking4/TaintTrackingImpl.qll",
35+
"csharp/ql/src/semmle/code/csharp/dataflow/internal/tainttracking5/TaintTrackingImpl.qll",
36+
"java/ql/src/semmle/code/java/dataflow/internal/tainttracking1/TaintTrackingImpl.qll",
37+
"java/ql/src/semmle/code/java/dataflow/internal/tainttracking2/TaintTrackingImpl.qll"
38+
],
2839
"IR Instruction": [
2940
"cpp/ql/src/semmle/code/cpp/ir/implementation/raw/Instruction.qll",
3041
"cpp/ql/src/semmle/code/cpp/ir/implementation/unaliased_ssa/Instruction.qll",

cpp/ql/src/semmle/code/cpp/Element.qll

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -206,7 +206,8 @@ class Element extends ElementBase {
206206
namequalifiers(underlyingElement(this), unresolveElement(result), _, _) or
207207
initialisers(underlyingElement(this), unresolveElement(result), _, _) or
208208
exprconv(unresolveElement(result), underlyingElement(this)) or
209-
param_decl_bind(underlyingElement(this),_,unresolveElement(result))
209+
param_decl_bind(underlyingElement(this),_,unresolveElement(result)) or
210+
using_container(unresolveElement(result),underlyingElement(this))
210211
}
211212

212213
/** Gets the closest `Element` enclosing this one. */

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

Lines changed: 0 additions & 23 deletions
Original file line numberDiff line numberDiff line change
@@ -12,27 +12,4 @@ import cpp
1212

1313
module DataFlow2 {
1414
import semmle.code.cpp.dataflow.internal.DataFlowImpl2
15-
16-
/**
17-
* This class exists to prevent mutual recursion between the user-overridden
18-
* member predicates of `Configuration` and the rest of the data-flow library.
19-
* Good performance cannot be guaranteed in the presence of such recursion, so
20-
* it should be replaced by using more than one copy of the data flow library.
21-
* Four copies are available: `DataFlow` through `DataFlow4`.
22-
*/
23-
private abstract
24-
class ConfigurationRecursionPrevention extends Configuration {
25-
bindingset[this]
26-
ConfigurationRecursionPrevention() { any() }
27-
28-
override predicate hasFlow(Node source, Node sink) {
29-
strictcount(Node n | this.isSource(n)) < 0
30-
or
31-
strictcount(Node n | this.isSink(n)) < 0
32-
or
33-
strictcount(Node n1, Node n2 | this.isAdditionalFlowStep(n1, n2)) < 0
34-
or
35-
super.hasFlow(source, sink)
36-
}
37-
}
3815
}

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

Lines changed: 0 additions & 23 deletions
Original file line numberDiff line numberDiff line change
@@ -12,27 +12,4 @@ import cpp
1212

1313
module DataFlow3 {
1414
import semmle.code.cpp.dataflow.internal.DataFlowImpl3
15-
16-
/**
17-
* This class exists to prevent mutual recursion between the user-overridden
18-
* member predicates of `Configuration` and the rest of the data-flow library.
19-
* Good performance cannot be guaranteed in the presence of such recursion, so
20-
* it should be replaced by using more than one copy of the data flow library.
21-
* Four copies are available: `DataFlow` through `DataFlow4`.
22-
*/
23-
private abstract
24-
class ConfigurationRecursionPrevention extends Configuration {
25-
bindingset[this]
26-
ConfigurationRecursionPrevention() { any() }
27-
28-
override predicate hasFlow(Node source, Node sink) {
29-
strictcount(Node n | this.isSource(n)) < 0
30-
or
31-
strictcount(Node n | this.isSink(n)) < 0
32-
or
33-
strictcount(Node n1, Node n2 | this.isAdditionalFlowStep(n1, n2)) < 0
34-
or
35-
super.hasFlow(source, sink)
36-
}
37-
}
3815
}

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

Lines changed: 0 additions & 23 deletions
Original file line numberDiff line numberDiff line change
@@ -12,27 +12,4 @@ import cpp
1212

1313
module DataFlow4 {
1414
import semmle.code.cpp.dataflow.internal.DataFlowImpl4
15-
16-
/**
17-
* This class exists to prevent mutual recursion between the user-overridden
18-
* member predicates of `Configuration` and the rest of the data-flow library.
19-
* Good performance cannot be guaranteed in the presence of such recursion, so
20-
* it should be replaced by using more than one copy of the data flow library.
21-
* Four copies are available: `DataFlow` through `DataFlow4`.
22-
*/
23-
private abstract
24-
class ConfigurationRecursionPrevention extends Configuration {
25-
bindingset[this]
26-
ConfigurationRecursionPrevention() { any() }
27-
28-
override predicate hasFlow(Node source, Node sink) {
29-
strictcount(Node n | this.isSource(n)) < 0
30-
or
31-
strictcount(Node n | this.isSink(n)) < 0
32-
or
33-
strictcount(Node n1, Node n2 | this.isAdditionalFlowStep(n1, n2)) < 0
34-
or
35-
super.hasFlow(source, sink)
36-
}
37-
}
3815
}

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

Lines changed: 5 additions & 250 deletions
Original file line numberDiff line numberDiff line change
@@ -9,259 +9,14 @@
99
*/
1010
import semmle.code.cpp.dataflow.DataFlow
1111
import semmle.code.cpp.dataflow.DataFlow2
12-
import semmle.code.cpp.models.interfaces.DataFlow
13-
import semmle.code.cpp.models.interfaces.Taint
1412

1513
module TaintTracking {
14+
import semmle.code.cpp.dataflow.internal.tainttracking1.TaintTrackingImpl
15+
private import semmle.code.cpp.dataflow.TaintTracking2
1616

1717
/**
18-
* A configuration of interprocedural taint tracking analysis. This defines
19-
* sources, sinks, and any other configurable aspect of the analysis. Each
20-
* use of the taint tracking library must define its own unique extension of
21-
* this abstract class.
22-
*
23-
* A taint-tracking configuration is a special data flow configuration
24-
* (`DataFlow::Configuration`) that allows for flow through nodes that do not
25-
* necessarily preserve values but are still relevant from a taint-tracking
26-
* perspective. (For example, string concatenation, where one of the operands
27-
* is tainted.)
28-
*
29-
* To create a configuration, extend this class with a subclass whose
30-
* characteristic predicate is a unique singleton string. For example, write
31-
*
32-
* ```
33-
* class MyAnalysisConfiguration extends TaintTracking::Configuration {
34-
* MyAnalysisConfiguration() { this = "MyAnalysisConfiguration" }
35-
* // Override `isSource` and `isSink`.
36-
* // Optionally override `isSanitizer`.
37-
* // Optionally override `isSanitizerEdge`.
38-
* // Optionally override `isAdditionalTaintStep`.
39-
* }
40-
* ```
41-
*
42-
* Then, to query whether there is flow between some `source` and `sink`,
43-
* write
44-
*
45-
* ```
46-
* exists(MyAnalysisConfiguration cfg | cfg.hasFlow(source, sink))
47-
* ```
48-
*
49-
* Multiple configurations can coexist, but it is unsupported to depend on a
50-
* `TaintTracking::Configuration` or a `DataFlow::Configuration` in the
51-
* overridden predicates that define sources, sinks, or additional steps.
52-
* Instead, the dependency should go to a `TaintTracking::Configuration2` or
53-
* a `DataFlow{2,3,4}::Configuration`.
18+
* DEPRECATED: Use TaintTracking2::Configuration instead.
5419
*/
55-
abstract class Configuration extends DataFlow::Configuration {
56-
bindingset[this]
57-
Configuration() { any() }
58-
59-
/** Holds if `source` is a taint source. */
60-
// overridden to provide taint-tracking specific qldoc
61-
abstract override predicate isSource(DataFlow::Node source);
62-
63-
/** Holds if `sink` is a taint sink. */
64-
// overridden to provide taint-tracking specific qldoc
65-
abstract override predicate isSink(DataFlow::Node sink);
66-
67-
/**
68-
* Holds if taint should not flow into `node`.
69-
*/
70-
predicate isSanitizer(DataFlow::Node node) { none() }
71-
72-
/** Holds if data flow from `node1` to `node2` is prohibited. */
73-
predicate isSanitizerEdge(DataFlow::Node node1, DataFlow::Node node2) {
74-
none()
75-
}
76-
77-
/**
78-
* Holds if the additional taint propagation step
79-
* from `source` to `target` must be taken into account in the analysis.
80-
* This step will only be followed if `target` is not in the `isSanitizer`
81-
* predicate.
82-
*/
83-
predicate isAdditionalTaintStep(DataFlow::Node source,
84-
DataFlow::Node target)
85-
{ none() }
86-
87-
final override
88-
predicate isBarrier(DataFlow::Node node) { isSanitizer(node) }
89-
90-
/** DEPRECATED: use `isSanitizerEdge` instead. */
91-
override deprecated
92-
predicate isBarrierEdge(DataFlow::Node node1, DataFlow::Node node2) {
93-
this.isSanitizerEdge(node1, node2)
94-
}
95-
96-
final override
97-
predicate isAdditionalFlowStep(DataFlow::Node source, DataFlow::Node target) {
98-
this.isAdditionalTaintStep(source, target)
99-
or
100-
localTaintStep(source, target)
101-
}
102-
}
103-
104-
/**
105-
* A taint-tracking configuration that is backed by the `DataFlow2` library
106-
* instead of `DataFlow`. Use this class when taint-tracking configurations
107-
* or data-flow configurations must depend on each other.
108-
*
109-
* See `TaintTracking::Configuration` for the full documentation.
110-
*/
111-
abstract class Configuration2 extends DataFlow2::Configuration {
112-
bindingset[this]
113-
Configuration2() { any() }
114-
115-
/** Holds if `source` is a taint source. */
116-
// overridden to provide taint-tracking specific qldoc
117-
abstract override predicate isSource(DataFlow::Node source);
118-
119-
/** Holds if `sink` is a taint sink. */
120-
// overridden to provide taint-tracking specific qldoc
121-
abstract override predicate isSink(DataFlow::Node sink);
122-
123-
/**
124-
* Holds if taint should not flow into `node`.
125-
*/
126-
predicate isSanitizer(DataFlow::Node node) { none() }
127-
128-
/** Holds if data flow from `node1` to `node2` is prohibited. */
129-
predicate isSanitizerEdge(DataFlow::Node node1, DataFlow::Node node2) {
130-
none()
131-
}
132-
133-
/**
134-
* Holds if the additional taint propagation step
135-
* from `source` to `target` must be taken into account in the analysis.
136-
* This step will only be followed if `target` is not in the `isSanitizer`
137-
* predicate.
138-
*/
139-
predicate isAdditionalTaintStep(DataFlow::Node source,
140-
DataFlow::Node target)
141-
{ none() }
142-
143-
final override
144-
predicate isBarrier(DataFlow::Node node) { isSanitizer(node) }
145-
146-
/** DEPRECATED: use `isSanitizerEdge` instead. */
147-
override deprecated
148-
predicate isBarrierEdge(DataFlow::Node node1, DataFlow::Node node2) {
149-
this.isSanitizerEdge(node1, node2)
150-
}
151-
152-
final override
153-
predicate isAdditionalFlowStep(DataFlow::Node source, DataFlow::Node target) {
154-
this.isAdditionalTaintStep(source, target)
155-
or
156-
localTaintStep(source, target)
157-
}
158-
}
159-
160-
/**
161-
* Holds if taint propagates from `nodeFrom` to `nodeTo` in exactly one local
162-
* (intra-procedural) step.
163-
*/
164-
predicate localTaintStep(DataFlow::Node nodeFrom, DataFlow::Node nodeTo) {
165-
// Taint can flow into using ordinary data flow.
166-
DataFlow::localFlowStep(nodeFrom, nodeTo)
167-
or
168-
// Taint can flow through expressions that alter the value but preserve
169-
// more than one bit of it _or_ expressions that follow data through
170-
// pointer indirections.
171-
exists(Expr exprFrom, Expr exprTo |
172-
exprFrom = nodeFrom.asExpr() and
173-
exprTo = nodeTo.asExpr()
174-
|
175-
exprFrom = exprTo.getAChild() and
176-
not noParentExprFlow(exprFrom, exprTo) and
177-
not noFlowFromChildExpr(exprTo)
178-
or
179-
// Taint can flow from the `x` variable in `x++` to all subsequent
180-
// accesses to the unmodified `x` variable.
181-
//
182-
// `DataFlow` without taint specifies flow from `++x` and `x += 1` into the
183-
// variable `x` and thus into subsequent accesses because those expressions
184-
// compute the same value as `x`. This is not the case for `x++`, which
185-
// computes a different value, so we have to add that ourselves for taint
186-
// tracking. The flow from expression `x` into `x++` etc. is handled in the
187-
// case above.
188-
exprTo = DataFlow::getAnAccessToAssignedVariable(
189-
exprFrom.(PostfixCrementOperation)
190-
)
191-
)
192-
or
193-
// Taint can flow through modeled functions
194-
exprToDefinitionByReferenceStep(nodeFrom.asExpr(), nodeTo.asDefiningArgument())
195-
}
196-
197-
/**
198-
* Holds if taint may propagate from `source` to `sink` in zero or more local
199-
* (intra-procedural) steps.
200-
*/
201-
predicate localTaint(DataFlow::Node source, DataFlow::Node sink) {
202-
localTaintStep*(source, sink)
203-
}
204-
205-
/**
206-
* Holds if we do not propagate taint from `fromExpr` to `toExpr`
207-
* even though `toExpr` is the AST parent of `fromExpr`.
208-
*/
209-
private predicate noParentExprFlow(Expr fromExpr, Expr toExpr) {
210-
fromExpr = toExpr.(ConditionalExpr).getCondition()
211-
or
212-
fromExpr = toExpr.(CommaExpr).getLeftOperand()
213-
or
214-
fromExpr = toExpr.(AssignExpr).getLValue() // LHS of `=`
215-
}
216-
217-
/**
218-
* Holds if we do not propagate taint from a child of `e` to `e` itself.
219-
*/
220-
private predicate noFlowFromChildExpr(Expr e) {
221-
e instanceof ComparisonOperation
222-
or
223-
e instanceof LogicalAndExpr
224-
or
225-
e instanceof LogicalOrExpr
226-
or
227-
e instanceof Call
228-
or
229-
e instanceof SizeofOperator
230-
or
231-
e instanceof AlignofOperator
232-
}
233-
234-
private predicate exprToDefinitionByReferenceStep(Expr exprIn, Expr argOut) {
235-
exists(DataFlowFunction f, Call call, FunctionOutput outModel, int argOutIndex |
236-
call.getTarget() = f and
237-
argOut = call.getArgument(argOutIndex) and
238-
outModel.isOutParameterPointer(argOutIndex) and
239-
exists(int argInIndex, FunctionInput inModel |
240-
f.hasDataFlow(inModel, outModel)
241-
|
242-
// Taint flows from a pointer to a dereference, which DataFlow does not handle
243-
// memcpy(&dest_var, tainted_ptr, len)
244-
inModel.isInParameterPointer(argInIndex) and
245-
exprIn = call.getArgument(argInIndex)
246-
)
247-
)
248-
or
249-
exists(TaintFunction f, Call call, FunctionOutput outModel, int argOutIndex |
250-
call.getTarget() = f and
251-
argOut = call.getArgument(argOutIndex) and
252-
outModel.isOutParameterPointer(argOutIndex) and
253-
exists(int argInIndex, FunctionInput inModel |
254-
f.hasTaintFlow(inModel, outModel)
255-
|
256-
inModel.isInParameterPointer(argInIndex) and
257-
exprIn = call.getArgument(argInIndex)
258-
or
259-
inModel.isInParameterPointer(argInIndex) and
260-
call.passesByReference(argInIndex, exprIn)
261-
or
262-
inModel.isInParameter(argInIndex) and
263-
exprIn = call.getArgument(argInIndex)
264-
)
265-
)
266-
}
20+
deprecated
21+
class Configuration2 = TaintTracking2::Configuration;
26722
}

0 commit comments

Comments
 (0)