Merge branch 'main' into jcogs33/java/do-not-use-finalizers

This commit is contained in:
Jami
2025-04-21 09:57:53 -04:00
committed by GitHub
1323 changed files with 91122 additions and 14580 deletions

View File

@@ -37,5 +37,6 @@ build --java_language_version=17
build --tool_java_language_version=17
build --tool_java_runtime_version=remotejdk_17
build --java_runtime_version=remotejdk_17
build --@rules_python//python/config_settings:python_version=3.12
try-import %workspace%/local.bazelrc

View File

@@ -8,3 +8,5 @@ common --registry=https://bcr.bazel.build
# its implementation packages without providing any code itself.
# We either can depend on internal implementation details, or turn of strict deps.
common --@rules_dotnet//dotnet/settings:strict_deps=false
build --@rules_python//python/config_settings:python_version=3.12

View File

@@ -1 +1 @@
8.0.0
8.1.1

View File

@@ -72,7 +72,7 @@ repos:
- id: rust-codegen
name: Run Rust checked in code generation
files: ^misc/codegen/|^rust/(prefix\.dbscheme|schema/|codegen/|.*/generated/|ql/lib/(rust\.dbscheme$|codeql/rust/elements)|\.generated.list)
files: ^misc/codegen/|^rust/(prefix\.dbscheme|schema/|codegen/|.*/generated/|ql/lib/(rust\.dbscheme$|codeql/rust/elements)|\.generated.list|ast-generator/)
language: system
entry: bazel run //rust/codegen -- --quiet
pass_filenames: false

View File

@@ -8,12 +8,16 @@
/javascript/ @github/codeql-javascript
/python/ @github/codeql-python
/ruby/ @github/codeql-ruby
/rust/ @github/codeql-rust
/swift/ @github/codeql-swift
/misc/codegen/ @github/codeql-swift
/java/kotlin-extractor/ @github/codeql-kotlin
/java/ql/test-kotlin1/ @github/codeql-kotlin
/java/ql/test-kotlin2/ @github/codeql-kotlin
# Experimental CodeQL cryptography
**/experimental/quantum/ @github/ps-codeql
# CodeQL tools and associated docs
/docs/codeql/codeql-cli/ @github/codeql-cli-reviewers
/docs/codeql/codeql-for-visual-studio-code/ @github/codeql-vscode-reviewers
@@ -38,6 +42,7 @@ MODULE.bazel @github/codeql-ci-reviewers
/.github/workflows/go-* @github/codeql-go
/.github/workflows/ql-for-ql-* @github/codeql-ql-for-ql-reviewers
/.github/workflows/ruby-* @github/codeql-ruby
/.github/workflows/rust.yml @github/codeql-rust
/.github/workflows/swift.yml @github/codeql-swift
# Misc

604
Cargo.lock generated

File diff suppressed because it is too large Load Diff

View File

