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

Skip to content

Commit e197f52

Browse files
committed
Merge branch 'main' into python-add-global-flow-steps
2 parents 0b641c5 + d21c101 commit e197f52

208 files changed

Lines changed: 7894 additions & 1167 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.

.github/workflows/query-list.yml

Lines changed: 49 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,49 @@
1+
name: Build code scanning query list
2+
3+
on:
4+
push:
5+
branches:
6+
- main
7+
- 'rc/**'
8+
pull_request:
9+
paths:
10+
- '.github/workflows/query-list.yml'
11+
- 'misc/scripts/generate-code-scanning-query-list.py'
12+
13+
jobs:
14+
build:
15+
16+
runs-on: ubuntu-latest
17+
18+
steps:
19+
- name: Clone self (github/codeql)
20+
uses: actions/checkout@v2
21+
with:
22+
path: codeql
23+
- name: Clone github/codeql-go
24+
uses: actions/checkout@v2
25+
with:
26+
repository: 'github/codeql-go'
27+
path: codeql-go
28+
- name: Set up Python 3.8
29+
uses: actions/setup-python@v2
30+
with:
31+
python-version: 3.8
32+
- name: Download CodeQL CLI
33+
uses: dsaltares/fetch-gh-release-asset@aa37ae5c44d3c9820bc12fe675e8670ecd93bd1c
34+
with:
35+
repo: "github/codeql-cli-binaries"
36+
version: "latest"
37+
file: "codeql-linux64.zip"
38+
token: ${{ secrets.GITHUB_TOKEN }}
39+
- name: Unzip CodeQL CLI
40+
run: unzip -d codeql-cli codeql-linux64.zip
41+
- name: Build code scanning query list
42+
run: |
43+
PATH="$PATH:codeql-cli/codeql" python codeql/misc/scripts/generate-code-scanning-query-list.py > code-scanning-query-list.csv
44+
- name: Upload code scanning query list
45+
uses: actions/upload-artifact@v2
46+
with:
47+
name: code-scanning-query-list
48+
path: code-scanning-query-list.csv
49+

