Skip to content

Commit deb1a4c

Browse files
committed
Merge branch 'main' of github.com:github/codeql into SharedDataflow_UseUseFlow
2 parents 7b10a3a + c457435 commit deb1a4c

File tree

44 files changed

+1357
-240
lines changed

Some content is hidden

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

44 files changed

+1357
-240
lines changed

change-notes/1.26/analysis-cpp.md

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -23,5 +23,6 @@ The following changes in version 1.26 affect C/C++ analysis in all applications.
2323
* The QL class `Block`, denoting the `{ ... }` statement, is renamed to `BlockStmt`.
2424
* The models library now models many taint flows through `std::array`, `std::vector`, `std::deque`, `std::list` and `std::forward_list`.
2525
* The models library now models many more taint flows through `std::string`.
26+
* The models library now models some taint flows through `std::ostream`.
2627
* The `SimpleRangeAnalysis` library now supports multiplications of the form
2728
`e1 * e2` and `x *= e2` when `e1` and `e2` are unsigned or constant.

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

Lines changed: 12 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -33,10 +33,10 @@ predicate defaultAdditionalTaintStep(DataFlow::Node src, DataFlow::Node sink) {
3333
}
3434

3535
/**
36-
* Holds if `node` should be a barrier in all global taint flow configurations
36+
* Holds if `node` should be a sanitizer in all global taint flow configurations
3737
* but not in local taint.
3838
*/
39-
predicate defaultTaintBarrier(DataFlow::Node node) { none() }
39+
predicate defaultTaintSanitizer(DataFlow::Node node) { none() }
4040

4141
/**
4242
* Holds if taint can flow in one local step from `nodeFrom` to `nodeTo` excluding
@@ -90,10 +90,17 @@ predicate localAdditionalTaintStep(DataFlow::Node nodeFrom, DataFlow::Node nodeT
9090
exists(TaintFunction f, Call call, FunctionInput inModel, FunctionOutput outModel |
9191
call.getTarget() = f and
9292
inModel.isReturnValueDeref() and
93-
outModel.isQualifierObject() and
94-
f.hasTaintFlow(inModel, outModel) and
9593
nodeFrom.(DataFlow::PostUpdateNode).getPreUpdateNode().asExpr() = call and
96-
nodeTo.asDefiningArgument() = call.getQualifier()
94+
f.hasTaintFlow(inModel, outModel) and
95+
(
96+
outModel.isQualifierObject() and
97+
nodeTo.asDefiningArgument() = call.getQualifier()
98+
or
99+
exists(int argOutIndex |
100+
outModel.isParameterDeref(argOutIndex) and
101+
nodeTo.asDefiningArgument() = call.getArgument(argOutIndex)
102+
)
103+
)
97104
)
98105
}
99106

cpp/ql/src/semmle/code/cpp/dataflow/internal/tainttracking1/TaintTrackingImpl.qll

Lines changed: 4 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -76,20 +76,20 @@ abstract class Configuration extends DataFlow::Configuration {
7676

7777
final override predicate isBarrier(DataFlow::Node node) {
7878
isSanitizer(node) or
79-
defaultTaintBarrier(node)
79+
defaultTaintSanitizer(node)
8080
}
8181

82-
/** Holds if data flow into `node` is prohibited. */
82+
/** Holds if taint propagation into `node` is prohibited. */
8383
predicate isSanitizerIn(DataFlow::Node node) { none() }
8484

8585
final override predicate isBarrierIn(DataFlow::Node node) { isSanitizerIn(node) }
8686

87-
/** Holds if data flow out of `node` is prohibited. */
87+
/** Holds if taint propagation out of `node` is prohibited. */
8888
predicate isSanitizerOut(DataFlow::Node node) { none() }
8989

9090
final override predicate isBarrierOut(DataFlow::Node node) { isSanitizerOut(node) }
9191

92-
/** Holds if data flow through nodes guarded by `guard` is prohibited. */
92+
/** Holds if taint propagation through nodes guarded by `guard` is prohibited. */
9393
predicate isSanitizerGuard(DataFlow::BarrierGuard guard) { none() }
9494

9595
final override predicate isBarrierGuard(DataFlow::BarrierGuard guard) { isSanitizerGuard(guard) }

cpp/ql/src/semmle/code/cpp/dataflow/internal/tainttracking2/TaintTrackingImpl.qll

