Skip to content

Commit 1d02838

Browse files
committed
Merge branch 'main' into wild-crest-ql
2 parents 6fad5b8 + 8349bd5 commit 1d02838

File tree

246 files changed

+11550
-3485
lines changed

Some content is hidden

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

246 files changed

+11550
-3485
lines changed

MODULE.bazel

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -21,7 +21,7 @@ bazel_dep(name = "rules_java", version = "9.6.1")
2121
bazel_dep(name = "rules_pkg", version = "1.2.0")
2222
bazel_dep(name = "rules_nodejs", version = "6.7.3")
2323
bazel_dep(name = "rules_python", version = "1.9.0")
24-
bazel_dep(name = "rules_shell", version = "0.6.1")
24+
bazel_dep(name = "rules_shell", version = "0.7.1")
2525
bazel_dep(name = "bazel_skylib", version = "1.9.0")
2626
bazel_dep(name = "abseil-cpp", version = "20260107.1", repo_name = "absl")
2727
bazel_dep(name = "nlohmann_json", version = "3.11.3", repo_name = "json")
Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,5 @@
1+
---
2+
category: feature
3+
---
4+
* Added a class `ConstructorDirectFieldInit` to represent field initializations that occur in member initializer lists.
5+
* Added a class `ConstructorDefaultFieldInit` to represent default field initializations.
Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,4 @@
1+
---
2+
category: breaking
3+
---
4+
* The `SourceModelCsv`, `SinkModelCsv`, and `SummaryModelCsv` classes and the associated CSV parsing infrastructure have been removed from `ExternalFlow.qll`. New models should be added as `.model.yml` files in the `ext/` directory.

cpp/ql/lib/ext/ZMQ.model.yml

Lines changed: 22 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,22 @@
1+
# ZeroMQ networking library models
2+
extensions:
3+
- addsTo:
4+
pack: codeql/cpp-all
5+
extensible: sourceModel
6+
data: # namespace, type, subtypes, name, signature, ext, output, kind, provenance
7+
- ["", "", False, "zmq_recv", "", "", "Argument[*1]", "remote", "manual"]
8+
- ["", "", False, "zmq_recvmsg", "", "", "Argument[*1]", "remote", "manual"]
9+
- ["", "", False, "zmq_msg_recv", "", "", "Argument[*0]", "remote", "manual"]
10+
- addsTo:
11+
pack: codeql/cpp-all
12+
extensible: sinkModel
13+
data: # namespace, type, subtypes, name, signature, ext, input, kind, provenance
14+
- ["", "", False, "zmq_send", "", "", "Argument[*1]", "remote-sink", "manual"]
15+
- ["", "", False, "zmq_sendmsg", "", "", "Argument[*1]", "remote-sink", "manual"]
16+
- ["", "", False, "zmq_msg_send", "", "", "Argument[*0]", "remote-sink", "manual"]
17+
- addsTo:
18+
pack: codeql/cpp-all
19+
extensible: summaryModel
20+
data: # namespace, type, subtypes, name, signature, ext, input, output, kind, provenance
21+
- ["", "", False, "zmq_msg_init_data", "", "", "Argument[*1]", "Argument[*0]", "taint", "manual"]
22+
- ["", "", False, "zmq_msg_data", "", "", "Argument[*0]", "ReturnValue[*]", "taint", "manual"]

cpp/ql/lib/ext/getc.model.yml

Lines changed: 19 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,19 @@
1+
# Models for getc and similar character-reading functions
2+
extensions:
3+
- addsTo:
4+
pack: codeql/cpp-all
5+
extensible: sourceModel
6+
data: # namespace, type, subtypes, name, signature, ext, output, kind, provenance
7+
- ["", "", False, "getc", "", "", "ReturnValue", "remote", "manual"]
8+
- ["", "", False, "getwc", "", "", "ReturnValue", "remote", "manual"]
9+
- ["", "", False, "_getc_nolock", "", "", "ReturnValue", "remote", "manual"]
10+
- ["", "", False, "_getwc_nolock", "", "", "ReturnValue", "remote", "manual"]
11+
- ["", "", False, "getch", "", "", "ReturnValue", "local", "manual"]
12+
- ["", "", False, "_getch", "", "", "ReturnValue", "local", "manual"]
13+
- ["", "", False, "_getwch", "", "", "ReturnValue", "local", "manual"]
14+
- ["", "", False, "_getch_nolock", "", "", "ReturnValue", "local", "manual"]
15+
- ["", "", False, "_getwch_nolock", "", "", "ReturnValue", "local", "manual"]
16+
- ["", "", False, "getchar", "", "", "ReturnValue", "local", "manual"]
17+
- ["", "", False, "getwchar", "", "", "ReturnValue", "local", "manual"]
18+
- ["", "", False, "_getchar_nolock", "", "", "ReturnValue", "local", "manual"]
19+
- ["", "", False, "_getwchar_nolock", "", "", "ReturnValue", "local", "manual"]

