Skip to content

Commit fe7e848

Browse files
authored
Merge branch 'main' into suspicioussizeof2
2 parents 0714ca8 + e095294 commit fe7e848

File tree

66 files changed

+543
-249
lines changed

Some content is hidden

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

66 files changed

+543
-249
lines changed

actions/ql/src/Security/CWE-275/MissingActionsPermissions.ql

Lines changed: 15 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -26,10 +26,23 @@ string permissionsForJob(Job job) {
2626
"{" + concat(string permission | permission = jobNeedsPermission(job) | permission, ", ") + "}"
2727
}
2828

29+
predicate jobHasPermissions(Job job) {
30+
exists(job.getPermissions())
31+
or
32+
exists(job.getEnclosingWorkflow().getPermissions())
33+
or
34+
// The workflow is reusable and cannot be triggered in any other way; check callers
35+
exists(ReusableWorkflow r | r = job.getEnclosingWorkflow() |
36+
not exists(Event e | e = r.getOn().getAnEvent() | e.getName() != "workflow_call") and
37+
forall(Job caller | caller = job.getEnclosingWorkflow().(ReusableWorkflow).getACaller() |
38+
jobHasPermissions(caller)
39+
)
40+
)
41+
}
42+
2943
from Job job, string permissions
3044
where
31-
not exists(job.getPermissions()) and
32-
not exists(job.getEnclosingWorkflow().getPermissions()) and
45+
not jobHasPermissions(job) and
3346
// exists a trigger event that is not a workflow_call
3447
exists(Event e |
3548
e = job.getATriggerEvent() and
Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,4 @@
1+
---
2+
category: minorAnalysis
3+
---
4+
* The query `actions/missing-workflow-permissions` no longer produces false positive results on reusable workflows where all callers set permissions.
Lines changed: 9 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,9 @@
1+
on:
2+
workflow_call:
3+
4+
jobs:
5+
build:
6+
name: Build and test
7+
runs-on: ubuntu-latest
8+
steps:
9+
- uses: actions/deploy-pages
Lines changed: 11 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,11 @@
1+
on:
2+
workflow_dispatch:
3+
4+
permissions:
5+
contents: read
6+
id-token: write
7+
pages: write
8+
9+
jobs:
10+
call-workflow:
11+
uses: ./.github/workflows/perms11.yml

cpp/ql/integration-tests/query-suite/cpp-code-scanning.qls.expected

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -7,10 +7,12 @@ ql/cpp/ql/src/Diagnostics/ExtractedFiles.ql
77
ql/cpp/ql/src/Diagnostics/ExtractionWarnings.ql
88
ql/cpp/ql/src/Diagnostics/FailedExtractorInvocations.ql
99
ql/cpp/ql/src/Likely Bugs/Arithmetic/BadAdditionOverflowCheck.ql
10+
ql/cpp/ql/src/Likely Bugs/Arithmetic/IntMultToLong.ql
1011
ql/cpp/ql/src/Likely Bugs/Arithmetic/SignedOverflowCheck.ql
1112
ql/cpp/ql/src/Likely Bugs/Conversion/CastArrayPointerArithmetic.ql
1213
ql/cpp/ql/src/Likely Bugs/Format/SnprintfOverflow.ql
1314
ql/cpp/ql/src/Likely Bugs/Format/WrongNumberOfFormatArguments.ql
15+
ql/cpp/ql/src/Likely Bugs/Format/WrongTypeFormatArguments.ql
1416
ql/cpp/ql/src/Likely Bugs/Memory Management/AllocaInLoop.ql
1517
ql/cpp/ql/src/Likely Bugs/Memory Management/PointerOverflow.ql
1618
ql/cpp/ql/src/Likely Bugs/Memory Management/ReturnStackAllocatedMemory.ql
@@ -28,6 +30,7 @@ ql/cpp/ql/src/Security/CWE/CWE-120/VeryLikelyOverrunWrite.ql
2830
ql/cpp/ql/src/Security/CWE/CWE-131/NoSpaceForZeroTerminator.ql
2931
ql/cpp/ql/src/Security/CWE/CWE-134/UncontrolledFormatString.ql
3032
ql/cpp/ql/src/Security/CWE/CWE-190/ArithmeticUncontrolled.ql
33+
ql/cpp/ql/src/Security/CWE/CWE-190/ComparisonWithWiderType.ql
3134
ql/cpp/ql/src/Security/CWE/CWE-191/UnsignedDifferenceExpressionComparedZero.ql
3235
ql/cpp/ql/src/Security/CWE/CWE-253/HResultBooleanConversion.ql
3336
ql/cpp/ql/src/Security/CWE/CWE-311/CleartextFileWrite.ql

cpp/ql/lib/semmle/code/cpp/commons/Printf.qll

Lines changed: 21 additions & 18 deletions
Original file line numberDiff line numberDiff line change
@@ -459,6 +459,13 @@ class FormatLiteral extends Literal instanceof StringLiteral {
459459
*/
460460
int getConvSpecOffset(int n) { result = this.getFormat().indexOf("%", n, 0) }
461461

462+
/**
463+
* Gets the nth conversion specifier string.
464+
*/
465+
private string getConvSpecString(int n) {
466+
n >= 0 and result = "%" + this.getFormat().splitAt("%", n + 1)
467+
}
468+
462469
/*
463470
* Each of these predicates gets a regular expressions to match each individual
464471
* parts of a conversion specifier.
@@ -524,22 +531,20 @@ class FormatLiteral extends Literal instanceof StringLiteral {
524531
int n, string spec, string params, string flags, string width, string prec, string len,
525532
string conv
526533
) {
527-
exists(int offset, string fmt, string rst, string regexp |
528-
offset = this.getConvSpecOffset(n) and
529-
fmt = this.getFormat() and
530-
rst = fmt.substring(offset, fmt.length()) and
534+
exists(string convSpec, string regexp |
535+
convSpec = this.getConvSpecString(n) and
531536
regexp = this.getConvSpecRegexp() and
532537
(
533-
spec = rst.regexpCapture(regexp, 1) and
534-
params = rst.regexpCapture(regexp, 2) and
535-
flags = rst.regexpCapture(regexp, 3) and
536-
width = rst.regexpCapture(regexp, 4) and
537-
prec = rst.regexpCapture(regexp, 5) and
538-
len = rst.regexpCapture(regexp, 6) and
539-
conv = rst.regexpCapture(regexp, 7)
538+
spec = convSpec.regexpCapture(regexp, 1) and
539+
params = convSpec.regexpCapture(regexp, 2) and
540+
flags = convSpec.regexpCapture(regexp, 3) and
541+
width = convSpec.regexpCapture(regexp, 4) and
542+
prec = convSpec.regexpCapture(regexp, 5) and
543+
len = convSpec.regexpCapture(regexp, 6) and
544+
conv = convSpec.regexpCapture(regexp, 7)
540545
or
541-
spec = rst.regexpCapture(regexp, 1) and
542-
not exists(rst.regexpCapture(regexp, 2)) and
546+
spec = convSpec.regexpCapture(regexp, 1) and
547+
not exists(convSpec.regexpCapture(regexp, 2)) and
543548
params = "" and
544549
flags = "" and
545550
width = "" and
@@ -554,12 +559,10 @@ class FormatLiteral extends Literal instanceof StringLiteral {
554559
* Gets the nth conversion specifier (including the initial `%`).
555560
*/
556561
string getConvSpec(int n) {
557-
exists(int offset, string fmt, string rst, string regexp |
558-
offset = this.getConvSpecOffset(n) and
559-
fmt = this.getFormat() and
560-
rst = fmt.substring(offset, fmt.length()) and
562+
exists(string convSpec, string regexp |
563+
convSpec = this.getConvSpecString(n) and
561564
regexp = this.getConvSpecRegexp() and
562-
result = rst.regexpCapture(regexp, 1)
565+
result = convSpec.regexpCapture(regexp, 1)
563566
)
564567
}
565568

cpp/ql/lib/semmle/code/cpp/commons/Scanf.qll

Lines changed: 13 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -194,6 +194,13 @@ class ScanfFormatLiteral extends Expr {
194194
)
195195
}
196196

197+
/**
198+
* Gets the nth conversion specifier string.
199+
*/
200+
private string getConvSpecString(int n) {
201+
n >= 0 and result = "%" + this.getFormat().splitAt("%", n + 1)
202+
}
203+
197204
/**
198205
* Gets the regular expression to match each individual part of a conversion specifier.
199206
*/
@@ -227,16 +234,14 @@ class ScanfFormatLiteral extends Expr {
227234
* specifier.
228235
*/
229236
predicate parseConvSpec(int n, string spec, string width, string len, string conv) {
230-
exists(int offset, string fmt, string rst, string regexp |
231-
offset = this.getConvSpecOffset(n) and
232-
fmt = this.getFormat() and
233-
rst = fmt.substring(offset, fmt.length()) and
237+
exists(string convSpec, string regexp |
238+
convSpec = this.getConvSpecString(n) and
234239
regexp = this.getConvSpecRegexp() and
235240
(
236-
spec = rst.regexpCapture(regexp, 1) and
237-
width = rst.regexpCapture(regexp, 2) and
238-
len = rst.regexpCapture(regexp, 3) and
239-
conv = rst.regexpCapture(regexp, 4)
241+
spec = convSpec.regexpCapture(regexp, 1) and
242+
width = convSpec.regexpCapture(regexp, 2) and
243+
len = convSpec.regexpCapture(regexp, 3) and
244+
conv = convSpec.regexpCapture(regexp, 4)
240245
)
241246
)
242247
}

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

Lines changed: 26 additions & 10 deletions
Original file line numberDiff line numberDiff line change
@@ -6,11 +6,15 @@
66
*
77
* The extensible relations have the following columns:
88
* - Sources:
9-
* `namespace; type; subtypes; name; signature; ext; output; kind`
9+
* `namespace; type; subtypes; name; signature; ext; output; kind; provenance`
1010
* - Sinks:
11-
* `namespace; type; subtypes; name; signature; ext; input; kind`
11+
* `namespace; type; subtypes; name; signature; ext; input; kind; provenance`
1212
* - Summaries:
13-
* `namespace; type; subtypes; name; signature; ext; input; output; kind`
13+
* `namespace; type; subtypes; name; signature; ext; input; output; kind; provenance`
14+
* - Barriers:
15+
* `namespace; type; subtypes; name; signature; ext; output; kind; provenance`
16+
* - BarrierGuards:
17+
* `namespace; type; subtypes; name; signature; ext; input; acceptingValue; kind; provenance`
1418
*
1519
* The interpretation of a row is similar to API-graphs with a left-to-right
1620
* reading.
@@ -87,11 +91,23 @@
8791
* value, and
8892
* - flow from the _second_ indirection of the 0th argument to the first
8993
* indirection of the return value, etc.
90-
* 8. The `kind` column is a tag that can be referenced from QL to determine to
94+
* 8. The `acceptingValue` column of barrier guard models specifies the condition
95+
* under which the guard blocks flow. It can be one of "true" or "false". In
96+
* the future "no-exception", "not-zero", "null", "not-null" may be supported.
97+
* 9. The `kind` column is a tag that can be referenced from QL to determine to
9198
* which classes the interpreted elements should be added. For example, for
9299
* sources "remote" indicates a default remote flow source, and for summaries
93100
* "taint" indicates a default additional taint step and "value" indicates a
94101
* globally applicable value-preserving step.
102+
* 10. The `provenance` column is a tag to indicate the origin and verification of a model.
103+
* The format is {origin}-{verification} or just "manual" where the origin describes
104+
* the origin of the model and verification describes how the model has been verified.
105+
* Some examples are:
106+
* - "df-generated": The model has been generated by the model generator tool.
107+
* - "df-manual": The model has been generated by the model generator and verified by a human.
108+
* - "manual": The model has been written by hand.
109+
* This information is used in a heuristic for dataflow analysis to determine, if a
110+
* model or source code should be used for determining flow.
95111
*/
96112

97113
import cpp
@@ -931,13 +947,13 @@ private module Cached {
931947

932948
private predicate barrierGuardChecks(IRGuardCondition g, Expr e, boolean gv, TKindModelPair kmp) {
933949
exists(
934-
SourceSinkInterpretationInput::InterpretNode n, Public::AcceptingValue acceptingvalue,
950+
SourceSinkInterpretationInput::InterpretNode n, Public::AcceptingValue acceptingValue,
935951
string kind, string model
936952
|
937-
isBarrierGuardNode(n, acceptingvalue, kind, model) and
953+
isBarrierGuardNode(n, acceptingValue, kind, model) and
938954
n.asNode().asExpr() = e and
939955
kmp = TMkPair(kind, model) and
940-
gv = convertAcceptingValue(acceptingvalue).asBooleanValue() and
956+
gv = convertAcceptingValue(acceptingValue).asBooleanValue() and
941957
n.asNode().(Private::ArgumentNode).getCall().asCallInstruction() = g
942958
)
943959
}
@@ -954,14 +970,14 @@ private module Cached {
954970
) {
955971
exists(
956972
SourceSinkInterpretationInput::InterpretNode interpretNode,
957-
Public::AcceptingValue acceptingvalue, string kind, string model, int indirectionIndex,
973+
Public::AcceptingValue acceptingValue, string kind, string model, int indirectionIndex,
958974
Private::ArgumentNode arg
959975
|
960-
isBarrierGuardNode(interpretNode, acceptingvalue, kind, model) and
976+
isBarrierGuardNode(interpretNode, acceptingValue, kind, model) and
961977
arg = interpretNode.asNode() and
962978
arg.asIndirectExpr(indirectionIndex) = e and
963979
kmp = MkKindModelPairIntPair(TMkPair(kind, model), indirectionIndex) and
964-
gv = convertAcceptingValue(acceptingvalue).asBooleanValue() and
980+
gv = convertAcceptingValue(acceptingValue).asBooleanValue() and
965981
arg.getCall().asCallInstruction() = g
966982
)
967983
}

cpp/ql/lib/semmle/code/cpp/dataflow/internal/ExternalFlowExtensions.qll

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -33,7 +33,7 @@ extensible predicate barrierModel(
3333
*/
3434
extensible predicate barrierGuardModel(
3535
string namespace, string type, boolean subtypes, string name, string signature, string ext,
36-
string input, string acceptingvalue, string kind, string provenance, QlBuiltins::ExtensionId madId
36+
string input, string acceptingValue, string kind, string provenance, QlBuiltins::ExtensionId madId
3737
);
3838

3939
/**

cpp/ql/lib/semmle/code/cpp/dataflow/internal/FlowSummaryImpl.qll

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -162,13 +162,13 @@ module SourceSinkInterpretationInput implements
162162
}
163163

164164
predicate barrierGuardElement(
165-
Element e, string input, Public::AcceptingValue acceptingvalue, string kind,
165+
Element e, string input, Public::AcceptingValue acceptingValue, string kind,
166166
Public::Provenance provenance, string model
167167
) {
168168
exists(
169169
string package, string type, boolean subtypes, string name, string signature, string ext
170170
|
171-
barrierGuardModel(package, type, subtypes, name, signature, ext, input, acceptingvalue, kind,
171+
barrierGuardModel(package, type, subtypes, name, signature, ext, input, acceptingValue, kind,
172172
provenance, model) and
173173
e = interpretElement(package, type, subtypes, name, signature, ext)
174174
)

0 commit comments

Comments
 (0)