@@ -14,4 +14,4 @@ members = [
[patch.crates-io]
# patch for build script bug preventing bazel build
# see https://github.com/rust-lang/rustc_apfloat/pull/17
rustc_apfloat = { git = "https://github.com/redsun82/rustc_apfloat.git", rev = "096d585100636bc2e9f09d7eefec38c5b334d47b" }
rustc_apfloat = { git = "https://github.com/redsun82/rustc_apfloat.git", rev = "32968f16ef1b082243f9bf43a3fbd65c381b3e27" }

View File

@@ -71,13 +71,13 @@ use_repo(
tree_sitter_extractors_deps = use_extension("//misc/bazel/3rdparty:tree_sitter_extractors_extension.bzl", "r")
use_repo(
tree_sitter_extractors_deps,
"vendor_ts__anyhow-1.0.96",
"vendor_ts__anyhow-1.0.97",
"vendor_ts__argfile-0.2.1",
"vendor_ts__chalk-ir-0.99.0",
"vendor_ts__chrono-0.4.39",
"vendor_ts__clap-4.5.31",
"vendor_ts__chalk-ir-0.100.0",
"vendor_ts__chrono-0.4.40",
"vendor_ts__clap-4.5.35",
"vendor_ts__dunce-1.0.5",
"vendor_ts__either-1.14.0",
"vendor_ts__either-1.15.0",
"vendor_ts__encoding-0.2.33",
"vendor_ts__figment-0.10.19",
"vendor_ts__flate2-1.1.0",
@@ -88,31 +88,31 @@ use_repo(
"vendor_ts__mustache-0.9.0",
"vendor_ts__num-traits-0.2.19",
"vendor_ts__num_cpus-1.16.0",
"vendor_ts__proc-macro2-1.0.93",
"vendor_ts__quote-1.0.38",
"vendor_ts__ra_ap_base_db-0.0.266",
"vendor_ts__ra_ap_cfg-0.0.266",
"vendor_ts__ra_ap_hir-0.0.266",
"vendor_ts__ra_ap_hir_def-0.0.266",
"vendor_ts__ra_ap_hir_expand-0.0.266",
"vendor_ts__ra_ap_hir_ty-0.0.266",
"vendor_ts__ra_ap_ide_db-0.0.266",
"vendor_ts__ra_ap_intern-0.0.266",
"vendor_ts__ra_ap_load-cargo-0.0.266",
"vendor_ts__ra_ap_parser-0.0.266",
"vendor_ts__ra_ap_paths-0.0.266",
"vendor_ts__ra_ap_project_model-0.0.266",
"vendor_ts__ra_ap_span-0.0.266",
"vendor_ts__ra_ap_stdx-0.0.266",
"vendor_ts__ra_ap_syntax-0.0.266",
"vendor_ts__ra_ap_vfs-0.0.266",
"vendor_ts__proc-macro2-1.0.94",
"vendor_ts__quote-1.0.40",
"vendor_ts__ra_ap_base_db-0.0.273",
"vendor_ts__ra_ap_cfg-0.0.273",
"vendor_ts__ra_ap_hir-0.0.273",
"vendor_ts__ra_ap_hir_def-0.0.273",
"vendor_ts__ra_ap_hir_expand-0.0.273",
"vendor_ts__ra_ap_hir_ty-0.0.273",
"vendor_ts__ra_ap_ide_db-0.0.273",
"vendor_ts__ra_ap_intern-0.0.273",
"vendor_ts__ra_ap_load-cargo-0.0.273",
"vendor_ts__ra_ap_parser-0.0.273",
"vendor_ts__ra_ap_paths-0.0.273",
"vendor_ts__ra_ap_project_model-0.0.273",
"vendor_ts__ra_ap_span-0.0.273",
"vendor_ts__ra_ap_stdx-0.0.273",
"vendor_ts__ra_ap_syntax-0.0.273",
"vendor_ts__ra_ap_vfs-0.0.273",
"vendor_ts__rand-0.9.0",
"vendor_ts__rayon-1.10.0",
"vendor_ts__regex-1.11.1",
"vendor_ts__serde-1.0.218",
"vendor_ts__serde_json-1.0.139",
"vendor_ts__serde-1.0.219",
"vendor_ts__serde_json-1.0.140",
"vendor_ts__serde_with-3.12.0",
"vendor_ts__syn-2.0.98",
"vendor_ts__syn-2.0.100",
"vendor_ts__toml-0.8.20",
"vendor_ts__tracing-0.1.41",
"vendor_ts__tracing-flame-0.2.0",
@@ -155,7 +155,7 @@ use_repo(csharp_main_extension, "paket.main")
pip = use_extension("@rules_python//python/extensions:pip.bzl", "pip")
pip.parse(
hub_name = "codegen_deps",
python_version = "3.11",
python_version = "3.12",
requirements_lock = "//misc/codegen:requirements_lock.txt",
)
use_repo(pip, "codegen_deps")

View File

@@ -1,27 +1,34 @@
if (($null -ne $env:LGTM_INDEX_INCLUDE) -or ($null -ne $env:LGTM_INDEX_EXCLUDE) -or ($null -ne $env:LGTM_INDEX_FILTERS)) {
Write-Output 'Path filters set. Passing them through to the JavaScript extractor.'
} else {
Write-Output 'No path filters set. Using the default filters.'
# Note: We're adding the `reusable_workflows` subdirectories to proactively
# record workflows that were called cross-repo, check them out locally,
# and enable an interprocedural analysis across the workflow files.
# These workflows follow the convention `.github/reusable_workflows/<nwo>/*.ya?ml`
$DefaultPathFilters = @(
'exclude:**/*',
'include:.github/workflows/*.yml',
'include:.github/workflows/*.yaml',
'include:.github/reusable_workflows/**/*.yml',
'include:.github/reusable_workflows/**/*.yaml',
'include:**/action.yml',
'include:**/action.yaml'
)
# Note: We're adding the `reusable_workflows` subdirectories to proactively
# record workflows that were called cross-repo, check them out locally,
# and enable an interprocedural analysis across the workflow files.
# These workflows follow the convention `.github/reusable_workflows/<nwo>/*.ya?ml`
$DefaultPathFilters = @(
'exclude:**/*',
'include:.github/workflows/*.yml',
'include:.github/workflows/*.yaml',
'include:.github/reusable_workflows/**/*.yml',
'include:.github/reusable_workflows/**/*.yaml',
'include:**/action.yml',
'include:**/action.yaml'
)
if ($null -ne $env:LGTM_INDEX_FILTERS) {
Write-Output 'LGTM_INDEX_FILTERS set. Using the default filters together with the user-provided filters, and passing through to the JavaScript extractor.'
# Begin with the default path inclusions only,
# followed by the user-provided filters.
# If the user provided `paths`, those patterns override the default inclusions
# (because `LGTM_INDEX_FILTERS` will begin with `exclude:**/*`).
# If the user provided `paths-ignore`, those patterns are excluded.
$PathFilters = ($DefaultPathFilters -join "`n") + "`n" + $env:LGTM_INDEX_FILTERS
$env:LGTM_INDEX_FILTERS = $PathFilters
} else {
Write-Output 'LGTM_INDEX_FILTERS not set. Using the default filters, and passing through to the JavaScript extractor.'
$env:LGTM_INDEX_FILTERS = $DefaultPathFilters -join "`n"
}
# Find the JavaScript extractor directory via `codeql resolve extractor`.
$CodeQL = Join-Path $env:CODEQL_DIST 'codeql.exe'
$env:CODEQL_EXTRACTOR_JAVASCRIPT_ROOT = &$CodeQL resolve extractor --language javascript
$env:CODEQL_EXTRACTOR_JAVASCRIPT_ROOT = &"$CodeQL" resolve extractor --language javascript
if ($LASTEXITCODE -ne 0) {
throw 'Failed to resolve JavaScript extractor.'
}
@@ -40,7 +47,7 @@ $env:CODEQL_EXTRACTOR_JAVASCRIPT_SOURCE_ARCHIVE_DIR = $env:CODEQL_EXTRACTOR_ACTI
$env:CODEQL_EXTRACTOR_JAVASCRIPT_TRAP_DIR = $env:CODEQL_EXTRACTOR_ACTIONS_TRAP_DIR
$env:CODEQL_EXTRACTOR_JAVASCRIPT_WIP_DATABASE = $env:CODEQL_EXTRACTOR_ACTIONS_WIP_DATABASE
&$JavaScriptAutoBuild
&"$JavaScriptAutoBuild"
if ($LASTEXITCODE -ne 0) {
throw "JavaScript autobuilder failed."
}

View File

@@ -1,3 +1,4 @@
@echo off
rem All of the work is done in the PowerShell script
powershell.exe %~dp0autobuild-impl.ps1
echo "Running PowerShell script at '%~dp0autobuild-impl.ps1'"
powershell.exe -File "%~dp0autobuild-impl.ps1"

View File

@@ -17,16 +17,28 @@ include:**/action.yaml
END
)
if [ -n "${LGTM_INDEX_INCLUDE:-}" ] || [ -n "${LGTM_INDEX_EXCLUDE:-}" ] || [ -n "${LGTM_INDEX_FILTERS:-}" ] ; then
echo "Path filters set. Passing them through to the JavaScript extractor."
if [ -n "${LGTM_INDEX_FILTERS:-}" ]; then
echo "LGTM_INDEX_FILTERS set. Using the default filters together with the user-provided filters, and passing through to the JavaScript extractor."
# Begin with the default path inclusions only,
# followed by the user-provided filters.
# If the user provided `paths`, those patterns override the default inclusions
# (because `LGTM_INDEX_FILTERS` will begin with `exclude:**/*`).
# If the user provided `paths-ignore`, those patterns are excluded.
PATH_FILTERS="$(cat << END
${DEFAULT_PATH_FILTERS}
${LGTM_INDEX_FILTERS}
END
)"
LGTM_INDEX_FILTERS="${PATH_FILTERS}"
export LGTM_INDEX_FILTERS
else
echo "No path filters set. Using the default filters."
echo "LGTM_INDEX_FILTERS not set. Using the default filters, and passing through to the JavaScript extractor."
LGTM_INDEX_FILTERS="${DEFAULT_PATH_FILTERS}"
export LGTM_INDEX_FILTERS
fi
# Find the JavaScript extractor directory via `codeql resolve extractor`.
CODEQL_EXTRACTOR_JAVASCRIPT_ROOT="$($CODEQL_DIST/codeql resolve extractor --language javascript)"
CODEQL_EXTRACTOR_JAVASCRIPT_ROOT="$("${CODEQL_DIST}/codeql" resolve extractor --language javascript)"
export CODEQL_EXTRACTOR_JAVASCRIPT_ROOT
echo "Found JavaScript extractor at '${CODEQL_EXTRACTOR_JAVASCRIPT_ROOT}'."
@@ -42,4 +54,4 @@ env CODEQL_EXTRACTOR_JAVASCRIPT_DIAGNOSTIC_DIR="${CODEQL_EXTRACTOR_ACTIONS_DIAGN
CODEQL_EXTRACTOR_JAVASCRIPT_SOURCE_ARCHIVE_DIR="${CODEQL_EXTRACTOR_ACTIONS_SOURCE_ARCHIVE_DIR}" \
CODEQL_EXTRACTOR_JAVASCRIPT_TRAP_DIR="${CODEQL_EXTRACTOR_ACTIONS_TRAP_DIR}" \
CODEQL_EXTRACTOR_JAVASCRIPT_WIP_DATABASE="${CODEQL_EXTRACTOR_ACTIONS_WIP_DATABASE}" \
${JAVASCRIPT_AUTO_BUILD}
"${JAVASCRIPT_AUTO_BUILD}"

View File

@@ -0,0 +1,5 @@
import actions
from AstNode n
where n instanceof Workflow or n instanceof CompositeAction
select n

View File

@@ -0,0 +1,6 @@
| src/.github/action.yaml:1:1:11:32 | name: ' ... action' |
| src/.github/actions/action-name/action.yml:1:1:11:32 | name: ' ... action' |
| src/.github/workflows/workflow.yml:1:1:12:33 | name: A workflow |
| src/action.yml:1:1:11:32 | name: ' ... action' |
| src/excluded/action.yml:1:1:11:32 | name: ' ... action' |
| src/included/action.yml:1:1:11:32 | name: ' ... action' |

View File

@@ -0,0 +1,2 @@
| src/included/action.yml:1:1:11:32 | name: ' ... action' |
| src/included/unreachable-workflow.yml:1:1:12:33 | name: A ... orkflow |

View File

@@ -0,0 +1,5 @@
| src/.github/action.yaml:1:1:11:32 | name: ' ... action' |
| src/.github/actions/action-name/action.yml:1:1:11:32 | name: ' ... action' |
| src/.github/workflows/workflow.yml:1:1:12:33 | name: A workflow |
| src/action.yml:1:1:11:32 | name: ' ... action' |
| src/included/action.yml:1:1:11:32 | name: ' ... action' |

View File

@@ -0,0 +1,2 @@
| src/included/action.yml:1:1:11:32 | name: ' ... action' |
| src/included/unreachable-workflow.yml:1:1:12:33 | name: A ... orkflow |

View File

@@ -0,0 +1,5 @@
import actions
from AstNode n
where n instanceof Workflow or n instanceof CompositeAction
select n

View File

@@ -0,0 +1,4 @@
paths:
- 'included'
paths-ignore:
- 'excluded'

View File

@@ -0,0 +1,2 @@
paths-ignore:
- 'excluded'

View File

@@ -0,0 +1,2 @@
paths:
- 'included'

View File

@@ -0,0 +1,6 @@
src/.github/action.yaml
src/.github/actions/action-name/action.yml
src/.github/workflows/workflow.yml
src/action.yml
src/excluded/action.yml
src/included/action.yml

View File

@@ -0,0 +1,3 @@
src/included/action.yml
src/included/not-an-action.yml
src/included/unreachable-workflow.yml

View File

@@ -0,0 +1,5 @@
src/.github/action.yaml
src/.github/actions/action-name/action.yml
src/.github/workflows/workflow.yml
src/action.yml
src/included/action.yml

View File

@@ -0,0 +1,3 @@
src/included/action.yml
src/included/not-an-action.yml
src/included/unreachable-workflow.yml

View File

@@ -0,0 +1,11 @@
name: 'A composite action'
description: 'Do something'
runs:
using: "composite"
steps:
- name: Print
run: echo "Hello world"
shell: bash
- name: Checkout
uses: actions/checkout@v4

View File

@@ -0,0 +1,11 @@
name: 'A composite action'
description: 'Do something'
runs:
using: "composite"
steps:
- name: Print
run: echo "Hello world"
shell: bash
- name: Checkout
uses: actions/checkout@v4

View File

@@ -0,0 +1,12 @@
name: An unreachable workflow
on:
push:
branches:
- main
jobs:
job:
runs-on: ubuntu-latest
steps:
- name: Checkout code
uses: actions/checkout@v4

View File

@@ -0,0 +1,12 @@
name: A workflow
on:
push:
branches:
- main
jobs:
job:
runs-on: ubuntu-latest
steps:
- name: Checkout code
uses: actions/checkout@v4

View File

@@ -0,0 +1,11 @@
name: 'A composite action'
description: 'Do something'
runs:
using: "composite"
steps:
- name: Print
run: echo "Hello world"
shell: bash
- name: Checkout
uses: actions/checkout@v4

View File

@@ -0,0 +1,11 @@
name: 'A composite action'
description: 'Do something'
runs:
using: "composite"
steps:
- name: Print
run: echo "Hello world"
shell: bash
- name: Checkout
uses: actions/checkout@v4

View File

@@ -0,0 +1,12 @@
name: An unreachable workflow
on:
push:
branches:
- main
jobs:
job:
runs-on: ubuntu-latest
steps:
- name: Checkout code
uses: actions/checkout@v4

View File

@@ -0,0 +1,11 @@
name: 'A composite action'
description: 'Do something'
runs:
using: "composite"
steps:
- name: Print
run: echo "Hello world"
shell: bash
- name: Checkout
uses: actions/checkout@v4

View File

@@ -0,0 +1 @@
name: 'Not an action, just a YAML file'

View File

@@ -0,0 +1,12 @@
name: An unreachable workflow
on:
push:
branches:
- main
jobs:
job:
runs-on: ubuntu-latest
steps:
- name: Checkout code
uses: actions/checkout@v4

View File

@@ -0,0 +1,12 @@
name: An unreachable workflow
on:
push:
branches:
- main
jobs:
job:
runs-on: ubuntu-latest
steps:
- name: Checkout code
uses: actions/checkout@v4

View File

@@ -0,0 +1,18 @@
import pytest
@pytest.mark.ql_test(expected=".default-filters.expected")
def test_default_filters(codeql, actions, check_source_archive):
check_source_archive.expected_suffix = ".default-filters.expected"
codeql.database.create(source_root="src")
@pytest.mark.ql_test(expected=".paths-only.expected")
def test_config_paths_only(codeql, actions):
codeql.database.create(source_root="src", codescanning_config="codeql-config.paths-only.yml")
@pytest.mark.ql_test(expected=".paths-ignore-only.expected")
def test_config_paths_ignore_only(codeql, actions):
codeql.database.create(source_root="src", codescanning_config="codeql-config.paths-ignore-only.yml")
@pytest.mark.ql_test(expected=".paths-and-paths-ignore.expected")
def test_config_paths_and_paths_ignore(codeql, actions):
codeql.database.create(source_root="src", codescanning_config="codeql-config.paths-and-paths-ignore.yml")

View File

@@ -1,3 +1,14 @@
## 0.4.7
No user-facing changes.
## 0.4.6
### Bug Fixes
* The query `actions/code-injection/medium` now produces alerts for injection
vulnerabilities on `pull_request` events.
## 0.4.5
No user-facing changes.

View File

@@ -1,5 +1,6 @@
---
category: fix
---
## 0.4.6
### Bug Fixes
* The query `actions/code-injection/medium` now produces alerts for injection
vulnerabilities on `pull_request` events.
vulnerabilities on `pull_request` events.

View File

@@ -0,0 +1,3 @@
## 0.4.7
No user-facing changes.

View File

@@ -1,2 +1,2 @@
---
lastReleaseVersion: 0.4.5
lastReleaseVersion: 0.4.7

View File

@@ -154,3 +154,13 @@ predicate untrustedGitCommandDataModel(string cmd_regex, string flag) {
predicate untrustedGhCommandDataModel(string cmd_regex, string flag) {
Extensions::untrustedGhCommandDataModel(cmd_regex, flag)
}
/**
* MaD models for permissions needed by actions
* Fields:
* - action: action name, e.g. `actions/checkout`
* - permission: permission name, e.g. `contents: read`
*/
predicate actionsPermissionsDataModel(string action, string permission) {
Extensions::actionsPermissionsDataModel(action, permission)
}

View File

@@ -77,3 +77,14 @@ extensible predicate untrustedGitCommandDataModel(string cmd_regex, string flag)
* Holds for gh commands that may introduce untrusted data
*/
extensible predicate untrustedGhCommandDataModel(string cmd_regex, string flag);
/**
* Holds if `action` needs `permission` to run.
* - 'action' is the name of the action without any version information.
* E.g. for the action selector `actions/checkout@v2`, `action` is `actions/checkout`.
* - `permission` is of the form `scope-name: read|write`, for example `contents: read`.
* - see https://github.com/actions/checkout?tab=readme-ov-file#recommended-permissions
* for an example of recommended permissions.
* - see https://docs.github.com/en/actions/writing-workflows/choosing-what-your-workflow-does/controlling-permissions-for-github_token for documentation of token permissions.
*/
extensible predicate actionsPermissionsDataModel(string action, string permission);

View File

@@ -0,0 +1,37 @@
extensions:
- addsTo:
pack: codeql/actions-all
extensible: actionsPermissionsDataModel
data:
- ["actions/checkout", "contents: read"]
- ["actions/setup-node", "contents: read"]
- ["actions/setup-python", "contents: read"]
- ["actions/setup-java", "contents: read"]
- ["actions/setup-go", "contents: read"]
- ["actions/setup-dotnet", "contents: read"]
- ["actions/labeler", "contents: read"]
- ["actions/labeler", "pull-requests: write"]
- ["actions/attest", "id-token: write"]
- ["actions/attest", "attestations: write"]
# No permissions needed for actions/add-to-project
- ["actions/dependency-review-action", "contents: read"]
- ["actions/attest-sbom", "id-token: write"]
- ["actions/attest-sbom", "attestations: write"]
- ["actions/stale", "contents: write"]
- ["actions/stale", "issues: write"]
- ["actions/stale", "pull-requests: write"]
- ["actions/attest-build-provenance", "id-token: write"]
- ["actions/attest-build-provenance", "attestations: write"]
- ["actions/jekyll-build-pages", "contents: read"]
- ["actions/jekyll-build-pages", "pages: write"]
- ["actions/jekyll-build-pages", "id-token: write"]
- ["actions/publish-action", "contents: write"]
- ["actions/versions-package-tools", "contents: read"]
- ["actions/versions-package-tools", "actions: read"]
- ["actions/reusable-workflows", "contents: read"]
- ["actions/reusable-workflows", "actions: read"]
# TODO: Add permissions for actions/download-artifact
# TODO: Add permissions for actions/upload-artifact
# TODO: Add permissions for actions/cache

View File

@@ -1,5 +1,5 @@
name: codeql/actions-all
version: 0.4.6-dev
version: 0.4.8-dev
library: true
warnOnImplicitThis: true
dependencies:

View File

@@ -1,3 +1,17 @@
## 0.5.4
### Bug Fixes
* Alerts produced by the query `actions/missing-workflow-permissions` now include a minimal set of recommended permissions in the alert message, based on well-known actions seen within the workflow file.
## 0.5.3
### Bug Fixes
* Fixed typos in the query and alert titles for the queries
`actions/envpath-injection/critical`, `actions/envpath-injection/medium`,
`actions/envvar-injection/critical`, and `actions/envvar-injection/medium`.
## 0.5.2
No user-facing changes.
@@ -7,9 +21,10 @@ No user-facing changes.
### Bug Fixes
* The `actions/unversioned-immutable-action` query will no longer report any alerts, since the
Immutable Actions feature is not yet available for customer use. The query remains in the
default Code Scanning suites for use internal to GitHub. Once the Immutable Actions feature is
available, the query will be updated to report alerts again.
Immutable Actions feature is not yet available for customer use. The query has also been moved
to the experimental folder and will not be used in code scanning unless it is explicitly added
to a code scanning configuration. Once the Immutable Actions feature is available, the query will
be updated to report alerts again.
## 0.5.0

View File

@@ -109,7 +109,7 @@ An attacker could craft a malicious artifact that writes dangerous environment v
### Exploitation
An attacker is be able to run arbitrary code by injecting environment variables such as `LD_PRELOAD`, `BASH_ENV`, etc.
An attacker would be able to run arbitrary code by injecting environment variables such as `LD_PRELOAD`, `BASH_ENV`, etc.
## References

View File

@@ -1,5 +1,5 @@
/**
* @name Use of a known vulnerable action.
* @name Use of a known vulnerable action
* @description The workflow is using an action with known vulnerabilities.
* @kind problem
* @problem.severity error

View File

@@ -1,6 +1,6 @@
/**
* @name Workflow does not contain permissions
* @description Workflows should contain permissions to provide a clear understanding has permissions to run the workflow.
* @description Workflows should contain explicit permissions to restrict the scope of the default GITHUB_TOKEN.
* @kind problem
* @security-severity 5.0
* @problem.severity warning
@@ -14,7 +14,19 @@
import actions
from Job job
Step stepInJob(Job job) { result = job.(LocalJob).getAStep() }
string jobNeedsPermission(Job job) {
actionsPermissionsDataModel(stepInJob(job).(UsesStep).getCallee(), result)
}
/** Gets a suggestion for the minimal token permissions for `job`, as a JSON string. */
string permissionsForJob(Job job) {
result =
"{" + concat(string permission | permission = jobNeedsPermission(job) | permission, ", ") + "}"
}
from Job job, string permissions
where
not exists(job.getPermissions()) and
not exists(job.getEnclosingWorkflow().getPermissions()) and
@@ -22,5 +34,8 @@ where
exists(Event e |
e = job.getATriggerEvent() and
not e.getName() = "workflow_call"
)
select job, "Actions Job or Workflow does not set permissions"
) and
permissions = permissionsForJob(job)
select job,
"Actions job or workflow does not limit the permissions of the GITHUB_TOKEN. Consider setting an explicit permissions block, using the following as a minimal starting point: "
+ permissions

View File

@@ -3,6 +3,7 @@
* @description All organization and repository secrets are passed to the workflow runner.
* @kind problem
* @precision high
* @security-severity 5.0
* @problem.severity warning
* @id actions/excessive-secrets-exposure
* @tags actions

View File

@@ -2,11 +2,11 @@
## Description
Secrets derived from other secrets are not know to the workflow runner and therefore not masked unless explicitly registered.
Secrets derived from other secrets are not known to the workflow runner, and therefore are not masked unless explicitly registered.
## Recommendations
Avoid defining non-plain secrets. For example, do not define a new secret containing a JSON object and then read properties out of it from the workflow since these read values will not be masked by the workflow runner.
Avoid defining non-plain secrets. For example, do not define a new secret containing a JSON object and then read properties out of it from the workflow, since these read values will not be masked by the workflow runner.
## Examples

View File

@@ -1,5 +1,5 @@
/**
* @name Checkout of untrusted code in trusted context
* @name Checkout of untrusted code in a privileged context
* @description Privileged workflows have read/write access to the base repository and access to secrets.
* By explicitly checking out and running the build script from a fork the untrusted code is running in an environment
* that is able to push to the base repository and to access secrets.

View File

@@ -0,0 +1,4 @@
---
category: fix
---
* Assigned a `security-severity` to the query `actions/excessive-secrets-exposure`.

View File

@@ -1,6 +1,7 @@
---
category: fix
---
## 0.5.3
### Bug Fixes
* Fixed typos in the query and alert titles for the queries
`actions/envpath-injection/critical`, `actions/envpath-injection/medium`,
`actions/envvar-injection/critical`, and `actions/envvar-injection/medium`.
`actions/envvar-injection/critical`, and `actions/envvar-injection/medium`.

View File

@@ -0,0 +1,5 @@
## 0.5.4
### Bug Fixes
* Alerts produced by the query `actions/missing-workflow-permissions` now include a minimal set of recommended permissions in the alert message, based on well-known actions seen within the workflow file.

View File

@@ -1,2 +1,2 @@
---
lastReleaseVersion: 0.5.2
lastReleaseVersion: 0.5.4

View File

@@ -1,5 +1,5 @@
name: codeql/actions-queries
version: 0.5.3-dev
version: 0.5.5-dev
library: false
warnOnImplicitThis: true
groups: [actions, queries]

View File

@@ -0,0 +1,13 @@
on:
workflow_call:
workflow_dispatch:
jobs:
build:
name: Build and test
runs-on: ubuntu-latest
steps:
- uses: actions/checkout@v2
- uses: actions/jekyll-build-pages

View File

@@ -0,0 +1,10 @@
on:
workflow_call:
workflow_dispatch:
jobs:
build:
name: Build and test
runs-on: ubuntu-latest
steps:
- uses: actions/add-to-project@v2

View File

@@ -1,3 +1,5 @@
| .github/workflows/perms1.yml:6:5:9:32 | Job: build | Actions Job or Workflow does not set permissions |
| .github/workflows/perms2.yml:6:5:10:2 | Job: build | Actions Job or Workflow does not set permissions |
| .github/workflows/perms5.yml:7:5:10:32 | Job: build | Actions Job or Workflow does not set permissions |
| .github/workflows/perms1.yml:6:5:9:32 | Job: build | Actions job or workflow does not limit the permissions of the GITHUB_TOKEN. Consider setting an explicit permissions block, using the following as a minimal starting point: {contents: read} |
| .github/workflows/perms2.yml:6:5:10:2 | Job: build | Actions job or workflow does not limit the permissions of the GITHUB_TOKEN. Consider setting an explicit permissions block, using the following as a minimal starting point: {contents: read} |
| .github/workflows/perms5.yml:7:5:10:32 | Job: build | Actions job or workflow does not limit the permissions of the GITHUB_TOKEN. Consider setting an explicit permissions block, using the following as a minimal starting point: {contents: read} |
| .github/workflows/perms6.yml:7:5:11:39 | Job: build | Actions job or workflow does not limit the permissions of the GITHUB_TOKEN. Consider setting an explicit permissions block, using the following as a minimal starting point: {contents: read, id-token: write, pages: write} |
| .github/workflows/perms7.yml:7:5:10:38 | Job: build | Actions job or workflow does not limit the permissions of the GITHUB_TOKEN. Consider setting an explicit permissions block, using the following as a minimal starting point: {} |

View File

@@ -58,7 +58,19 @@ def file_checksum(filename):
with open(filename, 'rb') as file_handle:
return hashlib.sha1(file_handle.read()).hexdigest()
def check_group(group_name, files, master_file_picker, emit_error):
def accept_prefix(line1, line2):
suffix = line2.removeprefix(line1)
return not suffix or suffix.lstrip().startswith("//")
def equivalent_lines(lines1, lines2):
if len(lines1) != len(lines2):
return False
for line1, line2 in zip(lines1, lines2):
if not accept_prefix(line1, line2) and not accept_prefix(line2, line1):
return False
return True
def check_group(group_name, files, master_file_picker, emit_error, accept_prefix):
extant_files = [f for f in files if path.isfile(f)]
if len(extant_files) == 0:
emit_error(__file__, 0, "No files found from group '" + group_name + "'.")
@@ -70,11 +82,23 @@ def check_group(group_name, files, master_file_picker, emit_error):
return
checksums = {file_checksum(f) for f in extant_files}
if len(checksums) == 1 and len(extant_files) == len(files):
same_lengths = len(extant_files) == len(files)
if len(checksums) == 1 and same_lengths:
# All files are present and identical.
return
# In this case we also consider files indentical, if
# (1) The group only containts two files.
# (2) The lines of one file are the same as the lines of another file
# modulo comments.
if accept_prefix and same_lengths and len(extant_files) == 2:
with open(extant_files[0], 'r') as f1:
file1_lines = [l.strip('\n\r') for l in f1.readlines()]
with open(extant_files[1], 'r') as f2:
file2_lines = [l.strip('\n\r') for l in f2.readlines()]
if equivalent_lines(file1_lines, file2_lines):
return
master_file = master_file_picker(extant_files)
if master_file is None:
emit_error(__file__, 0,
@@ -139,9 +163,10 @@ def sync_identical_files(emit_error):
raise Exception("Bad command line or file not found")
chdir_repo_root()
load_if_exists('.', 'config/identical-files.json')
file_groups.update(csharp_test_files())
for group_name, files in csharp_test_files().items():
check_group(group_name, files, master_file_picker, emit_error, True)
for group_name, files in file_groups.items():
check_group(group_name, files, master_file_picker, emit_error)
check_group(group_name, files, master_file_picker, emit_error, False)
def main():
sync_identical_files(emit_local_error)

File diff suppressed because it is too large Load Diff

File diff suppressed because it is too large Load Diff

View File

@@ -0,0 +1,3 @@
description: Add a new predicate `isVla()` to the `ArrayType` class
compatibility: full
type_is_vla.rel: delete

View File

@@ -0,0 +1,11 @@
class Expr extends @expr {
string toString() { none() }
}
class AggregateLiteral extends Expr, @aggregateliteral {
override string toString() { none() }
}
from AggregateLiteral aggregate, Expr initializer, int element_index, int position
where aggregate_array_init(aggregate, initializer, element_index, position, _)
select aggregate, initializer, element_index, position

View File

@@ -0,0 +1,15 @@
class Expr extends @expr {
string toString() { none() }
}
class AggregateLiteral extends Expr, @aggregateliteral {
override string toString() { none() }
}
class MemberVariable extends @membervariable {
string toString() { none() }
}
from AggregateLiteral aggregate, Expr initializer, MemberVariable field, int position
where aggregate_field_init(aggregate, initializer, field, position, _)
select aggregate, initializer, field, position

File diff suppressed because it is too large Load Diff

File diff suppressed because it is too large Load Diff

View File

@@ -0,0 +1,4 @@
description: add `hasDesignator` predicate to `ArrayOrVectorAggregateLiteral` and `ClassAggregateLiteral`
compatibility: backwards
aggregate_array_init.rel: run aggregate_array_init.qlo
aggregate_field_init.rel: run aggregate_field_init.qlo

View File

@@ -1,3 +1,16 @@
## 4.2.0
### New Features
* Calling conventions explicitly specified on function declarations (`__cdecl`, `__stdcall`, `__fastcall`, etc.) are now represented as specifiers of those declarations.
* A new class `CallingConventionSpecifier` extending the `Specifier` class was introduced, which represents explicitly specified calling conventions.
## 4.1.0
### New Features
* Added `Node.asUncertainDefinition` and `Node.asCertainDefinition` to the `DataFlow::Node` class for querying whether a definition overwrites the entire destination buffer.
## 4.0.3
No user-facing changes.

View File

@@ -0,0 +1,4 @@
---
category: feature
---
* Added the `isVla()` predicate to the `ArrayType` class. This allows queries to identify variable-length arrays (VLAs).

View File

@@ -0,0 +1,4 @@
---
category: feature
---
* Introduced `hasDesignator()` predicates to distinguish between designated and positional initializations for both struct/union fields and array elements.

View File

@@ -1,4 +1,5 @@
---
category: feature
---
* Added `Node.asUncertainDefinition` and `Node.asCertainDefinition` to the `DataFlow::Node` class for querying whether a definition overwrites the entire destination buffer.
## 4.1.0
### New Features
* Added `Node.asUncertainDefinition` and `Node.asCertainDefinition` to the `DataFlow::Node` class for querying whether a definition overwrites the entire destination buffer.

View File

@@ -0,0 +1,6 @@
## 4.2.0
### New Features
* Calling conventions explicitly specified on function declarations (`__cdecl`, `__stdcall`, `__fastcall`, etc.) are now represented as specifiers of those declarations.
* A new class `CallingConventionSpecifier` extending the `Specifier` class was introduced, which represents explicitly specified calling conventions.

View File

@@ -1,2 +1,2 @@
---
lastReleaseVersion: 4.0.3
lastReleaseVersion: 4.2.0

View File

@@ -1,5 +1,5 @@
name: codeql/cpp-all
version: 4.0.4-dev
version: 4.2.1-dev
groups: cpp
dbscheme: semmlecode.cpp.dbscheme
extractor: cpp

View File

@@ -97,6 +97,18 @@ class AccessSpecifier extends Specifier {
override string getAPrimaryQlClass() { result = "AccessSpecifier" }
}
/**
* A C/C++ calling convention specifier: `cdecl`, `fastcall`, `stdcall`, `thiscall`,
* `vectorcall`, or `clrcall`.
*/
class CallingConventionSpecifier extends Specifier {
CallingConventionSpecifier() {
this.hasName(["cdecl", "fastcall", "stdcall", "thiscall", "vectorcall", "clrcall"])
}
override string getAPrimaryQlClass() { result = "CallingConventionSpecifier" }
}
/**
* An attribute introduced by GNU's `__attribute__((name))` syntax,
* Microsoft's `__declspec(name)` syntax, Microsoft's `[name]` syntax, the

View File

@@ -1369,6 +1369,11 @@ class ArrayType extends DerivedType {
override predicate isDeeplyConst() { this.getBaseType().isDeeplyConst() } // No such thing as a const array type
override predicate isDeeplyConstBelow() { this.getBaseType().isDeeplyConst() }
/**
* Holds if this array is a variable-length array (VLA).
*/
predicate isVla() { type_is_vla(underlyingElement(this)) }
}
/**

View File

@@ -465,7 +465,7 @@ private predicate isFunctionConstructedFrom(Function f, Function templateFunc) {
}
/** Gets the fully templated version of `f`. */
private Function getFullyTemplatedFunction(Function f) {
Function getFullyTemplatedFunction(Function f) {
not f.isFromUninstantiatedTemplate(_) and
(
exists(Class c, Class templateClass, int i |
@@ -559,12 +559,15 @@ private string getTypeName(Type t, boolean needsSpace) {
/**
* Gets a type name for the `n`'th parameter of `f` without any template
* arguments. The result may be a string representing a type for which the
* typedefs have been resolved.
* arguments.
*
* If `canonical = false` then the result may be a string representing a type
* for which the typedefs have been resolved. If `canonical = true` then the
* result will be a string representing a type without resolving `typedefs`.
*/
bindingset[f]
pragma[inline_late]
string getParameterTypeWithoutTemplateArguments(Function f, int n) {
string getParameterTypeWithoutTemplateArguments(Function f, int n, boolean canonical) {
exists(string s, string base, string specifiers, Type t |
t = f.getParameter(n).getType() and
// The name of the string can either be the possibly typedefed name
@@ -572,14 +575,19 @@ string getParameterTypeWithoutTemplateArguments(Function f, int n) {
// `getTypeName(t, _)` is almost equal to `t.resolveTypedefs().getName()`,
// except that `t.resolveTypedefs()` doesn't have a result when the
// resulting type doesn't appear in the database.
s = [t.getName(), getTypeName(t, _)] and
(
s = t.getName() and canonical = true
or
s = getTypeName(t, _) and canonical = false
) and
parseAngles(s, base, _, specifiers) and
result = base + specifiers
)
or
f.isVarargs() and
n = f.getNumberOfParameters() and
result = "..."
result = "..." and
canonical = true
}
/**
@@ -590,7 +598,7 @@ private string getTypeNameWithoutFunctionTemplates(Function f, int n, int remain
exists(Function templateFunction |
templateFunction = getFullyTemplatedFunction(f) and
remaining = templateFunction.getNumberOfTemplateArguments() and
result = getParameterTypeWithoutTemplateArguments(templateFunction, n)
result = getParameterTypeWithoutTemplateArguments(templateFunction, n, _)
)
or
exists(string mid, TypeTemplateParameter tp, Function templateFunction |
@@ -627,7 +635,7 @@ private string getTypeNameWithoutClassTemplates(Function f, int n, int remaining
}
/** Gets the string representation of the `i`'th parameter of `c`. */
private string getParameterTypeName(Function c, int i) {
string getParameterTypeName(Function c, int i) {
result = getTypeNameWithoutClassTemplates(c, i, 0)
}

View File

@@ -213,7 +213,24 @@ class ClassAggregateLiteral extends AggregateLiteral {
Expr getFieldExpr(Field field, int position) {
field = classType.getAField() and
aggregate_field_init(underlyingElement(this), unresolveElement(result), unresolveElement(field),
position)
position, _)
}
/**
* Holds if the `position`-th initialization of `field` in this aggregate initializer
* uses a designated (e.g., `.x = ...`) rather than a positional initializer.
*
* For example, in:
* ```c
* struct S { int x, y; };
* struct S s = { .x = 1, 2 };
* ```
* - `.x = 1` is a designated initializer, therefore `hasDesignator(x, 0)` holds.
* - `2` is a positional initializer for `s.y`, therefore `hasDesignator(y, 1)` does not hold.
*/
predicate hasDesignator(Field field, int position) {
field = classType.getAField() and
aggregate_field_init(underlyingElement(this), _, unresolveElement(field), position, true)
}
/**
@@ -304,7 +321,24 @@ class ArrayOrVectorAggregateLiteral extends AggregateLiteral {
* - `a.getElementExpr(0, 2)` gives `789`.
*/
Expr getElementExpr(int elementIndex, int position) {
aggregate_array_init(underlyingElement(this), unresolveElement(result), elementIndex, position)
aggregate_array_init(underlyingElement(this), unresolveElement(result), elementIndex, position,
_)
}
/**
* Holds if the `position`-th initialization of the array element at `elementIndex`
* in this aggregate initializer uses a designated (e.g., `[0] = ...`) rather than
* a positional initializer.
*
* For example, in:
* ```c
* int x[] = { [0] = 1, 2 };
* ```
* - `[0] = 1` is a designated initializer, therefore `hasDesignator(0, 0)` holds.
* - `2` is a positional initializer for `x[1]`, therefore `hasDesignator(1, 1)` does not hold.
*/
predicate hasDesignator(int elementIndex, int position) {
aggregate_array_init(underlyingElement(this), _, elementIndex, position, true)
}
/**

View File

@@ -371,7 +371,7 @@ private class PrimaryArgumentNode extends ArgumentNode, OperandNode {
PrimaryArgumentNode() { exists(CallInstruction call | op = call.getAnArgumentOperand()) }
override predicate argumentOf(DataFlowCall call, ArgumentPosition pos) {
op = call.getArgumentOperand(pos.(DirectPosition).getIndex())
op = call.getArgumentOperand(pos.(DirectPosition).getArgumentIndex())
}
}
@@ -410,8 +410,16 @@ class ParameterPosition = Position;
class ArgumentPosition = Position;
abstract class Position extends TPosition {
/** Gets a textual representation of this position. */
abstract string toString();
/**
* Gets the argument index of this position. The qualifier of a call has
* argument index `-1`.
*/
abstract int getArgumentIndex();
/** Gets the indirection index of this position. */
abstract int getIndirectionIndex();
}
@@ -428,7 +436,7 @@ class DirectPosition extends Position, TDirectPosition {
result = index.toString()
}
int getIndex() { result = index }
override int getArgumentIndex() { result = index }
final override int getIndirectionIndex() { result = 0 }
}
@@ -445,16 +453,29 @@ class IndirectionPosition extends Position, TIndirectionPosition {
else result = repeatStars(indirectionIndex) + argumentIndex.toString()
}
int getArgumentIndex() { result = argumentIndex }
override int getArgumentIndex() { result = argumentIndex }
final override int getIndirectionIndex() { result = indirectionIndex }
}
newtype TPosition =
TDirectPosition(int argumentIndex) { exists(any(CallInstruction c).getArgument(argumentIndex)) } or
TDirectPosition(int argumentIndex) {
exists(any(CallInstruction c).getArgument(argumentIndex))
or
// Handle the rare case where there is a function definition but no call to
// the function.
exists(any(Cpp::Function f).getParameter(argumentIndex))
} or
TIndirectionPosition(int argumentIndex, int indirectionIndex) {
Ssa::hasIndirectOperand(any(CallInstruction call).getArgumentOperand(argumentIndex),
indirectionIndex)
or
// Handle the rare case where there is a function definition but no call to
// the function.
exists(Cpp::Function f, Cpp::Parameter p |
p = f.getParameter(argumentIndex) and
indirectionIndex = [1 .. Ssa::getMaxIndirectionsForType(p.getUnspecifiedType()) - 1]
)
}
private newtype TReturnKind =
@@ -501,6 +522,15 @@ class ReturnKind extends TReturnKind {
/** Gets a textual representation of this return kind. */
abstract string toString();
/** Holds if this `ReturnKind` is generated from a `return` statement. */
abstract predicate isNormalReturn();
/**
* Holds if this `ReturnKind` is generated from a write to the parameter with
* index `argumentIndex`
*/
abstract predicate isIndirectReturn(int argumentIndex);
}
/**
@@ -514,6 +544,10 @@ class NormalReturnKind extends ReturnKind, TNormalReturnKind {
override int getIndirectionIndex() { result = indirectionIndex }
override string toString() { result = "indirect return" }
override predicate isNormalReturn() { any() }
override predicate isIndirectReturn(int argumentIndex) { none() }
}
/**
@@ -528,6 +562,10 @@ private class IndirectReturnKind extends ReturnKind, TIndirectReturnKind {
override int getIndirectionIndex() { result = indirectionIndex }
override string toString() { result = "indirect outparam[" + argumentIndex.toString() + "]" }
override predicate isNormalReturn() { none() }
override predicate isIndirectReturn(int argumentIndex_) { argumentIndex_ = argumentIndex }
}
/** A data flow node that occurs as the result of a `ReturnStmt`. */
@@ -1834,7 +1872,47 @@ module IteratorFlow {
private module IteratorSsa = SsaImpl::Make<Location, SsaInput>;
private class Def extends IteratorSsa::DefinitionExt {
private module DataFlowIntegrationInput implements IteratorSsa::DataFlowIntegrationInputSig {
private import codeql.util.Void
class Expr extends Instruction {
Expr() {
exists(IRBlock bb, int i |
SsaInput::variableRead(bb, i, _, true) and
this = bb.getInstruction(i)
)
}
predicate hasCfgNode(SsaInput::BasicBlock bb, int i) { bb.getInstruction(i) = this }
}
predicate ssaDefHasSource(IteratorSsa::WriteDefinition def) { none() }
predicate allowFlowIntoUncertainDef(IteratorSsa::UncertainWriteDefinition def) { any() }
class Guard extends Void {
predicate controlsBranchEdge(
SsaInput::BasicBlock bb1, SsaInput::BasicBlock bb2, boolean branch
) {
none()
}
}
predicate guardDirectlyControlsBlock(Guard guard, SsaInput::BasicBlock bb, boolean branch) {
none()
}
predicate supportBarrierGuardsOnPhiEdges() { none() }
}
private module DataFlowIntegrationImpl =
IteratorSsa::DataFlowIntegration<DataFlowIntegrationInput>;
private class IteratorSynthNode extends DataFlowIntegrationImpl::SsaNode {
IteratorSynthNode() { not this.asDefinition() instanceof IteratorSsa::WriteDefinition }
}
private class Def extends IteratorSsa::Definition {
final override Location getLocation() { result = this.getImpl().getLocation() }
/**
@@ -1842,7 +1920,7 @@ module IteratorFlow {
* and is a definition (or use) of the variable `sv`.
*/
predicate hasIndexInBlock(IRBlock block, int index, SourceVariable sv) {
super.definesAt(sv, block, index, _)
super.definesAt(sv, block, index)
}
private Ssa::DefImpl getImpl() {
@@ -1859,46 +1937,15 @@ module IteratorFlow {
int getIndirectionIndex() { result = this.getImpl().getIndirectionIndex() }
}
private class PhiNode extends IteratorSsa::DefinitionExt {
PhiNode() {
this instanceof IteratorSsa::PhiNode or
this instanceof IteratorSsa::PhiReadNode
}
SsaIteratorNode getNode() { result.getIteratorFlowNode() = this }
}
cached
private module IteratorSsaCached {
cached
predicate adjacentDefRead(IRBlock bb1, int i1, SourceVariable sv, IRBlock bb2, int i2) {
IteratorSsa::adjacentDefReadExt(_, sv, bb1, i1, bb2, i2)
or
exists(PhiNode phi |
IteratorSsa::lastRefRedefExt(_, sv, bb1, i1, phi) and
phi.definesAt(sv, bb2, i2, _)
)
}
cached
Node getAPriorDefinition(IteratorSsa::DefinitionExt next) {
exists(IRBlock bb, int i, SourceVariable sv, IteratorSsa::DefinitionExt def |
IteratorSsa::lastRefRedefExt(pragma[only_bind_into](def), pragma[only_bind_into](sv),
pragma[only_bind_into](bb), pragma[only_bind_into](i), next) and
nodeToDefOrUse(result, sv, bb, i, _)
)
}
}
/** The set of nodes necessary for iterator flow. */
class IteratorFlowNode instanceof PhiNode {
class IteratorFlowNode instanceof IteratorSynthNode {
/** Gets a textual representation of this node. */
string toString() { result = super.toString() }
/** Gets the type of this node. */
DataFlowType getType() {
exists(Ssa::SourceVariable sv |
super.definesAt(sv, _, _, _) and
super.getSourceVariable() = sv and
result = sv.getType()
)
}
@@ -1910,60 +1957,33 @@ module IteratorFlow {
Location getLocation() { result = super.getBasicBlock().getLocation() }
}
private import IteratorSsaCached
private predicate defToNode(Node node, Def def, boolean uncertain) {
(
nodeHasOperand(node, def.getValue().asOperand(), def.getIndirectionIndex())
or
nodeHasInstruction(node, def.getValue().asInstruction(), def.getIndirectionIndex())
) and
uncertain = false
private predicate defToNode(Node node, Def def) {
nodeHasOperand(node, def.getValue().asOperand(), def.getIndirectionIndex())
or
nodeHasInstruction(node, def.getValue().asInstruction(), def.getIndirectionIndex())
}
private predicate nodeToDefOrUse(
Node node, SourceVariable sv, IRBlock bb, int i, boolean uncertain
) {
exists(Def def |
def.hasIndexInBlock(bb, i, sv) and
defToNode(node, def, uncertain)
bindingset[result, v]
pragma[inline_late]
private DataFlowIntegrationImpl::Node fromDfNode(Node n, SourceVariable v) {
result = n.(SsaIteratorNode).getIteratorFlowNode()
or
exists(Ssa::UseImpl use, IRBlock bb, int i |
result.(DataFlowIntegrationImpl::ExprNode).getExpr().hasCfgNode(bb, i) and
use.hasIndexInBlock(bb, i, v) and
use.getNode() = n
)
or
useToNode(bb, i, sv, node) and
uncertain = false
}
private predicate useToNode(IRBlock bb, int i, SourceVariable sv, Node nodeTo) {
exists(PhiNode phi |
phi.definesAt(sv, bb, i, _) and
nodeTo = phi.getNode()
)
or
exists(Ssa::UseImpl use |
use.hasIndexInBlock(bb, i, sv) and
nodeTo = use.getNode()
)
defToNode(n, result.(DataFlowIntegrationImpl::SsaDefinitionNode).getDefinition())
}
/**
* Holds if `nodeFrom` flows to `nodeTo` in a single step.
*/
predicate localFlowStep(Node nodeFrom, Node nodeTo) {
exists(
Node nFrom, SourceVariable sv, IRBlock bb1, int i1, IRBlock bb2, int i2, boolean uncertain
|
adjacentDefRead(bb1, i1, sv, bb2, i2) and
nodeToDefOrUse(nFrom, sv, bb1, i1, uncertain) and
useToNode(bb2, i2, sv, nodeTo)
|
if uncertain = true
then
nodeFrom =
[
nFrom,
getAPriorDefinition(any(IteratorSsa::DefinitionExt next | next.definesAt(sv, bb1, i1, _)))
]
else nFrom = nodeFrom
exists(SourceVariable v |
nodeFrom != nodeTo and
DataFlowIntegrationImpl::localFlowStep(v, fromDfNode(nodeFrom, v), fromDfNode(nodeTo, v), _)
)
}
}

View File

@@ -1445,7 +1445,7 @@ private class ExplicitParameterInstructionNode extends AbstractExplicitParameter
ExplicitParameterInstructionNode() { exists(instr.getParameter()) }
override predicate isSourceParameterOf(Function f, ParameterPosition pos) {
f.getParameter(pos.(DirectPosition).getIndex()) = instr.getParameter()
f.getParameter(pos.(DirectPosition).getArgumentIndex()) = instr.getParameter()
}
override string toStringImpl() { result = instr.getParameter().toString() }
@@ -1460,7 +1460,7 @@ class ThisParameterInstructionNode extends AbstractExplicitParameterNode,
ThisParameterInstructionNode() { instr.getIRVariable() instanceof IRThisVariable }
override predicate isSourceParameterOf(Function f, ParameterPosition pos) {
pos.(DirectPosition).getIndex() = -1 and
pos.(DirectPosition).getArgumentIndex() = -1 and
instr.getEnclosingFunction() = f
}
@@ -1494,7 +1494,7 @@ private class DirectBodyLessParameterNode extends AbstractExplicitParameterNode,
override predicate isSourceParameterOf(Function f, ParameterPosition pos) {
this.getFunction() = f and
f.getParameter(pos.(DirectPosition).getIndex()) = p
f.getParameter(pos.(DirectPosition).getArgumentIndex()) = p
}
override Parameter getParameter() { result = p }

View File

@@ -956,8 +956,6 @@ class GlobalDef extends Definition {
private module SsaImpl = SsaImplCommon::Make<Location, SsaInput>;
private module DataFlowIntegrationInput implements SsaImpl::DataFlowIntegrationInputSig {
private import codeql.util.Void
class Expr extends Instruction {
Expr() {
exists(IRBlock bb, int i |
@@ -977,13 +975,7 @@ private module DataFlowIntegrationInput implements SsaImpl::DataFlowIntegrationI
)
}
predicate ssaDefAssigns(SsaImpl::WriteDefinition def, Expr value) { none() }
class Parameter extends Void {
Location getLocation() { none() }
}
predicate ssaDefInitializesParam(SsaImpl::WriteDefinition def, Parameter p) { none() }
predicate ssaDefHasSource(SsaImpl::WriteDefinition def) { none() }
predicate allowFlowIntoUncertainDef(SsaImpl::UncertainWriteDefinition def) { any() }
@@ -1007,9 +999,11 @@ private module DataFlowIntegrationInput implements SsaImpl::DataFlowIntegrationI
}
}
predicate guardControlsBlock(Guard guard, SsaInput::BasicBlock bb, boolean branch) {
predicate guardDirectlyControlsBlock(Guard guard, SsaInput::BasicBlock bb, boolean branch) {
guard.(IRGuards::IRGuardCondition).controls(bb, branch)
}
predicate keepAllPhiInputBackEdges() { any() }
}
private module DataFlowIntegrationImpl = SsaImpl::DataFlowIntegration<DataFlowIntegrationInput>;
@@ -1075,7 +1069,7 @@ module BarrierGuard<guardChecksNodeSig/3 guardChecksNode> {
bindingset[result, v]
pragma[inline_late]
DataFlowIntegrationImpl::Node fromDfNode(Node n, SourceVariable v) {
private DataFlowIntegrationImpl::Node fromDfNode(Node n, SourceVariable v) {
result = n.(SsaSynthNode).getSynthNode()
or
exists(UseImpl use, IRBlock bb, int i |

View File

@@ -229,11 +229,11 @@ private module SpeculativeTaintFlow {
not exists(DataFlowDispatch::viableCallable(call)) and
src.(DataFlowPrivate::ArgumentNode).argumentOf(call, argpos)
|
not argpos.(DirectPosition).getIndex() = -1 and
not argpos.(DirectPosition).getArgumentIndex() = -1 and
sink.(PostUpdateNode)
.getPreUpdateNode()
.(DataFlowPrivate::ArgumentNode)
.argumentOf(call, any(DirectPosition qualpos | qualpos.getIndex() = -1))
.argumentOf(call, any(DirectPosition qualpos | qualpos.getArgumentIndex() = -1))
or
sink.(DataFlowPrivate::OutNode).getCall() = call
)

View File

@@ -2039,7 +2039,8 @@ aggregate_field_init(
int aggregate: @aggregateliteral ref,
int initializer: @expr ref,
int field: @membervariable ref,
int position: int ref
int position: int ref,
boolean is_designated: boolean ref
);
/**
@@ -2051,7 +2052,8 @@ aggregate_array_init(
int aggregate: @aggregateliteral ref,
int initializer: @expr ref,
int element_index: int ref,
int position: int ref
int position: int ref,
boolean is_designated: boolean ref
);
@ctorinit = @ctordirectinit
@@ -2178,6 +2180,8 @@ variable_vla(
int decl: @stmt_vla_decl ref
);
type_is_vla(unique int type_id: @derivedtype ref)
if_initialization(
unique int if_stmt: @stmt_if ref,
int init_id: @stmt ref

File diff suppressed because it is too large Load Diff

View File

@@ -0,0 +1,11 @@
class Expr extends @expr {
string toString() { none() }
}
class AggregateLiteral extends Expr, @aggregateliteral {
override string toString() { none() }
}
from AggregateLiteral aggregate, Expr initializer, int element_index, int position
where aggregate_array_init(aggregate, initializer, element_index, position)
select aggregate, initializer, element_index, position, false

View File

@@ -0,0 +1,15 @@
class Expr extends @expr {
string toString() { none() }
}
class AggregateLiteral extends Expr, @aggregateliteral {
override string toString() { none() }
}
class MemberVariable extends @membervariable {
string toString() { none() }
}
from AggregateLiteral aggregate, Expr initializer, MemberVariable field, int position
where aggregate_field_init(aggregate, initializer, field, position)
select aggregate, initializer, field, position, false

File diff suppressed because it is too large Load Diff

View File

@@ -0,0 +1,4 @@
description: add `hasDesignator` predicate to `ArrayOrVectorAggregateLiteral` and `ClassAggregateLiteral`
compatibility: backwards
aggregate_array_init.rel: run aggregate_array_init.qlo
aggregate_field_init.rel: run aggregate_field_init.qlo

File diff suppressed because it is too large Load Diff

View File

@@ -0,0 +1,2 @@
description: Add a new predicate `isVla()` to the `ArrayType` class
compatibility: backwards

View File

@@ -1,3 +1,14 @@
## 1.3.8
No user-facing changes.
## 1.3.7
### Minor Analysis Improvements
* Fixed a bug in the models for Microsoft's Active Template Library (ATL).
* The query "Use of basic integral type" (`cpp/jpl-c/basic-int-types`) no longer produces alerts for the standard fixed width integer types (`int8_t`, `uint8_t`, etc.), and the `_Bool` and `bool` types.
## 1.3.6
No user-facing changes.

View File

@@ -14,5 +14,5 @@ where
or
warning instanceof ExtractionUnknownProblem
select warning,
"Extraction failed in " + warning.getFile() + " with warning " + warning.getProblemMessage(),
warning.getSeverity()
"Extraction failed in " + warning.getFile() + " with warning " +
warning.getProblemMessage().replaceAll("$", "$$"), warning.getSeverity()

View File

@@ -17,5 +17,6 @@ from ExtractionError error
where
error instanceof ExtractionUnknownError or
exists(error.getFile().getRelativePath())
select error, "Extraction failed in " + error.getFile() + " with error " + error.getErrorMessage(),
error.getSeverity()
select error,
"Extraction failed in " + error.getFile() + " with error " +
error.getErrorMessage().replaceAll("$", "$$"), error.getSeverity()

View File

@@ -1,4 +0,0 @@
---
category: minorAnalysis
---
* Fixed a bug in the models for Microsoft's Active Template Library (ATL).

View File

@@ -1,4 +1,6 @@
---
category: minorAnalysis
---
* The query "Use of basic integral type" (`cpp/jpl-c/basic-int-types`) no longer produces alerts for the standard fixed width integer types (`int8_t`, `uint8_t`, etc.), and the `_Bool` and `bool` types.
## 1.3.7
### Minor Analysis Improvements
* Fixed a bug in the models for Microsoft's Active Template Library (ATL).
* The query "Use of basic integral type" (`cpp/jpl-c/basic-int-types`) no longer produces alerts for the standard fixed width integer types (`int8_t`, `uint8_t`, etc.), and the `_Bool` and `bool` types.

View File

@@ -0,0 +1,3 @@
## 1.3.8
No user-facing changes.

View File

@@ -1,2 +1,2 @@
---
lastReleaseVersion: 1.3.6
lastReleaseVersion: 1.3.8

Some files were not shown because too many files have changed in this diff Show More