Compare commits

..

1 Commits

Author SHA1 Message Date
copilot-swe-agent[bot]
53eb5fdf29 Initial plan 2026-05-28 12:19:39 +00:00
4011 changed files with 42272 additions and 127704 deletions

View File

@@ -1,208 +0,0 @@
name: Update Go version
on:
workflow_dispatch:
schedule:
- cron: "0 3 * * 1" # Run weekly on Mondays at 3 AM UTC (1 = Monday)
permissions:
contents: write
pull-requests: write
jobs:
update-go-version:
name: Check and update Go version
if: github.repository == 'github/codeql'
runs-on: ubuntu-latest
steps:
- name: Checkout repository
uses: actions/checkout@v5
with:
fetch-depth: 0
- name: Set up Git
run: |
git config user.name "github-actions[bot]"
git config user.email "41898282+github-actions[bot]@users.noreply.github.com"
- name: Fetch latest Go version
id: fetch-version
run: |
LATEST_GO_VERSION=$(curl -s https://go.dev/dl/?mode=json | jq -r '.[0].version')
if [ -z "$LATEST_GO_VERSION" ] || [ "$LATEST_GO_VERSION" = "null" ]; then
echo "Error: Failed to fetch latest Go version from go.dev"
exit 1
fi
echo "Latest Go version from go.dev: $LATEST_GO_VERSION"
echo "version=$LATEST_GO_VERSION" >> $GITHUB_OUTPUT
# Extract version numbers (e.g., go1.26.0 -> 1.26.0)
LATEST_VERSION_NUM=$(echo $LATEST_GO_VERSION | sed 's/^go//')
echo "version_num=$LATEST_VERSION_NUM" >> $GITHUB_OUTPUT
# Extract major.minor version (e.g., 1.26.0 -> 1.26)
LATEST_MAJOR_MINOR=$(echo $LATEST_VERSION_NUM | sed -E 's/^([0-9]+\.[0-9]+).*/\1/')
echo "major_minor=$LATEST_MAJOR_MINOR" >> $GITHUB_OUTPUT
- name: Check current Go version
id: current-version
run: |
CURRENT_VERSION=$(sed -n 's/.*go_sdk\.download(version = \"\([^\"]*\)\".*/\1/p' MODULE.bazel)
if [ -z "$CURRENT_VERSION" ]; then
echo "Error: Could not extract Go version from MODULE.bazel"
exit 1
fi
echo "Current Go version in MODULE.bazel: $CURRENT_VERSION"
echo "version=$CURRENT_VERSION" >> $GITHUB_OUTPUT
# Extract major.minor version
CURRENT_MAJOR_MINOR=$(echo $CURRENT_VERSION | sed -E 's/^([0-9]+\.[0-9]+).*/\1/')
echo "major_minor=$CURRENT_MAJOR_MINOR" >> $GITHUB_OUTPUT
- name: Compare versions
id: compare
run: |
LATEST="${{ steps.fetch-version.outputs.version_num }}"
CURRENT="${{ steps.current-version.outputs.version }}"
echo "Latest: $LATEST"
echo "Current: $CURRENT"
if [ "$LATEST" = "$CURRENT" ]; then
echo "Go version is up to date"
echo "needs_update=false" >> $GITHUB_OUTPUT
else
echo "Go version needs update from $CURRENT to $LATEST"
echo "needs_update=true" >> $GITHUB_OUTPUT
fi
- name: Update Go version in files
if: steps.compare.outputs.needs_update == 'true'
run: |
LATEST_VERSION_NUM="${{ steps.fetch-version.outputs.version_num }}"
LATEST_MAJOR_MINOR="${{ steps.fetch-version.outputs.major_minor }}"
CURRENT_VERSION="${{ steps.current-version.outputs.version }}"
CURRENT_MAJOR_MINOR="${{ steps.current-version.outputs.major_minor }}"
echo "Updating from $CURRENT_VERSION to $LATEST_VERSION_NUM"
# Escape dots in current version strings for use in sed patterns
CURRENT_VERSION_ESCAPED=$(echo "$CURRENT_VERSION" | sed 's/\./\\./g')
CURRENT_MAJOR_MINOR_ESCAPED=$(echo "$CURRENT_MAJOR_MINOR" | sed 's/\./\\./g')
# Update MODULE.bazel
sed -i "s/go_sdk\.download(version = \"$CURRENT_VERSION_ESCAPED\")/go_sdk.download(version = \"$LATEST_VERSION_NUM\")/" MODULE.bazel
if ! grep -q "go_sdk.download(version = \"$LATEST_VERSION_NUM\")" MODULE.bazel; then
echo "Error: Failed to update MODULE.bazel"
exit 1
fi
# Update go/extractor/go.mod
if ! sed -i "s/^go $CURRENT_MAJOR_MINOR_ESCAPED\$/go $LATEST_MAJOR_MINOR/" go/extractor/go.mod; then
echo "Warning: Failed to update go directive in go.mod"
fi
if ! sed -i "s/^toolchain go$CURRENT_VERSION_ESCAPED\$/toolchain go$LATEST_VERSION_NUM/" go/extractor/go.mod; then
echo "Warning: Failed to update toolchain in go.mod"
fi
# Update go/extractor/autobuilder/build-environment.go
if ! sed -i "s/var maxGoVersion = util\.NewSemVer(\"$CURRENT_MAJOR_MINOR_ESCAPED\")/var maxGoVersion = util.NewSemVer(\"$LATEST_MAJOR_MINOR\")/" go/extractor/autobuilder/build-environment.go; then
echo "Warning: Failed to update build-environment.go"
fi
# Update go/actions/test/action.yml
if ! sed -i "s/default: \"~$CURRENT_VERSION_ESCAPED\"/default: \"~$LATEST_VERSION_NUM\"/" go/actions/test/action.yml; then
echo "Warning: Failed to update action.yml"
fi
# Show what changed
git diff
- name: Check for changes
id: check-changes
if: steps.compare.outputs.needs_update == 'true'
run: |
if git diff --quiet; then
echo "No changes detected"
echo "has_changes=false" >> $GITHUB_OUTPUT
else
echo "Changes detected"
echo "has_changes=true" >> $GITHUB_OUTPUT
fi
- name: Check for existing PR
if: steps.check-changes.outputs.has_changes == 'true'
id: check-pr
env:
GH_TOKEN: ${{ secrets.GITHUB_TOKEN }}
run: |
BRANCH_NAME="workflow/go-version-update"
PR_NUMBER=$(gh pr list --head "$BRANCH_NAME" --state open --json number --jq '.[0].number')
if [ -n "$PR_NUMBER" ]; then
echo "Existing PR found: #$PR_NUMBER"
echo "pr_exists=true" >> $GITHUB_OUTPUT
echo "pr_number=$PR_NUMBER" >> $GITHUB_OUTPUT
else
echo "No existing PR found"
echo "pr_exists=false" >> $GITHUB_OUTPUT
fi
- name: Commit and push changes
if: steps.check-changes.outputs.has_changes == 'true'
run: |
BRANCH_NAME="workflow/go-version-update"
LATEST_VERSION_NUM="${{ steps.fetch-version.outputs.version_num }}"
LATEST_MAJOR_MINOR="${{ steps.fetch-version.outputs.major_minor }}"
# Create or switch to branch
git checkout -B "$BRANCH_NAME"
# Stage and commit changes
git add MODULE.bazel go/extractor/go.mod go/extractor/autobuilder/build-environment.go go/actions/test/action.yml
git commit -m "Go: Update to $LATEST_VERSION_NUM"
# Push changes
git push --force-with-lease origin "$BRANCH_NAME"
- name: Create or update PR
if: steps.check-changes.outputs.has_changes == 'true'
env:
GH_TOKEN: ${{ secrets.GITHUB_TOKEN }}
run: |
BRANCH_NAME="workflow/go-version-update"
LATEST_VERSION_NUM="${{ steps.fetch-version.outputs.version_num }}"
CURRENT_VERSION="${{ steps.current-version.outputs.version }}"
PR_TITLE="Go: Update to $LATEST_VERSION_NUM"
PR_BODY=$(cat <<EOF
This PR updates Go from $CURRENT_VERSION to $LATEST_VERSION_NUM.
Updated files:
- \`MODULE.bazel\` - go_sdk.download version
- \`go/extractor/go.mod\` - go directive and toolchain
- \`go/extractor/autobuilder/build-environment.go\` - maxGoVersion (only if MAJOR.MINOR changes)
- \`go/actions/test/action.yml\` - default go-test-version
This PR was automatically created by the [Go version update workflow](https://github.com/${{ github.repository }}/blob/main/.github/workflows/go-version-update.yml).
EOF
)
if [ "${{ steps.check-pr.outputs.pr_exists }}" = "true" ]; then
echo "Updating existing PR #${{ steps.check-pr.outputs.pr_number }}"
gh pr edit "${{ steps.check-pr.outputs.pr_number }}" --title "$PR_TITLE" --body "$PR_BODY"
else
echo "Creating new PR"
gh pr create \
--title "$PR_TITLE" \
--body "$PR_BODY" \
--base main \
--head "$BRANCH_NAME" \
--label "Go"
fi

View File

@@ -2,7 +2,7 @@
* @github/code-scanning-alert-coverage
# CodeQL language libraries
/actions/ @github/code-scanning-alert-coverage
/actions/ @github/codeql-dynamic
/cpp/ @github/codeql-c-analysis
/csharp/ @github/codeql-csharp
/csharp/autobuilder/Semmle.Autobuild.Cpp @github/codeql-c-extractor @github/code-scanning-language-coverage
@@ -59,5 +59,9 @@ MODULE.bazel @github/codeql-ci-reviewers
/.github/workflows/rust.yml @github/codeql-rust
/.github/workflows/swift.yml @github/codeql-swift
# Misc
/misc/scripts/accept-expected-changes-from-ci.py @RasmusWL
/misc/scripts/generate-code-scanning-query-list.py @RasmusWL
# .devcontainer
/.devcontainer/ @github/codeql-ci-reviewers

View File

@@ -248,7 +248,6 @@ use_repo(
"kotlin-compiler-2.2.20-Beta2",
"kotlin-compiler-2.3.0",
"kotlin-compiler-2.3.20",
"kotlin-compiler-2.4.0",
"kotlin-compiler-embeddable-1.8.0",
"kotlin-compiler-embeddable-1.9.0-Beta",
"kotlin-compiler-embeddable-1.9.20-Beta",
@@ -260,7 +259,6 @@ use_repo(
"kotlin-compiler-embeddable-2.2.20-Beta2",
"kotlin-compiler-embeddable-2.3.0",
"kotlin-compiler-embeddable-2.3.20",
"kotlin-compiler-embeddable-2.4.0",
"kotlin-stdlib-1.8.0",
"kotlin-stdlib-1.9.0-Beta",
"kotlin-stdlib-1.9.20-Beta",
@@ -272,11 +270,10 @@ use_repo(
"kotlin-stdlib-2.2.20-Beta2",
"kotlin-stdlib-2.3.0",
"kotlin-stdlib-2.3.20",
"kotlin-stdlib-2.4.0",
)
go_sdk = use_extension("@rules_go//go:extensions.bzl", "go_sdk")
go_sdk.download(version = "1.26.4")
go_sdk.download(version = "1.26.0")
go_deps = use_extension("@gazelle//:extensions.bzl", "go_deps")
go_deps.from_file(go_mod = "//go/extractor:go.mod")

View File

@@ -1,16 +1,3 @@
## 0.4.38
### Bug Fixes
* GitHub Actions queries now better account for permission checks on jobs that call reusable workflows.
* The query `actions/pr-on-self-hosted-runner` was updated to the latest standard runner labels reducing false positive results.
## 0.4.37
### Minor Analysis Improvements
* The GitHub Actions analysis now recognizes more Bash regex checks that restrict a value to alphanumeric characters, including regexes like `^[0-9a-zA-Z]{40}([0-9a-zA-Z]{24})?$` which check for a SHA-1 or SHA-256 hash. This may reduce false positive results where command output is validated with grouped or optional alphanumeric patterns before being used.
## 0.4.36
### Minor Analysis Improvements

View File

@@ -0,0 +1,4 @@
---
category: minorAnalysis
---
* The GitHub Actions analysis now recognizes more Bash regex checks that restrict a value to alphanumeric characters, include regexes like `^[0-9a-zA-Z]{40}([0-9a-zA-Z]{24})?$` which check for a sha1 or sha256 hash. This may reduce false positive results where command output is validated with grouped or optional alphanumeric patterns before being used.

View File

@@ -1,5 +0,0 @@
## 0.4.37
### Minor Analysis Improvements
* The GitHub Actions analysis now recognizes more Bash regex checks that restrict a value to alphanumeric characters, including regexes like `^[0-9a-zA-Z]{40}([0-9a-zA-Z]{24})?$` which check for a SHA-1 or SHA-256 hash. This may reduce false positive results where command output is validated with grouped or optional alphanumeric patterns before being used.

View File

@@ -1,6 +0,0 @@
## 0.4.38
### Bug Fixes
* GitHub Actions queries now better account for permission checks on jobs that call reusable workflows.
* The query `actions/pr-on-self-hosted-runner` was updated to the latest standard runner labels reducing false positive results.

View File

@@ -1,2 +1,2 @@
---
lastReleaseVersion: 0.4.38
lastReleaseVersion: 0.4.36

View File

@@ -1920,5 +1920,3 @@ private YamlMappingLikeNode resolveMatrixAccessPath(
else result = resolveMatrixAccessPath(newRoot, rest)
)
}
class Comment = YamlComment;

View File

@@ -52,12 +52,6 @@ private module YamlSig implements LibYaml::InputSig {
class ParseErrorBase extends LocatableBase, @yaml_error {
string getMessage() { yaml_errors(this, result) }
}
class CommentBase extends LocatableBase, @yaml_comment {
string getText() { yaml_comments(this, result, _) }
override string toString() { yaml_comments(this, _, result) }
}
}
import LibYaml::Make<YamlSig>

View File

@@ -42,15 +42,6 @@ string actor_not_attacker_event() {
]
}
/**
* Gets the outer caller of `ej`, i.e. the `ExternalJob` that calls the
* reusable workflow containing `ej`. Used with transitive closure to
* walk up nested reusable workflow chains.
*/
private ExternalJob getAnOuterCaller(ExternalJob ej) {
result = ej.getEnclosingWorkflow().(ReusableWorkflow).getACaller()
}
/** An If node that contains an actor, user or label check */
abstract class ControlCheck extends AstNode {
ControlCheck() {
@@ -62,170 +53,43 @@ abstract class ControlCheck extends AstNode {
predicate protects(AstNode node, Event event, string category) {
// The check dominates the step it should protect
this.dominates(node, event) and
this.dominates(node) and
// The check is effective against the event and category
this.protectsCategoryAndEvent(category, event.getName()) and
// The check can be triggered by the event
this.getATriggerEvent() = event and
// For reusable workflows, there must be no unprotected caller chain for this event.
(
not node.getEnclosingWorkflow() instanceof ReusableWorkflow
or
this.dominatesSameWorkflow(node, event)
or
not exists(ExternalJob directCaller |
directCaller = node.getEnclosingWorkflow().(ReusableWorkflow).getACaller() and
unprotectedCallerChain(directCaller, event, category)
)
)
this.getATriggerEvent() = event
}
/**
* Holds if this control check must execute and pass before `node` can run.
*/
predicate dominates(AstNode node, Event event) {
this.dominatesSameWorkflow(node, event)
or
// When the node is inside a reusable workflow,
// this check dominates via at least one caller chain.
this.dominatesViaCaller(node, event, _)
}
/**
* Holds if this control check dominates `node` within the same workflow.
*/
predicate dominatesSameWorkflow(AstNode node, Event event) {
this.getATriggerEvent() = event and
(
// Step-level: the check is an `if:` on the step containing `node`,
// or on the enclosing job, or on a needed job/step.
this instanceof If and
(
node.getEnclosingStep().getIf() = this or
node.getEnclosingJob().getIf() = this or
node.getEnclosingJob().getANeededJob().(LocalJob).getAStep().getIf() = this or
node.getEnclosingJob().getANeededJob().(LocalJob).getIf() = this
)
or
// Job-level: the check is an environment on the enclosing job or a needed job.
this instanceof Environment and
(
node.getEnclosingJob().getEnvironment() = this
or
node.getEnclosingJob().getANeededJob().getEnvironment() = this
)
or
// Step-level: the check is a Run/UsesStep that precedes `node`'s step
// in the same job, or is a step in a needed job.
(
this instanceof Run or
this instanceof UsesStep
) and
(
this.(Step).getAFollowingStep() = node.getEnclosingStep()
or
node.getEnclosingJob().getANeededJob().(LocalJob).getAStep() = this
)
)
}
/**
* Holds if this control check dominates `node` in a reusable workflow
* via the caller chain starting at `directCaller`.
*/
predicate dominatesViaCaller(AstNode node, Event event, ExternalJob directCaller) {
directCaller = node.getEnclosingWorkflow().(ReusableWorkflow).getACaller() and
directCaller.getATriggerEvent() = event and
exists(ExternalJob caller |
caller = getAnOuterCaller*(directCaller) and
this.dominatesCaller(caller)
)
}
/**
* Holds if this control check directly dominates `caller`.
*/
predicate dominatesCaller(ExternalJob caller) {
predicate dominates(AstNode node) {
this instanceof If and
(
caller.getIf() = this or
caller.getANeededJob().(LocalJob).getIf() = this or
caller.getANeededJob().(LocalJob).getAStep().getIf() = this
node.getEnclosingStep().getIf() = this or
node.getEnclosingJob().getIf() = this or
node.getEnclosingJob().getANeededJob().(LocalJob).getAStep().getIf() = this or
node.getEnclosingJob().getANeededJob().(LocalJob).getIf() = this
)
or
this instanceof Environment and
(
caller.getEnvironment() = this or
caller.getANeededJob().getEnvironment() = this
node.getEnclosingJob().getEnvironment() = this
or
node.getEnclosingJob().getANeededJob().getEnvironment() = this
)
or
(this instanceof Run or this instanceof UsesStep) and
caller.getANeededJob().(LocalJob).getAStep() = this
(
this instanceof Run or
this instanceof UsesStep
) and
(
this.(Step).getAFollowingStep() = node.getEnclosingStep()
or
node.getEnclosingJob().getANeededJob().(LocalJob).getAStep() = this.(Step)
)
}
abstract predicate protectsCategoryAndEvent(string category, string event);
}
/**
* Holds if this control check directly protects `caller`.
*/
bindingset[caller, event, category]
private predicate protectedCaller(ExternalJob caller, Event event, string category) {
exists(ControlCheck check |
check.protectsCategoryAndEvent(category, event.getName()) and
check.getATriggerEvent() = event and
check.dominatesCaller(caller)
)
}
cached
private newtype TCallerState =
MkCallerState(ExternalJob caller, Event event, string category) {
caller.getATriggerEvent() = event and
category = any_category()
}
private class CallerState extends TCallerState, MkCallerState {
ExternalJob caller;
Event event;
string category;
CallerState() { this = MkCallerState(caller, event, category) }
ExternalJob getCaller() { result = caller }
Event getEvent() { result = event }
string getCategory() { result = category }
/**
* Gets an outer caller state if this caller is not protected.
*/
CallerState getUnprotectedOuterState() {
not protectedCaller(this.getCaller(), this.getEvent(), this.getCategory()) and
result = MkCallerState(getAnOuterCaller(this.getCaller()), this.getEvent(), this.getCategory())
}
predicate isUnprotectedOutermost() {
not protectedCaller(this.getCaller(), this.getEvent(), this.getCategory()) and
not exists(getAnOuterCaller(this.getCaller()))
}
string toString() { result = caller + " / " + event + " / " + category }
}
/**
* Holds if there is a caller path from `caller` to an outer workflow that has no protection.
*/
bindingset[caller, event, category]
private predicate unprotectedCallerChain(ExternalJob caller, Event event, string category) {
exists(CallerState start, CallerState outermost |
start = MkCallerState(caller, event, category) and
outermost = start.getUnprotectedOuterState*() and
outermost.isUnprotectedOutermost()
)
}
abstract class AssociationCheck extends ControlCheck {
// Checks if the actor is a MEMBER/OWNER the repo
// - they are effective against pull requests and workflow_run (since these are triggered by pull_requests) since they can control who is making the PR

View File

@@ -2,12 +2,10 @@ import actions
bindingset[runner]
predicate isGithubHostedRunner(string runner) {
// The list of github hosted repos:
// https://github.com/actions/runner-images/blob/main/README.md#available-images
// https://docs.github.com/en/enterprise-cloud@latest/actions/how-tos/write-workflows/choose-where-workflows-run/choose-the-runner-for-a-job#standard-github-hosted-runners-for-public-repositories
runner.toLowerCase().regexpMatch("^ubuntu-([0-9.]+|latest|slim)(-arm)?$") or
runner.toLowerCase().regexpMatch("^macos-([0-9]+|latest)(-x?large|-intel)?$") or
runner.toLowerCase().regexpMatch("^windows-([0-9.]+|latest)(-vs[0-9.]+)?(-arm)?$")
// list of github hosted repos: https://github.com/actions/runner-images/blob/main/README.md#available-images
runner
.toLowerCase()
.regexpMatch("^(ubuntu-([0-9.]+|latest)|macos-([0-9]+|latest)(-x?large)?|windows-([0-9.]+|latest))$")
}
bindingset[runner]

View File

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

View File

@@ -1,28 +1,3 @@
## 0.6.30
### Query Metadata Changes
* The name, description, and alert message of `actions/untrusted-checkout/medium` have been corrected to describe a non-privileged context.
## 0.6.29
### Query Metadata Changes
* Reversed adjustment of the name of `actions/untrusted-checkout/high`, but kept the portion of the previous change for the word "trusted" to "privileged". Added a missing "a" to phrasing in `actions/untrusted-checkout/high` and `actions/untrusted-checkout/medium`.
### Major Analysis Improvements
* Adjusted `actions/untrusted-checkout/critical` to align more with other untrusted resource queries, where the alert location is the location where the artifact is obtained from (the checkout point). This aligns with the other 2 related queries. This will cause the same alerts to re-open for closed alerts of this query.
### Minor Analysis Improvements
* Altered the alert message for clarity for queries: `actions/untrusted-checkout/critical`, `actions/untrusted-checkout/high`.
* The `actions/unpinned-tag` query now recognizes 64-character SHA-256 commit hashes as properly pinned references, in addition to 40-character SHA-1 hashes.
### Bug Fixes
* Adjusted (minor) help file descriptions for queries: `actions/untrusted-checkout/critical`, `actions/untrusted-checkout/high`, `actions/untrusted-checkout/medium`. Clarified wording on a minor point, added one more listed resource and added one more recommendation for things to check.
## 0.6.28
### Query Metadata Changes

View File

@@ -18,7 +18,7 @@ from LocalJob job, LabelCheck check, MutableRefCheckoutStep checkout, Event even
where
job.isPrivileged() and
job.getAStep() = checkout and
check.dominates(checkout, event) and
check.dominates(checkout) and
(
job.getATriggerEvent() = event and
event.getName() = "pull_request_target" and

View File

@@ -34,8 +34,8 @@ where
check instanceof AssociationCheck or
check instanceof PermissionCheck
) and
check.dominates(checkout, event) and
date_check.dominates(checkout, event)
check.dominates(checkout) and
date_check.dominates(checkout)
)
or
// not issue_comment triggered workflows

View File

@@ -1,8 +1,8 @@
/**
* @name Checkout of untrusted code in a non-privileged context
* @description Checking out and running the build script from a fork executes untrusted code. Even in a
* non-privileged workflow, this can be abused, for example to compromise self-hosted runners
* or to poison caches and artifacts that are later consumed by privileged workflows.
* @name Checkout of untrusted code in a trusted 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.
* @kind problem
* @problem.severity warning
* @precision medium
@@ -20,4 +20,4 @@ from PRHeadCheckoutStep checkout
where
// the checkout occurs in a non-privileged context
inNonPrivilegedContext(checkout)
select checkout, "Potential unsafe checkout of untrusted pull request on non-privileged workflow."
select checkout, "Potential unsafe checkout of untrusted pull request on privileged workflow."

View File

@@ -0,0 +1,4 @@
---
category: majorAnalysis
---
* Adjusted `actions/untrusted-checkout/critical` to align more with other untrusted resource queries, where the alert location is the location where the artifact is obtained from (the checkout point). This aligns with the other 2 related queries. This will cause the same alerts to re-open for closed alerts of this query.

View File

@@ -0,0 +1,4 @@
---
category: minorAnalysis
---
* The `actions/unpinned-tag` query now recognizes 64-character SHA-256 commit hashes as properly pinned references, in addition to 40-character SHA-1 hashes.

View File

@@ -0,0 +1,4 @@
---
category: minorAnalysis
---
* Altered the alert message for clarity for queries: `actions/untrusted-checkout/critical`, `actions/untrusted-checkout/high`.

View File

@@ -0,0 +1,4 @@
---
category: fix
---
* Adjusted (minor) help file descriptions for queries: `actions/untrusted-checkout/critical`, `actions/untrusted-checkout/high`, `actions/untrusted-checkout/medium`. Clarified wording on in minor point, added one more listed resource and added one more recommendation for things to check.

View File

@@ -0,0 +1,4 @@
---
category: queryMetadata
---
* Reversed adjustment of the name of `actions/untrusted-checkout/high`, but kept the portion of the previous change for the word "trusted" to "privileged". Added a missing "a" to phrasing in `actions/untrusted-checkout/high` and `actions/untrusted-checkout/medium`.

View File

@@ -1,18 +0,0 @@
## 0.6.29
### Query Metadata Changes
* Reversed adjustment of the name of `actions/untrusted-checkout/high`, but kept the portion of the previous change for the word "trusted" to "privileged". Added a missing "a" to phrasing in `actions/untrusted-checkout/high` and `actions/untrusted-checkout/medium`.
### Major Analysis Improvements
* Adjusted `actions/untrusted-checkout/critical` to align more with other untrusted resource queries, where the alert location is the location where the artifact is obtained from (the checkout point). This aligns with the other 2 related queries. This will cause the same alerts to re-open for closed alerts of this query.
### Minor Analysis Improvements
* Altered the alert message for clarity for queries: `actions/untrusted-checkout/critical`, `actions/untrusted-checkout/high`.
* The `actions/unpinned-tag` query now recognizes 64-character SHA-256 commit hashes as properly pinned references, in addition to 40-character SHA-1 hashes.
### Bug Fixes
* Adjusted (minor) help file descriptions for queries: `actions/untrusted-checkout/critical`, `actions/untrusted-checkout/high`, `actions/untrusted-checkout/medium`. Clarified wording on a minor point, added one more listed resource and added one more recommendation for things to check.

View File

@@ -1,5 +0,0 @@
## 0.6.30
### Query Metadata Changes
* The name, description, and alert message of `actions/untrusted-checkout/medium` have been corrected to describe a non-privileged context.

View File

@@ -1,2 +1,2 @@
---
lastReleaseVersion: 0.6.30
lastReleaseVersion: 0.6.28

View File

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

View File

@@ -1,43 +0,0 @@
name: test
on:
pull_request:
jobs:
test:
strategy:
fail-fast: false
matrix:
os:
- ubuntu-latest
- ubuntu-24.04
- ubuntu-24.04-arm
- ubuntu-22.04
- ubuntu-22.04-arm
- ubuntu-26.04
- ubuntu-26.04-arm
- ubuntu-slim
- macos-26
- macos-26-xlarge
- macos-26-intel
- macos-26-large
- macos-latest-large
- macos-15-large
- macos-15
- macos-15-intel
- macos-latest
- macos-15
- macos-15-xlarge
- macos-14-large
- macos-14
- macos-14-xlarge
- windows-2025-vs2026
- windows-latest
- windows-2025
- windows-2022
- windows-11
- windows-11-arm
- windows-11-vs2026-arm
runs-on: ${{ matrix.os }}
steps:
- run: cmd

View File

@@ -1,17 +0,0 @@
on:
workflow_call:
inputs:
COMMIT_SHA:
type: string
jobs:
build:
runs-on: ubuntu-latest
steps:
- uses: actions/checkout@v6
with:
ref: ${{ inputs.COMMIT_SHA }}
- run: |
npm install
npm run lint

View File

@@ -1,13 +0,0 @@
on:
workflow_call:
inputs:
COMMIT_SHA:
type: string
jobs:
build:
uses: TestOrg/TestRepo/.github/workflows/build.yml@main
with:
COMMIT_SHA: ${{ inputs.COMMIT_SHA }}

View File

@@ -1,33 +0,0 @@
on:
workflow_call:
inputs:
COMMIT_SHA:
type: string
jobs:
is-collaborator:
runs-on: ubuntu-latest
steps:
- name: Get User Permission
id: checkAccess
uses: actions-cool/check-user-permission@cd622002ff25c2311d2e7fb82107c0d24be83f9b
with:
require: write
username: ${{ github.actor }}
env:
GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }}
- name: Check User Permission
if: steps.checkAccess.outputs.require-result == 'false'
run: |
echo "${{ github.actor }} does not have permissions on this repo."
echo "Current permission level is ${{ steps.checkAccess.outputs.user-permission }}"
exit 1
build_safe:
needs: is-collaborator
uses: TestOrg/TestRepo/.github/workflows/build_nested.yml@main
with:
COMMIT_SHA: ${{ inputs.COMMIT_SHA }}
build_unsafe:
uses: TestOrg/TestRepo/.github/workflows/build_nested.yml@main
with:
COMMIT_SHA: ${{ inputs.COMMIT_SHA }}

View File

@@ -1,31 +0,0 @@
on:
pull_request_target:
jobs:
is-collaborator:
runs-on: ubuntu-latest
steps:
- name: Get User Permission
id: checkAccess
uses: actions-cool/check-user-permission@cd622002ff25c2311d2e7fb82107c0d24be83f9b
with:
require: write
username: ${{ github.actor }}
env:
GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }}
- name: Check User Permission
if: steps.checkAccess.outputs.require-result == 'false'
run: |
echo "${{ github.actor }} does not have permissions on this repo."
echo "Current permission level is ${{ steps.checkAccess.outputs.user-permission }}"
exit 1
build:
runs-on: ubuntu-latest
#needs: is-collaborator Mistake, doesn't wait for the collaborator - no security check
steps:
- name: Checkout repo
uses: actions/checkout@4
with:
ref: ${{ github.event.pull_request.head.sha }} # should alert
fetch-depth: 2
- run: yarn test

View File

@@ -1,26 +0,0 @@
on:
pull_request_target:
jobs:
is-collaborator:
runs-on: ubuntu-latest
steps:
- name: Get User Permission
id: checkAccess
uses: actions-cool/check-user-permission@cd622002ff25c2311d2e7fb82107c0d24be83f9b
with:
require: write
username: ${{ github.actor }}
env:
GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }}
- name: Check User Permission
if: steps.checkAccess.outputs.require-result == 'false'
run: |
echo "${{ github.actor }} does not have permissions on this repo."
echo "Current permission level is ${{ steps.checkAccess.outputs.user-permission }}"
exit 1
build:
needs: is-collaborator
uses: TestOrg/TestRepo/.github/workflows/build.yml@main
with:
COMMIT_SHA: ${{ github.event.pull_request.head.sha }} # shouldn't alert since permission check

View File

@@ -1,31 +0,0 @@
on:
pull_request_target:
jobs:
is-collaborator:
runs-on: ubuntu-latest
steps:
- name: Get User Permission
id: checkAccess
uses: actions-cool/check-user-permission@cd622002ff25c2311d2e7fb82107c0d24be83f9b
with:
require: write
username: ${{ github.actor }}
env:
GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }}
- name: Check User Permission
if: steps.checkAccess.outputs.require-result == 'false'
run: |
echo "${{ github.actor }} does not have permissions on this repo."
echo "Current permission level is ${{ steps.checkAccess.outputs.user-permission }}"
exit 1
build_unsafe:
# needs: is-collaborator
uses: TestOrg/TestRepo/.github/workflows/build.yml@main
with:
COMMIT_SHA: ${{ github.event.pull_request.head.sha }} # should alert since no permission check
build_safe:
needs: is-collaborator
uses: TestOrg/TestRepo/.github/workflows/build.yml@main
with:
COMMIT_SHA: ${{ github.event.pull_request.head.sha }} # shouldn't alert since permission check

View File

@@ -1,8 +0,0 @@
on:
pull_request_target:
jobs:
build:
uses: TestOrg/TestRepo/.github/workflows/build_nested_branching.yml@main
with:
COMMIT_SHA: ${{ github.event.pull_request.head.sha }}

View File

@@ -1,26 +0,0 @@
on:
pull_request_target:
jobs:
is-collaborator:
runs-on: ubuntu-latest
steps:
- name: Get User Permission
id: checkAccess
uses: actions-cool/check-user-permission@cd622002ff25c2311d2e7fb82107c0d24be83f9b
with:
require: write
username: ${{ github.actor }}
env:
GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }}
- name: Check User Permission
if: steps.checkAccess.outputs.require-result == 'false'
run: |
echo "${{ github.actor }} does not have permissions on this repo."
echo "Current permission level is ${{ steps.checkAccess.outputs.user-permission }}"
exit 1
build:
needs: is-collaborator
uses: TestOrg/TestRepo/.github/workflows/build_nested.yml@main
with:
COMMIT_SHA: ${{ github.event.pull_request.head.sha }} # shouldn't alert since permission check

View File

@@ -1,26 +0,0 @@
on:
pull_request_target:
jobs:
is-collaborator:
runs-on: ubuntu-latest
steps:
- name: Get User Permission
id: checkAccess
uses: actions-cool/check-user-permission@cd622002ff25c2311d2e7fb82107c0d24be83f9b
with:
require: write
username: ${{ github.actor }}
env:
GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }}
- name: Check User Permission
if: steps.checkAccess.outputs.require-result == 'false'
run: |
echo "${{ github.actor }} does not have permissions on this repo."
echo "Current permission level is ${{ steps.checkAccess.outputs.user-permission }}"
exit 1
build:
# needs: is-collaborator
uses: TestOrg/TestRepo/.github/workflows/build_nested.yml@main
with:
COMMIT_SHA: ${{ github.event.pull_request.head.sha }}

View File

@@ -1,41 +0,0 @@
on:
pull_request_target:
jobs:
is-collaborator:
runs-on: ubuntu-latest
steps:
- name: Get User Permission
id: checkAccess
uses: actions-cool/check-user-permission@cd622002ff25c2311d2e7fb82107c0d24be83f9b
with:
require: write
username: ${{ github.actor }}
env:
GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }}
- name: Check User Permission
if: steps.checkAccess.outputs.require-result == 'false'
run: |
echo "${{ github.actor }} does not have permissions on this repo."
echo "Current permission level is ${{ steps.checkAccess.outputs.user-permission }}"
exit 1
build:
runs-on: ubuntu-latest
needs: is-collaborator
steps:
- name: Checkout repo
uses: actions/checkout@4
with:
ref: ${{ github.event.pull_request.head.sha }} # shouldn't alert since permission check
fetch-depth: 2
- run: yarn test
build_unsafe:
runs-on: ubuntu-latest
# needs: is-collaborator
steps:
- name: Checkout repo
uses: actions/checkout@4
with:
ref: ${{ github.event.pull_request.head.sha }} # should alert since no permission check
fetch-depth: 2
- run: yarn test

View File

@@ -1,48 +0,0 @@
on:
pull_request_target:
jobs:
is-collaborator-a:
runs-on: ubuntu-latest
steps:
- name: Get User Permission
id: checkAccess
uses: actions-cool/check-user-permission@cd622002ff25c2311d2e7fb82107c0d24be83f9b
with:
require: write
username: ${{ github.actor }}
env:
GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }}
- name: Check User Permission
if: steps.checkAccess.outputs.require-result == 'false'
run: |
echo "${{ github.actor }} does not have permissions on this repo."
echo "Current permission level is ${{ steps.checkAccess.outputs.user-permission }}"
exit 1
caller-a:
needs: is-collaborator-a
uses: TestOrg/TestRepo/.github/workflows/build.yml@main
with:
COMMIT_SHA: ${{ github.event.pull_request.head.sha }}
is-collaborator-b:
runs-on: ubuntu-latest
steps:
- name: Get User Permission
id: checkAccess
uses: actions-cool/check-user-permission@cd622002ff25c2311d2e7fb82107c0d24be83f9b
with:
require: write
username: ${{ github.actor }}
env:
GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }}
- name: Check User Permission
if: steps.checkAccess.outputs.require-result == 'false'
run: |
echo "${{ github.actor }} does not have permissions on this repo."
echo "Current permission level is ${{ steps.checkAccess.outputs.user-permission }}"
exit 1
caller-b:
needs: is-collaborator-b
uses: TestOrg/TestRepo/.github/workflows/build.yml@main
with:
COMMIT_SHA: ${{ github.event.pull_request.head.sha }}

View File

@@ -93,8 +93,6 @@ edges
| .github/workflows/dependabot3.yml:15:9:20:6 | Uses Step | .github/workflows/dependabot3.yml:20:9:25:6 | Uses Step |
| .github/workflows/dependabot3.yml:20:9:25:6 | Uses Step | .github/workflows/dependabot3.yml:25:9:48:6 | Run Step: set-milestone |
| .github/workflows/dependabot3.yml:25:9:48:6 | Run Step: set-milestone | .github/workflows/dependabot3.yml:48:9:52:57 | Run Step |
| .github/workflows/external/TestOrg/TestRepo/.github/workflows/build.yml:11:9:14:6 | Uses Step | .github/workflows/external/TestOrg/TestRepo/.github/workflows/build.yml:14:9:17:7 | Run Step |
| .github/workflows/external/TestOrg/TestRepo/.github/workflows/build_nested_branching.yml:11:9:19:6 | Uses Step: checkAccess | .github/workflows/external/TestOrg/TestRepo/.github/workflows/build_nested_branching.yml:19:9:25:2 | Run Step |
| .github/workflows/external/TestOrg/TestRepo/.github/workflows/formal.yml:14:9:19:6 | Uses Step | .github/workflows/external/TestOrg/TestRepo/.github/workflows/formal.yml:19:9:25:6 | Run Step |
| .github/workflows/external/TestOrg/TestRepo/.github/workflows/formal.yml:19:9:25:6 | Run Step | .github/workflows/external/TestOrg/TestRepo/.github/workflows/formal.yml:25:9:70:20 | Run Step |
| .github/workflows/external/TestOrg/TestRepo/.github/workflows/reusable.yml:23:9:26:6 | Uses Step | .github/workflows/external/TestOrg/TestRepo/.github/workflows/reusable.yml:26:9:29:7 | Run Step |
@@ -336,17 +334,6 @@ edges
| .github/workflows/untrusted_checkout_6.yml:11:9:14:6 | Uses Step | .github/workflows/untrusted_checkout_6.yml:14:9:17:6 | Uses Step |
| .github/workflows/untrusted_checkout_6.yml:14:9:17:6 | Uses Step | .github/workflows/untrusted_checkout_6.yml:17:9:21:6 | Uses Step |
| .github/workflows/untrusted_checkout_6.yml:17:9:21:6 | Uses Step | .github/workflows/untrusted_checkout_6.yml:21:9:23:23 | Run Step |
| .github/workflows/untrusted_checkout_no_needs.yml:8:9:16:6 | Uses Step: checkAccess | .github/workflows/untrusted_checkout_no_needs.yml:16:9:22:2 | Run Step |
| .github/workflows/untrusted_checkout_no_needs.yml:26:9:31:6 | Uses Step | .github/workflows/untrusted_checkout_no_needs.yml:31:9:31:23 | Run Step |
| .github/workflows/untrusted_checkout_permission_check_reusable2.yml:8:9:16:6 | Uses Step: checkAccess | .github/workflows/untrusted_checkout_permission_check_reusable2.yml:16:9:22:2 | Run Step |
| .github/workflows/untrusted_checkout_permission_check_reusable.yml:8:9:16:6 | Uses Step: checkAccess | .github/workflows/untrusted_checkout_permission_check_reusable.yml:16:9:22:2 | Run Step |
| .github/workflows/untrusted_checkout_permission_check_reusable_level2.yml:8:9:16:6 | Uses Step: checkAccess | .github/workflows/untrusted_checkout_permission_check_reusable_level2.yml:16:9:22:2 | Run Step |
| .github/workflows/untrusted_checkout_permission_check_reusable_no_needs.yml:8:9:16:6 | Uses Step: checkAccess | .github/workflows/untrusted_checkout_permission_check_reusable_no_needs.yml:16:9:22:2 | Run Step |
| .github/workflows/untrusted_checkout_permissions_check.yml:8:9:16:6 | Uses Step: checkAccess | .github/workflows/untrusted_checkout_permissions_check.yml:16:9:22:2 | Run Step |
| .github/workflows/untrusted_checkout_permissions_check.yml:26:9:31:6 | Uses Step | .github/workflows/untrusted_checkout_permissions_check.yml:31:9:32:2 | Run Step |
| .github/workflows/untrusted_checkout_permissions_check.yml:36:9:41:6 | Uses Step | .github/workflows/untrusted_checkout_permissions_check.yml:41:9:41:22 | Run Step |
| .github/workflows/untrusted_checkout_two_callers_both_protected.yml:8:9:16:6 | Uses Step: checkAccess | .github/workflows/untrusted_checkout_two_callers_both_protected.yml:16:9:22:2 | Run Step |
| .github/workflows/untrusted_checkout_two_callers_both_protected.yml:30:9:38:6 | Uses Step: checkAccess | .github/workflows/untrusted_checkout_two_callers_both_protected.yml:38:9:44:2 | Run Step |
| .github/workflows/workflow_run_untrusted_checkout.yml:13:9:16:6 | Uses Step | .github/workflows/workflow_run_untrusted_checkout.yml:16:9:18:31 | Uses Step |
| .github/workflows/workflow_run_untrusted_checkout_2.yml:13:9:16:6 | Uses Step | .github/workflows/workflow_run_untrusted_checkout_2.yml:16:9:18:31 | Uses Step |
| .github/workflows/workflow_run_untrusted_checkout_3.yml:13:9:16:6 | Uses Step | .github/workflows/workflow_run_untrusted_checkout_3.yml:16:9:18:31 | Uses Step |
@@ -357,9 +344,6 @@ edges
| .github/workflows/auto_ci.yml:67:9:74:6 | Uses Step | .github/workflows/auto_ci.yml:67:9:74:6 | Uses Step | .github/workflows/auto_ci.yml:79:9:84:6 | Run Step | Checkout of untrusted code in a privileged workflow with later potential execution (event trigger: $@). | .github/workflows/auto_ci.yml:6:3:6:21 | pull_request_target | pull_request_target |
| .github/workflows/auto_ci.yml:67:9:74:6 | Uses Step | .github/workflows/auto_ci.yml:67:9:74:6 | Uses Step | .github/workflows/auto_ci.yml:84:9:93:6 | Run Step | Checkout of untrusted code in a privileged workflow with later potential execution (event trigger: $@). | .github/workflows/auto_ci.yml:6:3:6:21 | pull_request_target | pull_request_target |
| .github/workflows/dependabot3.yml:15:9:20:6 | Uses Step | .github/workflows/dependabot3.yml:15:9:20:6 | Uses Step | .github/workflows/dependabot3.yml:25:9:48:6 | Run Step: set-milestone | Checkout of untrusted code in a privileged workflow with later potential execution (event trigger: $@). | .github/workflows/dependabot3.yml:3:5:3:23 | pull_request_target | pull_request_target |
| .github/workflows/external/TestOrg/TestRepo/.github/workflows/build.yml:11:9:14:6 | Uses Step | .github/workflows/external/TestOrg/TestRepo/.github/workflows/build.yml:11:9:14:6 | Uses Step | .github/workflows/external/TestOrg/TestRepo/.github/workflows/build.yml:14:9:17:7 | Run Step | Checkout of untrusted code in a privileged workflow with later potential execution (event trigger: $@). | .github/workflows/untrusted_checkout_permission_check_reusable2.yml:2:3:2:21 | pull_request_target | pull_request_target |
| .github/workflows/external/TestOrg/TestRepo/.github/workflows/build.yml:11:9:14:6 | Uses Step | .github/workflows/external/TestOrg/TestRepo/.github/workflows/build.yml:11:9:14:6 | Uses Step | .github/workflows/external/TestOrg/TestRepo/.github/workflows/build.yml:14:9:17:7 | Run Step | Checkout of untrusted code in a privileged workflow with later potential execution (event trigger: $@). | .github/workflows/untrusted_checkout_permission_check_reusable_branching_nested.yml:2:3:2:21 | pull_request_target | pull_request_target |
| .github/workflows/external/TestOrg/TestRepo/.github/workflows/build.yml:11:9:14:6 | Uses Step | .github/workflows/external/TestOrg/TestRepo/.github/workflows/build.yml:11:9:14:6 | Uses Step | .github/workflows/external/TestOrg/TestRepo/.github/workflows/build.yml:14:9:17:7 | Run Step | Checkout of untrusted code in a privileged workflow with later potential execution (event trigger: $@). | .github/workflows/untrusted_checkout_permission_check_reusable_no_needs.yml:2:3:2:21 | pull_request_target | pull_request_target |
| .github/workflows/external/TestOrg/TestRepo/.github/workflows/reusable.yml:23:9:26:6 | Uses Step | .github/workflows/external/TestOrg/TestRepo/.github/workflows/reusable.yml:23:9:26:6 | Uses Step | .github/workflows/external/TestOrg/TestRepo/.github/workflows/reusable.yml:26:9:29:7 | Run Step | Checkout of untrusted code in a privileged workflow with later potential execution (event trigger: $@). | .github/workflows/reusable_caller1.yaml:4:3:4:21 | pull_request_target | pull_request_target |
| .github/workflows/gitcheckout.yml:10:11:18:8 | Run Step | .github/workflows/gitcheckout.yml:10:11:18:8 | Run Step | .github/workflows/gitcheckout.yml:21:11:23:22 | Run Step | Checkout of untrusted code in a privileged workflow with later potential execution (event trigger: $@). | .github/workflows/gitcheckout.yml:2:3:2:21 | pull_request_target | pull_request_target |
| .github/workflows/label_trusted_checkout2.yml:12:7:16:4 | Uses Step | .github/workflows/label_trusted_checkout2.yml:12:7:16:4 | Uses Step | .github/workflows/label_trusted_checkout2.yml:17:7:21:4 | Run Step | Checkout of untrusted code in a privileged workflow with later potential execution (event trigger: $@). | .github/workflows/label_trusted_checkout2.yml:2:3:2:21 | pull_request_target | pull_request_target |
@@ -393,5 +377,3 @@ edges
| .github/workflows/untrusted_checkout4.yml:29:7:35:4 | Uses Step | .github/workflows/untrusted_checkout4.yml:29:7:35:4 | Uses Step | .github/workflows/untrusted_checkout4.yml:47:7:51:46 | Run Step | Checkout of untrusted code in a privileged workflow with later potential execution (event trigger: $@). | .github/workflows/untrusted_checkout4.yml:2:3:2:15 | issue_comment | issue_comment |
| .github/workflows/untrusted_checkout.yml:8:9:11:6 | Uses Step | .github/workflows/untrusted_checkout.yml:8:9:11:6 | Uses Step | .github/workflows/untrusted_checkout.yml:15:9:18:2 | Run Step | Checkout of untrusted code in a privileged workflow with later potential execution (event trigger: $@). | .github/workflows/untrusted_checkout.yml:2:3:2:21 | pull_request_target | pull_request_target |
| .github/workflows/untrusted_checkout.yml:23:9:26:6 | Uses Step | .github/workflows/untrusted_checkout.yml:23:9:26:6 | Uses Step | .github/workflows/untrusted_checkout.yml:30:9:32:23 | Run Step | Checkout of untrusted code in a privileged workflow with later potential execution (event trigger: $@). | .github/workflows/untrusted_checkout.yml:2:3:2:21 | pull_request_target | pull_request_target |
| .github/workflows/untrusted_checkout_no_needs.yml:26:9:31:6 | Uses Step | .github/workflows/untrusted_checkout_no_needs.yml:26:9:31:6 | Uses Step | .github/workflows/untrusted_checkout_no_needs.yml:31:9:31:23 | Run Step | Checkout of untrusted code in a privileged workflow with later potential execution (event trigger: $@). | .github/workflows/untrusted_checkout_no_needs.yml:2:3:2:21 | pull_request_target | pull_request_target |
| .github/workflows/untrusted_checkout_permissions_check.yml:36:9:41:6 | Uses Step | .github/workflows/untrusted_checkout_permissions_check.yml:36:9:41:6 | Uses Step | .github/workflows/untrusted_checkout_permissions_check.yml:41:9:41:22 | Run Step | Checkout of untrusted code in a privileged workflow with later potential execution (event trigger: $@). | .github/workflows/untrusted_checkout_permissions_check.yml:2:3:2:21 | pull_request_target | pull_request_target |

View File

@@ -1,10 +1,10 @@
| .github/workflows/artifactpoisoning81.yml:11:9:14:6 | Uses Step | Potential unsafe checkout of untrusted pull request on non-privileged workflow. |
| .github/workflows/dependabot2.yml:33:9:38:6 | Uses Step | Potential unsafe checkout of untrusted pull request on non-privileged workflow. |
| .github/workflows/mend.yml:22:9:29:6 | Uses Step | Potential unsafe checkout of untrusted pull request on non-privileged workflow. |
| .github/workflows/poc3.yml:18:7:25:4 | Uses Step | Potential unsafe checkout of untrusted pull request on non-privileged workflow. |
| .github/workflows/poc.yml:30:9:36:6 | Uses Step | Potential unsafe checkout of untrusted pull request on non-privileged workflow. |
| .github/workflows/priv_pull_request_checkout.yml:14:9:20:6 | Uses Step | Potential unsafe checkout of untrusted pull request on non-privileged workflow. |
| .github/workflows/test3.yml:28:9:33:6 | Uses Step | Potential unsafe checkout of untrusted pull request on non-privileged workflow. |
| .github/workflows/test4.yml:18:7:25:4 | Uses Step | Potential unsafe checkout of untrusted pull request on non-privileged workflow. |
| .github/workflows/test8.yml:20:9:26:6 | Uses Step | Potential unsafe checkout of untrusted pull request on non-privileged workflow. |
| .github/workflows/test9.yml:11:9:16:6 | Uses Step | Potential unsafe checkout of untrusted pull request on non-privileged workflow. |
| .github/workflows/artifactpoisoning81.yml:11:9:14:6 | Uses Step | Potential unsafe checkout of untrusted pull request on privileged workflow. |
| .github/workflows/dependabot2.yml:33:9:38:6 | Uses Step | Potential unsafe checkout of untrusted pull request on privileged workflow. |
| .github/workflows/mend.yml:22:9:29:6 | Uses Step | Potential unsafe checkout of untrusted pull request on privileged workflow. |
| .github/workflows/poc3.yml:18:7:25:4 | Uses Step | Potential unsafe checkout of untrusted pull request on privileged workflow. |
| .github/workflows/poc.yml:30:9:36:6 | Uses Step | Potential unsafe checkout of untrusted pull request on privileged workflow. |
| .github/workflows/priv_pull_request_checkout.yml:14:9:20:6 | Uses Step | Potential unsafe checkout of untrusted pull request on privileged workflow. |
| .github/workflows/test3.yml:28:9:33:6 | Uses Step | Potential unsafe checkout of untrusted pull request on privileged workflow. |
| .github/workflows/test4.yml:18:7:25:4 | Uses Step | Potential unsafe checkout of untrusted pull request on privileged workflow. |
| .github/workflows/test8.yml:20:9:26:6 | Uses Step | Potential unsafe checkout of untrusted pull request on privileged workflow. |
| .github/workflows/test9.yml:11:9:16:6 | Uses Step | Potential unsafe checkout of untrusted pull request on privileged workflow. |

View File

@@ -11,6 +11,10 @@
"java/ql/lib/semmle/code/java/dataflow/internal/rangeanalysis/SignAnalysisCommon.qll",
"csharp/ql/lib/semmle/code/csharp/dataflow/internal/rangeanalysis/SignAnalysisCommon.qll"
],
"Bound Java/C#": [
"java/ql/lib/semmle/code/java/dataflow/Bound.qll",
"csharp/ql/lib/semmle/code/csharp/dataflow/Bound.qll"
],
"ModulusAnalysis Java/C#": [
"java/ql/lib/semmle/code/java/dataflow/ModulusAnalysis.qll",
"csharp/ql/lib/semmle/code/csharp/dataflow/ModulusAnalysis.qll"

View File

@@ -1,2 +0,0 @@
description: Fix NameQualifier inconsistency
compatibility: full

View File

@@ -1,36 +1,3 @@
## 11.0.0
### Breaking Changes
* Removed the deprecated `overrideReturnsNull` predicate from `Options.qll`. Use `CustomOptions.overrideReturnsNull` instead.
* Removed the deprecated `returnsNull` predicate from `Options.qll`. Use `CustomOptions.returnsNull` instead.
* Removed the deprecated `exits` predicate from `Options.qll`. Use `CustomOptions.exits` instead.
* Removed the deprecated `exprExits` predicate from `Options.qll`. Use `CustomOptions.exprExits` instead.
* Removed the deprecated `alwaysCheckReturnValue` predicate from `Options.qll`. Use `CustomOptions.alwaysCheckReturnValue` instead.
* Removed the deprecated `okToIgnoreReturnValue` predicate from `Options.qll`. Use `CustomOptions.okToIgnoreReturnValue` instead.
* Removed the deprecated `semmle.code.cpp.Member`. Import `semmle.code.cpp.Element` and/or `semmle.code.cpp.Type` directly.
* Removed the deprecated `UnknownDefaultLocation` class. Use `UnknownLocation` instead.
* Removed the deprecated `UnknownExprLocation` class. Use `UnknownLocation` instead.
* Removed the deprecated `UnknownStmtLocation` class. Use `UnknownLocation` instead.
* Removed the deprecated `TemplateParameter` class. Use `TypeTemplateParameter` instead.
* Support for class resolution across link targets has been removed for databases which were created with CodeQL versions before 1.23.0.
## 10.2.0
### Deprecated APIs
* The `UsingAliasTypedefType` class has been deprecated. Use `TypeAliasType` instead.
### New Features
* Added a `getOriginalTemplate` predicate to `TemplateClass`, `TemplateFunction`, `TemplateVariable`, and `AliasTemplateType`, which yields the class member template the template was generated from. The predicates only have results for templates that are members of class template instantiations.
* Added `AliasTemplateType` and `AliasTemplateInstantiationType` classes, representing C++ alias templates and their instantiations.
### Minor Analysis Improvements
* Added flow source models for `scanf_s` and related functions.
* Added a `Call` column to `LocalFlowSourceFunction::hasLocalFlowSource` and `RemoteFlowSourceFunction::hasRemoteFlowSource`. The old predicates without a `Call` column continue to be supported.
## 10.1.1
### Minor Analysis Improvements

View File

@@ -0,0 +1,5 @@
---
category: minorAnalysis
---
* Added flow source models for `scanf_s` and related functions.
* Added a `Call` column to `LocalFlowSourceFunction::hasLocalFlowSource` and `RemoteFlowSourceFunction::hasRemoteFlowSource`. The old predicates without a `Call` column continue to be supported.

View File

@@ -0,0 +1,4 @@
---
category: feature
---
* Added `AliasTemplateType` and `AliasTemplateInstantiationType` classes, representing C++ alias templates and their instantiations.

View File

@@ -0,0 +1,4 @@
---
category: deprecated
---
* The `UsingAliasTypedefType` class has been deprecated. Use `TypeAliasType` instead.

View File

@@ -0,0 +1,4 @@
---
category: feature
---
* Added a `getOriginalTemplate` predicate to `TemplateClass`, `TemplateFunction`, `TemplateVariable`, and `AliasTemplateType`, which yields the class member template the template was generated from. The predicates only have results for templates that are members of class template instantiations.

View File

@@ -1,7 +1,6 @@
## 11.0.0
### Breaking Changes
---
category: breaking
---
* Removed the deprecated `overrideReturnsNull` predicate from `Options.qll`. Use `CustomOptions.overrideReturnsNull` instead.
* Removed the deprecated `returnsNull` predicate from `Options.qll`. Use `CustomOptions.returnsNull` instead.
* Removed the deprecated `exits` predicate from `Options.qll`. Use `CustomOptions.exits` instead.

View File

@@ -1,4 +0,0 @@
---
category: deprecated
---
* Models-as-data flow summaries now use fully qualified field names (for example, `MyNamespace::MyStruct::myField`) instead of unqualified field names such as `myField`. We recommend updating existing flow summaries to use fully qualified field names. Unqualified field names are still supported, but that support will be removed in a future release.

View File

@@ -1,4 +0,0 @@
---
category: breaking
---
* Removed support for using variables as sources and sinks in models-as-data. Users of this feature should convert such sources and sinks to models defined using the QL language.

View File

@@ -1,15 +0,0 @@
## 10.2.0
### Deprecated APIs
* The `UsingAliasTypedefType` class has been deprecated. Use `TypeAliasType` instead.
### New Features
* Added a `getOriginalTemplate` predicate to `TemplateClass`, `TemplateFunction`, `TemplateVariable`, and `AliasTemplateType`, which yields the class member template the template was generated from. The predicates only have results for templates that are members of class template instantiations.
* Added `AliasTemplateType` and `AliasTemplateInstantiationType` classes, representing C++ alias templates and their instantiations.
### Minor Analysis Improvements
* Added flow source models for `scanf_s` and related functions.
* Added a `Call` column to `LocalFlowSourceFunction::hasLocalFlowSource` and `RemoteFlowSourceFunction::hasRemoteFlowSource`. The old predicates without a `Call` column continue to be supported.

View File

@@ -1,2 +1,2 @@
---
lastReleaseVersion: 11.0.0
lastReleaseVersion: 10.1.1

View File

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

View File

@@ -1071,7 +1071,7 @@ class NullPointerType extends BuiltInType {
* const float fa[40];
* ```
*/
class DerivedType extends Type, NameQualifyingElement, @derivedtype {
class DerivedType extends Type, @derivedtype {
override string toString() { result = this.getName() }
override string getName() { derivedtypes(underlyingElement(this), result, _, _) }

View File

@@ -276,45 +276,6 @@ private predicate isClassConstructedFrom(Class c, Class templateClass) {
not c.isConstructedFrom(_) and c = templateClass
}
/** Gets the fully templated version of `c`. */
private Class getFullyTemplatedClassOld(Class c) {
not c.isFromUninstantiatedTemplate(_) and
isClassConstructedFrom(c, result)
}
private TemplateClass getOriginalClassTemplate(TemplateClass tc) {
result = tc.getOriginalTemplate()
or
not exists(tc.getOriginalTemplate()) and
result = tc
}
/** Gets the fully templated version of `c`. */
private Class getFullyTemplatedClassNew(Class c) {
not c.isFromUninstantiatedTemplate(_) and
exists(Class mid |
c.isConstructedFrom(mid)
or
not c.isConstructedFrom(_) and c = mid
|
result = getOriginalClassTemplate(mid)
or
not mid instanceof TemplateClass and mid = result
)
}
/** Gets the fully templated version of `c`. */
private Class getFullyTemplatedClass(Class c) {
// The `Class::getOriginalTemplate` predicate was introduced in CodeQL
// version 2.25.6 and the upgrade script leaves the
// `class_template_generated_from` extensionals empty if the database
// was generated with an older extractor. So we use the old implementation
// if the `class_template_generated_from` extensional is empty.
if class_template_generated_from(_, _)
then result = getFullyTemplatedClassNew(c)
else result = getFullyTemplatedClassOld(c)
}
/**
* Holds if `f` is an instantiation of a function template `templateFunc`, or
* holds with `f = templateFunc` if `f` is not an instantiation of any function
@@ -331,7 +292,7 @@ private predicate isFunctionConstructedFrom(Function f, Function templateFunc) {
}
/** Gets the fully templated version of `f`. */
private Function getFullyTemplatedFunctionOld(Function f) {
Function getFullyTemplatedFunction(Function f) {
not f.isFromUninstantiatedTemplate(_) and
(
exists(Class c, Class templateClass, int i |
@@ -345,46 +306,13 @@ private Function getFullyTemplatedFunctionOld(Function f) {
)
}
private TemplateFunction getOriginalFunctionTemplate(TemplateFunction tf) {
result = tf.getOriginalTemplate()
or
not exists(tf.getOriginalTemplate()) and
result = tf
}
/** Gets the fully templated version of `f`. */
private Function getFullyTemplatedFunctionNew(Function f) {
not f.isFromUninstantiatedTemplate(_) and
exists(Function mid |
f.isConstructedFrom(mid)
or
not f.isConstructedFrom(_) and f = mid
|
result = getOriginalFunctionTemplate(mid)
or
not mid instanceof TemplateFunction and mid = result
)
}
/** Gets the fully templated version of `f`. */
Function getFullyTemplatedFunction(Function f) {
// The `Function::getOriginalTemplate` predicate was introduced in CodeQL
// version 2.25.6 and the upgrade script leaves the
// `function_template_generated_from` extensionals empty if the database
// was generated with an older extractor. So we use the old implementation
// if the `function_template_generated_from` extensional is empty.
if function_template_generated_from(_, _)
then result = getFullyTemplatedFunctionNew(f)
else result = getFullyTemplatedFunctionOld(f)
}
/** Prefixes `const` to `s` if `t` is const, or returns `s` otherwise. */
bindingset[s, t]
private string withConst(string s, Type t) {
if t.isConst() then result = "const " + s else result = s
}
/** Prefixes `volatile` to `s` if `t` is volatile, or returns `s` otherwise. */
/** Prefixes `volatile` to `s` if `t` is const, or returns `s` otherwise. */
bindingset[s, t]
private string withVolatile(string s, Type t) {
if t.isVolatile() then result = "volatile " + s else result = s
@@ -562,7 +490,7 @@ pragma[nomagic]
private string getTypeNameWithoutClassTemplates(Function f, int n, int remaining) {
// If there is a declaring type then we start by expanding the function templates
exists(Class template |
template = getFullyTemplatedClass(f.getDeclaringType()) and
isClassConstructedFrom(f.getDeclaringType(), template) and
remaining = getNumberOfSupportedClassTemplateArguments(template) and
result = getTypeNameWithoutFunctionTemplates(f, n, 0)
)
@@ -574,7 +502,7 @@ private string getTypeNameWithoutClassTemplates(Function f, int n, int remaining
or
exists(string mid, TypeTemplateParameter tp, Class template |
mid = getTypeNameWithoutClassTemplates(f, n, remaining + 1) and
template = getFullyTemplatedClass(f.getDeclaringType()) and
isClassConstructedFrom(f.getDeclaringType(), template) and
tp = getSupportedClassTemplateArgument(template, remaining)
|
result = mid.replaceAll(tp.getName(), "class:" + remaining.toString())
@@ -931,6 +859,31 @@ private Element interpretElement0(
signature = "" and
elementSpec(namespace, type, subtypes, name, signature, _)
)
or
// Member variables
elementSpec(namespace, type, subtypes, name, signature, _) and
signature = "" and
exists(Class namedClass, Class classWithMember, MemberVariable member |
member.getName() = name and
member = classWithMember.getAMember() and
namedClass.hasQualifiedName(namespace, type) and
result = member
|
// field declared in the named type or a subtype of it (or an extension of any)
subtypes = true and
classWithMember = namedClass.getADerivedClass*()
or
// field declared directly in the named type (or an extension of it)
subtypes = false and
classWithMember = namedClass
)
or
// Global or namespace variables
elementSpec(namespace, type, subtypes, name, signature, _) and
signature = "" and
type = "" and
subtypes = false and
result = any(GlobalOrNamespaceVariable v | v.hasQualifiedName(namespace, name))
}
cached

View File

@@ -6,7 +6,6 @@ private import cpp as Cpp
private import codeql.dataflow.internal.FlowSummaryImpl
private import codeql.dataflow.internal.AccessPathSyntax as AccessPath
private import semmle.code.cpp.ir.dataflow.internal.DataFlowPrivate
private import semmle.code.cpp.ir.dataflow.internal.DataFlowNodes
private import semmle.code.cpp.ir.dataflow.internal.DataFlowUtil
private import semmle.code.cpp.ir.dataflow.internal.DataFlowImplSpecific as DataFlowImplSpecific
private import semmle.code.cpp.dataflow.ExternalFlow
@@ -21,22 +20,8 @@ module Input implements InputSig<Location, DataFlowImplSpecific::CppDataFlow> {
class SinkBase = Void;
class FlowSummaryCallBase = CallInstruction;
predicate callableFromSource(SummarizedCallableBase c) { exists(c.getBlock()) }
FlowSummaryCallBase getASourceCall(SummarizedCallableBase sc) {
result.getStaticCallTarget() = sc
}
DataFlowCallable getSummarizedCallableAsDataFlowCallable(SummarizedCallableBase c) {
result.asSummarizedCallable() = c
}
DataFlowCallable getSourceCallEnclosingCallable(FlowSummaryCallBase call) {
result.asSourceCallable() = call.getEnclosingFunction()
}
ArgumentPosition callbackSelfParameterPosition() { result = TDirectPosition(-1) }
ReturnKind getStandardReturnValueKind() { result = getReturnValueKind("") }
@@ -45,10 +30,6 @@ module Input implements InputSig<Location, DataFlowImplSpecific::CppDataFlow> {
arg = repeatStars(result.(NormalReturnKind).getIndirectionIndex())
}
ParameterPosition getFlowSummaryParameterPosition(ReturnKind rk) {
result = TFlowSummaryPosition(rk)
}
string encodeParameterPosition(ParameterPosition pos) { result = pos.toString() }
string encodeArgumentPosition(ArgumentPosition pos) { result = pos.toString() }
@@ -59,24 +40,12 @@ module Input implements InputSig<Location, DataFlowImplSpecific::CppDataFlow> {
arg = repeatStars(rk.(NormalReturnKind).getIndirectionIndex())
}
bindingset[namespace, type, base]
private string formatQualifiedName(string namespace, string type, string base) {
if namespace = ""
then result = type + "::" + base
else result = namespace + "::" + type + "::" + base
}
string encodeContent(ContentSet cs, string arg) {
exists(FieldContent c, string namespace, string type, string base |
exists(FieldContent c |
cs.isSingleton(c) and
// FieldContent indices have 0 for the address, 1 for content, so we need to subtract one.
result = "Field" and
c.getField().hasQualifiedName(namespace, type, base)
|
arg = repeatStars(c.getIndirectionIndex() - 1) + formatQualifiedName(namespace, type, base)
or
// TODO: This disjunct can be removed once we stop supporting unqualified field names.
arg = repeatStars(c.getIndirectionIndex() - 1) + base
arg = repeatStars(c.getIndirectionIndex() - 1) + c.getField().getName()
)
or
exists(ElementContent ec |
@@ -133,22 +102,10 @@ module Input implements InputSig<Location, DataFlowImplSpecific::CppDataFlow> {
private import Make<Location, DataFlowImplSpecific::CppDataFlow, Input> as Impl
private module StepsInput implements Impl::Private::StepsInputSig {
Impl::Private::SummaryNode getSummaryNode(Node n) {
result = n.(FlowSummaryNode).getSummaryNode()
}
DataFlowCall getACall(Public::SummarizedCallable sc) {
result.getStaticCallTarget().getUnderlyingCallable() = sc
}
Node getSourceOutNode(Input::FlowSummaryCallBase call, ReturnKind rk) {
exists(IndirectReturnOutNode out | result = out |
out.getCallInstruction() = call and
pragma[only_bind_out](rk.(NormalReturnKind).getIndirectionIndex()) =
pragma[only_bind_out](out.getIndirectionIndex())
)
}
DataFlowCallable getSourceNodeEnclosingCallable(Input::SourceBase source) { none() }
Node getSourceNode(Input::SourceBase source, Impl::Private::SummaryComponentStack s) { none() }
@@ -261,11 +218,40 @@ module SourceSinkInterpretationInput implements
/** Provides additional sink specification logic. */
bindingset[c]
predicate interpretOutput(string c, InterpretNode mid, InterpretNode node) { none() }
predicate interpretOutput(string c, InterpretNode mid, InterpretNode node) {
// Allow variables to be picked as output nodes.
exists(Node n, Element ast |
n = node.asNode() and
ast = mid.asElement()
|
c = "" and
n.asExpr().(VariableAccess).getTarget() = ast
)
}
/** Provides additional source specification logic. */
bindingset[c]
predicate interpretInput(string c, InterpretNode mid, InterpretNode node) { none() }
predicate interpretInput(string c, InterpretNode mid, InterpretNode node) {
exists(Node n, Element ast, VariableAccess e |
n = node.asNode() and
ast = mid.asElement() and
e.getTarget() = ast
|
// Allow variables to be picked as input nodes.
// We could simply do this as `e = n.asExpr()`, but that would not allow
// us to pick `x` as a sink in an example such as `x = source()` (but
// only subsequent uses of `x`) since the variable access on `x` doesn't
// actually load the value of `x`. So instead, we pick the instruction
// node corresponding to the generated `StoreInstruction` and use the
// expression associated with the destination instruction. This means
// that the `x` in `x = source()` can be marked as an input.
c = "" and
exists(StoreInstruction store |
store.getDestinationAddress().getUnconvertedResultExpression() = e and
n.asInstruction() = store
)
)
}
}
module Private {

View File

@@ -1534,8 +1534,12 @@ class FlowSummaryNode extends Node, TFlowSummaryNode {
result = this.getSummaryNode().getSummarizedCallable()
}
/**
* Gets the enclosing callable. For a `FlowSummaryNode` this is always the
* summarized function this node is part of.
*/
override DataFlowCallable getEnclosingCallable() {
result = FlowSummaryImpl::Private::getEnclosingCallable(this.getSummaryNode())
result.asSummarizedCallable() = this.getSummarizedCallable()
}
override Location getLocationImpl() { result = this.getSummarizedCallable().getLocation() }

View File

@@ -561,21 +561,6 @@ class SummaryArgumentNode extends ArgumentNode, FlowSummaryNode {
}
}
/** An argument node that re-enters return output as input to a flow summary. */
private class FlowSummaryArgumentNode extends ArgumentNode, FlowSummaryNode {
private CallInstruction callInstruction;
private ReturnKind rk;
FlowSummaryArgumentNode() {
this.getSummaryNode() = FlowSummaryImpl::Private::summaryArgumentNode(callInstruction, rk)
}
override predicate argumentOf(DataFlowCall call, ArgumentPosition pos) {
call.asCallInstruction() = callInstruction and
pos = TFlowSummaryPosition(rk)
}
}
/** A parameter position represented by an integer. */
class ParameterPosition = Position;
@@ -631,18 +616,6 @@ class IndirectionPosition extends Position, TIndirectionPosition {
final override int getIndirectionIndex() { result = indirectionIndex }
}
class FlowSummaryPosition extends Position, TFlowSummaryPosition {
ReturnKind rk;
FlowSummaryPosition() { this = TFlowSummaryPosition(rk) }
override string toString() { result = "write to: " + rk.toString() }
override int getArgumentIndex() { none() }
final override int getIndirectionIndex() { result = rk.getIndirectionIndex() }
}
newtype TPosition =
TDirectPosition(int argumentIndex) {
exists(any(CallInstruction c).getArgument(argumentIndex))
@@ -661,8 +634,7 @@ newtype TPosition =
p = f.getParameter(argumentIndex) and
indirectionIndex = [1 .. Ssa::getMaxIndirectionsForType(p.getUnspecifiedType()) - 1]
)
} or
TFlowSummaryPosition(ReturnKind rk) { FlowSummaryImpl::Private::relevantFlowSummaryPosition(rk) }
}
private newtype TReturnKind =
TNormalReturnKind(int indirectionIndex) {
@@ -1406,8 +1378,6 @@ predicate nodeIsHidden(Node n) {
n instanceof InitialGlobalValue
or
n instanceof SsaSynthNode
or
n.(FlowSummaryNode).getSummaryNode().isHidden()
}
predicate neverSkipInPathGraph(Node n) {

View File

@@ -158,7 +158,7 @@ private module Cached {
model = ""
or
// models-as-data summarized flow
FlowSummaryImpl::Private::Steps::summaryLocalStep(nodeFrom,
FlowSummaryImpl::Private::Steps::summaryLocalStep(nodeFrom.(FlowSummaryNode).getSummaryNode(),
nodeTo.(FlowSummaryNode).getSummaryNode(), true, model)
}

View File

@@ -67,7 +67,7 @@ private module Cached {
model = ""
or
// models-as-data summarized flow
FlowSummaryImpl::Private::Steps::summaryLocalStep(nodeFrom,
FlowSummaryImpl::Private::Steps::summaryLocalStep(nodeFrom.(FlowSummaryNode).getSummaryNode(),
nodeTo.(FlowSummaryNode).getSummaryNode(), false, model)
or
// object->field conflation for content that is a `TaintInheritingContent`.

View File

@@ -1430,8 +1430,7 @@ specialnamequalifyingelements(
@namequalifyingelement = @namespace
| @specialnamequalifyingelement
| @usertype
| @decltype
| @derivedtype;
| @decltype;
namequalifiers(
unique int id: @namequalifier,

File diff suppressed because it is too large Load Diff

View File

@@ -1,2 +0,0 @@
description: Fix NameQualifier inconsistency
compatibility: full

View File

@@ -1,11 +1,3 @@
## 1.6.5
No user-facing changes.
## 1.6.4
No user-facing changes.
## 1.6.3
### Minor Analysis Improvements

View File

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

View File

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

View File

@@ -1,2 +1,2 @@
---
lastReleaseVersion: 1.6.5
lastReleaseVersion: 1.6.3

View File

@@ -1,5 +1,5 @@
name: codeql/cpp-queries
version: 1.6.6-dev
version: 1.6.4-dev
groups:
- cpp
- queries

View File

@@ -1,2 +1 @@
query: jsf/4.13 Functions/AV Rule 107.ql
postprocess: utils/test/InlineExpectationsTestQuery.ql
jsf/4.13 Functions/AV Rule 107.ql

View File

@@ -1,2 +1 @@
query: Best Practices/Hiding/LocalVariableHidesGlobalVariable.ql
postprocess: utils/test/InlineExpectationsTestQuery.ql
Best Practices/Hiding/LocalVariableHidesGlobalVariable.ql

View File

@@ -48,7 +48,7 @@ void test1()
void test2()
{
Lock<Mutex> myLock(); // $ Alert[cpp/function-in-block] // BAD (interpreted as a function declaration, this does nothing)
Lock<Mutex> myLock(); // BAD (interpreted as a function declaration, this does nothing)
// ...
}
@@ -62,14 +62,14 @@ void test3()
void test4()
{
Lock<Mutex>(myMutex); // $ Alert[cpp/local-variable-hides-global-variable] // BAD (creates an uninitialized variable called `myMutex`, probably not intended)
Lock<Mutex>(myMutex); // BAD (creates an uninitialized variable called `myMutex`, probably not intended)
// ...
}
void test5()
{
Lock<Mutex> myLock(Mutex); // $ Alert[cpp/function-in-block] // BAD (interpreted as a function declaration, this does nothing)
Lock<Mutex> myLock(Mutex); // BAD (interpreted as a function declaration, this does nothing)
// ...
}
@@ -86,7 +86,7 @@ public:
void test7()
{
Lock<Mutex>(memberMutex); // $ MISSING: Alert // BAD (creates an uninitialized variable called `memberMutex`, probably not intended) [NOT DETECTED]
Lock<Mutex>(memberMutex); // BAD (creates an uninitialized variable called `memberMutex`, probably not intended) [NOT DETECTED]
// ...
}

View File

@@ -1,2 +1 @@
query: experimental/Security/CWE/CWE-020/NoCheckBeforeUnsafePutUser.ql
postprocess: utils/test/InlineExpectationsTestQuery.ql
experimental/Security/CWE/CWE-020/NoCheckBeforeUnsafePutUser.ql

View File

@@ -19,7 +19,7 @@ void test1(int p)
{
sys_somesystemcall(&p);
unsafe_put_user(123, &p); // $ MISSING: Alert // BAD [NOT DETECTED]
unsafe_put_user(123, &p); // BAD [NOT DETECTED]
}
void test2(int p)
@@ -40,7 +40,7 @@ void test3()
sys_somesystemcall(&v);
unsafe_put_user(123, &v); // $ MISSING: Alert // BAD [NOT DETECTED]
unsafe_put_user(123, &v); // BAD [NOT DETECTED]
}
void test4()
@@ -68,7 +68,7 @@ void test5()
sys_somesystemcall(&myData);
unsafe_put_user(123, &(myData.x)); // $ MISSING: Alert // BAD [NOT DETECTED]
unsafe_put_user(123, &(myData.x)); // BAD [NOT DETECTED]
}
void test6()

View File

@@ -1,2 +1 @@
query: experimental/Security/CWE/CWE-020/LateCheckOfFunctionArgument.ql
postprocess: utils/test/InlineExpectationsTestQuery.ql
experimental/Security/CWE/CWE-020/LateCheckOfFunctionArgument.ql

View File

@@ -3,6 +3,6 @@ void workFunction_0(char *s) {
char buf[80], buf1[8];
if(len<0) return;
memset(buf,0,len); //GOOD
memset(buf1,0,len1); // $ Alert //BAD
memset(buf1,0,len1); //BAD
if(len1<0) return;
}

View File

@@ -1,2 +1 @@
query: experimental/Security/CWE/CWE-078/WordexpTainted.ql
postprocess: utils/test/InlineExpectationsTestQuery.ql
experimental/Security/CWE/CWE-078/WordexpTainted.ql

View File

@@ -19,14 +19,14 @@ enum {
int wordexp(const char *restrict s, wordexp_t *restrict p, int flags);
int main(int argc, char** argv) { // $ Source
int main(int argc, char** argv) {
char *filePath = argv[2];
{
// BAD: the user string is injected directly into `wordexp` which performs command substitution
wordexp_t we;
wordexp(filePath, &we, 0); // $ Alert
wordexp(filePath, &we, 0);
}
{

View File

@@ -1,2 +1 @@
query: experimental/Security/CWE/CWE-1041/FindWrapperFunctions.ql
postprocess: utils/test/InlineExpectationsTestQuery.ql
experimental/Security/CWE/CWE-1041/FindWrapperFunctions.ql

View File

@@ -20,7 +20,7 @@ void myFclose(FILE * fmy)
int main(int argc, char *argv[])
{
fe = fopen("myFile.txt", "wt");
fclose(fe); // $ Alert // BAD
fclose(fe); // BAD
fe = fopen("myFile.txt", "wt");
myFclose(fe); // GOOD
return 0;

View File

@@ -1,2 +1 @@
query: experimental/Security/CWE/CWE-1126/DeclarationOfVariableWithUnnecessarilyWideScope.ql
postprocess: utils/test/InlineExpectationsTestQuery.ql
experimental/Security/CWE/CWE-1126/DeclarationOfVariableWithUnnecessarilyWideScope.ql

View File

@@ -11,7 +11,7 @@ void workFunction_0(char *s) {
while(intIndex > 2)
{
buf[intIndex] = 1;
int intIndex; // $ Alert // BAD
int intIndex; // BAD
intIndex--;
}
intIndex = 10;

View File

@@ -1,2 +1 @@
query: experimental/Security/CWE/CWE-1240/CustomCryptographicPrimitive.ql
postprocess: utils/test/InlineExpectationsTestQuery.ql
experimental/Security/CWE/CWE-1240/CustomCryptographicPrimitive.ql

View File

@@ -8,7 +8,7 @@ int strlen(const char *string);
// the following function is homebrew crypto written for this test. This is a bad algorithm
// on multiple levels and should never be used in cryptography.
void encryptString(char *string, unsigned int key) { // $ Alert
void encryptString(char *string, unsigned int key) {
char *ptr = string;
int len = strlen(string);
@@ -27,7 +27,7 @@ void encryptString(char *string, unsigned int key) { // $ Alert
// the following function is homebrew crypto written for this test. This is a bad algorithm
// on multiple levels and should never be used in cryptography.
void MyEncrypt(const unsigned int *dataIn, unsigned int *dataOut, unsigned int dataSize, unsigned int key[2]) { // $ Alert
void MyEncrypt(const unsigned int *dataIn, unsigned int *dataOut, unsigned int dataSize, unsigned int key[2]) {
unsigned int state[2];
unsigned int t;
@@ -48,7 +48,7 @@ void MyEncrypt(const unsigned int *dataIn, unsigned int *dataOut, unsigned int d
// the following function resembles an implementation of the AES "mix columns"
// step. It is not accurate, efficient or safe and should never be used in
// cryptography.
void mix_columns(const uint8_t inputs[4], uint8_t outputs[4]) { // $ Alert
void mix_columns(const uint8_t inputs[4], uint8_t outputs[4]) {
// The "mix columns" step takes four bytes as inputs. Each byte represents a
// polynomial with 8 one-bit coefficients, e.g. input bits 00001101
// represent the polynomial x^3 + x^2 + 1. Arithmetic is reduced modulo
@@ -80,7 +80,7 @@ void mix_columns(const uint8_t inputs[4], uint8_t outputs[4]) { // $ Alert
// the following function resembles initialization of an S-box as may be done
// in an implementation of DES, AES and other encryption algorithms. It is not
// accurate, efficient or safe and should never be used in cryptography.
void init_aes_sbox(unsigned char data[256]) { // $ Alert
void init_aes_sbox(unsigned char data[256]) {
// initialize `data` in a loop using lots of ^, ^= and << operations and
// a few fixed constants.
unsigned int state = 0x12345678;

View File

@@ -1,2 +1 @@
query: experimental/Security/CWE/CWE-125/DangerousWorksWithMultibyteOrWideCharacters.ql
postprocess: utils/test/InlineExpectationsTestQuery.ql
experimental/Security/CWE/CWE-125/DangerousWorksWithMultibyteOrWideCharacters.ql

View File

@@ -63,7 +63,7 @@ static void badTest1(const char* ptr)
int ret;
int len;
len = strlen(ptr);
for (wchar_t wc; (ret = mbtowc(&wc, ptr, 4)) > 0; len-=ret) { // $ Alert // BAD:we can get unpredictable results
for (wchar_t wc; (ret = mbtowc(&wc, ptr, 4)) > 0; len-=ret) { // BAD:we can get unpredictable results
wprintf(L"%lc", wc);
ptr += ret;
}
@@ -73,7 +73,7 @@ static void badTest2(const char* ptr)
int ret;
int len;
len = strlen(ptr);
for (wchar_t wc; (ret = mbtowc(&wc, ptr, sizeof(wchar_t))) > 0; len-=ret) { // $ Alert // BAD:we can get unpredictable results
for (wchar_t wc; (ret = mbtowc(&wc, ptr, sizeof(wchar_t))) > 0; len-=ret) { // BAD:we can get unpredictable results
wprintf(L"%lc", wc);
ptr += ret;
}
@@ -103,7 +103,7 @@ static void badTest3(const char* ptr,int wc_len)
len = wc_len;
wchar_t *wc = new wchar_t[wc_len];
while (*ptr && len > 0) {
ret = mbtowc(wc, ptr, MB_CUR_MAX); // $ Alert // BAD
ret = mbtowc(wc, ptr, MB_CUR_MAX); // BAD
if (ret <0)
break;
if (ret == 0 || ret > len)
@@ -120,7 +120,7 @@ static void badTest4(const char* ptr,int wc_len)
len = wc_len;
wchar_t *wc = new wchar_t[wc_len];
while (*ptr && len > 0) {
ret = mbtowc(wc, ptr, 16); // $ Alert // BAD
ret = mbtowc(wc, ptr, 16); // BAD
if (ret <0)
break;
if (ret == 0 || ret > len)
@@ -137,7 +137,7 @@ static void badTest5(const char* ptr,int wc_len)
len = wc_len;
wchar_t *wc = new wchar_t[wc_len];
while (*ptr && len > 0) {
ret = mbtowc(wc, ptr, sizeof(wchar_t)); // $ Alert // BAD
ret = mbtowc(wc, ptr, sizeof(wchar_t)); // BAD
if (ret <0)
break;
if (ret == 0 || ret > len)
@@ -155,7 +155,7 @@ static void badTest6(const char* ptr,int wc_len)
len = wc_len;
wchar_t *wc = new wchar_t[wc_len];
while (*ptr && wc_len > 0) {
ret = mbtowc(wc, ptr, wc_len); // $ Alert // BAD
ret = mbtowc(wc, ptr, wc_len); // BAD
if (ret <0)
if (checkErrors()) {
++ptr;
@@ -178,7 +178,7 @@ static void badTest7(const char* ptr,int wc_len)
len = wc_len;
wchar_t *wc = new wchar_t[wc_len];
while (*ptr && wc_len > 0) {
ret = mbtowc(wc, ptr, len); // $ Alert // BAD
ret = mbtowc(wc, ptr, len); // BAD
if (ret <0)
break;
if (ret == 0 || ret > len)
@@ -194,7 +194,7 @@ static void badTest8(const char* ptr,wchar_t *wc)
int len;
len = strlen(ptr);
while (*ptr && len > 0) {
ret = mbtowc(wc, ptr, len); // $ Alert // BAD
ret = mbtowc(wc, ptr, len); // BAD
if (ret <0)
break;
if (ret == 0 || ret > len)

View File

@@ -25,8 +25,8 @@ void* calloc (size_t num, size_t size);
void* malloc (size_t size);
static void badTest1(void *src, int size) {
WideCharToMultiByte(CP_ACP, 0, (LPCWSTR)src, -1, (LPSTR)src, size, 0, 0); // $ Alert // BAD
MultiByteToWideChar(CP_ACP, 0, (LPCSTR)src, -1, (LPCWSTR)src, 30); // $ Alert // BAD
WideCharToMultiByte(CP_ACP, 0, (LPCWSTR)src, -1, (LPSTR)src, size, 0, 0); // BAD
MultiByteToWideChar(CP_ACP, 0, (LPCSTR)src, -1, (LPCWSTR)src, 30); // BAD
}
void goodTest2(){
wchar_t src[] = L"0123456789ABCDEF";
@@ -42,7 +42,7 @@ void goodTest2(){
static void badTest2(){
wchar_t src[] = L"0123456789ABCDEF";
char dst[16];
WideCharToMultiByte(CP_UTF8, 0, src, -1, dst, 16, NULL, NULL); // $ Alert // BAD
WideCharToMultiByte(CP_UTF8, 0, src, -1, dst, 16, NULL, NULL); // BAD
printf("%s\n", dst);
}
static void goodTest3(){
@@ -55,7 +55,7 @@ static void badTest3(){
char src[] = "0123456789ABCDEF";
int size = MultiByteToWideChar(CP_UTF8, 0, src,sizeof(src),NULL,0);
wchar_t * dst = (wchar_t*)calloc(size + 1, 1);
MultiByteToWideChar(CP_UTF8, 0, src, -1, dst, size+1); // $ Alert // BAD
MultiByteToWideChar(CP_UTF8, 0, src, -1, dst, size+1); // BAD
}
static void goodTest4(){
char src[] = "0123456789ABCDEF";
@@ -67,13 +67,13 @@ static void badTest4(){
char src[] = "0123456789ABCDEF";
int size = MultiByteToWideChar(CP_UTF8, 0, src,sizeof(src),NULL,0);
wchar_t * dst = (wchar_t*)malloc(size + 1);
MultiByteToWideChar(CP_UTF8, 0, src, -1, dst, size+1); // $ Alert // BAD
MultiByteToWideChar(CP_UTF8, 0, src, -1, dst, size+1); // BAD
}
static int goodTest5(void *src){
return WideCharToMultiByte(CP_ACP, 0, (LPCWSTR)src, -1, 0, 0, 0, 0); // GOOD
}
static int badTest5 (void *src) {
return WideCharToMultiByte(CP_ACP, 0, (LPCWSTR)src, -1, 0, 3, 0, 0); // $ Alert // BAD
return WideCharToMultiByte(CP_ACP, 0, (LPCWSTR)src, -1, 0, 3, 0, 0); // BAD
}
static void goodTest6(WCHAR *src)
{
@@ -90,6 +90,6 @@ static void goodTest6(WCHAR *src)
static void badTest6(WCHAR *src)
{
char dst[5] ="";
WideCharToMultiByte(CP_ACP, 0, src, -1, dst, 260, 0, 0); // $ Alert // BAD
WideCharToMultiByte(CP_ACP, 0, src, -1, dst, 260, 0, 0); // BAD
printf("%s\n", dst);
}

View File

@@ -12,11 +12,11 @@ size_t mbsrtowcs(wchar_t *wcstr,const char *mbstr,size_t count, mbstate_t *mbsta
static void badTest1(void *src, int size) {
mbstowcs((wchar_t*)src,(char*)src,size); // $ Alert // BAD
mbstowcs((wchar_t*)src,(char*)src,size); // BAD
_locale_t locale;
_mbstowcs_l((wchar_t*)src,(char*)src,size,locale); // $ Alert // BAD
_mbstowcs_l((wchar_t*)src,(char*)src,size,locale); // BAD
mbstate_t *mbstate;
mbsrtowcs((wchar_t*)src,(char*)src,size,mbstate); // $ Alert // BAD
mbsrtowcs((wchar_t*)src,(char*)src,size,mbstate); // BAD
}
static void goodTest2(){
char src[] = "0123456789ABCDEF";
@@ -32,7 +32,7 @@ static void goodTest2(){
static void badTest2(){
char src[] = "0123456789ABCDEF";
wchar_t dst[16];
mbstowcs(dst, src,16); // $ Alert // BAD
mbstowcs(dst, src,16); // BAD
printf("%s\n", dst);
}
static void goodTest3(){
@@ -45,7 +45,7 @@ static void badTest3(){
char src[] = "0123456789ABCDEF";
int size = mbstowcs(NULL, src,NULL);
wchar_t * dst = (wchar_t*)calloc(size + 1, 1);
mbstowcs(dst, src,size+1); // $ Alert // BAD
mbstowcs(dst, src,size+1); // BAD
}
static void goodTest4(){
char src[] = "0123456789ABCDEF";
@@ -57,13 +57,13 @@ static void badTest4(){
char src[] = "0123456789ABCDEF";
int size = mbstowcs(NULL, src,NULL);
wchar_t * dst = (wchar_t*)malloc(size + 1);
mbstowcs(dst, src,size+1); // $ Alert // BAD
mbstowcs(dst, src,size+1); // BAD
}
static int goodTest5(void *src){
return mbstowcs(NULL, (char*)src,NULL); // GOOD
}
static int badTest5 (void *src) {
return mbstowcs(NULL, (char*)src,3); // $ Alert // BAD
return mbstowcs(NULL, (char*)src,3); // BAD
}
static void goodTest6(void *src){
wchar_t dst[5];
@@ -77,6 +77,6 @@ static void goodTest6(void *src){
}
static void badTest6(void *src){
wchar_t dst[5];
mbstowcs(dst, (char*)src,260); // $ Alert // BAD
mbstowcs(dst, (char*)src,260); // BAD
printf("%s\n", dst);
}

View File

@@ -13,7 +13,7 @@ static size_t badTest1(unsigned char *src){
int cb = 0;
unsigned char dst[50];
while( cb < sizeof(dst) )
dst[cb++]=*src++; // $ Alert // BAD
dst[cb++]=*src++; // BAD
return _mbclen(dst);
}
static void goodTest2(unsigned char *src){
@@ -33,7 +33,7 @@ static void badTest2(unsigned char *src){
unsigned char dst[50];
while( cb < sizeof(dst) )
{
_mbccpy(dst+cb,src); // $ Alert // BAD
_mbccpy(dst+cb,src); // BAD
cb+=_mbclen(src);
src=_mbsinc(src);
}
@@ -44,5 +44,5 @@ static void goodTest3(){
}
static void badTest3(){
wchar_t name[50];
name[sizeof(name) - 1] = L'\0'; // $ Alert // BAD
name[sizeof(name) - 1] = L'\0'; // BAD
}

View File

@@ -1,2 +1 @@
query: experimental/Security/CWE/CWE-190/AllocMultiplicationOverflow.ql
postprocess: utils/test/InlineExpectationsTestQuery.ql
experimental/Security/CWE/CWE-190/AllocMultiplicationOverflow.ql

View File

@@ -10,31 +10,31 @@ void test()
int y = getAnInt();
char *buffer1 = (char *)malloc(x + y); // GOOD
char *buffer2 = (char *)malloc(x * y); // $ Alert // BAD
char *buffer2 = (char *)malloc(x * y); // BAD
int *buffer3 = (int *)malloc(x * sizeof(int)); // GOOD
int *buffer4 = (int *)malloc(x * y * sizeof(int)); // $ Alert // BAD
int *buffer4 = (int *)malloc(x * y * sizeof(int)); // BAD
if ((x <= 1000) && (y <= 1000))
{
char *buffer5 = (char *)malloc(x * y); // $ SPURIOUS: Alert // GOOD [FALSE POSITIVE]
char *buffer5 = (char *)malloc(x * y); // GOOD [FALSE POSITIVE]
}
size_t size1 = x * y; // $ Source
char *buffer5 = (char *)malloc(size1); // $ Alert // BAD
size_t size1 = x * y;
char *buffer5 = (char *)malloc(size1); // BAD
size_t size2 = x;
size2 *= y;
char *buffer6 = (char *)malloc(size2); // $ MISSING: Alert // BAD [NOT DETECTED]
char *buffer6 = (char *)malloc(size2); // BAD [NOT DETECTED]
char *buffer7 = new char[x * 10]; // GOOD
char *buffer8 = new char[x * y]; // $ Alert // BAD
char *buffer9 = new char[x * x]; // $ Alert // BAD
char *buffer8 = new char[x * y]; // BAD
char *buffer9 = new char[x * x]; // BAD
}
// --- custom allocators ---
void *MyMalloc1(size_t size) { return malloc(size); } // $ Alert // [additional detection here]
void *MyMalloc1(size_t size) { return malloc(size); } // [additional detection here]
void *MyMalloc2(size_t size);
void customAllocatorTests()
@@ -42,6 +42,6 @@ void customAllocatorTests()
int x = getAnInt();
int y = getAnInt();
char *buffer1 = (char *)MyMalloc1(x * y); // $ Alert Source // BAD
char *buffer2 = (char *)MyMalloc2(x * y); // $ Alert // BAD
char *buffer1 = (char *)MyMalloc1(x * y); // BAD
char *buffer2 = (char *)MyMalloc2(x * y); // BAD
}

View File

@@ -1,2 +1 @@
query: experimental/Security/CWE/CWE-190/DangerousUseOfTransformationAfterOperation.ql
postprocess: utils/test/InlineExpectationsTestQuery.ql
experimental/Security/CWE/CWE-190/DangerousUseOfTransformationAfterOperation.ql

View File

@@ -6,17 +6,17 @@ void functionWork(char aA[10],unsigned int aUI) {
int aI;
aI = (aUI*8)/10; // GOOD
aI = aUI*8; // $ Alert // BAD
aI = aUI*8; // BAD
aP = aA+aI;
aI = (int)aUI*8; // GOOD
aL = (unsigned long)(aI*aI); // $ Alert // BAD
aL = (unsigned long)(aI*aI); // BAD
aL = ((unsigned long)aI*aI); // GOOD
testCall((unsigned long)(aI*aI)); // $ Alert // BAD
testCall((unsigned long)(aI*aI)); // BAD
testCall(((unsigned long)aI*aI)); // GOOD
if((unsigned long)(aI*aI) > aL) // $ Alert // BAD
if((unsigned long)(aI*aI) > aL) // BAD
return;
if(((unsigned long)aI*aI) > aL) // GOOD
return;

View File

@@ -1,2 +1 @@
query: experimental/Security/CWE/CWE-190/IfStatementAdditionOverflow.ql
postprocess: utils/test/InlineExpectationsTestQuery.ql
experimental/Security/CWE/CWE-190/IfStatementAdditionOverflow.ql

View File

@@ -15,49 +15,49 @@ void test()
unsigned short b1 = getAnUnsignedShort();
unsigned short c1 = getAnUnsignedShort();
if (a+b>c) a = c-b; // $ Alert // BAD
if (a+b>c) { a = c-b; } // $ Alert // BAD
if (b+a>c) a = c-b; // $ Alert // BAD
if (b+a>c) { a = c-b; } // $ Alert // BAD
if (c>a+b) a = c-b; // $ Alert // BAD
if (c>a+b) { a = c-b; } // $ Alert // BAD
if (c>b+a) a = c-b; // $ Alert // BAD
if (c>b+a) { a = c-b; } // $ Alert // BAD
if (a+b>c) a = c-b; // BAD
if (a+b>c) { a = c-b; } // BAD
if (b+a>c) a = c-b; // BAD
if (b+a>c) { a = c-b; } // BAD
if (c>a+b) a = c-b; // BAD
if (c>a+b) { a = c-b; } // BAD
if (c>b+a) a = c-b; // BAD
if (c>b+a) { a = c-b; } // BAD
if (a+b>=c) a = c-b; // $ Alert // BAD
if (a+b>=c) { a = c-b; } // $ Alert // BAD
if (b+a>=c) a = c-b; // $ Alert // BAD
if (b+a>=c) { a = c-b; } // $ Alert // BAD
if (c>=a+b) a = c-b; // $ Alert // BAD
if (c>=a+b) { a = c-b; } // $ Alert // BAD
if (c>=b+a) a = c-b; // $ Alert // BAD
if (c>=b+a) { a = c-b; } // $ Alert // BAD
if (a+b>=c) a = c-b; // BAD
if (a+b>=c) { a = c-b; } // BAD
if (b+a>=c) a = c-b; // BAD
if (b+a>=c) { a = c-b; } // BAD
if (c>=a+b) a = c-b; // BAD
if (c>=a+b) { a = c-b; } // BAD
if (c>=b+a) a = c-b; // BAD
if (c>=b+a) { a = c-b; } // BAD
if (a+b<c) a = c-b; // $ Alert // BAD
if (a+b<c) { a = c-b; } // $ Alert // BAD
if (b+a<c) a = c-b; // $ Alert // BAD
if (b+a<c) { a = c-b; } // $ Alert // BAD
if (c<a+b) a = c-b; // $ Alert // BAD
if (c<a+b) { a = c-b; } // $ Alert // BAD
if (c<b+a) a = c-b; // $ Alert // BAD
if (c<b+a) { a = c-b; } // $ Alert // BAD
if (a+b<c) a = c-b; // BAD
if (a+b<c) { a = c-b; } // BAD
if (b+a<c) a = c-b; // BAD
if (b+a<c) { a = c-b; } // BAD
if (c<a+b) a = c-b; // BAD
if (c<a+b) { a = c-b; } // BAD
if (c<b+a) a = c-b; // BAD
if (c<b+a) { a = c-b; } // BAD
if (a+b<=c) a = c-b; // $ Alert // BAD
if (a+b<=c) { a = c-b; } // $ Alert // BAD
if (b+a<=c) a = c-b; // $ Alert // BAD
if (b+a<=c) { a = c-b; } // $ Alert // BAD
if (c<=a+b) a = c-b; // $ Alert // BAD
if (c<=a+b) { a = c-b; } // $ Alert // BAD
if (c<=b+a) a = c-b; // $ Alert // BAD
if (c<=b+a) { a = c-b; } // $ Alert // BAD
if (a+b<=c) a = c-b; // BAD
if (a+b<=c) { a = c-b; } // BAD
if (b+a<=c) a = c-b; // BAD
if (b+a<=c) { a = c-b; } // BAD
if (c<=a+b) a = c-b; // BAD
if (c<=a+b) { a = c-b; } // BAD
if (c<=b+a) a = c-b; // BAD
if (c<=b+a) { a = c-b; } // BAD
if (a+b>d) a = d-b; // $ Alert // BAD
if (a+b>d) a = d-b; // BAD
if (a+(double)b>c) a = c-b; // GOOD
if (a+(-x)>c) a = c-(-y); // GOOD
if (a+b>c) { b++; a = c-b; } // GOOD
if (a+d>c) a = c-d; // GOOD
if (a1+b1>c1) a1 = c1-b1; // GOOD
if (a+b<=c) { /* ... */ } else { a = c-b; } // $ Alert // BAD
if (a+b<=c) { return; } a = c-b; // $ Alert // BAD
if (a+b<=c) { /* ... */ } else { a = c-b; } // BAD
if (a+b<=c) { return; } a = c-b; // BAD
}

View File

@@ -1,2 +1 @@
query: experimental/Likely Bugs/ArrayAccessProductFlow.ql
postprocess: utils/test/InlineExpectationsTestQuery.ql
experimental/Likely Bugs/ArrayAccessProductFlow.ql

View File

@@ -1,13 +1,13 @@
char *malloc(int size);
void test1(int size) {
char *arr = malloc(size); // $ Source
char *arr = malloc(size);
for (int i = 0; i < size; i++) {
arr[i] = 0; // GOOD
}
for (int i = 0; i <= size; i++) {
arr[i] = i; // $ Alert // BAD
arr[i] = i; // BAD
}
}
@@ -18,7 +18,7 @@ typedef struct {
array_t mk_array(int size) {
array_t arr;
arr.p = malloc(size); // $ Source
arr.p = malloc(size);
arr.size = size;
return arr;
@@ -32,7 +32,7 @@ void test2(int size) {
}
for (int i = 0; i <= arr.size; i++) {
arr.p[i] = i; // $ Alert // BAD
arr.p[i] = i; // BAD
}
}
@@ -42,7 +42,7 @@ void test3_callee(array_t arr) {
}
for (int i = 0; i <= arr.size; i++) {
arr.p[i] = i; // $ Alert // BAD
arr.p[i] = i; // BAD
}
}
@@ -52,7 +52,7 @@ void test3(int size) {
void test4(int size) {
array_t arr;
arr.p = malloc(size); // $ Source
arr.p = malloc(size);
arr.size = size;
for (int i = 0; i < arr.size; i++) {
@@ -60,13 +60,13 @@ void test4(int size) {
}
for (int i = 0; i <= arr.size; i++) {
arr.p[i] = i; // $ Alert // BAD
arr.p[i] = i; // BAD
}
}
array_t *mk_array_p(int size) {
array_t *arr = (array_t*) malloc(sizeof(array_t));
arr->p = malloc(size); // $ Source
arr->p = malloc(size);
arr->size = size;
return arr;
@@ -80,7 +80,7 @@ void test5(int size) {
}
for (int i = 0; i <= arr->size; i++) {
arr->p[i] = i; // $ Alert // BAD
arr->p[i] = i; // BAD
}
}
@@ -90,7 +90,7 @@ void test6_callee(array_t *arr) {
}
for (int i = 0; i <= arr->size; i++) {
arr->p[i] = i; // $ Alert // BAD
arr->p[i] = i; // BAD
}
}
@@ -105,6 +105,6 @@ void test7(int size) {
}
for (char *p = arr; p <= arr + size; p++) {
*p = 0; // $ MISSING: Alert // BAD [NOT DETECTED]
*p = 0; // BAD [NOT DETECTED]
}
}

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