Compare commits

..

12 Commits

Author SHA1 Message Date
yoff
709566ecb1 Python: visit function parameter and return annotations in new CFG
The new (shared-CFG-based) Python control flow graph in
`semmle.python.controlflow.internal.Cfg` previously did not emit CFG
nodes for parameter type annotations (`def f(x: T): ...`) or for the
return type annotation (`-> T`). The legacy CFG emitted both, and a
small number of framework models rely on this: `LocalSources.qll`'s
`annotatedInstance` walks the parameter annotation expression by way
of its CFG node to track that a parameter receives an instance of the
annotated class.

After the dataflow flip to the new CFG/SSA this regression manifested
as lost flows in any test exercising annotation-based parameter
tracking: FastAPI `Depends()` receivers, Pydantic request bodies,
Starlette `WebSocket`, the call-graph type-annotation test, and so on.
Extend `FunctionDefExpr` to visit each annotation as a child of the
function-def expression, in CPython evaluation order: positional
parameter annotations, `*args` annotation, keyword-only parameter
annotations, `**kwargs` annotation, then the return annotation. (Lambda
expressions have no annotations in Python syntax, so `LambdaExpr` is
unchanged.) PEP 695 type parameters remain out of scope; they belong
to the inner annotation scope, not the enclosing CFG.

Restored test results across `framework/aiohttp`, `framework/fastapi`,
`framework/lxml`, the `CallGraph-type-annotations` test, and
`CWE-022-PathInjection`. Two FastAPI list-comprehension MISSING markers
become positive (`taint_test.py:41,55`). CPython CFG consistency
remains clean.

Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com>
2026-06-05 08:10:14 +00:00
yoff
b783ed69c5 Python: model exception edges for raise-prone expressions inside try/with
The new CFG previously only emitted exception edges for explicit `raise`
and `assert` statements. As a result, code that became reachable only
via the exception path of an arbitrary expression (e.g., the body of an
`except` handler following a try-body whose `call()` could raise) was
classified as dead, breaking analyses like StackTraceExposure,
FileNotAlwaysClosed, ExceptionInfo, UseOfExit, and CatchingBaseException.

