Skip to content

Commit fdc2be8

Browse files
authored
Merge branch 'main' into aibaars/limit-diagnostics
2 parents c960af8 + b2f7b89 commit fdc2be8

File tree

1,657 files changed

+129807
-25289
lines changed

Some content is hidden

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

1,657 files changed

+129807
-25289
lines changed

.github/workflows/build-ripunzip.yml

Lines changed: 3 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -6,18 +6,18 @@ on:
66
ripunzip-version:
77
description: "what reference to checktout from google/runzip"
88
required: false
9-
default: v1.2.1
9+
default: v2.0.2
1010
openssl-version:
1111
description: "what reference to checkout from openssl/openssl for Linux"
1212
required: false
13-
default: openssl-3.3.0
13+
default: openssl-3.5.0
1414

1515
jobs:
1616
build:
1717
strategy:
1818
fail-fast: false
1919
matrix:
20-
os: [ubuntu-22.04, macos-13, windows-2019]
20+
os: [ubuntu-22.04, macos-13, windows-2022]
2121
runs-on: ${{ matrix.os }}
2222
steps:
2323
- uses: actions/checkout@v4

.github/workflows/csharp-qltest.yml

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -36,7 +36,7 @@ jobs:
3636
unit-tests:
3737
strategy:
3838
matrix:
39-
os: [ubuntu-latest, windows-2019]
39+
os: [ubuntu-latest, windows-latest]
4040
runs-on: ${{ matrix.os }}
4141
steps:
4242
- uses: actions/checkout@v4

.github/workflows/codegen.yml renamed to .github/workflows/python-tooling.yml

Lines changed: 6 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -1,10 +1,11 @@
1-
name: Codegen
1+
name: Python tooling
22

33
on:
44
pull_request:
55
paths:
66
- "misc/bazel/**"
77
- "misc/codegen/**"
8+
- "misc/scripts/models-as-data/bulk_generate_mad.py"
89
- "*.bazel*"
910
- .github/workflows/codegen.yml
1011
- .pre-commit-config.yaml
@@ -17,17 +18,17 @@ permissions:
1718
contents: read
1819

1920
jobs:
20-
codegen:
21+
check-python-tooling:
2122
runs-on: ubuntu-latest
2223
steps:
2324
- uses: actions/checkout@v4
24-
- uses: actions/setup-python@v4
25+
- uses: actions/setup-python@v5
2526
with:
26-
python-version-file: 'misc/codegen/.python-version'
27+
python-version: '3.12'
2728
- uses: pre-commit/action@646c83fcd040023954eafda54b4db0192ce70507
2829
name: Check that python code is properly formatted
2930
with:
30-
extra_args: autopep8 --all-files
31+
extra_args: black --all-files
3132
- name: Run codegen tests
3233
shell: bash
3334
run: |

.github/workflows/validate-change-notes.yml

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -31,4 +31,4 @@ jobs:
3131
- name: Fail if there are any errors with existing change notes
3232

3333
run: |
34-
codeql pack release --groups cpp,csharp,java,javascript,python,ruby,-examples,-test,-experimental
34+
codeql pack release --groups actions,cpp,csharp,go,java,javascript,python,ruby,shared,swift -examples,-test,-experimental

.pre-commit-config.yaml

Lines changed: 6 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,7 @@
11
# See https://pre-commit.com for more information
22
# See https://pre-commit.com/hooks.html for more hooks
3+
default_language_version:
4+
python: python3.12
35
repos:
46
- repo: https://github.com/pre-commit/pre-commit-hooks
57
rev: v3.2.0
@@ -14,11 +16,11 @@ repos:
1416
hooks:
1517
- id: clang-format
1618

17-
- repo: https://github.com/pre-commit/mirrors-autopep8
18-
rev: v2.0.4
19+
- repo: https://github.com/psf/black
20+
rev: 25.1.0
1921
hooks:
20-
- id: autopep8
21-
files: ^misc/codegen/.*\.py
22+
- id: black
23+
files: ^(misc/codegen/.*|misc/scripts/models-as-data/bulk_generate_mad)\.py$
2224

2325
- repo: local
2426
hooks:

CODEOWNERS

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -16,7 +16,7 @@
1616
/java/ql/test-kotlin2/ @github/codeql-kotlin
1717

1818
# Experimental CodeQL cryptography
19-
**/experimental/quantum/ @github/ps-codeql
19+
**/experimental/**/quantum/ @github/ps-codeql
2020
/shared/quantum/ @github/ps-codeql
2121

2222
# CodeQL tools and associated docs

MODULE.bazel

Lines changed: 10 additions & 10 deletions
Original file line numberDiff line numberDiff line change
@@ -239,24 +239,24 @@ go_deps = use_extension("@gazelle//:extensions.bzl", "go_deps")
239239
go_deps.from_file(go_mod = "//go/extractor:go.mod")
240240
use_repo(go_deps, "org_golang_x_mod", "org_golang_x_tools")
241241