Lines changed: 4 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -76,20 +76,20 @@ abstract class Configuration extends DataFlow::Configuration {
7676

7777
final override predicate isBarrier(DataFlow::Node node) {
7878
isSanitizer(node) or
79-
defaultTaintBarrier(node)
79+
defaultTaintSanitizer(node)
8080
}
8181

82-
/** Holds if data flow into `node` is prohibited. */
82+
/** Holds if taint propagation into `node` is prohibited. */
8383
predicate isSanitizerIn(DataFlow::Node node) { none() }
8484

8585
final override predicate isBarrierIn(DataFlow::Node node) { isSanitizerIn(node) }
8686

87-
/** Holds if data flow out of `node` is prohibited. */
87+
/** Holds if taint propagation out of `node` is prohibited. */
8888
predicate isSanitizerOut(DataFlow::Node node) { none() }
8989

9090
final override predicate isBarrierOut(DataFlow::Node node) { isSanitizerOut(node) }
9191

92-
/** Holds if data flow through nodes guarded by `guard` is prohibited. */
92+
/** Holds if taint propagation through nodes guarded by `guard` is prohibited. */
9393
predicate isSanitizerGuard(DataFlow::BarrierGuard guard) { none() }
9494

9595
final override predicate isBarrierGuard(DataFlow::BarrierGuard guard) { isSanitizerGuard(guard) }

cpp/ql/src/semmle/code/cpp/ir/dataflow/internal/TaintTrackingUtil.qll

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -100,10 +100,10 @@ predicate defaultAdditionalTaintStep(DataFlow::Node src, DataFlow::Node sink) {
100100
}
101101

102102
/**
103-
* Holds if `node` should be a barrier in all global taint flow configurations
103+
* Holds if `node` should be a sanitizer in all global taint flow configurations
104104
* but not in local taint.
105105
*/
106-
predicate defaultTaintBarrier(DataFlow::Node node) { none() }
106+
predicate defaultTaintSanitizer(DataFlow::Node node) { none() }
107107

108108
/**
109109
* Holds if taint can flow from `instrIn` to `instrOut` through a call to a

cpp/ql/src/semmle/code/cpp/ir/dataflow/internal/tainttracking1/TaintTrackingImpl.qll

Lines changed: 4 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -76,20 +76,20 @@ abstract class Configuration extends DataFlow::Configuration {
7676

7777
final override predicate isBarrier(DataFlow::Node node) {
7878
isSanitizer(node) or
79-
defaultTaintBarrier(node)
79+
defaultTaintSanitizer(node)
8080
}
8181

82-
/** Holds if data flow into `node` is prohibited. */
82+
/** Holds if taint propagation into `node` is prohibited. */
8383
predicate isSanitizerIn(DataFlow::Node node) { none() }
8484

8585
final override predicate isBarrierIn(DataFlow::Node node) { isSanitizerIn(node) }
8686

87-
/** Holds if data flow out of `node` is prohibited. */
87+
/** Holds if taint propagation out of `node` is prohibited. */
8888
predicate isSanitizerOut(DataFlow::Node node) { none() }
8989

9090
final override predicate isBarrierOut(DataFlow::Node node) { isSanitizerOut(node) }
9191

92-
/** Holds if data flow through nodes guarded by `guard` is prohibited. */
92+
/** Holds if taint propagation through nodes guarded by `guard` is prohibited. */
9393
predicate isSanitizerGuard(DataFlow::BarrierGuard guard) { none() }
9494

9595
final override predicate isBarrierGuard(DataFlow::BarrierGuard guard) { isSanitizerGuard(guard) }

cpp/ql/src/semmle/code/cpp/ir/dataflow/internal/tainttracking2/TaintTrackingImpl.qll

Lines changed: 4 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -76,20 +76,20 @@ abstract class Configuration extends DataFlow::Configuration {
7676

7777
final override predicate isBarrier(DataFlow::Node node) {
7878
isSanitizer(node) or
79-
defaultTaintBarrier(node)
79+
defaultTaintSanitizer(node)
8080
}
8181

82-
/** Holds if data flow into `node` is prohibited. */
82+
/** Holds if taint propagation into `node` is prohibited. */
8383
predicate isSanitizerIn(DataFlow::Node node) { none() }
8484

8585
final override predicate isBarrierIn(DataFlow::Node node) { isSanitizerIn(node) }
8686

87-
/** Holds if data flow out of `node` is prohibited. */
87+
/** Holds if taint propagation out of `node` is prohibited. */
8888
predicate isSanitizerOut(DataFlow::Node node) { none() }
8989

9090
final override predicate isBarrierOut(DataFlow::Node node) { isSanitizerOut(node) }
9191

92-
/** Holds if data flow through nodes guarded by `guard` is prohibited. */
92+
/** Holds if taint propagation through nodes guarded by `guard` is prohibited. */
9393
predicate isSanitizerGuard(DataFlow::BarrierGuard guard) { none() }
9494

9595
final override predicate isBarrierGuard(DataFlow::BarrierGuard guard) { isSanitizerGuard(guard) }

cpp/ql/src/semmle/code/cpp/models/implementations/StdString.qll

Lines changed: 68 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -1,7 +1,7 @@
11
/**
2-
* Provides implementation classes modeling `std::string` and other
3-
* instantiations of `std::basic_string`. See `semmle.code.cpp.models.Models`
4-
* for usage information.
2+
* Provides implementation classes modeling `std::string` (and other
3+
* instantiations of `std::basic_string`) and `std::ostream`. See
4+
* `semmle.code.cpp.models.Models` for usage information.
55
*/
66

77
import semmle.code.cpp.models.interfaces.Taint
@@ -287,3 +287,68 @@ class StdStringAt extends TaintFunction {
287287
output.isQualifierObject()
288288
}
289289
}
290+
291+
/**
292+
* The `std::basic_ostream` template class.
293+
*/
294+
class StdBasicOStream extends TemplateClass {
295+
StdBasicOStream() { this.hasQualifiedName("std", "basic_ostream") }
296+
}
297+
298+
/**
299+
* The `std::ostream` function `operator<<` (defined as a member function).
300+
*/
301+
class StdOStreamOut extends DataFlowFunction, TaintFunction {
302+
StdOStreamOut() { this.hasQualifiedName("std", "basic_ostream", "operator<<") }
303+
304+
override predicate hasDataFlow(FunctionInput input, FunctionOutput output) {
305+
// flow from qualifier to return value
306+
input.isQualifierAddress() and
307+
output.isReturnValue()
308+
}
309+
310+
override predicate hasTaintFlow(FunctionInput input, FunctionOutput output) {
311+
// flow from parameter to qualifier
312+
input.isParameter(0) and
313+
output.isQualifierObject()
314+
or
315+
// flow from parameter to return value
316+
input.isParameter(0) and
317+
output.isReturnValueDeref()
318+
or
319+
// reverse flow from returned reference to the qualifier
320+
input.isReturnValueDeref() and
321+
output.isQualifierObject()
322+
}
323+
}
324+
325+
/**
326+
* The `std::ostream` function `operator<<` (defined as a non-member function).
327+
*/
328+
class StdOStreamOutNonMember extends DataFlowFunction, TaintFunction {
329+
StdOStreamOutNonMember() {
330+
this.hasQualifiedName("std", "operator<<") and
331+
this.getUnspecifiedType().(ReferenceType).getBaseType() =
332+
any(StdBasicOStream s).getAnInstantiation()
333+
}
334+
335+
override predicate hasDataFlow(FunctionInput input, FunctionOutput output) {
336+
// flow from first parameter to return value
337+
input.isParameter(0) and
338+
output.isReturnValue()
339+
}
340+
341+
override predicate hasTaintFlow(FunctionInput input, FunctionOutput output) {
342+
// flow from second parameter to first parameter
343+
input.isParameter(1) and
344+
output.isParameterDeref(0)
345+
or
346+
// flow from second parameter to return value
347+
input.isParameter(1) and
348+
output.isReturnValueDeref()
349+
or
350+
// reverse flow from returned reference to the first parameter
351+
input.isReturnValueDeref() and
352+
output.isParameterDeref(0)
353+
}
354+
}

cpp/ql/test/library-tests/dataflow/DefaultTaintTracking/stl.cpp

Lines changed: 4 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -88,14 +88,14 @@ void test_stringstream()
8888
ss5 << t;
8989

9090
sink(ss1);
91-
sink(ss2); // tainted [NOT DETECTED]
91+
sink(ss2); // tainted
9292
sink(ss3); // tainted [NOT DETECTED]
93-
sink(ss4); // tainted [NOT DETECTED]
93+
sink(ss4); // tainted
9494
sink(ss5); // tainted [NOT DETECTED]
9595
sink(ss1.str());
96-
sink(ss2.str()); // tainted [NOT DETECTED]
96+
sink(ss2.str()); // tainted
9797
sink(ss3.str()); // tainted [NOT DETECTED]
98-
sink(ss4.str()); // tainted [NOT DETECTED]
98+
sink(ss4.str()); // tainted
9999
sink(ss5.str()); // tainted [NOT DETECTED]
100100
}
101101