This commit adds a `mayThrow` predicate over expressions that are known
sources of implicit exceptions in Python (calls, attribute access,
subscripts, arithmetic/comparison operators, imports, await/yield/yield
from) plus `from m import *` at the statement level, and routes them
through the shared CFG's `beginAbruptCompletion(_, _, ExceptionSuccessor,
always=false)` hook.

The set of exception sources is restricted to nodes that are
syntactically inside a `try`/`with` statement in the same scope.
This mirrors Java's `ControlFlowGraph::mayThrow`, which only emits
exception edges where local handling can observe them — outside such
contexts, the edges add CFG complexity (weakening BarrierGuard
precision and breaking SSA continuity around augmented assignments and
subscript stores) without analysis benefit, since exceptions just
propagate to the function exit anyway.

Net effect on the test suite: ~100 alerts restored across the exception-
related query tests (StackTraceExposure +29, ExceptionInfo +17,
FileNotAlwaysClosed +52, UseOfExit +1, CatchingBaseException restored)
with no precision regressions. Affected `.expected` files and the
regression-guard `dead_under_no_raise.py` are updated accordingly.

Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com>
2026-06-05 08:10:06 +00:00
yoff
5b9803e03c Python: switch dataflow library to new (shared) CFG + SSA
Flips the Python dataflow trunk from the legacy CFG (semmle/python/Flow.qll)
and legacy ESSA SSA (semmle/python/essa/*) to the new shared CFG facade
(semmle.python.controlflow.internal.Cfg) and the new SSA adapter
(semmle.python.dataflow.new.internal.SsaImpl), both introduced
additively in the preceding PRs in this stack.

This is the trunk-flip equivalent of the original draft PR #21894 (kept
around as documentation), rebased on top of the four preparatory PRs:

  P1: Remove AstNode.getAFlowNode() and rewrite callers (#21919).
  P2: Qualify Flow.qll's AST references with Py:: prefix (#21920).
  P3: Add new shared-CFG-backed control flow graph (#21921).
  P4: Add new shared-SSA-backed SSA adapter (#21923).

The Python dataflow library (semmle/python/dataflow/new/) now imports
the new CFG facade and SSA adapter. All CFG-typed predicates
(ControlFlowNode, CallNode, BasicBlock, NameNode, AttrNode, ...) are
qualified with the Cfg:: prefix; SSA references switch from
EssaVariable/EssaDefinition to SsaImpl::Definition/SourceVariable.

GuardNode is redesigned to use the new CFG's outcome-node model
(isAfterTrue / isAfterFalse) instead of the legacy ConditionBlock +
flipped indirection. Only BarrierGuard<...> is preserved as public
API.

Framework files (Bottle, FastApi, Django, Tornado, Pyramid, Stdlib,
...) are updated to take CFG nodes from the new facade.

A handful of dataflow consistency tweaks for the new CFG:
- Augmented-assignment targets are treated as both load and store.
- 'from X import *' produces uncertain SSA writes for unknown names.
- CFG nodes are canonicalised so dataflow does not see equivalent
  pre/post-order pairs as distinct nodes.

Two AST tweaks for the new CFG:
- AstNodeImpl: omit PEP 695 type-parameter names from
  FunctionDefExpr / ClassDefExpr children.
- ImportResolution: drop the legacy essa import.

Test churn (~175 files): reblessed library- and query-test .expected
files reflect slightly different CFG granularity, different toString
output, and a handful of true alert deltas in security queries.

Verification: all 367 lib + src + consistency-queries compile clean.

Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com>
2026-06-05 08:04:01 +00:00
Copilot
b2ff09f70a Python: add new shared-SSA-backed SSA adapter
Preparatory refactor for the shared-CFG dataflow migration. Adds the
new Python SSA adapter additively, without changing any production
behaviour.

Library additions:

- semmle.python.dataflow.new.internal.SsaImpl — Python SSA
  implementation built on the new (shared) CFG. Mirrors the Java SSA
  adapter (java/ql/lib/semmle/code/java/dataflow/internal/SsaImpl.qll):
  an InputSig is defined in terms of positional (BasicBlock, int)
  variable references, and the shared
  codeql.ssa.Ssa::Make<Location, Cfg, Input> module is then
  instantiated.

  SourceVariable is the AST-level Py::Variable. Variable references
  are looked up via the new CFG facade's NameNode.defines/uses/deletes
  predicates (added in the preceding PR), which themselves are
  one-line bridges to AST-level Name.defines/uses/deletes.

  Implicit-entry definitions are inserted for non-local/global/builtin
  reads, captured variables, and (when needed) parameters.

Test additions:

- library-tests/dataflow-new-ssa/ — exercises the new SSA over a
  representative test corpus and checks expected def/use chains.

- library-tests/dataflow-new-ssa-vs-legacy/ — runs both new SSA and
  legacy ESSA over the same corpus and diffs the results, so any
  semantic divergence shows up as a test failure.

Production impact:

None. The new SSA adapter has zero callers in lib/ and src/ — the
legacy ESSA SSA (semmle/python/essa/*) remains the default. The
dataflow library is not migrated yet; that lands in a follow-up PR.

Verified by:
- All 367 lib + src + consistency-queries compile clean.
- All 641 ControlFlow + PointsTo + dataflow + essa + consistency
  library-tests pass.
- Both new dataflow-new-ssa[/vs-legacy] test packs pass.

Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com>
2026-06-05 08:03:48 +00:00
Copilot
4aee0b3c87 Python: add new shared-CFG-backed control flow graph
Preparatory refactor for the shared-CFG dataflow migration. Adds the
new Python CFG library additively, without changing any production
behaviour.

Library additions:

- semmle.python.controlflow.internal.AstNodeImpl — mediates between
  the Python AST and the shared codeql.controlflow.ControlFlowGraph
  signature. Wraps Python's Stmt/Expr/Scope/Pattern and adds two
  synthetic kinds of node (BlockStmt for body slots, intermediate
  nodes for multi-operand boolean expressions).

- semmle.python.controlflow.internal.Cfg — public facade
  re-exposing the same API surface as semmle/python/Flow.qll
  (ControlFlowNode, CallNode, BasicBlock, NameNode, DefinitionNode,
  CompareNode, ...), backed by the shared CFG.

- lib/printCfgNew.ql — debug/visualisation query for the new CFG.

- consistency-queries/CfgConsistency.ql — consistency query running
  the shared CFG's standard checks against Python.

Shared library:

- shared.controlflow.ControlFlowGraph — adds two defaulted
  getWhileElse / getForeachElse predicates to AstSig so Python can
  model while-else / for-else (no behavioural change for other
  languages).

Test additions:

- ControlFlow/bindings/* — annotation-driven SSA-binding tests for
  the new CFG (annassign, compound, comprehension, decorated,
  except_handler, imports, match_pattern, parameters, simple,
  type_params, walrus_starred, with_stmt, dead_under_no_raise).

- ControlFlow/store-load/* — basic store/load coverage.

- ControlFlow/evaluation-order/NewCfg*.ql — mirrors of the existing
  OldCfg evaluation-order self-validation suite, run against the
  new CFG via NewCfgImpl.qll.

- Minor extensions to existing test_if.py / test_boolean.py +
  cosmetic .expected churn on a handful of OldCfg tests.

No dataflow, SSA, or production query is migrated yet — that lands in
follow-up PRs. The new CFG library has zero callers in lib/ and src/.

Verified by:
- All lib + src + consistency-queries compile clean (367 queries).
- All 56 ControlFlow library-tests pass.
- All 474 dataflow + PointsTo library-tests + consistency tests pass.
- syntax_error/CONSISTENCY/CfgConsistency passes.

Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com>
2026-06-05 08:03:29 +00:00
yoff
a2295e7216 Apply suggestions from code review
Co-authored-by: Copilot Autofix powered by AI <175728472+Copilot@users.noreply.github.com>
2026-06-05 07:57:43 +00:00
Copilot
0623acc7f5 Python: qualify Flow.qll's AST references with Py:: prefix
Preparatory refactor for the shared-CFG dataflow migration. Switches
'import python' to 'import python as Py' inside Flow.qll, and qualifies
every AST-class reference (Expr, Bytes, Dict, AssignExpr, Compare,
Module, Scope, Call, Attribute, SsaVariable, AugAssign, etc.) with the
Py:: prefix.

Flow.qll's own CFG types (ControlFlowNode, BasicBlock, CallNode,
NameNode, DefinitionNode, CompareNode, ...) keep their unqualified
names — they remain the public CFG API exported from this file.

This is a semantic noop: the qualification was applied mechanically by
script and no name resolution changes. Verified by:
- All 361 lib/ + src/ queries compile clean.
- All 186 ControlFlow + PointsTo + dataflow library-tests pass.

Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com>
2026-06-05 07:57:42 +00:00
yoff
dc5aa8e0f5 Python: deprecate Function.getAReturnValueFlowNode() and rewrite internal callers
Follow-up to the getAFlowNode deprecation in the same PR: same AST→legacy-CFG
bridge pattern. The 11 internal call sites (across objects/, types/,
frameworks/, and TypeTrackingImpl) are rewritten to bind a `Return ret`
explicitly, then constrain via `ret.getScope() = f and n.getNode() = ret.getValue()`.

The predicate itself is preserved with a deprecation note so external
users do not experience churn.

Semantic noop.

Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com>
2026-06-05 07:57:42 +00:00
Copilot
db1e5035b4 Python: deprecate AstNode.getAFlowNode() and rewrite internal callers
Preparatory refactor for the shared-CFG dataflow migration.

Deprecates the AstNode.getAFlowNode() cached predicate on the public
Python QL API and rewrites all ~140 internal callers across lib/, src/,
test/, and tools/ from `expr.getAFlowNode() = cfgNode` to
`cfgNode.getNode() = expr`, using ControlFlowNode.getNode() which
already exists in Flow.qll.

The predicate itself is preserved (with a deprecation note pointing at
the new pattern) so external users do not experience churn — they can
migrate at their own pace and the AST/CFG hierarchies still get the
intended untangling once the deprecation eventually elapses.

Semantic noop verified by:
- All 361 lib/ + src/ queries compile clean.
- All 122 ControlFlow + PointsTo library-tests pass.
- All 64 dataflow library-tests pass.
- All 113 Variables/Exceptions/Expressions/Statements/Functions/Imports/
  Security/CWE-798/ModificationOfParameterWithDefault query-tests pass.

Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com>
2026-06-05 07:57:42 +00:00
yoff
7a3f546587 Python: inline init_module_submodule_defn into ImportResolution
The new-dataflow ImportResolution module only used
semmle.python.essa.SsaDefinitions for the 5-line helper predicate
SsaSource::init_module_submodule_defn. Inline it locally and drop the
dependency on legacy SsaDefinitions. This is the only remaining direct
import of semmle.python.essa.* in the new dataflow stack, so dropping
it makes the layering cleaner.

Semantic noop on the current SSA: SsaSourceVariable.getName() and
GlobalVariable.getId() both project the same DB column
(variable(_,_,result)), and the old call's 'init.getEntryNode() = f'
join was just constraining init = package via Scope.getEntryNode()'s
functional uniqueness. RA dump of accesses.ql confirms only the
expected predicate-rename shuffle; all 70 dataflow + ApiGraphs library
tests pass.

This factors out commit 8cab5a20f2 from the larger shared-CFG
migration #21925.

Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com>
2026-06-05 07:57:42 +00:00
yoff
821325b7e5 Python: simplify decorator-detection predicates to pure AST match
The internal predicates that identify `@staticmethod`, `@classmethod` and
`@property` decorators previously required the decorator's `NameNode` to
satisfy `isGlobal()` (i.e. no SSA def reaches the decorator's name use).
That filter was correct but unnecessarily indirect: these three names
are builtins, and even when a class body redefines one, the class body
has not started executing at the decorator position, so Python uses the
builtin.

Match the decorator's AST `Name` directly instead, dropping the CFG/SSA
detour. The slight semantic change — `isGlobal()` would have rejected
module-level shadowing of these builtins — is negligible in practice
and explicitly documented in the change note.

`hasContextmanagerDecorator` and `hasOverloadDecorator` keep the
`NameNode.isGlobal()` check because their target names (`contextmanager`,
`overload`) are imported, not builtin, and local shadowing is a real
concern.

Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com>
2026-06-05 07:57:42 +00:00
yoff
4d2296d4f0 Shared CFG: add defaulted getWhileElse/getForeachElse/getCatchType to AstSig
Adds three new defaulted signature predicates to the shared CFG library:

- getWhileElse / getForeachElse: `else` block of a while/for loop, if
  any (used by Python's `while-else` / `for-else` constructs).
- getCatchType: type expression of a catch clause, if any (used by
  Python's `except SomeExpr:` where the catch type is a runtime
  expression that needs CFG evaluation).

Each predicate defaults to `none()`, so behaviour is unchanged for any
language that doesn't override it (verified by re-running
java/ql/test/library-tests/controlflow/).

The Make0 succession rules are extended:
- WhileStmt/ForeachStmt: route the loop-exit edge through the else
  block before reaching the after-position.
- CatchClause: route the matching-evaluation through the type
  expression (if present) before reaching the after-value position.

Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com>
2026-06-05 07:57:37 +00:00
2513 changed files with 20082 additions and 42264 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

@@ -273,7 +273,7 @@ use_repo(
) )
go_sdk = use_extension("@rules_go//go:extensions.bzl", "go_sdk") 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 = use_extension("@gazelle//:extensions.bzl", "go_deps")
go_deps.from_file(go_mod = "//go/extractor:go.mod") go_deps.from_file(go_mod = "//go/extractor:go.mod")

View File

@@ -11,6 +11,10 @@
"java/ql/lib/semmle/code/java/dataflow/internal/rangeanalysis/SignAnalysisCommon.qll", "java/ql/lib/semmle/code/java/dataflow/internal/rangeanalysis/SignAnalysisCommon.qll",
"csharp/ql/lib/semmle/code/csharp/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#": [ "ModulusAnalysis Java/C#": [
"java/ql/lib/semmle/code/java/dataflow/ModulusAnalysis.qll", "java/ql/lib/semmle/code/java/dataflow/ModulusAnalysis.qll",
"csharp/ql/lib/semmle/code/csharp/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

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

View File

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

View File

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

View File

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

View File

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

View File

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

View File

@@ -1 +1 @@
query: semmle/code/cpp/PrintAST.ql semmle/code/cpp/PrintAST.ql

View File

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

View File

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

View File

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

View File

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

View File

@@ -19,14 +19,14 @@ enum {
int wordexp(const char *restrict s, wordexp_t *restrict p, int flags); 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]; char *filePath = argv[2];
{ {
// BAD: the user string is injected directly into `wordexp` which performs command substitution // BAD: the user string is injected directly into `wordexp` which performs command substitution
wordexp_t we; 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 experimental/Security/CWE/CWE-1041/FindWrapperFunctions.ql
postprocess: utils/test/InlineExpectationsTestQuery.ql

View File

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

View File

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

View File

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

View File

@@ -1,2 +1 @@
query: experimental/Security/CWE/CWE-1240/CustomCryptographicPrimitive.ql experimental/Security/CWE/CWE-1240/CustomCryptographicPrimitive.ql
postprocess: utils/test/InlineExpectationsTestQuery.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 // 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. // 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; char *ptr = string;
int len = strlen(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 // 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. // 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 state[2];
unsigned int t; 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" // 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 // step. It is not accurate, efficient or safe and should never be used in
// cryptography. // 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 // The "mix columns" step takes four bytes as inputs. Each byte represents a
// polynomial with 8 one-bit coefficients, e.g. input bits 00001101 // polynomial with 8 one-bit coefficients, e.g. input bits 00001101
// represent the polynomial x^3 + x^2 + 1. Arithmetic is reduced modulo // 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 // 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 // in an implementation of DES, AES and other encryption algorithms. It is not
// accurate, efficient or safe and should never be used in cryptography. // 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 // initialize `data` in a loop using lots of ^, ^= and << operations and
// a few fixed constants. // a few fixed constants.
unsigned int state = 0x12345678; unsigned int state = 0x12345678;

View File

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

View File

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

View File

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

View File

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

View File

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

View File

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

View File

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

View File

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

View File

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

View File

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

View File

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

View File

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

View File

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

View File

@@ -32,60 +32,60 @@ void testOneArray(OneArray *arr) {
void testBig(BigArray *arr) { void testBig(BigArray *arr) {
arr->buf[MAX_SIZE-1] = 0; // GOOD arr->buf[MAX_SIZE-1] = 0; // GOOD
arr->buf[MAX_SIZE] = 0; // BAD // $ Alert arr->buf[MAX_SIZE] = 0; // BAD
arr->buf[MAX_SIZE+1] = 0; // BAD // $ Alert arr->buf[MAX_SIZE+1] = 0; // BAD
for(int i = 0; i < MAX_SIZE; i++) { for(int i = 0; i < MAX_SIZE; i++) {
arr->buf[i] = 0; // GOOD arr->buf[i] = 0; // GOOD
} }
for(int i = 0; i <= MAX_SIZE; i++) { for(int i = 0; i <= MAX_SIZE; i++) {
arr->buf[i] = 0; // BAD // $ Alert arr->buf[i] = 0; // BAD
} }
} }
void testFields(ArrayAndFields *arr) { void testFields(ArrayAndFields *arr) {
arr->buf[MAX_SIZE-1] = 0; // GOOD arr->buf[MAX_SIZE-1] = 0; // GOOD
arr->buf[MAX_SIZE] = 0; // BAD? // $ Alert arr->buf[MAX_SIZE] = 0; // BAD?
arr->buf[MAX_SIZE+1] = 0; // BAD? // $ Alert arr->buf[MAX_SIZE+1] = 0; // BAD?
for(int i = 0; i < MAX_SIZE; i++) { for(int i = 0; i < MAX_SIZE; i++) {
arr->buf[i] = 0; // GOOD arr->buf[i] = 0; // GOOD
} }
for(int i = 0; i <= MAX_SIZE; i++) { for(int i = 0; i <= MAX_SIZE; i++) {
arr->buf[i] = 0; // BAD? // $ Alert arr->buf[i] = 0; // BAD?
} }
for(int i = 0; i < MAX_SIZE+2; i++) { for(int i = 0; i < MAX_SIZE+2; i++) {
arr->buf[i] = 0; // BAD? // $ Alert arr->buf[i] = 0; // BAD?
} }
// is this different if it's a memcpy? // is this different if it's a memcpy?
} }
void assignThroughPointer(int *p) { // $ Sink void assignThroughPointer(int *p) {
*p = 0; // ??? should the result go at a flow source? *p = 0; // ??? should the result go at a flow source?
} }
void addToPointerAndAssign(int *p) { void addToPointerAndAssign(int *p) {
p[MAX_SIZE-1] = 0; // GOOD p[MAX_SIZE-1] = 0; // GOOD
p[MAX_SIZE] = 0; // BAD // $ Alert p[MAX_SIZE] = 0; // BAD
} }
void testInterproc(BigArray *arr) { void testInterproc(BigArray *arr) {
assignThroughPointer(&arr->buf[MAX_SIZE-1]); // GOOD assignThroughPointer(&arr->buf[MAX_SIZE-1]); // GOOD
assignThroughPointer(&arr->buf[MAX_SIZE]); // BAD // $ Alert assignThroughPointer(&arr->buf[MAX_SIZE]); // BAD
addToPointerAndAssign(arr->buf); // $ Source addToPointerAndAssign(arr->buf);
} }
#define MAX_SIZE_BYTES 4096 #define MAX_SIZE_BYTES 4096
void testCharIndex(BigArray *arr) { void testCharIndex(BigArray *arr) {
char *charBuf = (char*) arr->buf; // $ Source char *charBuf = (char*) arr->buf;
charBuf[MAX_SIZE_BYTES - 1] = 0; // GOOD charBuf[MAX_SIZE_BYTES - 1] = 0; // GOOD
charBuf[MAX_SIZE_BYTES] = 0; // BAD // $ Alert charBuf[MAX_SIZE_BYTES] = 0; // BAD
} }
void testEqRefinement() { void testEqRefinement() {
@@ -125,7 +125,7 @@ void testStackAllocated() {
char *arr[MAX_SIZE]; char *arr[MAX_SIZE];
for(int i = 0; i <= MAX_SIZE; i++) { for(int i = 0; i <= MAX_SIZE; i++) {
arr[i] = 0; // BAD // $ Alert arr[i] = 0; // BAD
} }
} }
@@ -133,18 +133,18 @@ int strncmp(const char*, const char*, int);
char testStrncmp2(char *arr) { char testStrncmp2(char *arr) {
if(strncmp(arr, "<test>", 6) == 0) { if(strncmp(arr, "<test>", 6) == 0) {
arr += 6; // $ Alert arr += 6;
} }
return *arr; // GOOD [FALSE POSITIVE] // $ Sink return *arr; // GOOD [FALSE POSITIVE]
} }
void testStrncmp1() { void testStrncmp1() {
char asdf[5]; char asdf[5];
testStrncmp2(asdf); // $ Source testStrncmp2(asdf);
} }
void countdownBuf1(int **p) { void countdownBuf1(int **p) {
*--(*p) = 1; // GOOD [FALSE POSITIVE] // $ Sink *--(*p) = 1; // GOOD [FALSE POSITIVE]
*--(*p) = 2; // GOOD *--(*p) = 2; // GOOD
*--(*p) = 3; // GOOD *--(*p) = 3; // GOOD
*--(*p) = 4; // GOOD *--(*p) = 4; // GOOD
@@ -153,7 +153,7 @@ void countdownBuf1(int **p) {
void countdownBuf2() { void countdownBuf2() {
int buf[4]; int buf[4];
int *x = buf + 4; // $ Alert int *x = buf + 4;
countdownBuf1(&x); countdownBuf1(&x);
} }
@@ -215,10 +215,10 @@ int countdownLength2() {
void pointer_size_larger_than_array_element_size() { void pointer_size_larger_than_array_element_size() {
unsigned char buffer[100]; // getByteSize() = 100 unsigned char buffer[100]; // getByteSize() = 100
int *ptr = (int *)buffer; // pai.getElementSize() will be sizeof(int) = 4 -> size = 25 // $ Source int *ptr = (int *)buffer; // pai.getElementSize() will be sizeof(int) = 4 -> size = 25
ptr[24] = 0; // GOOD: writes bytes 96, 97, 98, 99 ptr[24] = 0; // GOOD: writes bytes 96, 97, 98, 99
ptr[25] = 0; // BAD: writes bytes 100, 101, 102, 103 // $ Alert ptr[25] = 0; // BAD: writes bytes 100, 101, 102, 103
} }
struct vec2 { int x, y; }; struct vec2 { int x, y; };
@@ -226,10 +226,10 @@ struct vec3 { int x, y, z; };
void pointer_size_smaller_than_array_element_size_but_does_not_divide_it() { void pointer_size_smaller_than_array_element_size_but_does_not_divide_it() {
vec3 array[3]; // getByteSize() = 9 * sizeof(int) vec3 array[3]; // getByteSize() = 9 * sizeof(int)
vec2 *ptr = (vec2 *)array; // pai.getElementSize() will be 2 * sizeof(int) -> size = 4 // $ Source vec2 *ptr = (vec2 *)array; // pai.getElementSize() will be 2 * sizeof(int) -> size = 4
ptr[3] = vec2{}; // GOOD: writes ints 6, 7 ptr[3] = vec2{}; // GOOD: writes ints 6, 7
ptr[4] = vec2{}; // BAD: writes ints 8, 9 // $ Alert ptr[4] = vec2{}; // BAD: writes ints 8, 9
} }
void pointer_size_larger_than_array_element_size_and_does_not_divide_it() { void pointer_size_larger_than_array_element_size_and_does_not_divide_it() {
@@ -258,7 +258,7 @@ void call_use(unsigned char* p, int n) {
if(n == 3) { if(n == 3) {
unsigned char x = p[0]; unsigned char x = p[0];
unsigned char y = p[1]; unsigned char y = p[1];
unsigned char z = p[2]; // GOOD [FALSE POSITIVE]: `call_use(buffer2, 2)` won't reach this point. // $ Alert unsigned char z = p[2]; // GOOD [FALSE POSITIVE]: `call_use(buffer2, 2)` won't reach this point.
use(x, y, z); use(x, y, z);
} }
} }
@@ -283,7 +283,7 @@ void test_call_use2() {
call_call_use(buffer1,1); call_call_use(buffer1,1);
unsigned char buffer2[2]; unsigned char buffer2[2];
call_call_use(buffer2,2); // $ Source call_call_use(buffer2,2);
unsigned char buffer3[3]; unsigned char buffer3[3];
call_call_use(buffer3,3); call_call_use(buffer3,3);
@@ -296,7 +296,7 @@ int guardingCallee(int *arr, int size) {
int sum; int sum;
for (int i = 0; i < size; i++) { for (int i = 0; i < size; i++) {
sum += arr[i]; // GOOD [FALSE POSITIVE] - guarded by size // $ Alert sum += arr[i]; // GOOD [FALSE POSITIVE] - guarded by size
} }
return sum; return sum;
} }
@@ -306,7 +306,7 @@ int guardingCaller() {
guardingCallee(arr1, MAX_SIZE); guardingCallee(arr1, MAX_SIZE);
int arr2[10]; int arr2[10];
guardingCallee(arr2, 10); // $ Source guardingCallee(arr2, 10);
} }
// simplified md5 padding // simplified md5 padding
@@ -319,10 +319,10 @@ void correlatedCondition(int num) {
end = temp + 56; end = temp + 56;
} }
else if (num < 64) { else if (num < 64) {
end = temp + 64; // GOOD [FALSE POSITVE] // $ Alert end = temp + 64; // GOOD [FALSE POSITVE]
} }
char *temp2 = temp + num; char *temp2 = temp + num;
while(temp2 != end) { // $ Sink while(temp2 != end) {
*temp2 = 0; *temp2 = 0;
temp2++; temp2++;
} }

View File

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

View File

@@ -9,7 +9,7 @@ int main(int argc, char *argv[])
{ {
//umask(0022); //umask(0022);
FILE *fp; FILE *fp;
fp = fopen("myFile.txt","w"); // BAD // $ Alert fp = fopen("myFile.txt","w"); // BAD
//chmod("myFile.txt",0644); //chmod("myFile.txt",0644);
fprintf(fp,"%s\n","data to file"); fprintf(fp,"%s\n","data to file");
fclose(fp); fclose(fp);

View File

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

View File

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

View File

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

View File

@@ -9,7 +9,7 @@ int chdir(char *path);
void exit(int status); void exit(int status);
int funTest1(){ int funTest1(){
if (chroot("/myFold/myTmp") == -1) { // BAD // $ Alert if (chroot("/myFold/myTmp") == -1) { // BAD
exit(-1); exit(-1);
} }
return 0; return 0;
@@ -26,7 +26,7 @@ int funTest2(){
} }
int funTest3(){ int funTest3(){
chdir("/myFold/myTmp"); // BAD // $ Alert chdir("/myFold/myTmp"); // BAD
return 0; return 0;
} }
int main(int argc, char *argv[]) int main(int argc, char *argv[])

View File

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

View File

@@ -6,7 +6,7 @@ int fclose(FILE *stream);
void funcTest1() void funcTest1()
{ {
umask(0666); // BAD // $ Alert umask(0666); // BAD
FILE *fe; FILE *fe;
fe = fopen("myFile.txt", "wt"); fe = fopen("myFile.txt", "wt");
fclose(fe); fclose(fe);
@@ -27,7 +27,7 @@ void funcTest2(int mode)
FILE *fe; FILE *fe;
fe = fopen("myFile.txt", "wt"); fe = fopen("myFile.txt", "wt");
fclose(fe); fclose(fe);
chmod("myFile.txt",0555-mode); // BAD // $ Alert chmod("myFile.txt",0555-mode); // BAD
} }
void funcTest2g(int mode) void funcTest2g(int mode)

View File

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

View File

@@ -26,7 +26,7 @@ bool PamAuthBad(const std::string &username_in,
return false; return false;
} }
err = pam_authenticate(pamh, 0); // $ Alert err = pam_authenticate(pamh, 0);
if (err != PAM_SUCCESS) if (err != PAM_SUCCESS)
return err; return err;

View File

@@ -22,8 +22,8 @@ char host[] = "codeql.com";
void bad(void) { void bad(void) {
std::unique_ptr<CURL> curl = std::unique_ptr<CURL>(curl_easy_init()); std::unique_ptr<CURL> curl = std::unique_ptr<CURL>(curl_easy_init());
curl_easy_setopt(curl.get(), CURLOPT_SSL_VERIFYPEER, 0); // $ Alert curl_easy_setopt(curl.get(), CURLOPT_SSL_VERIFYPEER, 0);
curl_easy_setopt(curl.get(), CURLOPT_SSL_VERIFYHOST, 0); // $ Alert curl_easy_setopt(curl.get(), CURLOPT_SSL_VERIFYHOST, 0);
curl_easy_setopt(curl.get(), CURLOPT_URL, host); curl_easy_setopt(curl.get(), CURLOPT_URL, host);
curl_easy_perform(curl.get()); curl_easy_perform(curl.get());
} }

View File

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

View File

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

View File

@@ -54,7 +54,7 @@ void file()
FILE *file; FILE *file;
// BAD: write zipcode to file in cleartext // BAD: write zipcode to file in cleartext
fputs(theZipcode, file); // $ Alert fputs(theZipcode, file);
// GOOD: encrypt first // GOOD: encrypt first
char *encrypted = encrypt(theZipcode); char *encrypted = encrypt(theZipcode);
@@ -71,15 +71,15 @@ int main(int argc, char **argv)
char *buff4; char *buff4;
// BAD: write medical to buffer in cleartext // BAD: write medical to buffer in cleartext
sprintf(buff1, "%s", medical); // $ Alert Source sprintf(buff1, "%s", medical);
// BAD: write medical to buffer in cleartext // BAD: write medical to buffer in cleartext
char *temp = medical; // $ Source char *temp = medical;
sprintf(buff2, "%s", temp); // $ Alert sprintf(buff2, "%s", temp);
// BAD: write medical to buffer in cleartext // BAD: write medical to buffer in cleartext
char *buff5 = func(medical); // $ Source char *buff5 = func(medical);
sprintf(buff3, "%s", buff5); // $ Alert sprintf(buff3, "%s", buff5);
char *buff6 = encrypt(medical); char *buff6 = encrypt(medical);
// GOOD: encrypt first // GOOD: encrypt first
@@ -93,10 +93,10 @@ void stream()
ofstream mystream; ofstream mystream;
// BAD: write zipcode to file in cleartext // BAD: write zipcode to file in cleartext
mystream << "the zipcode is: " << theZipcode; // $ Alert Source mystream << "the zipcode is: " << theZipcode;
// BAD: write zipcode to file in cleartext // BAD: write zipcode to file in cleartext
(mystream << "the zipcode is: ").write(theZipcode, strlen(theZipcode)); // $ Alert (mystream << "the zipcode is: ").write(theZipcode, strlen(theZipcode));
// GOOD: encrypt first // GOOD: encrypt first
char *encrypted = encrypt(theZipcode); char *encrypted = encrypt(theZipcode);

View File

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

View File

@@ -44,13 +44,13 @@ int getSize2(int type) {
int badTestf1(int type, int met) { int badTestf1(int type, int met) {
int is = getSize(type); int is = getSize(type);
if (met == 1) return 123 / is; // BAD // $ Alert if (met == 1) return 123 / is; // BAD
else return 123 / getSize2(type); // BAD // $ Alert else return 123 / getSize2(type); // BAD
} }
int badTestf2(int type) { int badTestf2(int type) {
int is; int is;
is = getSize(type); is = getSize(type);
return 123 / is; // BAD // $ Alert return 123 / is; // BAD
} }
int badTestf3(int type, int met) { int badTestf3(int type, int met) {
@@ -62,23 +62,23 @@ int badTestf3(int type, int met) {
case 2: case 2:
if (0 == is) return 123 / is; // BAD [NOT DETECTED] if (0 == is) return 123 / is; // BAD [NOT DETECTED]
case 3: case 3:
if (!is & 123 / is) // BAD // $ Alert if (!is & 123 / is) // BAD
return 123; return 123;
case 4: case 4:
if (!is | 123 / is) // BAD // $ Alert if (!is | 123 / is) // BAD
return 123; return 123;
case 5: case 5:
if (123 / is || !is) // BAD // $ Alert if (123 / is || !is) // BAD
return 123; return 123;
case 6: case 6:
if (123 / is && !is) // BAD // $ Alert if (123 / is && !is) // BAD
return 123; return 123;
case 7: case 7:
if (!is) return 123 / is; // BAD // $ Alert if (!is) return 123 / is; // BAD
case 8: case 8:
if (is > -1) return 123 / is; // BAD // $ Alert if (is > -1) return 123 / is; // BAD
case 9: case 9:
if (is < 2) return 123 / is; // BAD // $ Alert if (is < 2) return 123 / is; // BAD
} }
if (is != 0) return -1; if (is != 0) return -1;
if (is == 0) type += 1; if (is == 0) type += 1;
@@ -125,20 +125,20 @@ int badTestf4(int type) {
int is = getSize(type); int is = getSize(type);
int d; int d;
d = type * is; d = type * is;
return 123 / d; // BAD // $ Alert return 123 / d; // BAD
} }
int badTestf5(int type) { int badTestf5(int type) {
int is = getSize(type); int is = getSize(type);
int d; int d;
d = is / type; d = is / type;
return 123 / d; // BAD // $ Alert return 123 / d; // BAD
} }
int badTestf6(int type) { int badTestf6(int type) {
int is = getSize(type); int is = getSize(type);
int d; int d;
d = is / type; d = is / type;
return type * 123 / d; // BAD // $ Alert return type * 123 / d; // BAD
} }
int badTestf7(int type, int met) { int badTestf7(int type, int met) {
@@ -150,7 +150,7 @@ int badTestf7(int type, int met) {
return 123 / is; // GOOD return 123 / is; // GOOD
} }
quit: quit:
return 123 / is; // BAD // $ Alert return 123 / is; // BAD
} }
int goodTestf7(int type, int met) { int goodTestf7(int type, int met) {
@@ -169,8 +169,8 @@ int goodTestf7(int type, int met) {
int badTestf8(int type) { int badTestf8(int type) {
int is = getSize(type); int is = getSize(type);
type /= is; // BAD // $ Alert type /= is; // BAD
type %= is; // BAD // $ Alert type %= is; // BAD
return type; return type;
} }
@@ -184,7 +184,7 @@ float getSizeFloat(float type) {
} }
float badTestf9(float type) { float badTestf9(float type) {
float is = getSizeFloat(type); float is = getSizeFloat(type);
return 123 / is; // BAD // $ Alert return 123 / is; // BAD
} }
float goodTestf9(float type) { float goodTestf9(float type) {
float is = getSizeFloat(type); float is = getSizeFloat(type);
@@ -196,18 +196,18 @@ int badTestf10(int type) {
int out = type; int out = type;
int is = getSize(type); int is = getSize(type);
if (is > -2) { if (is > -2) {
out /= 123 / (is + 1); // BAD // $ Alert out /= 123 / (is + 1); // BAD
} }
if (is > 0) { if (is > 0) {
return 123 / (is - 1); // BAD // $ Alert return 123 / (is - 1); // BAD
} }
if (is <= 0) return 0; if (is <= 0) return 0;
return 123 / (is - 1); // BAD // $ Alert return 123 / (is - 1); // BAD
return 0; return 0;
} }
int badTestf11(int type) { int badTestf11(int type) {
int is = getSize(type); int is = getSize(type);
return 123 / (is - 3); // BAD // $ Alert return 123 / (is - 3); // BAD
} }
int goodTestf11(int type) { int goodTestf11(int type) {
@@ -255,12 +255,12 @@ int badMySubDiv(int type, int is) {
void badTestf13(int type) { void badTestf13(int type) {
int is = getSize(type); int is = getSize(type);
badMyDiv(type, is); // BAD // $ Alert badMyDiv(type, is); // BAD
badMyDiv(type, is - 2); // BAD // $ Alert badMyDiv(type, is - 2); // BAD
badMySubDiv(type, is); // BAD // $ Alert badMySubDiv(type, is); // BAD
goodMyDiv(type, is); // GOOD goodMyDiv(type, is); // GOOD
if (is < 5) if (is < 5)
badMySubDiv(type, is); // BAD // $ Alert badMySubDiv(type, is); // BAD
if (is < 0) if (is < 0)
badMySubDiv(type, is); // BAD [NOT DETECTED] badMySubDiv(type, is); // BAD [NOT DETECTED]
if (is > 5) if (is > 5)
@@ -270,9 +270,9 @@ void badTestf13(int type) {
if (is > 0) if (is > 0)
badMyDiv(type, is); // GOOD badMyDiv(type, is); // GOOD
if (is < 5) if (is < 5)
badMyDiv(type, is - 3); // BAD // $ Alert badMyDiv(type, is - 3); // BAD
if (is < 0) if (is < 0)
badMyDiv(type, is + 1); // BAD // $ Alert badMyDiv(type, is + 1); // BAD
if (is > 5) if (is > 5)
badMyDiv(type, is - 3); // GOOD badMyDiv(type, is - 3); // GOOD
} }

View File

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

View File

@@ -13,7 +13,7 @@ int fclose(FILE *stream);
int funcTest1() int funcTest1()
{ {
FILE *fp; FILE *fp;
char *filename = tmpnam(NULL); // BAD // $ Alert char *filename = tmpnam(NULL); // BAD
fp = fopen(filename,"w"); fp = fopen(filename,"w");
fprintf(fp,"%s\n","data to file"); fprintf(fp,"%s\n","data to file");
fclose(fp); fclose(fp);

View File

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

View File

@@ -31,7 +31,7 @@ unsigned char * badResize_0(unsigned char * buffer,size_t currentSize,size_t new
// BAD: on unsuccessful call to realloc, we will lose a pointer to a valid memory block // BAD: on unsuccessful call to realloc, we will lose a pointer to a valid memory block
if (currentSize < newSize) if (currentSize < newSize)
{ {
buffer = (unsigned char *)realloc(buffer, newSize); // $ Alert buffer = (unsigned char *)realloc(buffer, newSize);
} }
return buffer; return buffer;
} }
@@ -60,7 +60,7 @@ unsigned char * badResize_1_0(unsigned char * buffer,size_t currentSize,size_t n
// BAD: on unsuccessful call to realloc, we will lose a pointer to a valid memory block // BAD: on unsuccessful call to realloc, we will lose a pointer to a valid memory block
if (currentSize < newSize) if (currentSize < newSize)
{ {
buffer = (unsigned char *)realloc(buffer, newSize); // $ Alert buffer = (unsigned char *)realloc(buffer, newSize);
} }
return buffer; return buffer;
} }
@@ -136,7 +136,7 @@ unsigned char * badResize_1_1(unsigned char * buffer,size_t currentSize,size_t n
// BAD: on unsuccessful call to realloc, we will lose a pointer to a valid memory block // BAD: on unsuccessful call to realloc, we will lose a pointer to a valid memory block
if (currentSize < newSize) if (currentSize < newSize)
{ {
buffer = (unsigned char *)realloc(buffer, newSize); // $ Alert buffer = (unsigned char *)realloc(buffer, newSize);
} }
if(!buffer) if(!buffer)
aFakeFailed_1(1, 1); aFakeFailed_1(1, 1);
@@ -183,7 +183,7 @@ unsigned char * badResize_2_0(unsigned char * buffer,size_t currentSize,size_t n
assert(buffer!=0); assert(buffer!=0);
if (currentSize < newSize) if (currentSize < newSize)
{ {
buffer = (unsigned char *)realloc(buffer, newSize); // $ Alert buffer = (unsigned char *)realloc(buffer, newSize);
} }
return buffer; return buffer;
} }
@@ -279,7 +279,7 @@ unsigned char *goodResize_3_1(unsigned char *buffer, size_t currentSize, size_t
unsigned char *tmp = buffer; unsigned char *tmp = buffer;
if (currentSize < newSize) if (currentSize < newSize)
{ {
buffer = (unsigned char *)realloc(buffer, newSize); // $ Alert buffer = (unsigned char *)realloc(buffer, newSize);
if (buffer == NULL) if (buffer == NULL)
{ {
free(tmp); free(tmp);
@@ -296,7 +296,7 @@ unsigned char *goodResize_3_2(unsigned char *buffer, size_t currentSize, size_t
unsigned char *tmp = buffer; unsigned char *tmp = buffer;
if (currentSize < newSize) if (currentSize < newSize)
{ {
tmp = (unsigned char *)realloc(tmp, newSize); // $ Alert tmp = (unsigned char *)realloc(tmp, newSize);
if (tmp != 0) if (tmp != 0)
{ {
buffer = tmp; buffer = tmp;
@@ -325,7 +325,7 @@ unsigned char * badResize_5_2(unsigned char *buffer, size_t currentSize, size_t
// BAD: on unsuccessful call to realloc, we will lose a pointer to a valid memory block // BAD: on unsuccessful call to realloc, we will lose a pointer to a valid memory block
if (currentSize < newSize) if (currentSize < newSize)
{ {
buffer = (unsigned char *)realloc(buffer, newSize); // $ Alert buffer = (unsigned char *)realloc(buffer, newSize);
} }
if (cond) if (cond)
{ {
@@ -339,7 +339,7 @@ unsigned char * badResize_5_1(unsigned char *buffer, size_t currentSize, size_t
// BAD: on unsuccessful call to realloc, we will lose a pointer to a valid memory block // BAD: on unsuccessful call to realloc, we will lose a pointer to a valid memory block
if (currentSize < newSize) if (currentSize < newSize)
{ {
buffer = (unsigned char *)realloc(buffer, newSize); // $ Alert buffer = (unsigned char *)realloc(buffer, newSize);
assert(cond); // irrelevant assert(cond); // irrelevant
} }
return buffer; return buffer;

View File

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

View File

@@ -15,12 +15,12 @@ BrotliDecoderResult BrotliDecoderDecompressStream(
void brotli_test(int argc, const char **argv) { void brotli_test(int argc, const char **argv) {
uint8_t output[1024]; uint8_t output[1024];
size_t output_size = sizeof(output); size_t output_size = sizeof(output);
BrotliDecoderDecompress(1024, (uint8_t *) argv[2], &output_size, output); // BAD // $ Alert BrotliDecoderDecompress(1024, (uint8_t *) argv[2], &output_size, output); // BAD
size_t input_size = 1024; size_t input_size = 1024;
const uint8_t *input_p = (const uint8_t*)argv[2]; const uint8_t *input_p = (const uint8_t*)argv[2];
uint8_t *output_p = output; uint8_t *output_p = output;
size_t out_size; size_t out_size;
BrotliDecoderDecompressStream(0, &input_size, &input_p, &output_size, // BAD // $ Alert BrotliDecoderDecompressStream(0, &input_size, &input_p, &output_size, // BAD
&output_p, &out_size); &output_p, &out_size);
} }

View File

@@ -19,7 +19,7 @@ static int read_data(archive *ar) {
size_t size; size_t size;
la_int64_t offset; la_int64_t offset;
int r = archive_read_data_block(ar, &buff, &size, &offset); // BAD // $ Alert int r = archive_read_data_block(ar, &buff, &size, &offset); // BAD
if (r == ARCHIVE_EOF) if (r == ARCHIVE_EOF)
return ARCHIVE_OK; return ARCHIVE_OK;
if (r < ARCHIVE_OK) if (r < ARCHIVE_OK)

View File

@@ -4,7 +4,7 @@ void minizip_test(int argc, const char **argv);
void zlib_test(int argc, const char **argv); void zlib_test(int argc, const char **argv);
void zstd_test(int argc, const char **argv); void zstd_test(int argc, const char **argv);
int main(int argc, const char **argv) { // $ Source int main(int argc, const char **argv) {
brotli_test(argc, argv); brotli_test(argc, argv);
libarchive_test(argc, argv); libarchive_test(argc, argv);
minizip_test(argc, argv); minizip_test(argc, argv);

View File

@@ -14,7 +14,7 @@ void minizip_test(int argc, const char **argv) {
int32_t bytes_read; int32_t bytes_read;
char buf[4096]; char buf[4096];
while(true) { while(true) {
bytes_read = mz_zip_entry_read(zip_handle, (char *) argv[1], sizeof(buf)); // BAD // $ Alert bytes_read = mz_zip_entry_read(zip_handle, (char *) argv[1], sizeof(buf)); // BAD
if (bytes_read <= 0) { if (bytes_read <= 0) {
break; break;
} }
@@ -23,7 +23,7 @@ void minizip_test(int argc, const char **argv) {
void *zip_reader = mz_zip_reader_create(); void *zip_reader = mz_zip_reader_create();
mz_zip_reader_open_file(zip_reader, argv[1]); mz_zip_reader_open_file(zip_reader, argv[1]);
mz_zip_reader_goto_first_entry(zip_reader); mz_zip_reader_goto_first_entry(zip_reader);
mz_zip_reader_entry_save(zip_reader, 0, 0); // BAD // $ Alert mz_zip_reader_entry_save(zip_reader, 0, 0); // BAD
UnzOpen(argv[3]); // BAD // $ Alert UnzOpen(argv[3]); // BAD
} }

View File

@@ -22,7 +22,7 @@ void UnsafeInflate(char *input) {
infstream.next_out = output; // output char array infstream.next_out = output; // output char array
inflateInit(&infstream); inflateInit(&infstream);
inflate(&infstream, 0); // BAD // $ Alert inflate(&infstream, 0); // BAD
} }
@@ -38,7 +38,7 @@ void UnsafeGzread(char *fileName) {
gzFile inFileZ = gzopen(fileName, "rb"); gzFile inFileZ = gzopen(fileName, "rb");
unsigned char unzipBuffer[8192]; unsigned char unzipBuffer[8192];
while (true) { while (true) {
if (gzread(inFileZ, unzipBuffer, 8192) <= 0) { // BAD // $ Alert if (gzread(inFileZ, unzipBuffer, 8192) <= 0) { // BAD
break; break;
} }
} }
@@ -48,7 +48,7 @@ void UnsafeGzfread(char *fileName) {
gzFile inFileZ = gzopen(fileName, "rb"); gzFile inFileZ = gzopen(fileName, "rb");
while (true) { while (true) {
char buffer[1000]; char buffer[1000];
if (!gzfread(buffer, 999, 1, inFileZ)) { // BAD // $ Alert if (!gzfread(buffer, 999, 1, inFileZ)) { // BAD
break; break;
} }
} }
@@ -59,7 +59,7 @@ void UnsafeGzgets(char *fileName) {
char *buffer = new char[4000000000]; char *buffer = new char[4000000000];
char *result; char *result;
while (true) { while (true) {
result = gzgets(inFileZ, buffer, 1000000000); // BAD // $ Alert result = gzgets(inFileZ, buffer, 1000000000); // BAD
if (result == nullptr) { if (result == nullptr) {
break; break;
} }
@@ -74,7 +74,7 @@ void InflateString(char *input) {
uLong source_length = 500; uLong source_length = 500;
uLong destination_length = sizeof(output); uLong destination_length = sizeof(output);
uncompress(output, &destination_length, (Bytef *) input, source_length); // BAD // $ Alert uncompress(output, &destination_length, (Bytef *) input, source_length); // BAD
} }
void zlib_test(int argc, char **argv) { void zlib_test(int argc, char **argv) {

View File

@@ -36,7 +36,7 @@ void zstd_test(int argc, const char **argv) {
ZSTD_inBuffer input = {buffIn, read, 0}; ZSTD_inBuffer input = {buffIn, read, 0};
while (input.pos < input.size) { while (input.pos < input.size) {
ZSTD_outBuffer output = {buffOut, buffOutSize, 0}; ZSTD_outBuffer output = {buffOut, buffOutSize, 0};
size_t const ret = ZSTD_decompressStream(dctx, &output, &input); // BAD // $ Alert size_t const ret = ZSTD_decompressStream(dctx, &output, &input); // BAD
CHECK_ZSTD(ret); CHECK_ZSTD(ret);
} }
} }

View File

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

View File

@@ -8,14 +8,14 @@ void workFunction_0(char *s) {
char *buf; char *buf;
buf = (char *) malloc(intSize); buf = (char *) malloc(intSize);
free(buf); // GOOD free(buf); // GOOD
if(buf) free(buf); // BAD // $ Alert if(buf) free(buf); // BAD
} }
void workFunction_1(char *s) { void workFunction_1(char *s) {
int intSize = 10; int intSize = 10;
char *buf; char *buf;
buf = (char *) malloc(intSize); buf = (char *) malloc(intSize);
free(buf); // GOOD free(buf); // GOOD
free(buf); // BAD // $ Alert free(buf); // BAD
} }
void workFunction_2(char *s) { void workFunction_2(char *s) {
int intSize = 10; int intSize = 10;
@@ -54,7 +54,7 @@ void workFunction_5(char *s, int intFlag) {
if(intFlag) { if(intFlag) {
free(buf); // GOOD free(buf); // GOOD
} }
free(buf); // BAD // $ Alert free(buf); // BAD
} }
void workFunction_6(char *s, int intFlag) { void workFunction_6(char *s, int intFlag) {
int intSize = 10; int intSize = 10;
@@ -75,7 +75,7 @@ void workFunction_7(char *s) {
char *buf1; char *buf1;
buf = (char *) malloc(intSize); buf = (char *) malloc(intSize);
buf1 = (char *) realloc(buf,intSize*4); buf1 = (char *) realloc(buf,intSize*4);
free(buf); // BAD // $ Alert free(buf); // BAD
} }
void workFunction_8(char *s) { void workFunction_8(char *s) {
int intSize = 10; int intSize = 10;

View File

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

View File

@@ -68,7 +68,7 @@ void funcWork1b() {
} }
delete [] bufMyData; delete [] bufMyData;
} // $ Alert }
} }
void funcWork1() { void funcWork1() {
@@ -97,7 +97,7 @@ void funcWork1() {
} }
delete [] bufMyData; delete [] bufMyData;
} // $ Alert }
} }
void funcWork2() { void funcWork2() {
@@ -125,7 +125,7 @@ void funcWork2() {
} }
delete [] bufMyData; delete [] bufMyData;
} // $ Alert }
} }
void funcWork3() { void funcWork3() {
int a; int a;
@@ -148,7 +148,7 @@ void funcWork3() {
} }
delete [] bufMyData; delete [] bufMyData;
} // $ Alert }
} }
@@ -180,7 +180,7 @@ void funcWork4b() {
catch (...) catch (...)
{ {
delete valData; // BAD delete valData; // BAD
} // $ Alert }
} }
void funcWork5() { void funcWork5() {
int a; int a;
@@ -218,7 +218,7 @@ void funcWork5b() {
catch (...) catch (...)
{ {
delete valData; // BAD delete valData; // BAD
} // $ Alert }
} }
void funcWork6() { void funcWork6() {
int a; int a;

View File

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

View File

@@ -25,7 +25,7 @@ void testFunction(char c1,int i1)
case 9: case 9:
break; break;
dafault: dafault:
} // $ Alert }
switch(c1){ // BAD switch(c1){ // BAD
c1=c1*2; c1=c1*2;
@@ -35,7 +35,7 @@ void testFunction(char c1,int i1)
break; break;
case 9: case 9:
break; break;
} // $ Alert }
if((c1<6)&&(c1>0)) if((c1<6)&&(c1>0))
switch(c1){ // BAD switch(c1){ // BAD
@@ -47,7 +47,7 @@ void testFunction(char c1,int i1)
break; break;
case 1: case 1:
break; break;
} // $ Alert }
if((c1<6)&&(c1>0)) if((c1<6)&&(c1>0))
switch(c1){ // BAD switch(c1){ // BAD
@@ -55,6 +55,6 @@ void testFunction(char c1,int i1)
break; break;
case 1: case 1:
break; break;
} // $ Alert }
} }

View File

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

View File

@@ -42,7 +42,7 @@ int gootTest2(SSL *ssl)
int badTest1(SSL *ssl) int badTest1(SSL *ssl)
{ {
int ret; int ret;
switch ((ret = SSL_shutdown(ssl))) { // $ Alert switch ((ret = SSL_shutdown(ssl))) {
case 1: case 1:
break; break;
case 0: case 0:
@@ -58,7 +58,7 @@ int badTest1(SSL *ssl)
int badTest2(SSL *ssl) int badTest2(SSL *ssl)
{ {
int ret; int ret;
ret = SSL_shutdown(ssl); // $ Alert ret = SSL_shutdown(ssl);
switch (ret) { switch (ret) {
case 1: case 1:
break; break;

View File

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

View File

@@ -17,7 +17,7 @@ void test2()
FILE *f; FILE *f;
f = fopen("myFile.txt", "wt"); f = fopen("myFile.txt", "wt");
fclose(f); // BAD // $ Alert fclose(f); // BAD
fclose(f); fclose(f);
} }
@@ -28,14 +28,14 @@ void test3()
f = fopen("myFile.txt", "wt"); f = fopen("myFile.txt", "wt");
g = f; g = f;
fclose(f); // BAD // $ Alert fclose(f); // BAD
fclose(g); fclose(g);
} }
int fGtest4_1() int fGtest4_1()
{ {
fe = fopen("myFile.txt", "wt"); fe = fopen("myFile.txt", "wt");
fclose(fe); // BAD // $ Alert fclose(fe); // BAD
return -1; return -1;
} }

View File

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

View File

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

View File

@@ -5,25 +5,25 @@ void workFunction_0(char *s) {
int intSize; int intSize;
char buf[80]; char buf[80];
if(intSize>0 && intSize<80 && memset(buf,0,intSize)) return; // GOOD if(intSize>0 && intSize<80 && memset(buf,0,intSize)) return; // GOOD
if(intSize>0 & intSize<80 & memset(buf,0,intSize)) return; // BAD // $ Alert[cpp/errors-when-using-bit-operations] if(intSize>0 & intSize<80 & memset(buf,0,intSize)) return; // BAD
if(intSize>0 && tmpFunction()) return; if(intSize>0 && tmpFunction()) return;
if(intSize<0 & tmpFunction()) return; // BAD // $ Alert[cpp/errors-when-using-bit-operations] if(intSize<0 & tmpFunction()) return; // BAD
} }
void workFunction_1(char *s) { void workFunction_1(char *s) {
int intA,intB; int intA,intB;
if(intA + intB) return; // BAD // $ Alert[cpp/errors-after-refactoring] if(intA + intB) return; // BAD
if(intA + intB>4) return; // GOOD if(intA + intB>4) return; // GOOD
if(intA>0 && (intA + intB)) return; // BAD // $ Alert[cpp/errors-after-refactoring] if(intA>0 && (intA + intB)) return; // BAD
while(intA>0) while(intA>0)
{ {
if(intB - intA<10) break; if(intB - intA<10) break;
intA--; intA--;
}while(intA>0); // BAD // $ Alert[cpp/errors-after-refactoring] }while(intA>0); // BAD
for(intA=100; intA>0; intA--) for(intA=100; intA>0; intA--)
{ {
if(intB - intA<10) break; if(intB - intA<10) break;
}while(intA>0); // BAD // $ Alert[cpp/errors-after-refactoring] }while(intA>0); // BAD
while(intA>0) while(intA>0)
{ {
if(intB - intA<10) break; if(intB - intA<10) break;

View File

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

View File

@@ -32,13 +32,13 @@ void funcTest2()
void funcTest3() void funcTest3()
{ {
std::runtime_error("msg error"); // BAD // $ Alert std::runtime_error("msg error"); // BAD
throw std::runtime_error("msg error"); // GOOD throw std::runtime_error("msg error"); // GOOD
} }
void TestFunc() void TestFunc()
{ {
funcTest1(); // $ Alert funcTest1();
DllMain(); // $ Alert DllMain();
funcTest2(); funcTest2();
} }

View File

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

View File

@@ -49,9 +49,9 @@ int functionWork1b(int retIndex) {
char a[10]; char a[10];
int b; int b;
int *p = &b; int *p = &b;
scanf("%i", &i); // BAD // $ Alert scanf("%i", &i); // BAD
scanf("%s", a); // BAD // $ Alert scanf("%s", a); // BAD
scanf("%i", p); // BAD // $ Alert scanf("%i", p); // BAD
if(retIndex == 0) if(retIndex == 0)
return (int)*a; return (int)*a;
if(retIndex == 1) if(retIndex == 1)
@@ -102,9 +102,9 @@ int functionWork2b() {
char a[10]; char a[10];
int b; int b;
int *p = &b; int *p = &b;
scanf("%i", &i); // BAD // $ Alert scanf("%i", &i); // BAD
scanf("%s", a); // BAD // $ Alert scanf("%s", a); // BAD
scanf("%i", p); // BAD // $ Alert scanf("%i", p); // BAD
globalVal = i; globalVal = i;
globalVala = a; globalVala = a;
globalValp = p; globalValp = p;
@@ -112,12 +112,12 @@ int functionWork2b() {
} }
int functionWork2b_() { int functionWork2b_() {
char a[10]; char a[10];
scanf("%s", a); // BAD // $ Alert scanf("%s", a); // BAD
globalVala2 = a[0]; globalVala2 = a[0];
return 0; return 0;
} }
int functionWork3b(int * i) { int functionWork3b(int * i) {
scanf("%i", i); // BAD // $ Alert scanf("%i", i); // BAD
return 0; return 0;
} }
int functionWork3() { int functionWork3() {

View File

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

View File

@@ -10,10 +10,10 @@ char tmpFunction2(char * buf)
} }
void workFunction_0(char *s, char * buf) { void workFunction_0(char *s, char * buf) {
int intA; int intA;
intA = tmpFunction1(buf) + tmpFunction2(buf); // BAD // $ Alert intA = tmpFunction1(buf) + tmpFunction2(buf); // BAD
intA = tmpFunction1(buf); //GOOD intA = tmpFunction1(buf); //GOOD
intA += tmpFunction2(buf); // GOOD intA += tmpFunction2(buf); // GOOD
buf[intA] = intA++; // BAD // $ Alert buf[intA] = intA++; // BAD
intA++; intA++;
buf[intA] = intA; // GOOD buf[intA] = intA; // GOOD
} }

View File

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

View File

@@ -1,14 +1,14 @@
void testFunction(int i1, int i2, int i3, bool b1, bool b2, bool b3, char c1) void testFunction(int i1, int i2, int i3, bool b1, bool b2, bool b3, char c1)
{ {
if(b1||b2&&b3) //BAD // $ Alert if(b1||b2&&b3) //BAD
return; return;
if((b1||b2)&&b3) //GOOD if((b1||b2)&&b3) //GOOD
return; return;
if(b1||(b2&&b3)) //GOOD if(b1||(b2&&b3)) //GOOD
return; return;
if(b1||b2&i1) //BAD // $ Alert if(b1||b2&i1) //BAD
return; return;
if((b1||b2)&i1) //GOOD if((b1||b2)&i1) //GOOD
return; return;
@@ -16,26 +16,26 @@ void testFunction(int i1, int i2, int i3, bool b1, bool b2, bool b3, char c1)
return; return;
if(b1&&b2&0) //GOOD if(b1&&b2&0) //GOOD
return; return;
if(b1||b2|i1) //BAD // $ Alert if(b1||b2|i1) //BAD
return; return;
if((b1||b2)|i1) //GOOD if((b1||b2)|i1) //GOOD
return; return;
if(i1|i2&c1) //BAD // $ Alert if(i1|i2&c1) //BAD
return; return;
if((i1|i2)&i3) //GOOD if((i1|i2)&i3) //GOOD
return; return;
if(i1^i2&c1) //BAD // $ Alert if(i1^i2&c1) //BAD
return; return;
if((i1^i2)&i3) //GOOD if((i1^i2)&i3) //GOOD
return; return;
if(i1|i2^c1) //BAD // $ Alert if(i1|i2^c1) //BAD
return; return;
if((i1|i2)^i3) //GOOD if((i1|i2)^i3) //GOOD
return; return;
if(b1|b2^b3) //BAD // $ Alert if(b1|b2^b3) //BAD
return; return;
if((b1|b2)^b3) //GOOD if((b1|b2)^b3) //GOOD
return; return;

View File

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

View File

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

View File

@@ -13,15 +13,15 @@ void strlen_test1(){
struct buffers buffAll; struct buffers buffAll;
struct buffers * buffAll1; struct buffers * buffAll1;
buff1[strlen(buff1)]=0; // BAD // $ Alert[cpp/access-memory-location-after-end-buffer-strlen] buff1[strlen(buff1)]=0; // BAD
buffAll.array[strlen(buffAll.array)]=0; // BAD // $ Alert[cpp/access-memory-location-after-end-buffer-strlen] buffAll.array[strlen(buffAll.array)]=0; // BAD
buffAll.pointer[strlen(buffAll.pointer)]=0; // BAD // $ Alert[cpp/access-memory-location-after-end-buffer-strlen] buffAll.pointer[strlen(buffAll.pointer)]=0; // BAD
buffAll1->array[strlen(buffAll1->array)]=0; // BAD // $ Alert[cpp/access-memory-location-after-end-buffer-strlen] buffAll1->array[strlen(buffAll1->array)]=0; // BAD
buffAll1->pointer[strlen(buffAll1->pointer)]=0; // BAD // $ Alert[cpp/access-memory-location-after-end-buffer-strlen] buffAll1->pointer[strlen(buffAll1->pointer)]=0; // BAD
globalBuff1.array[strlen(globalBuff1.array)]=0; // BAD // $ Alert[cpp/access-memory-location-after-end-buffer-strlen] globalBuff1.array[strlen(globalBuff1.array)]=0; // BAD
globalBuff1.pointer[strlen(globalBuff1.pointer)]=0; // BAD // $ Alert[cpp/access-memory-location-after-end-buffer-strlen] globalBuff1.pointer[strlen(globalBuff1.pointer)]=0; // BAD
globalBuff2->array[strlen(globalBuff2->array)]=0; // BAD // $ Alert[cpp/access-memory-location-after-end-buffer-strlen] globalBuff2->array[strlen(globalBuff2->array)]=0; // BAD
globalBuff2->pointer[strlen(globalBuff2->pointer)]=0; // BAD // $ Alert[cpp/access-memory-location-after-end-buffer-strlen] globalBuff2->pointer[strlen(globalBuff2->pointer)]=0; // BAD
} }
void strlen_test2(){ void strlen_test2(){

View File

@@ -7,13 +7,13 @@ void testFunction()
int i1,i2,i3; int i1,i2,i3;
bool b1,b2,b3; bool b1,b2,b3;
char c1,c2,c3; char c1,c2,c3;
b1 = -b2; //BAD // $ Alert[cpp/operator-precedence-logic-error-when-use-bool-type] b1 = -b2; //BAD
b1 = !b2; //GOOD b1 = !b2; //GOOD
b1++; //BAD // $ Alert[cpp/operator-precedence-logic-error-when-use-bool-type] b1++; //BAD
++b1; //BAD // $ Alert[cpp/operator-precedence-logic-error-when-use-bool-type] ++b1; //BAD
if(i1=tmpFunc()!=i2) //BAD // $ Alert[cpp/operator-precedence-logic-error-when-use-bool-type] if(i1=tmpFunc()!=i2) //BAD
return; return;
if(i1=tmpFunc()!=11) //BAD // $ Alert[cpp/operator-precedence-logic-error-when-use-bool-type] if(i1=tmpFunc()!=11) //BAD
return; return;
if((i1=tmpFunc())!=i2) //GOOD if((i1=tmpFunc())!=i2) //GOOD
return; return;

View File

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

View File

@@ -24,7 +24,7 @@ bool badTest1(SSL *ssl,char *text)
char buf[256]; char buf[256];
if( peer = SSL_get_peer_certificate(ssl)) if( peer = SSL_get_peer_certificate(ssl))
{ {
X509_NAME_oneline(X509_get_subject_name(peer),buf,1024); // BAD // $ Alert X509_NAME_oneline(X509_get_subject_name(peer),buf,1024); // BAD
if((char*)strcasestr(buf,text)) return true; if((char*)strcasestr(buf,text)) return true;
} }
return false; return false;

View File

@@ -16,7 +16,7 @@ int main(int argc, char **argv)
// BAD, do not use scanf without specifying a length first // BAD, do not use scanf without specifying a length first
char buf1[10]; char buf1[10];
scanf("%s", buf1); // $ Alert scanf("%s", buf1);
// GOOD, length is specified. The length should be one less than the size of the destination buffer, since the last character is the NULL terminator. // GOOD, length is specified. The length should be one less than the size of the destination buffer, since the last character is the NULL terminator.
char buf2[20]; char buf2[20];
@@ -25,7 +25,7 @@ int main(int argc, char **argv)
// BAD, do not use scanf without specifying a length first // BAD, do not use scanf without specifying a length first
char file[10]; char file[10];
fscanf(file, "%s", buf2); // $ Alert fscanf(file, "%s", buf2);
// GOOD, with 'sscanf' the input can be checked first and enough room allocated [FALSE POSITIVE] // GOOD, with 'sscanf' the input can be checked first and enough room allocated [FALSE POSITIVE]
if (argc >= 1) if (argc >= 1)
@@ -33,7 +33,7 @@ int main(int argc, char **argv)
char *src = argv[0]; char *src = argv[0];
char *dest = (char *)malloc(strlen(src) + 1); char *dest = (char *)malloc(strlen(src) + 1);
sscanf(src, "%s", dest); // $ Alert sscanf(src, "%s", dest);
} }
return 0; return 0;

View File

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

View File

@@ -1 +1 @@
query: semmle/code/cpp/PrintAST.ql semmle/code/cpp/PrintAST.ql

View File

@@ -1 +1 @@
query: semmle/code/cpp/ASTConsistency.ql semmle/code/cpp/ASTConsistency.ql

View File

@@ -1 +1 @@
query: Telemetry/CompilerErrors.ql Telemetry/CompilerErrors.ql

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