cpp/ql/lib/semmle/code/cpp/dataflow/ExternalFlow.qll

Lines changed: 9 additions & 151 deletions
Original file line numberDiff line numberDiff line change
@@ -1,9 +1,10 @@
11
/**
22
* INTERNAL use only. This is an experimental API subject to change without notice.
33
*
4-
* Provides classes and predicates for dealing with flow models specified in CSV format.
4+
* Provides classes and predicates for dealing with flow models specified
5+
* in data extension files.
56
*
6-
* The CSV specification has the following columns:
7+
* The extensible relations have the following columns:
78
* - Sources:
89
* `namespace; type; subtypes; name; signature; ext; output; kind`
910
* - Sinks:
@@ -104,117 +105,9 @@ private import internal.FlowSummaryImpl::Private
104105
private import internal.FlowSummaryImpl::Private::External
105106
private import internal.ExternalFlowExtensions::Extensions as Extensions
106107
private import codeql.mad.ModelValidation as SharedModelVal
107-
private import codeql.util.Unit
108108
private import codeql.mad.static.ModelsAsData as SharedMaD
109109

110-
/**
111-
* A unit class for adding additional source model rows.
112-
*
113-
* Extend this class to add additional source definitions.
114-
*/
115-
class SourceModelCsv extends Unit {
116-
/** Holds if `row` specifies a source definition. */
117-
abstract predicate row(string row);
118-
}
119-
120-
/**
121-
* A unit class for adding additional sink model rows.
122-
*
123-
* Extend this class to add additional sink definitions.
124-
*/
125-
class SinkModelCsv extends Unit {
126-
/** Holds if `row` specifies a sink definition. */
127-
abstract predicate row(string row);
128-
}
129-
130-
/**
131-
* A unit class for adding additional summary model rows.
132-
*
133-
* Extend this class to add additional flow summary definitions.
134-
*/
135-
class SummaryModelCsv extends Unit {
136-
/** Holds if `row` specifies a summary definition. */
137-
abstract predicate row(string row);
138-
}
139-
140-
/** Holds if `row` is a source model. */
141-
predicate sourceModel(string row) { any(SourceModelCsv s).row(row) }
142-
143-
/** Holds if `row` is a sink model. */
144-
predicate sinkModel(string row) { any(SinkModelCsv s).row(row) }
145-
146-
/** Holds if `row` is a summary model. */
147-
predicate summaryModel(string row) { any(SummaryModelCsv s).row(row) }
148-
149110
private module MadInput implements SharedMaD::InputSig {
150-
/** Holds if a source model exists for the given parameters. */
151-
predicate additionalSourceModel(
152-
string namespace, string type, boolean subtypes, string name, string signature, string ext,
153-
string output, string kind, string provenance, string model
154-
) {
155-
exists(string row |
156-
sourceModel(row) and
157-
row.splitAt(";", 0) = namespace and
158-
row.splitAt(";", 1) = type and
159-
row.splitAt(";", 2) = subtypes.toString() and
160-
subtypes = [true, false] and
161-
row.splitAt(";", 3) = name and
162-
row.splitAt(";", 4) = signature and
163-
row.splitAt(";", 5) = ext and
164-
row.splitAt(";", 6) = output and
165-
row.splitAt(";", 7) = kind
166-
) and
167-
provenance = "manual" and
168-
model = ""
169-
}
170-
171-
/** Holds if a sink model exists for the given parameters. */
172-
predicate additionalSinkModel(
173-
string namespace, string type, boolean subtypes, string name, string signature, string ext,
174-
string input, string kind, string provenance, string model
175-
) {
176-
exists(string row |
177-
sinkModel(row) and
178-
row.splitAt(";", 0) = namespace and
179-
row.splitAt(";", 1) = type and
180-
row.splitAt(";", 2) = subtypes.toString() and
181-
subtypes = [true, false] and
182-
row.splitAt(";", 3) = name and
183-
row.splitAt(";", 4) = signature and
184-
row.splitAt(";", 5) = ext and
185-
row.splitAt(";", 6) = input and
186-
row.splitAt(";", 7) = kind
187-
) and
188-
provenance = "manual" and
189-
model = ""
190-
}
191-
192-
/**
193-
* Holds if a summary model exists for the given parameters.
194-
*
195-
* This predicate does not expand `@` to `*`s.
196-
*/
197-
predicate additionalSummaryModel(
198-
string namespace, string type, boolean subtypes, string name, string signature, string ext,
199-
string input, string output, string kind, string provenance, string model
200-
) {
201-
exists(string row |
202-
summaryModel(row) and
203-
row.splitAt(";", 0) = namespace and
204-
row.splitAt(";", 1) = type and
205-
row.splitAt(";", 2) = subtypes.toString() and
206-
subtypes = [true, false] and
207-
row.splitAt(";", 3) = name and
208-
row.splitAt(";", 4) = signature and
209-
row.splitAt(";", 5) = ext and
210-
row.splitAt(";", 6) = input and
211-
row.splitAt(";", 7) = output and
212-
row.splitAt(";", 8) = kind
213-
) and
214-
provenance = "manual" and
215-
model = ""
216-
}
217-
218111
string namespaceSegmentSeparator() { result = "::" }
219112
}
220113