cpp/ql/test/library-tests/dataflow/DefaultTaintTracking/tainted.expected

Lines changed: 21 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -197,8 +197,10 @@
197197
| globals.cpp:23:15:23:20 | call to getenv | globals.cpp:23:15:23:20 | call to getenv |
198198
| stl.cpp:62:25:62:30 | call to getenv | shared.h:5:23:5:31 | sinkparam |
199199
| stl.cpp:62:25:62:30 | call to getenv | stl.cpp:21:29:21:29 | s |
200+
| stl.cpp:62:25:62:30 | call to getenv | stl.cpp:43:78:43:104 | p#0 |
200201
| stl.cpp:62:25:62:30 | call to getenv | stl.cpp:43:114:43:118 | p#1 |
201202
| stl.cpp:62:25:62:30 | call to getenv | stl.cpp:62:25:62:30 | call to getenv |
203+
| stl.cpp:62:25:62:30 | call to getenv | stl.cpp:64:36:64:36 | s |
202204
| stl.cpp:62:25:62:30 | call to getenv | stl.cpp:68:8:68:8 | a |
203205
| stl.cpp:62:25:62:30 | call to getenv | stl.cpp:68:12:68:17 | call to source |
204206
| stl.cpp:62:25:62:30 | call to getenv | stl.cpp:70:16:70:21 | call to source |
@@ -209,12 +211,31 @@
209211
| stl.cpp:62:25:62:30 | call to getenv | stl.cpp:82:16:82:21 | call to source |
210212
| stl.cpp:62:25:62:30 | call to getenv | stl.cpp:82:16:82:23 | (const char *)... |
211213
| stl.cpp:62:25:62:30 | call to getenv | stl.cpp:82:16:82:24 | call to basic_string |
214+
| stl.cpp:62:25:62:30 | call to getenv | stl.cpp:85:6:85:6 | call to operator<< |
215+
| stl.cpp:62:25:62:30 | call to getenv | stl.cpp:85:6:85:17 | (reference dereference) |
212216
| stl.cpp:62:25:62:30 | call to getenv | stl.cpp:85:9:85:14 | call to source |
213217
| stl.cpp:62:25:62:30 | call to getenv | stl.cpp:85:9:85:16 | (const char *)... |
218+
| stl.cpp:62:25:62:30 | call to getenv | stl.cpp:86:15:86:15 | call to operator<< |
219+
| stl.cpp:62:25:62:30 | call to getenv | stl.cpp:86:15:86:26 | (reference dereference) |
214220
| stl.cpp:62:25:62:30 | call to getenv | stl.cpp:86:18:86:23 | call to source |
215221
| stl.cpp:62:25:62:30 | call to getenv | stl.cpp:86:18:86:25 | (const char *)... |
222+
| stl.cpp:62:25:62:30 | call to getenv | stl.cpp:87:6:87:6 | call to operator<< |
223+
| stl.cpp:62:25:62:30 | call to getenv | stl.cpp:87:6:87:19 | (reference dereference) |
224+
| stl.cpp:62:25:62:30 | call to getenv | stl.cpp:87:6:87:19 | (reference to) |
216225
| stl.cpp:62:25:62:30 | call to getenv | stl.cpp:87:9:87:14 | call to source |
217226
| stl.cpp:62:25:62:30 | call to getenv | stl.cpp:87:9:87:16 | (const char *)... |
227+
| stl.cpp:62:25:62:30 | call to getenv | stl.cpp:87:18:87:18 | call to operator<< |
228+
| stl.cpp:62:25:62:30 | call to getenv | stl.cpp:87:18:87:26 | (reference dereference) |
229+
| stl.cpp:62:25:62:30 | call to getenv | stl.cpp:91:7:91:9 | (const stringstream)... |
230+
| stl.cpp:62:25:62:30 | call to getenv | stl.cpp:91:7:91:9 | (reference to) |
231+
| stl.cpp:62:25:62:30 | call to getenv | stl.cpp:91:7:91:9 | ss2 |
232+
| stl.cpp:62:25:62:30 | call to getenv | stl.cpp:93:7:93:9 | (const stringstream)... |
233+
| stl.cpp:62:25:62:30 | call to getenv | stl.cpp:93:7:93:9 | (reference to) |
234+
| stl.cpp:62:25:62:30 | call to getenv | stl.cpp:93:7:93:9 | ss4 |
235+
| stl.cpp:62:25:62:30 | call to getenv | stl.cpp:96:7:96:9 | (const basic_stringstream<char, char_traits<char>, allocator<char>>)... |
236+
| stl.cpp:62:25:62:30 | call to getenv | stl.cpp:96:7:96:9 | ss2 |
237+
| stl.cpp:62:25:62:30 | call to getenv | stl.cpp:98:7:98:9 | (const basic_stringstream<char, char_traits<char>, allocator<char>>)... |
238+
| stl.cpp:62:25:62:30 | call to getenv | stl.cpp:98:7:98:9 | ss4 |
218239
| stl.cpp:62:25:62:30 | call to getenv | stl.cpp:118:10:118:15 | call to source |
219240
| stl.cpp:62:25:62:30 | call to getenv | stl.cpp:125:16:125:28 | call to basic_string |
220241
| stl.cpp:62:25:62:30 | call to getenv | stl.cpp:125:17:125:26 | call to user_input |

0 commit comments

Comments
 (0)