242-
lfs_files = use_repo_rule("//misc/bazel:lfs.bzl", "lfs_files")
242+
lfs_archive = use_repo_rule("//misc/bazel:lfs.bzl", "lfs_archive")
243243

244-
lfs_files(
244+
lfs_archive(
245245
name = "ripunzip-linux",
246-
srcs = ["//misc/ripunzip:ripunzip-linux"],
247-
executable = True,
246+
src = "//misc/ripunzip:ripunzip-Linux.zip",
247+
build_file = "//misc/ripunzip:BUILD.ripunzip.bazel",
248248
)
249249

250-
lfs_files(
250+
lfs_archive(
251251
name = "ripunzip-windows",
252-
srcs = ["//misc/ripunzip:ripunzip-windows.exe"],
253-
executable = True,
252+
src = "//misc/ripunzip:ripunzip-Windows.zip",
253+
build_file = "//misc/ripunzip:BUILD.ripunzip.bazel",
254254
)
255255

256-
lfs_files(
256+
lfs_archive(
257257
name = "ripunzip-macos",
258-
srcs = ["//misc/ripunzip:ripunzip-macos"],
259-
executable = True,
258+
src = "//misc/ripunzip:ripunzip-macOS.zip",
259+
build_file = "//misc/ripunzip:BUILD.ripunzip.bazel",
260260
)
261261

262262
register_toolchains(

actions/ql/lib/CHANGELOG.md

Lines changed: 8 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1,3 +1,11 @@
1+
## 0.4.11
2+
3+
No user-facing changes.
4+
5+
## 0.4.10
6+
7+
No user-facing changes.
8+
19
## 0.4.9
210

311
No user-facing changes.
Lines changed: 6 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,6 @@
1+
---
2+
category: minorAnalysis
3+
---
4+
* Fixed performance issues in the parsing of Bash scripts in workflow files,
5+
which led to out-of-disk errors when analysing certain workflow files with
6+
complex interpolations of shell commands or quoted strings.
Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,3 @@
1+
## 0.4.10
2+
3+
No user-facing changes.
Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,3 @@
1+
## 0.4.11
2+
3+
No user-facing changes.
Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,2 +1,2 @@
11
---
2-
lastReleaseVersion: 0.4.9
2+
lastReleaseVersion: 0.4.11

actions/ql/lib/codeql/actions/Ast.qll

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -50,8 +50,8 @@ class Expression extends AstNode instanceof ExpressionImpl {
5050
string getNormalizedExpression() { result = normalizeExpr(expression) }
5151
}
5252

53-
/** A common class for `env` in workflow, job or step. */
54-
abstract class Env extends AstNode instanceof EnvImpl {
53+
/** An `env` in workflow, job or step. */
54+
class Env extends AstNode instanceof EnvImpl {
5555
/** Gets an environment variable value given its name. */
5656
ScalarValueImpl getEnvVarValue(string name) { result = super.getEnvVarValue(name) }
5757

actions/ql/lib/codeql/actions/Bash.qll

Lines changed: 98 additions & 44 deletions
Original file line numberDiff line numberDiff line change
@@ -8,35 +8,64 @@ class BashShellScript extends ShellScript {
88
)
99
}
1010

11-
private string lineProducer(int i) {
12-
result = this.getRawScript().regexpReplaceAll("\\\\\\s*\n", "").splitAt("\n", i)
13-
}
14-
15-
private predicate cmdSubstitutionReplacement(string cmdSubs, string id, int k) {
16-
exists(string line | line = this.lineProducer(k) |
17-
exists(int i, int j |
18-
cmdSubs =
19-
// $() cmd substitution
20-
line.regexpFind("\\$\\((?:[^()]+|\\((?:[^()]+|\\([^()]*\\))*\\))*\\)", i, j)
21-
.regexpReplaceAll("^\\$\\(", "")
22-
.regexpReplaceAll("\\)$", "") and
23-
id = "cmdsubs:" + k + ":" + i + ":" + j
24-
)
25-
or
26-
exists(int i, int j |
27-
// `...` cmd substitution
28-
cmdSubs =
29-
line.regexpFind("\\`[^\\`]+\\`", i, j)
30-
.regexpReplaceAll("^\\`", "")
31-
.regexpReplaceAll("\\`$", "") and
32-
id = "cmd:" + k + ":" + i + ":" + j
33-
)
11+
/**
12+
* Gets the line at 0-based index `lineIndex` within this shell script,
13+
* assuming newlines as separators.
14+
*/
15+
private string lineProducer(int lineIndex) {
16+
result = this.getRawScript().regexpReplaceAll("\\\\\\s*\n", "").splitAt("\n", lineIndex)
17+
}
18+
19+
private predicate cmdSubstitutionReplacement(string command, string id, int lineIndex) {
20+
this.commandInSubstitution(lineIndex, command, id)
21+
or
22+
this.commandInBackticks(lineIndex, command, id)
23+
}
24+
25+
/**
26+
* Holds if there is a command substitution `$(command)` in
27+
* the line at `lineIndex` in the shell script,
28+
* and `id` is a unique identifier for this command.
29+
*/
30+
private predicate commandInSubstitution(int lineIndex, string command, string id) {
31+
exists(int occurrenceIndex, int occurrenceOffset |
32+
command =
33+
// Look for the command inside a $(...) command substitution
34+
this.lineProducer(lineIndex)
35+
.regexpFind("\\$\\((?:[^()]+|\\((?:[^()]+|\\([^()]*\\))*\\))*\\)", occurrenceIndex,
36+
occurrenceOffset)
37+
// trim starting $( - TODO do this in first regex
38+
.regexpReplaceAll("^\\$\\(", "")
39+
// trim ending ) - TODO do this in first regex
40+
.regexpReplaceAll("\\)$", "") and
41+
id = "cmdsubs:" + lineIndex + ":" + occurrenceIndex + ":" + occurrenceOffset
3442
)
3543
}
3644

37-
private predicate rankedCmdSubstitutionReplacements(int i, string old, string new) {
38-
old = rank[i](string old2 | this.cmdSubstitutionReplacement(old2, _, _) | old2) and
39-
this.cmdSubstitutionReplacement(old, new, _)
45+
/**
46+
* Holds if `command` is a command in backticks `` `...` `` in
47+
* the line at `lineIndex` in the shell script,
48+
* and `id` is a unique identifier for this command.
49+
*/
50+
private predicate commandInBackticks(int lineIndex, string command, string id) {
51+
exists(int occurrenceIndex, int occurrenceOffset |
52+
command =
53+
this.lineProducer(lineIndex)
54+
.regexpFind("\\`[^\\`]+\\`", occurrenceIndex, occurrenceOffset)
55+
// trim leading backtick - TODO do this in first regex
56+
.regexpReplaceAll("^\\`", "")
57+
// trim trailing backtick - TODO do this in first regex
58+
.regexpReplaceAll("\\`$", "") and
59+
id = "cmd:" + lineIndex + ":" + occurrenceIndex + ":" + occurrenceOffset
60+
)
61+
}
62+
63+
private predicate rankedCmdSubstitutionReplacements(int i, string command, string commandId) {
64+
// rank commands by their unique IDs
65+
commandId = rank[i](string c, string id | this.cmdSubstitutionReplacement(c, id, _) | id) and
66+
// since we cannot output (command, ID) tuples from the rank operation,
67+
// we need to work out the specific command associated with the resulting ID
68+
this.cmdSubstitutionReplacement(command, commandId, _)
4069
}
4170

4271
private predicate doReplaceCmdSubstitutions(int line, int round, string old, string new) {
@@ -64,31 +93,56 @@ class BashShellScript extends ShellScript {
6493
this.cmdSubstitutionReplacement(result, _, i)
6594
}
6695

96+
/**
97+
* Holds if `quotedStr` is a string in double quotes in
98+
* the line at `lineIndex` in the shell script,
99+
* and `id` is a unique identifier for this quoted string.
100+
*/
101+
private predicate doubleQuotedString(int lineIndex, string quotedStr, string id) {
102+
exists(int occurrenceIndex, int occurrenceOffset |
103+
// double quoted string
104+
quotedStr =
105+
this.cmdSubstitutedLineProducer(lineIndex)
106+
.regexpFind("\"((?:[^\"\\\\]|\\\\.)*)\"", occurrenceIndex, occurrenceOffset) and
107+
id =
108+
"qstr:" + lineIndex + ":" + occurrenceIndex + ":" + occurrenceOffset + ":" +
109+
quotedStr.length() + ":" + quotedStr.regexpReplaceAll("[^a-zA-Z0-9]", "")
110+
)
111+
}
112+
113+
/**
114+
* Holds if `quotedStr` is a string in single quotes in
115+
* the line at `lineIndex` in the shell script,
116+
* and `id` is a unique identifier for this quoted string.
117+
*/
118+
private predicate singleQuotedString(int lineIndex, string quotedStr, string id) {
119+
exists(int occurrenceIndex, int occurrenceOffset |
120+
// single quoted string
121+
quotedStr =
122+
this.cmdSubstitutedLineProducer(lineIndex)
123+
.regexpFind("'((?:\\\\.|[^'\\\\])*)'", occurrenceIndex, occurrenceOffset) and
124+
id =
125+
"qstr:" + lineIndex + ":" + occurrenceIndex + ":" + occurrenceOffset + ":" +
126+
quotedStr.length() + ":" + quotedStr.regexpReplaceAll("[^a-zA-Z0-9]", "")
127+
)
128+
}
129+
67130
private predicate quotedStringReplacement(string quotedStr, string id) {
68-
exists(string line, int k | line = this.cmdSubstitutedLineProducer(k) |
69-
exists(int i, int j |
70-
// double quoted string
71-
quotedStr = line.regexpFind("\"((?:[^\"\\\\]|\\\\.)*)\"", i, j) and
72-
id =
73-
"qstr:" + k + ":" + i + ":" + j + ":" + quotedStr.length() + ":" +
74-
quotedStr.regexpReplaceAll("[^a-zA-Z0-9]", "")
75-
)
131+
exists(int lineIndex |
132+
this.doubleQuotedString(lineIndex, quotedStr, id)
76133
or
77-
exists(int i, int j |
78-
// single quoted string
79-
quotedStr = line.regexpFind("'((?:\\\\.|[^'\\\\])*)'", i, j) and
80-
id =
81-
"qstr:" + k + ":" + i + ":" + j + ":" + quotedStr.length() + ":" +
82-
quotedStr.regexpReplaceAll("[^a-zA-Z0-9]", "")
83-
)
134+
this.singleQuotedString(lineIndex, quotedStr, id)
84135
) and
85136
// Only do this for strings that might otherwise disrupt subsequent parsing
86137
quotedStr.regexpMatch("[\"'].*[$\n\r'\"" + Bash::separator() + "].*[\"']")
87138
}
88139

89-
private predicate rankedQuotedStringReplacements(int i, string old, string new) {
90-
old = rank[i](string old2 | this.quotedStringReplacement(old2, _) | old2) and
91-
this.quotedStringReplacement(old, new)
140+
private predicate rankedQuotedStringReplacements(int i, string quotedString, string quotedStringId) {
141+
// rank quoted strings by their nearly-unique IDs
142+
quotedStringId = rank[i](string s, string id | this.quotedStringReplacement(s, id) | id) and
143+
// since we cannot output (string, ID) tuples from the rank operation,
144+
// we need to work out the specific string associated with the resulting ID
145+
this.quotedStringReplacement(quotedString, quotedStringId)
92146
}
93147

94148
private predicate doReplaceQuotedStrings(int line, int round, string old, string new) {

actions/ql/lib/codeql/actions/security/OutputClobberingQuery.qll

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -214,6 +214,8 @@ private module OutputClobberingConfig implements DataFlow::ConfigSig {
214214
)
215215
)
216216
}
217+
218+
predicate observeDiffInformedIncrementalMode() { any() }
217219
}
218220

219221
/** Tracks flow of unsafe user input that is used to construct and evaluate an environment variable. */

actions/ql/lib/codeql/actions/security/RequestForgeryQuery.qll

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -16,6 +16,8 @@ private module RequestForgeryConfig implements DataFlow::ConfigSig {
1616
predicate isSource(DataFlow::Node source) { source instanceof RemoteFlowSource }
1717

1818
predicate isSink(DataFlow::Node sink) { sink instanceof RequestForgerySink }
19+
20+
predicate observeDiffInformedIncrementalMode() { any() }
1921
}
2022

2123
/** Tracks flow of unsafe user input that is used to construct and evaluate a system command. */

actions/ql/lib/codeql/actions/security/SecretExfiltrationQuery.qll

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -15,6 +15,8 @@ private module SecretExfiltrationConfig implements DataFlow::ConfigSig {
1515
predicate isSource(DataFlow::Node source) { source instanceof RemoteFlowSource }
1616

1717
predicate isSink(DataFlow::Node sink) { sink instanceof SecretExfiltrationSink }
18+
19+
predicate observeDiffInformedIncrementalMode() { any() }
1820
}
1921

2022
/** Tracks flow of unsafe user input that is used in a context where it may lead to a secret exfiltration. */

actions/ql/lib/qlpack.yml

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,5 @@
11
name: codeql/actions-all
2-
version: 0.4.10-dev
2+
version: 0.4.12-dev
33
library: true
44
warnOnImplicitThis: true
55
dependencies:

actions/ql/src/CHANGELOG.md

Lines changed: 10 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1,3 +1,13 @@
1+
## 0.6.3
2+
3+
No user-facing changes.
4+
5+
## 0.6.2
6+
7+
### Minor Analysis Improvements
8+
9+
* The query `actions/missing-workflow-permissions` is now aware of the minimal permissions needed for the actions `deploy-pages`, `delete-package-versions`, `ai-inference`. This should lead to better alert messages and better fix suggestions.
10+
111
## 0.6.1
212

313
No user-facing changes.

0 commit comments

Comments
 (0)