@@ -250,8 +143,8 @@ predicate summaryModel(
250143
)
251144
}
252145

253-
/** Provides a query predicate to check the CSV data for validation errors. */
254-
module CsvValidation {
146+
/** Provides a query predicate to check the data for validation errors. */
147+
module ModelValidation {
255148
private string getInvalidModelInput() {
256149
exists(string pred, AccessPath input, string part |
257150
sinkModel(_, _, _, _, _, _, input, _, _, _) and pred = "sink"
@@ -294,40 +187,6 @@ module CsvValidation {
294187

295188
private module KindVal = SharedModelVal::KindValidation<KindValConfig>;
296189

297-
private string getInvalidModelSubtype() {
298-
exists(string pred, string row |
299-
sourceModel(row) and pred = "source"
300-
or
301-
sinkModel(row) and pred = "sink"
302-
or
303-
summaryModel(row) and pred = "summary"
304-
|
305-
exists(string b |
306-
b = row.splitAt(";", 2) and
307-
not b = ["true", "false"] and
308-
result = "Invalid boolean \"" + b + "\" in " + pred + " model."
309-
)
310-
)
311-
}
312-
313-
private string getInvalidModelColumnCount() {
314-
exists(string pred, string row, int expect |
315-
sourceModel(row) and expect = 8 and pred = "source"
316-
or
317-
sinkModel(row) and expect = 8 and pred = "sink"
318-
or
319-
summaryModel(row) and expect = 9 and pred = "summary"
320-
|
321-
exists(int cols |
322-
cols = 1 + max(int n | exists(row.splitAt(";", n))) and
323-
cols != expect and
324-
result =
325-
"Wrong number of columns in " + pred + " model row, expected " + expect + ", got " + cols +
326-
"."
327-
)
328-
)
329-
}
330-
331190
private string getInvalidModelSignature() {
332191
exists(string pred, string namespace, string type, string name, string signature, string ext |
333192
sourceModel(namespace, type, _, name, signature, ext, _, _, _, _) and pred = "source"
@@ -366,13 +225,12 @@ module CsvValidation {
366225
)
367226
}
368227

369-
/** Holds if some row in a CSV-based flow model appears to contain typos. */
228+
/** Holds if some row in a MaD flow model appears to contain typos. */
370229
query predicate invalidModelRow(string msg) {
371230
msg =
372231
[
373232
getInvalidModelSignature(), getInvalidModelInput(), getInvalidModelOutput(),
374-
getInvalidModelSubtype(), getInvalidModelColumnCount(), KindVal::getInvalidModelKind(),
375-
getIncorrectConstructorSummaryOutput()
233+
KindVal::getInvalidModelKind(), getIncorrectConstructorSummaryOutput()
376234
]
377235
}
378236
}
@@ -1026,7 +884,7 @@ private module Cached {
1026884
}
1027885

1028886
/**
1029-
* Holds if `node` is specified as a source with the given kind in a CSV flow
887+
* Holds if `node` is specified as a source with the given kind in a MaD flow
1030888
* model.
1031889
*/
1032890
cached
@@ -1037,7 +895,7 @@ private module Cached {
1037895
}
1038896

1039897
/**
1040-
* Holds if `node` is specified as a sink with the given kind in a CSV flow
898+
* Holds if `node` is specified as a sink with the given kind in a MaD flow
1041899
* model.
1042900
*/
1043901
cached

cpp/ql/lib/semmle/code/cpp/exprs/Call.qll

Lines changed: 27 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -585,12 +585,15 @@ class ConstructorDelegationInit extends ConstructorBaseInit, @ctordelegatinginit
585585

586586
/**
587587
* An initialization of a member variable performed as part of a
588-
* constructor's explicit initializer list or implicit actions.
588+
* constructor's initializer list or by default initialization.
589+
*
589590
* In the example below, member variable `b` is being initialized by
590-
* constructor parameter `a`:
591+
* constructor parameter `a`, and `c` is initialized by default
592+
* initialization:
591593
* ```
592594
* struct S {
593595
* int b;
596+
* int c = 3;
594597
* S(int a): b(a) {}
595598
* } s(2);
596599
* ```
@@ -616,6 +619,28 @@ class ConstructorFieldInit extends ConstructorInit, @ctorfieldinit {
616619
override predicate mayBeGloballyImpure() { this.getExpr().mayBeGloballyImpure() }
617620
}
618621

622+
/**
623+
* An initialization of a member variable performed as part of a
624+
* constructor's explicit initializer list.
625+
*/
626+
class ConstructorDirectFieldInit extends ConstructorFieldInit {
627+
ConstructorDirectFieldInit() { exists(this.getChild(0)) }
628+
629+
override string getAPrimaryQlClass() { result = "ConstructorDirectFieldInit" }
630+
}
631+
632+
/**
633+
* An initialization of a member variable performed by default
634+
* initialization.
635+
*/
636+
class ConstructorDefaultFieldInit extends ConstructorFieldInit {
637+
ConstructorDefaultFieldInit() {
638+
not exists(this.getChild(0)) and exists(this.getTarget().getInitializer())
639+
}
640+
641+
override string getAPrimaryQlClass() { result = "ConstructorDefaultFieldInit" }
642+
}
643+
619644
/**
620645
* A call to a destructor of a base class or field as part of a destructor's
621646
* compiler-generated actions.

cpp/ql/lib/semmle/code/cpp/ir/dataflow/internal/DataFlowDispatch.qll

Lines changed: 20 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -238,7 +238,12 @@ private module TrackVirtualDispatch<methodDispatchSig/1 virtualDispatch0> {
238238

239239
private import TypeTracking<Location, TtInput>::TypeTrack<qualifierSource/1>::Graph<qualifierOfVirtualCall/1>
240240

241-
private predicate edgePlus(PathNode n1, PathNode n2) = fastTC(edges/2)(n1, n2)
241+
private predicate isSource(PathNode n) { n.isSource() }
242+
243+
private predicate isSink(PathNode n) { n.isSink() }
244+
245+
private predicate edgePlus(PathNode n1, PathNode n2) =
246+
doublyBoundedFastTC(edges/2, isSource/1, isSink/1)(n1, n2)
242247

243248
/**
244249
* Gets the most specific implementation of `mf` that may be called when the
@@ -255,6 +260,15 @@ private module TrackVirtualDispatch<methodDispatchSig/1 virtualDispatch0> {
255260
)
256261
}
257262

263+
pragma[nomagic]
264+
private MemberFunction mostSpecificForSource(PathNode p1, MemberFunction mf) {
265+
p1.isSource() and
266+
exists(Class derived |
267+
qualifierSourceImpl(p1.getNode(), derived) and
268+
result = mostSpecific(mf, derived)
269+
)
270+
}
271+
258272
/**
259273
* Gets a possible pair of end-points `(p1, p2)` where:
260274
* - `p1` is a derived-to-base conversion that converts from some
@@ -264,16 +278,16 @@ private module TrackVirtualDispatch<methodDispatchSig/1 virtualDispatch0> {
264278
* - `callable` is the most specific implementation that may be called when
265279
* the qualifier has type `derived`.
266280
*/
281+
bindingset[p1, p2]
282+
pragma[inline_late]
267283
private predicate pairCand(
268284
PathNode p1, PathNode p2, DataFlowPrivate::DataFlowCallable callable,
269285
DataFlowPrivate::DataFlowCall call
270286
) {
271-
exists(Class derived, MemberFunction mf |
272-
qualifierSourceImpl(p1.getNode(), derived) and
287+
p2.isSink() and
288+
exists(MemberFunction mf |
273289
qualifierOfVirtualCallImpl(p2.getNode(), call.asCallInstruction(), mf) and
274-
p1.isSource() and
275-
p2.isSink() and
276-
callable.asSourceCallable() = mostSpecific(mf, derived)
290+
callable.asSourceCallable() = mostSpecificForSource(p1, mf)
277291
)
278292
}
279293

cpp/ql/lib/semmle/code/cpp/ir/dataflow/internal/DataFlowNodes.qll

Lines changed: 5 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -878,7 +878,11 @@ module Public {
878878

879879
/** Gets the parameter through which this value is assigned. */
880880
Parameter getParameter() {
881-
result = this.getCallInstruction().getStaticCallTarget().getParameter(this.getArgumentIndex())
881+
result =
882+
this.getCallInstruction()
883+
.getStaticCallTarget()
884+
.(Function)
885+
.getParameter(this.getArgumentIndex())
882886
}
883887
}
884888

0 commit comments

Comments
 (0)