change-notes/1.26/analysis-cpp.md

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -24,5 +24,6 @@ The following changes in version 1.26 affect C/C++ analysis in all applications.
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`.
2626
* The models library now models some taint flows through `std::ostream`.
27+
* The models library now models some taint flows through `std::shared_ptr`, `std::unique_ptr`, `std::make_shared` and `std::make_unique`.
2728
* The `SimpleRangeAnalysis` library now supports multiplications of the form
2829
`e1 * e2` and `x *= e2` when `e1` and `e2` are unsigned or constant.

cpp/ql/src/jsf/4.06 Pre-Processing Directives/AV Rule 32.ql

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -18,6 +18,7 @@ from Include i, File f, string extension
1818
where
1919
f = i.getIncludedFile() and
2020
extension = f.getExtension().toLowerCase() and
21+
extension != "inc" and
2122
extension != "inl" and
2223
extension != "tcc" and
2324
extension != "tpp" and

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

Lines changed: 2 additions & 2 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

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/exprs/Expr.qll

Lines changed: 10 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -402,7 +402,7 @@ class Expr extends StmtParent, @expr {
402402
*/
403403
predicate hasImplicitConversion() {
404404
exists(Expr e |
405-
exprconv(underlyingElement(this), unresolveElement(e)) and e.(Cast).isImplicit()
405+
exprconv(underlyingElement(this), unresolveElement(e)) and e.(Conversion).isImplicit()
406406
)
407407
}
408408

@@ -414,7 +414,7 @@ class Expr extends StmtParent, @expr {
414414
*/
415415
predicate hasExplicitConversion() {
416416
exists(Expr e |
417-
exprconv(underlyingElement(this), unresolveElement(e)) and not e.(Cast).isImplicit()
417+
exprconv(underlyingElement(this), unresolveElement(e)) and not e.(Conversion).isImplicit()
418418
)
419419
}
420420

@@ -453,12 +453,14 @@ class Expr extends StmtParent, @expr {
453453
* cast from B to C. Only (1) and (2) would be included.
454454
*/
455455
Expr getExplicitlyConverted() {
456-
// result is this or one of its conversions
457-
result = this.getConversion*() and
458-
// result is not an implicit conversion - it's either the expr or an explicit cast
459-
(result = this or not result.(Cast).isImplicit()) and
460-
// there is no further explicit conversion after result
461-
not exists(Cast other | other = result.getConversion+() and not other.isImplicit())
456+
// For performance, we avoid a full transitive closure over `getConversion`.
457+
// Since there can be several implicit conversions before and after an
458+
// explicit conversion, use `getImplicitlyConverted` to step over them
459+
// cheaply. Then, if there is an explicit conversion following the implict
460+
// conversion sequence, recurse to handle multiple explicit conversions.
461+
if this.getImplicitlyConverted().hasExplicitConversion()
462+
then result = this.getImplicitlyConverted().getConversion().getExplicitlyConverted()
463+
else result = this
462464
}
463465

464466
/**

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

Lines changed: 73 additions & 19 deletions
Original file line numberDiff line numberDiff line change
@@ -144,8 +144,23 @@ OutNode getAnOutNode(DataFlowCall call, ReturnKind kind) {
144144
*/
145145
predicate jumpStep(Node n1, Node n2) { none() }
146146

147+
/**
148+
* Gets a field corresponding to the bit range `[startBit..endBit)` of class `c`, if any.
149+
*/
150+
private Field getAField(Class c, int startBit, int endBit) {
151+
result.getDeclaringType() = c and
152+
startBit = 8 * result.getByteOffset() and
153+
endBit = 8 * result.getType().getSize() + startBit
154+
or
155+
exists(Field f, Class cInner |
156+
f = c.getAField() and
157+
cInner = f.getUnderlyingType() and
158+
result = getAField(cInner, startBit - 8 * f.getByteOffset(), endBit - 8 * f.getByteOffset())
159+
)
160+
}
161+
147162
private newtype TContent =
148-
TFieldContent(Field f) or
163+
TFieldContent(Class c, int startBit, int endBit) { exists(getAField(c, startBit, endBit)) } or
149164
TCollectionContent() or
150165
TArrayContent()
151166

@@ -163,17 +178,18 @@ class Content extends TContent {
163178
}
164179

165180
private class FieldContent extends Content, TFieldContent {
166-
Field f;
181+
Class c;
182+
int startBit;
183+
int endBit;
167184

168-
FieldContent() { this = TFieldContent(f) }
185+
FieldContent() { this = TFieldContent(c, startBit, endBit) }
169186

170-
Field getField() { result = f }
187+
// Ensure that there's just 1 result for `toString`.
188+
override string toString() { result = min(Field f | f = getAField() | f.toString()) }
171189

172-
override string toString() { result = f.toString() }
190+
predicate hasOffset(Class cl, int start, int end) { cl = c and start = startBit and end = endBit }
173191

174-
override predicate hasLocationInfo(string path, int sl, int sc, int el, int ec) {
175-
f.getLocation().hasLocationInfo(path, sl, sc, el, ec)
176-
}
192+
Field getAField() { result = getAField(c, startBit, endBit) }
177193
}
178194

179195
private class CollectionContent extends Content, TCollectionContent {
@@ -185,20 +201,38 @@ private class ArrayContent extends Content, TArrayContent {
185201
}
186202

187203
private predicate storeStepNoChi(Node node1, Content f, PostUpdateNode node2) {
188-
exists(FieldAddressInstruction fa, StoreInstruction store |
204+
exists(StoreInstruction store, Class c |
189205
store = node2.asInstruction() and
190-
store.getDestinationAddress() = fa and
191206
store.getSourceValue() = node1.asInstruction() and
192-
f.(FieldContent).getField() = fa.getField()
207+
getWrittenField(store, f.(FieldContent).getAField(), c) and
208+
f.(FieldContent).hasOffset(c, _, _)
209+
)
210+
}
211+
212+
pragma[noinline]
213+
private predicate getWrittenField(StoreInstruction store, Field f, Class c) {
214+
exists(FieldAddressInstruction fa |
215+
fa = store.getDestinationAddress() and
216+
f = fa.getField() and
217+
c = f.getDeclaringType()
193218
)
194219
}
195220

196221
private predicate storeStepChi(Node node1, Content f, PostUpdateNode node2) {
197-
exists(FieldAddressInstruction fa, StoreInstruction store |
222+
exists(StoreInstruction store, ChiInstruction chi |
198223
node1.asInstruction() = store and
199-
store.getDestinationAddress() = fa and
200-
node2.asInstruction().(ChiInstruction).getPartial() = store and
201-
f.(FieldContent).getField() = fa.getField()
224+
node2.asInstruction() = chi and
225+
chi.getPartial() = store and
226+
exists(Class c |
227+
c = chi.getResultType() and
228+
exists(int startBit, int endBit |
229+
chi.getUpdatedInterval(startBit, endBit) and
230+
f.(FieldContent).hasOffset(c, startBit, endBit)
231+
)
232+
or
233+
getWrittenField(store, f.(FieldContent).getAField(), c) and
234+
f.(FieldContent).hasOffset(c, _, _)
235+
)
202236
)
203237
}
204238

@@ -212,17 +246,37 @@ predicate storeStep(Node node1, Content f, PostUpdateNode node2) {
212246
storeStepChi(node1, f, node2)
213247
}
214248

249+
bindingset[result, i]
250+
private int unbindInt(int i) { i <= result and i >= result }
251+
252+
pragma[noinline]
253+
private predicate getLoadedField(LoadInstruction load, Field f, Class c) {
254+
exists(FieldAddressInstruction fa |
255+
fa = load.getSourceAddress() and
256+
f = fa.getField() and
257+
c = f.getDeclaringType()
258+
)
259+
}
260+
215261
/**
216262
* Holds if data can flow from `node1` to `node2` via a read of `f`.
217263
* Thus, `node1` references an object with a field `f` whose value ends up in
218264
* `node2`.
219265
*/
220266
predicate readStep(Node node1, Content f, Node node2) {
221-
exists(FieldAddressInstruction fa, LoadInstruction load |
222-
load.getSourceAddress() = fa and
267+
exists(LoadInstruction load |
268+
node2.asInstruction() = load and
223269
node1.asInstruction() = load.getSourceValueOperand().getAnyDef() and
224-
fa.getField() = f.(FieldContent).getField() and
225-
load = node2.asInstruction()
270+
exists(Class c |
271+
c = load.getSourceValueOperand().getAnyDef().getResultType() and
272+
exists(int startBit, int endBit |
273+
load.getSourceValueOperand().getUsedInterval(unbindInt(startBit), unbindInt(endBit)) and
274+
f.(FieldContent).hasOffset(c, startBit, endBit)
275+
)
276+
or
277+
getLoadedField(load, f.(FieldContent).getAField(), c) and
278+
f.(FieldContent).hasOffset(c, _, _)
279+
)
226280
)
227281
}
228282

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

Lines changed: 20 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -335,12 +335,14 @@ abstract private class PartialDefinitionNode extends PostUpdateNode {
335335

336336
private class ExplicitFieldStoreQualifierNode extends PartialDefinitionNode {
337337
override ChiInstruction instr;
338-
FieldAddressInstruction field;
338+
StoreInstruction store;
339339

340340
ExplicitFieldStoreQualifierNode() {
341341
not instr.isResultConflated() and
342-
exists(StoreInstruction store |
343-
instr.getPartial() = store and field = store.getDestinationAddress()
342+
instr.getPartial() = store and
343+
(
344+
instr.getUpdatedInterval(_, _) or
345+
store.getDestinationAddress() instanceof FieldAddressInstruction
344346
)
345347
}
346348

@@ -351,7 +353,12 @@ private class ExplicitFieldStoreQualifierNode extends PartialDefinitionNode {
351353
override Node getPreUpdateNode() { result.asOperand() = instr.getTotalOperand() }
352354

353355
override Expr getDefinedExpr() {
354-
result = field.getObjectAddress().getUnconvertedResultExpression()
356+
result =
357+
store
358+
.getDestinationAddress()
359+
.(FieldAddressInstruction)
360+
.getObjectAddress()
361+
.getUnconvertedResultExpression()
355362
}
356363
}
357364

@@ -363,17 +370,22 @@ private class ExplicitFieldStoreQualifierNode extends PartialDefinitionNode {
363370
*/
364371
private class ExplicitSingleFieldStoreQualifierNode extends PartialDefinitionNode {
365372
override StoreInstruction instr;
366-
FieldAddressInstruction field;
367373

368374
ExplicitSingleFieldStoreQualifierNode() {
369-
field = instr.getDestinationAddress() and
370-
not exists(ChiInstruction chi | chi.getPartial() = instr)
375+
not exists(ChiInstruction chi | chi.getPartial() = instr) and
376+
// Without this condition any store would create a `PostUpdateNode`.
377+
instr.getDestinationAddress() instanceof FieldAddressInstruction
371378
}
372379

373380
override Node getPreUpdateNode() { none() }
374381

375382
override Expr getDefinedExpr() {
376-
result = field.getObjectAddress().getUnconvertedResultExpression()
383+
result =
384+
instr
385+
.getDestinationAddress()
386+
.(FieldAddressInstruction)
387+
.getObjectAddress()
388+
.getUnconvertedResultExpression()
377389
}
378390
}
379391

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

0 commit comments

Comments
 (0)