mirror of
https://github.com/github/codeql.git
synced 2026-06-03 04:40:14 +02:00
Compare commits
1 Commits
mbg/bazel/
...
alexet/rub
| Author | SHA1 | Date | |
|---|---|---|---|
|
|
31a2e37418 |
6
.github/workflows/build-ripunzip.yml
vendored
6
.github/workflows/build-ripunzip.yml
vendored
@@ -6,18 +6,18 @@ on:
|
||||
ripunzip-version:
|
||||
description: "what reference to checktout from google/runzip"
|
||||
required: false
|
||||
default: v2.0.2
|
||||
default: v1.2.1
|
||||
openssl-version:
|
||||
description: "what reference to checkout from openssl/openssl for Linux"
|
||||
required: false
|
||||
default: openssl-3.5.0
|
||||
default: openssl-3.3.0
|
||||
|
||||
jobs:
|
||||
build:
|
||||
strategy:
|
||||
fail-fast: false
|
||||
matrix:
|
||||
os: [ubuntu-22.04, macos-13, windows-2022]
|
||||
os: [ubuntu-22.04, macos-13, windows-2019]
|
||||
runs-on: ${{ matrix.os }}
|
||||
steps:
|
||||
- uses: actions/checkout@v4
|
||||
|
||||
@@ -1,11 +1,10 @@
|
||||
name: Python tooling
|
||||
name: Codegen
|
||||
|
||||
on:
|
||||
pull_request:
|
||||
paths:
|
||||
- "misc/bazel/**"
|
||||
- "misc/codegen/**"
|
||||
- "misc/scripts/models-as-data/bulk_generate_mad.py"
|
||||
- "*.bazel*"
|
||||
- .github/workflows/codegen.yml
|
||||
- .pre-commit-config.yaml
|
||||
@@ -18,17 +17,17 @@ permissions:
|
||||
contents: read
|
||||
|
||||
jobs:
|
||||
check-python-tooling:
|
||||
codegen:
|
||||
runs-on: ubuntu-latest
|
||||
steps:
|
||||
- uses: actions/checkout@v4
|
||||
- uses: actions/setup-python@v5
|
||||
- uses: actions/setup-python@v4
|
||||
with:
|
||||
python-version: '3.12'
|
||||
python-version-file: 'misc/codegen/.python-version'
|
||||
- uses: pre-commit/action@646c83fcd040023954eafda54b4db0192ce70507
|
||||
name: Check that python code is properly formatted
|
||||
with:
|
||||
extra_args: black --all-files
|
||||
extra_args: autopep8 --all-files
|
||||
- name: Run codegen tests
|
||||
shell: bash
|
||||
run: |
|
||||
4
.github/workflows/csharp-qltest.yml
vendored
4
.github/workflows/csharp-qltest.yml
vendored
@@ -36,7 +36,7 @@ jobs:
|
||||
unit-tests:
|
||||
strategy:
|
||||
matrix:
|
||||
os: [ubuntu-latest, windows-latest]
|
||||
os: [ubuntu-latest, windows-2019]
|
||||
runs-on: ${{ matrix.os }}
|
||||
steps:
|
||||
- uses: actions/checkout@v4
|
||||
@@ -66,6 +66,6 @@ jobs:
|
||||
# Update existing stubs in the repo with the freshly generated ones
|
||||
mv "$STUBS_PATH/output/stubs/_frameworks" ql/test/resources/stubs/
|
||||
git status
|
||||
codeql test run --threads=0 --search-path "${{ github.workspace }}" --check-databases --check-diff-informed --check-undefined-labels --check-repeated-labels --check-redefined-labels --consistency-queries ql/consistency-queries -- ql/test/library-tests/dataflow/flowsources/aspremote
|
||||
codeql test run --threads=0 --search-path "${{ github.workspace }}" --check-databases --check-undefined-labels --check-repeated-labels --check-redefined-labels --consistency-queries ql/consistency-queries -- ql/test/library-tests/dataflow/flowsources/aspremote
|
||||
env:
|
||||
GITHUB_TOKEN: ${{ github.token }}
|
||||
|
||||
3
.github/workflows/go-tests-other-os.yml
vendored
3
.github/workflows/go-tests-other-os.yml
vendored
@@ -26,8 +26,9 @@ jobs:
|
||||
uses: ./go/actions/test
|
||||
|
||||
test-win:
|
||||
if: github.repository_owner == 'github'
|
||||
name: Test Windows
|
||||
runs-on: windows-latest
|
||||
runs-on: windows-latest-xl
|
||||
steps:
|
||||
- name: Check out code
|
||||
uses: actions/checkout@v4
|
||||
|
||||
2
.github/workflows/ruby-qltest-rtjo.yml
vendored
2
.github/workflows/ruby-qltest-rtjo.yml
vendored
@@ -35,6 +35,6 @@ jobs:
|
||||
key: ruby-qltest
|
||||
- name: Run QL tests
|
||||
run: |
|
||||
codeql test run --dynamic-join-order-mode=all --threads=0 --ram 50000 --search-path "${{ github.workspace }}" --check-databases --check-diff-informed --check-undefined-labels --check-unused-labels --check-repeated-labels --check-redefined-labels --check-use-before-definition --consistency-queries ql/consistency-queries ql/test --compilation-cache "${{ steps.query-cache.outputs.cache-dir }}"
|
||||
codeql test run --dynamic-join-order-mode=all --threads=0 --ram 50000 --search-path "${{ github.workspace }}" --check-databases --check-undefined-labels --check-unused-labels --check-repeated-labels --check-redefined-labels --check-use-before-definition --consistency-queries ql/consistency-queries ql/test --compilation-cache "${{ steps.query-cache.outputs.cache-dir }}"
|
||||
env:
|
||||
GITHUB_TOKEN: ${{ github.token }}
|
||||
|
||||
2
.github/workflows/ruby-qltest.yml
vendored
2
.github/workflows/ruby-qltest.yml
vendored
@@ -68,6 +68,6 @@ jobs:
|
||||
key: ruby-qltest
|
||||
- name: Run QL tests
|
||||
run: |
|
||||
codeql test run --threads=0 --ram 50000 --search-path "${{ github.workspace }}" --check-databases --check-diff-informed --check-undefined-labels --check-unused-labels --check-repeated-labels --check-redefined-labels --check-use-before-definition --consistency-queries ql/consistency-queries ql/test --compilation-cache "${{ steps.query-cache.outputs.cache-dir }}"
|
||||
codeql test run --threads=0 --ram 50000 --search-path "${{ github.workspace }}" --check-databases --check-undefined-labels --check-unused-labels --check-repeated-labels --check-redefined-labels --check-use-before-definition --consistency-queries ql/consistency-queries ql/test --compilation-cache "${{ steps.query-cache.outputs.cache-dir }}"
|
||||
env:
|
||||
GITHUB_TOKEN: ${{ github.token }}
|
||||
|
||||
2
.github/workflows/swift.yml
vendored
2
.github/workflows/swift.yml
vendored
@@ -32,7 +32,7 @@ jobs:
|
||||
if: github.repository_owner == 'github'
|
||||
strategy:
|
||||
matrix:
|
||||
runner: [ubuntu-latest, macos-15-xlarge]
|
||||
runner: [ubuntu-latest, macos-13-xlarge]
|
||||
fail-fast: false
|
||||
runs-on: ${{ matrix.runner }}
|
||||
steps:
|
||||
|
||||
2
.github/workflows/validate-change-notes.yml
vendored
2
.github/workflows/validate-change-notes.yml
vendored
@@ -31,4 +31,4 @@ jobs:
|
||||
- name: Fail if there are any errors with existing change notes
|
||||
|
||||
run: |
|
||||
codeql pack release --groups actions,cpp,csharp,go,java,javascript,python,ruby,shared,swift -examples,-test,-experimental
|
||||
codeql pack release --groups cpp,csharp,java,javascript,python,ruby,-examples,-test,-experimental
|
||||
|
||||
5
.gitignore
vendored
5
.gitignore
vendored
@@ -62,7 +62,6 @@ node_modules/
|
||||
|
||||
# Temporary folders for working with generated models
|
||||
.model-temp
|
||||
/mad-generation-build
|
||||
|
||||
# bazel-built in-tree extractor packs
|
||||
/*/extractor-pack
|
||||
@@ -72,7 +71,3 @@ node_modules/
|
||||
|
||||
# cargo build directory
|
||||
/target
|
||||
|
||||
# some upgrade/downgrade checks create these files
|
||||
**/upgrades/*/*.dbscheme.stats
|
||||
**/downgrades/*/*.dbscheme.stats
|
||||
|
||||
@@ -1,7 +1,5 @@
|
||||
# See https://pre-commit.com for more information
|
||||
# See https://pre-commit.com/hooks.html for more hooks
|
||||
default_language_version:
|
||||
python: python3.12
|
||||
repos:
|
||||
- repo: https://github.com/pre-commit/pre-commit-hooks
|
||||
rev: v3.2.0
|
||||
@@ -16,11 +14,11 @@ repos:
|
||||
hooks:
|
||||
- id: clang-format
|
||||
|
||||
- repo: https://github.com/psf/black
|
||||
rev: 25.1.0
|
||||
- repo: https://github.com/pre-commit/mirrors-autopep8
|
||||
rev: v2.0.4
|
||||
hooks:
|
||||
- id: black
|
||||
files: ^(misc/codegen/.*|misc/scripts/models-as-data/bulk_generate_mad)\.py$
|
||||
- id: autopep8
|
||||
files: ^misc/codegen/.*\.py
|
||||
|
||||
- repo: local
|
||||
hooks:
|
||||
|
||||
@@ -16,7 +16,7 @@
|
||||
/java/ql/test-kotlin2/ @github/codeql-kotlin
|
||||
|
||||
# Experimental CodeQL cryptography
|
||||
**/experimental/**/quantum/ @github/ps-codeql
|
||||
**/experimental/quantum/ @github/ps-codeql
|
||||
/shared/quantum/ @github/ps-codeql
|
||||
|
||||
# CodeQL tools and associated docs
|
||||
|
||||
47
Cargo.lock
generated
47
Cargo.lock
generated
@@ -242,8 +242,6 @@ version = "1.2.7"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "a012a0df96dd6d06ba9a1b29d6402d1a5d77c6befd2566afdc26e10603dc93d7"
|
||||
dependencies = [
|
||||
"jobserver",
|
||||
"libc",
|
||||
"shlex",
|
||||
]
|
||||
|
||||
@@ -392,7 +390,6 @@ dependencies = [
|
||||
"tree-sitter",
|
||||
"tree-sitter-json",
|
||||
"tree-sitter-ql",
|
||||
"zstd",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
@@ -426,7 +423,6 @@ dependencies = [
|
||||
"figment",
|
||||
"glob",
|
||||
"itertools 0.14.0",
|
||||
"mustache",
|
||||
"num-traits",
|
||||
"ra_ap_base_db",
|
||||
"ra_ap_cfg",
|
||||
@@ -987,15 +983,6 @@ version = "1.0.15"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "4a5f13b858c8d314ee3e8f639011f7ccefe71f97f96e50151fb991f267928e2c"
|
||||
|
||||
[[package]]
|
||||
name = "jobserver"
|
||||
version = "0.1.32"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "48d1dbcbbeb6a7fec7e059840aa538bd62aaccf972c7346c4d9d2059312853d0"
|
||||
dependencies = [
|
||||
"libc",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "jod-thread"
|
||||
version = "0.1.2"
|
||||
@@ -1347,12 +1334,6 @@ version = "0.2.16"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "3b3cff922bd51709b605d9ead9aa71031d81447142d828eb4a6eba76fe619f9b"
|
||||
|
||||
[[package]]
|
||||
name = "pkg-config"
|
||||
version = "0.3.32"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "7edddbd0b52d732b21ad9a5fab5c704c14cd949e5e9a1ec5929a24fded1b904c"
|
||||
|
||||
[[package]]
|
||||
name = "portable-atomic"
|
||||
version = "1.11.0"
|
||||
@@ -3046,31 +3027,3 @@ dependencies = [
|
||||
"quote",
|
||||
"syn",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "zstd"
|
||||
version = "0.13.3"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "e91ee311a569c327171651566e07972200e76fcfe2242a4fa446149a3881c08a"
|
||||
dependencies = [
|
||||
"zstd-safe",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "zstd-safe"
|
||||
version = "7.2.4"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "8f49c4d5f0abb602a93fb8736af2a4f4dd9512e36f7f570d66e65ff867ed3b9d"
|
||||
dependencies = [
|
||||
"zstd-sys",
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "zstd-sys"
|
||||
version = "2.0.15+zstd.1.5.7"
|
||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||
checksum = "eb81183ddd97d0c74cedf1d50d85c8d08c1b8b68ee863bdee9e706eedba1a237"
|
||||
dependencies = [
|
||||
"cc",
|
||||
"pkg-config",
|
||||
]
|
||||
|
||||
@@ -10,7 +10,6 @@ members = [
|
||||
"rust/ast-generator",
|
||||
"rust/autobuild",
|
||||
]
|
||||
exclude = ["mad-generation-build"]
|
||||
|
||||
[patch.crates-io]
|
||||
# patch for build script bug preventing bazel build
|
||||
|
||||
23
MODULE.bazel
23
MODULE.bazel
@@ -15,7 +15,7 @@ local_path_override(
|
||||
# see https://registry.bazel.build/ for a list of available packages
|
||||
|
||||
bazel_dep(name = "platforms", version = "0.0.11")
|
||||
bazel_dep(name = "rules_go", version = "0.55.1")
|
||||
bazel_dep(name = "rules_go", version = "0.50.1")
|
||||
bazel_dep(name = "rules_pkg", version = "1.0.1")
|
||||
bazel_dep(name = "rules_nodejs", version = "6.2.0-codeql.1")
|
||||
bazel_dep(name = "rules_python", version = "0.40.0")
|
||||
@@ -124,7 +124,6 @@ use_repo(
|
||||
"vendor_ts__tree-sitter-ruby-0.23.1",
|
||||
"vendor_ts__triomphe-0.1.14",
|
||||
"vendor_ts__ungrammar-1.16.1",
|
||||
"vendor_ts__zstd-0.13.3",
|
||||
)
|
||||
|
||||
http_archive = use_repo_rule("@bazel_tools//tools/build_defs/repo:http.bzl", "http_archive")
|
||||
@@ -239,24 +238,24 @@ go_deps = use_extension("@gazelle//:extensions.bzl", "go_deps")
|
||||
go_deps.from_file(go_mod = "//go/extractor:go.mod")
|
||||
use_repo(go_deps, "org_golang_x_mod", "org_golang_x_tools")
|
||||
|
||||
lfs_archive = use_repo_rule("//misc/bazel:lfs.bzl", "lfs_archive")
|
||||
lfs_files = use_repo_rule("//misc/bazel:lfs.bzl", "lfs_files")
|
||||
|
||||
lfs_archive(
|
||||
lfs_files(
|
||||
name = "ripunzip-linux",
|
||||
src = "//misc/ripunzip:ripunzip-Linux.zip",
|
||||
build_file = "//misc/ripunzip:BUILD.ripunzip.bazel",
|
||||
srcs = ["//misc/ripunzip:ripunzip-linux"],
|
||||
executable = True,
|
||||
)
|
||||
|
||||
lfs_archive(
|
||||
lfs_files(
|
||||
name = "ripunzip-windows",
|
||||
src = "//misc/ripunzip:ripunzip-Windows.zip",
|
||||
build_file = "//misc/ripunzip:BUILD.ripunzip.bazel",
|
||||
srcs = ["//misc/ripunzip:ripunzip-windows.exe"],
|
||||
executable = True,
|
||||
)
|
||||
|
||||
lfs_archive(
|
||||
lfs_files(
|
||||
name = "ripunzip-macos",
|
||||
src = "//misc/ripunzip:ripunzip-macOS.zip",
|
||||
build_file = "//misc/ripunzip:BUILD.ripunzip.bazel",
|
||||
srcs = ["//misc/ripunzip:ripunzip-macos"],
|
||||
executable = True,
|
||||
)
|
||||
|
||||
register_toolchains(
|
||||
|
||||
@@ -1 +0,0 @@
|
||||
|
||||
@@ -2,7 +2,7 @@ import runs_on
|
||||
import pytest
|
||||
from query_suites import *
|
||||
|
||||
well_known_query_suites = ['actions-code-quality.qls', 'actions-code-quality-extended.qls', 'actions-security-and-quality.qls', 'actions-security-extended.qls', 'actions-code-scanning.qls']
|
||||
well_known_query_suites = ['actions-code-quality.qls', 'actions-security-and-quality.qls', 'actions-security-extended.qls', 'actions-code-scanning.qls']
|
||||
|
||||
@runs_on.posix
|
||||
@pytest.mark.parametrize("query_suite", well_known_query_suites)
|
||||
|
||||
@@ -1,11 +1,3 @@
|
||||
## 0.4.11
|
||||
|
||||
No user-facing changes.
|
||||
|
||||
## 0.4.10
|
||||
|
||||
No user-facing changes.
|
||||
|
||||
## 0.4.9
|
||||
|
||||
No user-facing changes.
|
||||
|
||||
@@ -1,6 +0,0 @@
|
||||
---
|
||||
category: minorAnalysis
|
||||
---
|
||||
* Fixed performance issues in the parsing of Bash scripts in workflow files,
|
||||
which led to out-of-disk errors when analysing certain workflow files with
|
||||
complex interpolations of shell commands or quoted strings.
|
||||
@@ -1,3 +0,0 @@
|
||||
## 0.4.10
|
||||
|
||||
No user-facing changes.
|
||||
@@ -1,3 +0,0 @@
|
||||
## 0.4.11
|
||||
|
||||
No user-facing changes.
|
||||
@@ -1,2 +1,2 @@
|
||||
---
|
||||
lastReleaseVersion: 0.4.11
|
||||
lastReleaseVersion: 0.4.9
|
||||
|
||||
@@ -50,8 +50,8 @@ class Expression extends AstNode instanceof ExpressionImpl {
|
||||
string getNormalizedExpression() { result = normalizeExpr(expression) }
|
||||
}
|
||||
|
||||
/** An `env` in workflow, job or step. */
|
||||
class Env extends AstNode instanceof EnvImpl {
|
||||
/** A common class for `env` in workflow, job or step. */
|
||||
abstract class Env extends AstNode instanceof EnvImpl {
|
||||
/** Gets an environment variable value given its name. */
|
||||
ScalarValueImpl getEnvVarValue(string name) { result = super.getEnvVarValue(name) }
|
||||
|
||||
|
||||
@@ -8,64 +8,35 @@ class BashShellScript extends ShellScript {
|
||||
)
|
||||
}
|
||||
|
||||
/**
|
||||
* Gets the line at 0-based index `lineIndex` within this shell script,
|
||||
* assuming newlines as separators.
|
||||
*/
|
||||
private string lineProducer(int lineIndex) {
|
||||
result = this.getRawScript().regexpReplaceAll("\\\\\\s*\n", "").splitAt("\n", lineIndex)
|
||||
private string lineProducer(int i) {
|
||||
result = this.getRawScript().regexpReplaceAll("\\\\\\s*\n", "").splitAt("\n", i)
|
||||
}
|
||||
|
||||
private predicate cmdSubstitutionReplacement(string command, string id, int lineIndex) {
|
||||
this.commandInSubstitution(lineIndex, command, id)
|
||||
or
|
||||
this.commandInBackticks(lineIndex, command, id)
|
||||
}
|
||||
|
||||
/**
|
||||
* Holds if there is a command substitution `$(command)` in
|
||||
* the line at `lineIndex` in the shell script,
|
||||
* and `id` is a unique identifier for this command.
|
||||
*/
|
||||
private predicate commandInSubstitution(int lineIndex, string command, string id) {
|
||||
exists(int occurrenceIndex, int occurrenceOffset |
|
||||
command =
|
||||
// Look for the command inside a $(...) command substitution
|
||||
this.lineProducer(lineIndex)
|
||||
.regexpFind("\\$\\((?:[^()]+|\\((?:[^()]+|\\([^()]*\\))*\\))*\\)", occurrenceIndex,
|
||||
occurrenceOffset)
|
||||
// trim starting $( - TODO do this in first regex
|
||||
.regexpReplaceAll("^\\$\\(", "")
|
||||
// trim ending ) - TODO do this in first regex
|
||||
.regexpReplaceAll("\\)$", "") and
|
||||
id = "cmdsubs:" + lineIndex + ":" + occurrenceIndex + ":" + occurrenceOffset
|
||||
private predicate cmdSubstitutionReplacement(string cmdSubs, string id, int k) {
|
||||
exists(string line | line = this.lineProducer(k) |
|
||||
exists(int i, int j |
|
||||
cmdSubs =
|
||||
// $() cmd substitution
|
||||
line.regexpFind("\\$\\((?:[^()]+|\\((?:[^()]+|\\([^()]*\\))*\\))*\\)", i, j)
|
||||
.regexpReplaceAll("^\\$\\(", "")
|
||||
.regexpReplaceAll("\\)$", "") and
|
||||
id = "cmdsubs:" + k + ":" + i + ":" + j
|
||||
)
|
||||
or
|
||||
exists(int i, int j |
|
||||
// `...` cmd substitution
|
||||
cmdSubs =
|
||||
line.regexpFind("\\`[^\\`]+\\`", i, j)
|
||||
.regexpReplaceAll("^\\`", "")
|
||||
.regexpReplaceAll("\\`$", "") and
|
||||
id = "cmd:" + k + ":" + i + ":" + j
|
||||
)
|
||||
)
|
||||
}
|
||||
|
||||
/**
|
||||
* Holds if `command` is a command in backticks `` `...` `` in
|
||||
* the line at `lineIndex` in the shell script,
|
||||
* and `id` is a unique identifier for this command.
|
||||
*/
|
||||
private predicate commandInBackticks(int lineIndex, string command, string id) {
|
||||
exists(int occurrenceIndex, int occurrenceOffset |
|
||||
command =
|
||||
this.lineProducer(lineIndex)
|
||||
.regexpFind("\\`[^\\`]+\\`", occurrenceIndex, occurrenceOffset)
|
||||
// trim leading backtick - TODO do this in first regex
|
||||
.regexpReplaceAll("^\\`", "")
|
||||
// trim trailing backtick - TODO do this in first regex
|
||||
.regexpReplaceAll("\\`$", "") and
|
||||
id = "cmd:" + lineIndex + ":" + occurrenceIndex + ":" + occurrenceOffset
|
||||
)
|
||||
}
|
||||
|
||||
private predicate rankedCmdSubstitutionReplacements(int i, string command, string commandId) {
|
||||
// rank commands by their unique IDs
|
||||
commandId = rank[i](string c, string id | this.cmdSubstitutionReplacement(c, id, _) | id) and
|
||||
// since we cannot output (command, ID) tuples from the rank operation,
|
||||
// we need to work out the specific command associated with the resulting ID
|
||||
this.cmdSubstitutionReplacement(command, commandId, _)
|
||||
private predicate rankedCmdSubstitutionReplacements(int i, string old, string new) {
|
||||
old = rank[i](string old2 | this.cmdSubstitutionReplacement(old2, _, _) | old2) and
|
||||
this.cmdSubstitutionReplacement(old, new, _)
|
||||
}
|
||||
|
||||
private predicate doReplaceCmdSubstitutions(int line, int round, string old, string new) {
|
||||
@@ -93,56 +64,31 @@ class BashShellScript extends ShellScript {
|
||||
this.cmdSubstitutionReplacement(result, _, i)
|
||||
}
|
||||
|
||||
/**
|
||||
* Holds if `quotedStr` is a string in double quotes in
|
||||
* the line at `lineIndex` in the shell script,
|
||||
* and `id` is a unique identifier for this quoted string.
|
||||
*/
|
||||
private predicate doubleQuotedString(int lineIndex, string quotedStr, string id) {
|
||||
exists(int occurrenceIndex, int occurrenceOffset |
|
||||
// double quoted string
|
||||
quotedStr =
|
||||
this.cmdSubstitutedLineProducer(lineIndex)
|
||||
.regexpFind("\"((?:[^\"\\\\]|\\\\.)*)\"", occurrenceIndex, occurrenceOffset) and
|
||||
id =
|
||||
"qstr:" + lineIndex + ":" + occurrenceIndex + ":" + occurrenceOffset + ":" +
|
||||
quotedStr.length() + ":" + quotedStr.regexpReplaceAll("[^a-zA-Z0-9]", "")
|
||||
)
|
||||
}
|
||||
|
||||
/**
|
||||
* Holds if `quotedStr` is a string in single quotes in
|
||||
* the line at `lineIndex` in the shell script,
|
||||
* and `id` is a unique identifier for this quoted string.
|
||||
*/
|
||||
private predicate singleQuotedString(int lineIndex, string quotedStr, string id) {
|
||||
exists(int occurrenceIndex, int occurrenceOffset |
|
||||
// single quoted string
|
||||
quotedStr =
|
||||
this.cmdSubstitutedLineProducer(lineIndex)
|
||||
.regexpFind("'((?:\\\\.|[^'\\\\])*)'", occurrenceIndex, occurrenceOffset) and
|
||||
id =
|
||||
"qstr:" + lineIndex + ":" + occurrenceIndex + ":" + occurrenceOffset + ":" +
|
||||
quotedStr.length() + ":" + quotedStr.regexpReplaceAll("[^a-zA-Z0-9]", "")
|
||||
)
|
||||
}
|
||||
|
||||
private predicate quotedStringReplacement(string quotedStr, string id) {
|
||||
exists(int lineIndex |
|
||||
this.doubleQuotedString(lineIndex, quotedStr, id)
|
||||
exists(string line, int k | line = this.cmdSubstitutedLineProducer(k) |
|
||||
exists(int i, int j |
|
||||
// double quoted string
|
||||
quotedStr = line.regexpFind("\"((?:[^\"\\\\]|\\\\.)*)\"", i, j) and
|
||||
id =
|
||||
"qstr:" + k + ":" + i + ":" + j + ":" + quotedStr.length() + ":" +
|
||||
quotedStr.regexpReplaceAll("[^a-zA-Z0-9]", "")
|
||||
)
|
||||
or
|
||||
this.singleQuotedString(lineIndex, quotedStr, id)
|
||||
exists(int i, int j |
|
||||
// single quoted string
|
||||
quotedStr = line.regexpFind("'((?:\\\\.|[^'\\\\])*)'", i, j) and
|
||||
id =
|
||||
"qstr:" + k + ":" + i + ":" + j + ":" + quotedStr.length() + ":" +
|
||||
quotedStr.regexpReplaceAll("[^a-zA-Z0-9]", "")
|
||||
)
|
||||
) and
|
||||
// Only do this for strings that might otherwise disrupt subsequent parsing
|
||||
quotedStr.regexpMatch("[\"'].*[$\n\r'\"" + Bash::separator() + "].*[\"']")
|
||||
}
|
||||
|
||||
private predicate rankedQuotedStringReplacements(int i, string quotedString, string quotedStringId) {
|
||||
// rank quoted strings by their nearly-unique IDs
|
||||
quotedStringId = rank[i](string s, string id | this.quotedStringReplacement(s, id) | id) and
|
||||
// since we cannot output (string, ID) tuples from the rank operation,
|
||||
// we need to work out the specific string associated with the resulting ID
|
||||
this.quotedStringReplacement(quotedString, quotedStringId)
|
||||
private predicate rankedQuotedStringReplacements(int i, string old, string new) {
|
||||
old = rank[i](string old2 | this.quotedStringReplacement(old2, _) | old2) and
|
||||
this.quotedStringReplacement(old, new)
|
||||
}
|
||||
|
||||
private predicate doReplaceQuotedStrings(int line, int round, string old, string new) {
|
||||
|
||||
@@ -214,10 +214,6 @@ private module OutputClobberingConfig implements DataFlow::ConfigSig {
|
||||
)
|
||||
)
|
||||
}
|
||||
|
||||
predicate observeDiffInformedIncrementalMode() { any() }
|
||||
|
||||
Location getASelectedSourceLocation(DataFlow::Node sink) { none() }
|
||||
}
|
||||
|
||||
/** Tracks flow of unsafe user input that is used to construct and evaluate an environment variable. */
|
||||
|
||||
@@ -16,10 +16,6 @@ private module RequestForgeryConfig implements DataFlow::ConfigSig {
|
||||
predicate isSource(DataFlow::Node source) { source instanceof RemoteFlowSource }
|
||||
|
||||
predicate isSink(DataFlow::Node sink) { sink instanceof RequestForgerySink }
|
||||
|
||||
predicate observeDiffInformedIncrementalMode() { any() }
|
||||
|
||||
Location getASelectedSourceLocation(DataFlow::Node sink) { none() }
|
||||
}
|
||||
|
||||
/** Tracks flow of unsafe user input that is used to construct and evaluate a system command. */
|
||||
|
||||
@@ -15,10 +15,6 @@ private module SecretExfiltrationConfig implements DataFlow::ConfigSig {
|
||||
predicate isSource(DataFlow::Node source) { source instanceof RemoteFlowSource }
|
||||
|
||||
predicate isSink(DataFlow::Node sink) { sink instanceof SecretExfiltrationSink }
|
||||
|
||||
predicate observeDiffInformedIncrementalMode() { any() }
|
||||
|
||||
Location getASelectedSourceLocation(DataFlow::Node sink) { none() }
|
||||
}
|
||||
|
||||
/** Tracks flow of unsafe user input that is used in a context where it may lead to a secret exfiltration. */
|
||||
|
||||
@@ -22,21 +22,16 @@ extensions:
|
||||
- ["actions/stale", "pull-requests: write"]
|
||||
- ["actions/attest-build-provenance", "id-token: write"]
|
||||
- ["actions/attest-build-provenance", "attestations: write"]
|
||||
- ["actions/deploy-pages", "pages: write"]
|
||||
- ["actions/deploy-pages", "id-token: write"]
|
||||
- ["actions/delete-package-versions", "packages: write"]
|
||||
- ["actions/jekyll-build-pages", "contents: read"]
|
||||
- ["actions/jekyll-build-pages", "pages: write"]
|
||||
- ["actions/jekyll-build-pages", "id-token: write"]
|
||||
- ["actions/publish-action", "contents: write"]
|
||||
- ["actions/versions-package-tools", "contents: read"]
|
||||
- ["actions/versions-package-tools", "contents: read"]
|
||||
- ["actions/versions-package-tools", "actions: read"]
|
||||
- ["actions/reusable-workflows", "contents: read"]
|
||||
- ["actions/reusable-workflows", "contents: read"]
|
||||
- ["actions/reusable-workflows", "actions: read"]
|
||||
- ["actions/ai-inference", "contents: read"]
|
||||
- ["actions/ai-inference", "models: read"]
|
||||
# TODO: Add permissions for actions/download-artifact
|
||||
# TODO: Add permissions for actions/upload-artifact
|
||||
# No permissions needed for actions/upload-pages-artifact
|
||||
# TODO: Add permissions for actions/cache
|
||||
# No permissions needed for actions/configure-pages
|
||||
|
||||
|
||||
|
||||
@@ -1,5 +1,5 @@
|
||||
name: codeql/actions-all
|
||||
version: 0.4.12-dev
|
||||
version: 0.4.10-dev
|
||||
library: true
|
||||
warnOnImplicitThis: true
|
||||
dependencies:
|
||||
|
||||
@@ -1,13 +1,3 @@
|
||||
## 0.6.3
|
||||
|
||||
No user-facing changes.
|
||||
|
||||
## 0.6.2
|
||||
|
||||
### Minor Analysis Improvements
|
||||
|
||||
* The query `actions/missing-workflow-permissions` is now aware of the minimal permissions needed for the actions `deploy-pages`, `delete-package-versions`, `ai-inference`. This should lead to better alert messages and better fix suggestions.
|
||||
|
||||
## 0.6.1
|
||||
|
||||
No user-facing changes.
|
||||
|
||||
@@ -24,10 +24,6 @@ private module MyConfig implements DataFlow::ConfigSig {
|
||||
predicate isSink(DataFlow::Node sink) {
|
||||
sink instanceof CodeInjectionSink and not madSink(sink, "code-injection")
|
||||
}
|
||||
|
||||
predicate observeDiffInformedIncrementalMode() { any() }
|
||||
|
||||
Location getASelectedSourceLocation(DataFlow::Node sink) { none() }
|
||||
}
|
||||
|
||||
module MyFlow = TaintTracking::Global<MyConfig>;
|
||||
|
||||
@@ -34,10 +34,6 @@ private module MyConfig implements DataFlow::ConfigSig {
|
||||
isSink(node) and
|
||||
set instanceof DataFlow::FieldContent
|
||||
}
|
||||
|
||||
predicate observeDiffInformedIncrementalMode() { any() }
|
||||
|
||||
Location getASelectedSourceLocation(DataFlow::Node sink) { none() }
|
||||
}
|
||||
|
||||
module MyFlow = TaintTracking::Global<MyConfig>;
|
||||
|
||||
@@ -25,10 +25,6 @@ private module MyConfig implements DataFlow::ConfigSig {
|
||||
predicate isSink(DataFlow::Node sink) {
|
||||
exists(CompositeAction c | c.getAnOutputExpr() = sink.asExpr())
|
||||
}
|
||||
|
||||
predicate observeDiffInformedIncrementalMode() { any() }
|
||||
|
||||
Location getASelectedSourceLocation(DataFlow::Node sink) { none() }
|
||||
}
|
||||
|
||||
module MyFlow = TaintTracking::Global<MyConfig>;
|
||||
|
||||
@@ -24,10 +24,6 @@ private module MyConfig implements DataFlow::ConfigSig {
|
||||
predicate isSink(DataFlow::Node sink) {
|
||||
sink instanceof CodeInjectionSink and not madSink(sink, "code-injection")
|
||||
}
|
||||
|
||||
predicate observeDiffInformedIncrementalMode() { any() }
|
||||
|
||||
Location getASelectedSourceLocation(DataFlow::Node sink) { none() }
|
||||
}
|
||||
|
||||
module MyFlow = TaintTracking::Global<MyConfig>;
|
||||
|
||||
@@ -34,10 +34,6 @@ private module MyConfig implements DataFlow::ConfigSig {
|
||||
isSink(node) and
|
||||
set instanceof DataFlow::FieldContent
|
||||
}
|
||||
|
||||
predicate observeDiffInformedIncrementalMode() { any() }
|
||||
|
||||
Location getASelectedSourceLocation(DataFlow::Node sink) { none() }
|
||||
}
|
||||
|
||||
module MyFlow = TaintTracking::Global<MyConfig>;
|
||||
|
||||
@@ -25,10 +25,6 @@ private module MyConfig implements DataFlow::ConfigSig {
|
||||
predicate isSink(DataFlow::Node sink) {
|
||||
exists(ReusableWorkflow w | w.getAnOutputExpr() = sink.asExpr())
|
||||
}
|
||||
|
||||
predicate observeDiffInformedIncrementalMode() { any() }
|
||||
|
||||
Location getASelectedSourceLocation(DataFlow::Node sink) { none() }
|
||||
}
|
||||
|
||||
module MyFlow = TaintTracking::Global<MyConfig>;
|
||||
|
||||
@@ -1,5 +0,0 @@
|
||||
## 0.6.2
|
||||
|
||||
### Minor Analysis Improvements
|
||||
|
||||
* The query `actions/missing-workflow-permissions` is now aware of the minimal permissions needed for the actions `deploy-pages`, `delete-package-versions`, `ai-inference`. This should lead to better alert messages and better fix suggestions.
|
||||
@@ -1,3 +0,0 @@
|
||||
## 0.6.3
|
||||
|
||||
No user-facing changes.
|
||||
@@ -1,2 +1,2 @@
|
||||
---
|
||||
lastReleaseVersion: 0.6.3
|
||||
lastReleaseVersion: 0.6.1
|
||||
|
||||
@@ -1,3 +0,0 @@
|
||||
- queries: .
|
||||
- apply: code-quality-extended-selectors.yml
|
||||
from: codeql/suite-helpers
|
||||
@@ -1,5 +1,5 @@
|
||||
name: codeql/actions-queries
|
||||
version: 0.6.4-dev
|
||||
version: 0.6.2-dev
|
||||
library: false
|
||||
warnOnImplicitThis: true
|
||||
groups: [actions, queries]
|
||||
|
||||
@@ -1,81 +0,0 @@
|
||||
name: Workflow with complex interpolation
|
||||
on:
|
||||
workflow_dispatch:
|
||||
inputs:
|
||||
choice-a:
|
||||
required: true
|
||||
type: choice
|
||||
description: choice-a
|
||||
default: a1
|
||||
options:
|
||||
- a1
|
||||
- a2
|
||||
- a3
|
||||
string-b:
|
||||
required: false
|
||||
type: string
|
||||
description: string-b
|
||||
string-c:
|
||||
required: false
|
||||
type: string
|
||||
description: string-c
|
||||
list-d:
|
||||
required: true
|
||||
type: string
|
||||
default: d1 d2
|
||||
description: list-d whitespace separated
|
||||
list-e:
|
||||
required: false
|
||||
type: string
|
||||
description: list-e whitespace separated
|
||||
choice-f:
|
||||
required: true
|
||||
type: choice
|
||||
description: choice-f
|
||||
options:
|
||||
- false
|
||||
- true
|
||||
|
||||
env:
|
||||
DRY_TEST: false
|
||||
B: ${{ github.event.inputs.string-b }}
|
||||
|
||||
jobs:
|
||||
job:
|
||||
runs-on: ubuntu-latest
|
||||
steps:
|
||||
- name: Produce values
|
||||
id: produce-values
|
||||
run: |
|
||||
echo "region=region" >> $GITHUB_OUTPUT
|
||||
echo "zone=zone" >> $GITHUB_OUTPUT
|
||||
|
||||
- name: Step with complex interpolation
|
||||
id: complex
|
||||
env:
|
||||
CHOICE_A: ${{ github.event.inputs.choice-a }}
|
||||
STRING_B: ${{ github.event.inputs.string-b }}
|
||||
STRING_C: ${{ github.event.inputs.string-c }}
|
||||
LIST_D: ${{ github.event.inputs.list-d }}
|
||||
LIST_E: ${{ github.event.inputs.list-e }}
|
||||
CHOICE_F: ${{ github.event.inputs.choice-f }}
|
||||
REGION: ${{ steps.produce-values.outputs.region }}
|
||||
ZONE: ${{ steps.produce-values.outputs.zone }}
|
||||
DRY_TEST_JSON: ${{ fromJSON(env.DRY_TEST) }}
|
||||
FUNCTION_NAME: my-function
|
||||
USER_EMAIL: 'example@example.com'
|
||||
TYPE: type
|
||||
RANGE: '0-100'
|
||||
|
||||
run: |
|
||||
comma_separated_list_d=$(echo "${LIST_D}" | sed "s/ /\",\"/g")
|
||||
comma_separated_list_e=$(echo "${LIST_E}" | sed "s/ /\",\"/g")
|
||||
c1=$(echo "${STRING_C}" | cut -d "-" -f 1)
|
||||
c2=$(echo "${STRING_C}" | cut -d "-" -f 2)
|
||||
# Similar commands that use JSON payloads with string interpolation.
|
||||
response=$(aws lambda invoke --invocation-type RequestResponse --function-name "${FUNCTION_NAME}" --region "${REGION}" --cli-read-timeout 0 --cli-binary-format raw-in-base64-out --payload '{"appName":"my-app","chA":"'"${CHOICE_A}"'","c1":"'"${c1}"'","c2":"'"${c2}"'","a":"${CHOICE_A}","bValue":"${B}","zone":"${ZONE}","userEmail":"'"${USER_EMAIL}"'","region":"${REGION}","range":"${RANGE}","type":"${TYPE}","b":"${STRING_B}","listD":"","listE":"","dryTest":'"${DRY_TEST_JSON}"',"f":"${CHOICE_F}"}' ./config.json --log-type Tail)
|
||||
response=$(aws lambda invoke --invocation-type RequestResponse --function-name "${FUNCTION_NAME}" --region "${REGION}" --cli-read-timeout 0 --cli-binary-format raw-in-base64-out --payload '{"appName":"my-app","chA":"'"${CHOICE_A}"'","c1":"'"${c1}"'","c2":"'"${c2}"'","a":"${CHOICE_A}","bValue":"${B}","zone":"${ZONE}","userEmail":"'"${USER_EMAIL}"'","region":"${REGION}","range":"${RANGE}","type":"${TYPE}","b":"${STRING_B}","listD":["'"${comma_separated_list_d}"'"],"listE":"","dryTest":'"${DRY_TEST_JSON}"',"f":"${CHOICE_F}"}' ./config.json --log-type Tail)
|
||||
response=$(aws lambda invoke --invocation-type RequestResponse --function-name "${FUNCTION_NAME}" --region "${REGION}" --cli-read-timeout 0 --cli-binary-format raw-in-base64-out --payload '{"appName":"my-app","chA":"'"${CHOICE_A}"'","c1":"'"${c1}"'","c2":"'"${c2}"'","a":"${CHOICE_A}","bValue":"${B}","zone":"${ZONE}","userEmail":"'"${USER_EMAIL}"'","region":"${REGION}","range":"${RANGE}","type":"${TYPE}","b":"${STRING_B}","listD":["'"${comma_separated_list_d}"'"],"listE":"","dryTest":'"${DRY_TEST_JSON}"',"f":"${CHOICE_F}"}' ./config.json --log-type Tail)
|
||||
response=$(aws lambda invoke --invocation-type RequestResponse --function-name "${FUNCTION_NAME}" --region "${REGION}" --cli-read-timeout 0 --cli-binary-format raw-in-base64-out --payload '{"appName":"my-app","chA":"'"${CHOICE_A}"'","c1":"'"${c1}"'","c2":"'"${c2}"'","a":"${CHOICE_A}","bValue":"${B}","zone":"${ZONE}","userEmail":"'"${USER_EMAIL}"'","region":"${REGION}","range":"${RANGE}","type":"${TYPE}","b":"${STRING_B}","listD":["'"${comma_separated_list_d}"'"],"listE":"","dryTest":'"${DRY_TEST_JSON}"',"f":"${CHOICE_F}"}' ./config.json --log-type Tail)
|
||||
response=$(aws lambda invoke --invocation-type RequestResponse --function-name "${FUNCTION_NAME}" --region "${REGION}" --cli-read-timeout 0 --cli-binary-format raw-in-base64-out --payload '{"appName":"my-app","chA":"'"${CHOICE_A}"'","c1":"'"${c1}"'","c2":"'"${c2}"'","a":"${CHOICE_A}","bValue":"${B}","zone":"${ZONE}","userEmail":"'"${USER_EMAIL}"'","region":"${REGION}","range":"${RANGE}","type":"${TYPE}","b":"${STRING_B}","listD":"","listE":["'"${comma_separated_list_e}"'"],"dryTest":'"${DRY_TEST_JSON}"',"f":"${CHOICE_F}"}' ./config.json --log-type Tail)
|
||||
shell: bash
|
||||
@@ -1,10 +0,0 @@
|
||||
on:
|
||||
workflow_call:
|
||||
workflow_dispatch:
|
||||
|
||||
jobs:
|
||||
build:
|
||||
name: Build and test
|
||||
runs-on: ubuntu-latest
|
||||
steps:
|
||||
- uses: actions/ai-inference
|
||||
@@ -1,10 +0,0 @@
|
||||
on:
|
||||
workflow_call:
|
||||
workflow_dispatch:
|
||||
|
||||
jobs:
|
||||
build:
|
||||
name: Build and test
|
||||
runs-on: ubuntu-latest
|
||||
steps:
|
||||
- uses: actions/deploy-pages
|
||||
@@ -1,10 +0,0 @@
|
||||
on:
|
||||
workflow_call:
|
||||
workflow_dispatch:
|
||||
|
||||
jobs:
|
||||
build:
|
||||
name: Build and test
|
||||
runs-on: ubuntu-latest
|
||||
steps:
|
||||
- uses: actions/delete-package-versions
|
||||
@@ -3,6 +3,3 @@
|
||||
| .github/workflows/perms5.yml:7:5:10:32 | Job: build | Actions job or workflow does not limit the permissions of the GITHUB_TOKEN. Consider setting an explicit permissions block, using the following as a minimal starting point: {contents: read} |
|
||||
| .github/workflows/perms6.yml:7:5:11:39 | Job: build | Actions job or workflow does not limit the permissions of the GITHUB_TOKEN. Consider setting an explicit permissions block, using the following as a minimal starting point: {contents: read, id-token: write, pages: write} |
|
||||
| .github/workflows/perms7.yml:7:5:10:38 | Job: build | Actions job or workflow does not limit the permissions of the GITHUB_TOKEN. Consider setting an explicit permissions block, using the following as a minimal starting point: {} |
|
||||
| .github/workflows/perms8.yml:7:5:10:33 | Job: build | Actions job or workflow does not limit the permissions of the GITHUB_TOKEN. Consider setting an explicit permissions block, using the following as a minimal starting point: {id-token: write, pages: write} |
|
||||
| .github/workflows/perms9.yml:7:5:10:44 | Job: build | Actions job or workflow does not limit the permissions of the GITHUB_TOKEN. Consider setting an explicit permissions block, using the following as a minimal starting point: {packages: write} |
|
||||
| .github/workflows/perms10.yml:7:5:10:33 | Job: build | Actions job or workflow does not limit the permissions of the GITHUB_TOKEN. Consider setting an explicit permissions block, using the following as a minimal starting point: {contents: read, models: read} |
|
||||
|
||||
@@ -1,31 +0,0 @@
|
||||
language: cpp
|
||||
strategy: dca
|
||||
destination: cpp/ql/lib/ext/generated
|
||||
targets:
|
||||
- name: zlib
|
||||
with-sinks: false
|
||||
with-sources: false
|
||||
- name: brotli
|
||||
with-sinks: false
|
||||
with-sources: false
|
||||
- name: libidn2
|
||||
with-sinks: false
|
||||
with-sources: false
|
||||
- name: libssh2
|
||||
with-sinks: false
|
||||
with-sources: false
|
||||
- name: sqlite
|
||||
with-sinks: false
|
||||
with-sources: false
|
||||
- name: openssl
|
||||
with-sinks: false
|
||||
with-sources: false
|
||||
- name: nghttp2
|
||||
with-sinks: false
|
||||
with-sources: false
|
||||
- name: libuv
|
||||
with-sinks: false
|
||||
with-sources: false
|
||||
- name: curl
|
||||
with-sinks: false
|
||||
with-sources: false
|
||||
@@ -1,7 +0,0 @@
|
||||
class LambdaExpr extends @lambdaexpr {
|
||||
string toString() { none() }
|
||||
}
|
||||
|
||||
from LambdaExpr lambda, string default_capture, boolean has_explicit_return_type
|
||||
where lambdas(lambda, default_capture, has_explicit_return_type, _)
|
||||
select lambda, default_capture, has_explicit_return_type
|
||||
File diff suppressed because it is too large
Load Diff
File diff suppressed because it is too large
Load Diff
@@ -1,3 +0,0 @@
|
||||
description: capture whether a lambda has an explicitly specified parameter list.
|
||||
compatibility: full
|
||||
lambdas.rel: run lambdas.qlo
|
||||
@@ -11,7 +11,7 @@ int getKind(int kind) {
|
||||
if kind = 14
|
||||
then result = 6 // Represent MSFT #import as #include
|
||||
else
|
||||
if kind = 15 or kind = 16
|
||||
if kind = 15 or kind = 6
|
||||
then result = 3 // Represent #elifdef and #elifndef as #elif
|
||||
else result = kind
|
||||
}
|
||||
|
||||
File diff suppressed because it is too large
Load Diff
File diff suppressed because it is too large
Load Diff
@@ -1,3 +0,0 @@
|
||||
description: Add a predicate `getAnAttribute` to `Namespace`
|
||||
compatibility: full
|
||||
namespaceattributes.rel: delete
|
||||
File diff suppressed because it is too large
Load Diff
File diff suppressed because it is too large
Load Diff
@@ -1,13 +0,0 @@
|
||||
class Stmt extends @stmt {
|
||||
string toString() { none() }
|
||||
}
|
||||
|
||||
class Location extends @location_stmt {
|
||||
string toString() { none() }
|
||||
}
|
||||
|
||||
from Stmt id, int kind, Location loc, int new_kind
|
||||
where
|
||||
stmts(id, kind, loc) and
|
||||
if kind = 40 then new_kind = 4 else new_kind = kind
|
||||
select id, new_kind, loc
|
||||
@@ -1,3 +0,0 @@
|
||||
description: Support `__leave` statement
|
||||
compatibility: full
|
||||
stmts.rel: run stmts.qlo
|
||||
@@ -1,9 +0,0 @@
|
||||
class BuiltinType extends @builtintype {
|
||||
string toString() { none() }
|
||||
}
|
||||
|
||||
from BuiltinType id, string name, int kind, int new_kind, int size, int sign, int alignment
|
||||
where
|
||||
builtintypes(id, name, kind, size, sign, alignment) and
|
||||
if kind = 62 then new_kind = 1 else new_kind = kind
|
||||
select id, name, new_kind, size, sign, alignment
|
||||
File diff suppressed because it is too large
Load Diff
File diff suppressed because it is too large
Load Diff
@@ -1,3 +0,0 @@
|
||||
description: Support __mfp8 type
|
||||
compatibility: backwards
|
||||
builtintypes.rel: run builtintypes.qlo
|
||||
@@ -1,9 +0,0 @@
|
||||
class BuiltinType extends @builtintype {
|
||||
string toString() { none() }
|
||||
}
|
||||
|
||||
from BuiltinType id, string name, int kind, int new_kind, int size, int sign, int alignment
|
||||
where
|
||||
builtintypes(id, name, kind, size, sign, alignment) and
|
||||
if kind = 63 then /* @errortype */ new_kind = 1 else new_kind = kind
|
||||
select id, name, new_kind, size, sign, alignment
|
||||
@@ -1,9 +0,0 @@
|
||||
class Type extends @type {
|
||||
string toString() { none() }
|
||||
}
|
||||
|
||||
from Type type, string name, int kind, int new_kind, Type type_id
|
||||
where
|
||||
derivedtypes(type, name, kind, type_id) and
|
||||
if kind = 11 then /* @gnu_vector */ new_kind = 5 else new_kind = kind
|
||||
select type, name, new_kind, type_id
|
||||
File diff suppressed because it is too large
Load Diff
File diff suppressed because it is too large
Load Diff
@@ -1,5 +0,0 @@
|
||||
description: Arm scalable vector type support
|
||||
compatibility: backwards
|
||||
builtintypes.rel: run builtintypes.qlo
|
||||
derivedtypes.rel: run derivedtypes.qlo
|
||||
tupleelements.rel: delete
|
||||
@@ -1 +0,0 @@
|
||||
|
||||
@@ -2,7 +2,7 @@ import runs_on
|
||||
import pytest
|
||||
from query_suites import *
|
||||
|
||||
well_known_query_suites = ['cpp-code-quality.qls', 'cpp-code-quality-extended.qls', 'cpp-security-and-quality.qls', 'cpp-security-extended.qls', 'cpp-code-scanning.qls']
|
||||
well_known_query_suites = ['cpp-code-quality.qls', 'cpp-security-and-quality.qls', 'cpp-security-extended.qls', 'cpp-code-scanning.qls']
|
||||
|
||||
@runs_on.posix
|
||||
@pytest.mark.parametrize("query_suite", well_known_query_suites)
|
||||
|
||||
@@ -1,33 +1,3 @@
|
||||
## 5.1.0
|
||||
|
||||
### New Features
|
||||
|
||||
* Added a predicate `getReferencedMember` to `UsingDeclarationEntry`, which yields a member depending on a type template parameter.
|
||||
|
||||
## 5.0.0
|
||||
|
||||
### Breaking Changes
|
||||
|
||||
* Deleted the deprecated `userInputArgument` predicate and its convenience accessor from the `Security.qll`.
|
||||
* Deleted the deprecated `userInputReturned` predicate and its convenience accessor from the `Security.qll`.
|
||||
* Deleted the deprecated `userInputReturn` predicate from the `Security.qll`.
|
||||
* Deleted the deprecated `isUserInput` predicate and its convenience accessor from the `Security.qll`.
|
||||
* Deleted the deprecated `userInputArgument` predicate from the `SecurityOptions.qll`.
|
||||
* Deleted the deprecated `userInputReturned` predicate from the `SecurityOptions.qll`.
|
||||
|
||||
### New Features
|
||||
|
||||
* Added local flow source models for `ReadFile`, `ReadFileEx`, `MapViewOfFile`, `MapViewOfFile2`, `MapViewOfFile3`, `MapViewOfFile3FromApp`, `MapViewOfFileEx`, `MapViewOfFileFromApp`, `MapViewOfFileNuma2`, and `NtReadFile`.
|
||||
* Added the `pCmdLine` arguments of `WinMain` and `wWinMain` as local flow sources.
|
||||
* Added source models for `GetCommandLineA`, `GetCommandLineW`, `GetEnvironmentStringsA`, `GetEnvironmentStringsW`, `GetEnvironmentVariableA`, and `GetEnvironmentVariableW`.
|
||||
* Added summary models for `CommandLineToArgvA` and `CommandLineToArgvW`.
|
||||
* Added support for `wmain` as part of the ArgvSource model.
|
||||
|
||||
### Bug Fixes
|
||||
|
||||
* Fixed a problem where `asExpr()` on `DataFlow::Node` would never return `ArrayAggregateLiteral`s.
|
||||
* Fixed a problem where `asExpr()` on `DataFlow::Node` would never return `ClassAggregateLiteral`s.
|
||||
|
||||
## 4.3.1
|
||||
|
||||
### Bug Fixes
|
||||
|
||||
@@ -1,4 +0,0 @@
|
||||
---
|
||||
category: deprecated
|
||||
---
|
||||
* The `ThrowingFunction` class (`semmle.code.cpp.models.interfaces.Throwing`) has been deprecated. Please use the `AlwaysSehThrowingFunction` class instead.
|
||||
@@ -1,4 +0,0 @@
|
||||
---
|
||||
category: feature
|
||||
---
|
||||
* Added a predicate `hasParameterList` to `LambdaExpression` to capture whether a lambda has an explicitly specified parameter list.
|
||||
@@ -1,5 +0,0 @@
|
||||
---
|
||||
category: feature
|
||||
---
|
||||
* The Microsoft-specific `__leave` statement is now supported.
|
||||
* A new class `LeaveStmt` extending `JumpStmt` was added to represent `__leave` statements.
|
||||
@@ -1,4 +0,0 @@
|
||||
---
|
||||
category: feature
|
||||
---
|
||||
* Added a predicate `getAnAttribute` to `Namespace` to retrieve a namespace attribute.
|
||||
@@ -1,4 +0,0 @@
|
||||
---
|
||||
category: fix
|
||||
---
|
||||
* `resolveTypedefs` now properly resolves typedefs for `ArrayType`s.
|
||||
@@ -1,23 +0,0 @@
|
||||
## 5.0.0
|
||||
|
||||
### Breaking Changes
|
||||
|
||||
* Deleted the deprecated `userInputArgument` predicate and its convenience accessor from the `Security.qll`.
|
||||
* Deleted the deprecated `userInputReturned` predicate and its convenience accessor from the `Security.qll`.
|
||||
* Deleted the deprecated `userInputReturn` predicate from the `Security.qll`.
|
||||
* Deleted the deprecated `isUserInput` predicate and its convenience accessor from the `Security.qll`.
|
||||
* Deleted the deprecated `userInputArgument` predicate from the `SecurityOptions.qll`.
|
||||
* Deleted the deprecated `userInputReturned` predicate from the `SecurityOptions.qll`.
|
||||
|
||||
### New Features
|
||||
|
||||
* Added local flow source models for `ReadFile`, `ReadFileEx`, `MapViewOfFile`, `MapViewOfFile2`, `MapViewOfFile3`, `MapViewOfFile3FromApp`, `MapViewOfFileEx`, `MapViewOfFileFromApp`, `MapViewOfFileNuma2`, and `NtReadFile`.
|
||||
* Added the `pCmdLine` arguments of `WinMain` and `wWinMain` as local flow sources.
|
||||
* Added source models for `GetCommandLineA`, `GetCommandLineW`, `GetEnvironmentStringsA`, `GetEnvironmentStringsW`, `GetEnvironmentVariableA`, and `GetEnvironmentVariableW`.
|
||||
* Added summary models for `CommandLineToArgvA` and `CommandLineToArgvW`.
|
||||
* Added support for `wmain` as part of the ArgvSource model.
|
||||
|
||||
### Bug Fixes
|
||||
|
||||
* Fixed a problem where `asExpr()` on `DataFlow::Node` would never return `ArrayAggregateLiteral`s.
|
||||
* Fixed a problem where `asExpr()` on `DataFlow::Node` would never return `ClassAggregateLiteral`s.
|
||||
@@ -1,5 +0,0 @@
|
||||
## 5.1.0
|
||||
|
||||
### New Features
|
||||
|
||||
* Added a predicate `getReferencedMember` to `UsingDeclarationEntry`, which yields a member depending on a type template parameter.
|
||||
@@ -1,2 +1,2 @@
|
||||
---
|
||||
lastReleaseVersion: 5.1.0
|
||||
lastReleaseVersion: 4.3.1
|
||||
|
||||
@@ -1,7 +1,6 @@
|
||||
private import cpp as Language
|
||||
import semmle.code.cpp.dataflow.new.TaintTracking
|
||||
import semmle.code.cpp.dataflow.new.DataFlow
|
||||
import codeql.quantum.experimental.Model
|
||||
private import OpenSSL.GenericSourceCandidateLiteral
|
||||
|
||||
module CryptoInput implements InputSig<Language::Location> {
|
||||
class DataFlowNode = DataFlow::Node;
|
||||
@@ -13,9 +12,7 @@ module CryptoInput implements InputSig<Language::Location> {
|
||||
LocatableElement dfn_to_element(DataFlow::Node node) {
|
||||
result = node.asExpr() or
|
||||
result = node.asParameter() or
|
||||
result = node.asVariable() or
|
||||
result = node.asDefiningArgument()
|
||||
// TODO: do we need asIndirectExpr()?
|
||||
result = node.asVariable()
|
||||
}
|
||||
|
||||
string locationToFileBaseNameAndLineNumberString(Location location) {
|
||||
@@ -89,21 +86,6 @@ module GenericDataSourceFlowConfig implements DataFlow::ConfigSig {
|
||||
}
|
||||
}
|
||||
|
||||
module GenericDataSourceFlow = TaintTracking::Global<GenericDataSourceFlowConfig>;
|
||||
|
||||
private class ConstantDataSource extends Crypto::GenericConstantSourceInstance instanceof Literal {
|
||||
ConstantDataSource() { this instanceof OpenSslGenericSourceCandidateLiteral }
|
||||
|
||||
override DataFlow::Node getOutputNode() { result.asExpr() = this }
|
||||
|
||||
override predicate flowsTo(Crypto::FlowAwareElement other) {
|
||||
// TODO: separate config to avoid blowing up data-flow analysis
|
||||
GenericDataSourceFlow::flow(this.getOutputNode(), other.getInputNode())
|
||||
}
|
||||
|
||||
override string getAdditionalDescription() { result = this.toString() }
|
||||
}
|
||||
|
||||
module ArtifactUniversalFlowConfig implements DataFlow::ConfigSig {
|
||||
predicate isSource(DataFlow::Node source) {
|
||||
source = any(Crypto::ArtifactInstance artifact).getOutputNode()
|
||||
|
||||
@@ -1,9 +1,7 @@
|
||||
import cpp
|
||||
private import experimental.quantum.Language
|
||||
private import semmle.code.cpp.dataflow.new.DataFlow
|
||||
private import experimental.quantum.OpenSSL.AlgorithmInstances.KnownAlgorithmConstants
|
||||
private import experimental.quantum.OpenSSL.AlgorithmValueConsumers.OpenSSLAlgorithmValueConsumers
|
||||
private import PaddingAlgorithmInstance
|
||||
import semmle.code.cpp.dataflow.new.DataFlow
|
||||
import experimental.quantum.OpenSSL.AlgorithmInstances.KnownAlgorithmConstants
|
||||
import experimental.quantum.OpenSSL.AlgorithmValueConsumers.OpenSSLAlgorithmValueConsumers
|
||||
|
||||
/**
|
||||
* Traces 'known algorithms' to AVCs, specifically
|
||||
@@ -12,19 +10,14 @@ private import PaddingAlgorithmInstance
|
||||
* overlap with the known algorithm constants.
|
||||
* Padding consumers (specific padding consumers) are excluded from the set of sinks.
|
||||
*/
|
||||
module KnownOpenSslAlgorithmToAlgorithmValueConsumerConfig implements DataFlow::ConfigSig {
|
||||
module KnownOpenSSLAlgorithmToAlgorithmValueConsumerConfig implements DataFlow::ConfigSig {
|
||||
predicate isSource(DataFlow::Node source) {
|
||||
source.asExpr() instanceof KnownOpenSslAlgorithmExpr and
|
||||
// No need to flow direct operations to AVCs
|
||||
not source.asExpr() instanceof OpenSslDirectAlgorithmOperationCall
|
||||
source.asExpr() instanceof KnownOpenSSLAlgorithmConstant
|
||||
}
|
||||
|
||||
predicate isSink(DataFlow::Node sink) {
|
||||
exists(OpenSslAlgorithmValueConsumer c |
|
||||
exists(OpenSSLAlgorithmValueConsumer c |
|
||||
c.getInputNode() = sink and
|
||||
// exclude padding algorithm consumers, since
|
||||
// these consumers take in different constant values
|
||||
// not in the typical "known algorithm" set
|
||||
not c instanceof PaddingAlgorithmValueConsumer
|
||||
)
|
||||
}
|
||||
@@ -45,11 +38,13 @@ module KnownOpenSslAlgorithmToAlgorithmValueConsumerConfig implements DataFlow::
|
||||
}
|
||||
}
|
||||
|
||||
module KnownOpenSslAlgorithmToAlgorithmValueConsumerFlow =
|
||||
DataFlow::Global<KnownOpenSslAlgorithmToAlgorithmValueConsumerConfig>;
|
||||
module KnownOpenSSLAlgorithmToAlgorithmValueConsumerFlow =
|
||||
DataFlow::Global<KnownOpenSSLAlgorithmToAlgorithmValueConsumerConfig>;
|
||||
|
||||
module RSAPaddingAlgorithmToPaddingAlgorithmValueConsumerConfig implements DataFlow::ConfigSig {
|
||||
predicate isSource(DataFlow::Node source) { source.asExpr() instanceof OpenSslPaddingLiteral }
|
||||
predicate isSource(DataFlow::Node source) {
|
||||
source.asExpr() instanceof KnownOpenSSLAlgorithmConstant
|
||||
}
|
||||
|
||||
predicate isSink(DataFlow::Node sink) {
|
||||
exists(PaddingAlgorithmValueConsumer c | c.getInputNode() = sink)
|
||||
@@ -63,8 +58,8 @@ module RSAPaddingAlgorithmToPaddingAlgorithmValueConsumerConfig implements DataF
|
||||
module RSAPaddingAlgorithmToPaddingAlgorithmValueConsumerFlow =
|
||||
DataFlow::Global<RSAPaddingAlgorithmToPaddingAlgorithmValueConsumerConfig>;
|
||||
|
||||
class OpenSslAlgorithmAdditionalFlowStep extends AdditionalFlowInputStep {
|
||||
OpenSslAlgorithmAdditionalFlowStep() { exists(AlgorithmPassthroughCall c | c.getInNode() = this) }
|
||||
class OpenSSLAlgorithmAdditionalFlowStep extends AdditionalFlowInputStep {
|
||||
OpenSSLAlgorithmAdditionalFlowStep() { exists(AlgorithmPassthroughCall c | c.getInNode() = this) }
|
||||
|
||||
override DataFlow::Node getOutput() {
|
||||
exists(AlgorithmPassthroughCall c | c.getInNode() = this and c.getOutNode() = result)
|
||||
|
||||
@@ -1,20 +1,19 @@
|
||||
import cpp
|
||||
private import experimental.quantum.Language
|
||||
private import OpenSSLAlgorithmInstanceBase
|
||||
private import experimental.quantum.OpenSSL.AlgorithmInstances.KnownAlgorithmConstants
|
||||
private import experimental.quantum.OpenSSL.AlgorithmValueConsumers.DirectAlgorithmValueConsumer
|
||||
private import experimental.quantum.OpenSSL.AlgorithmValueConsumers.OpenSSLAlgorithmValueConsumerBase
|
||||
private import AlgToAVCFlow
|
||||
import experimental.quantum.Language
|
||||
import OpenSSLAlgorithmInstanceBase
|
||||
import experimental.quantum.OpenSSL.AlgorithmInstances.KnownAlgorithmConstants
|
||||
import experimental.quantum.OpenSSL.AlgorithmValueConsumers.DirectAlgorithmValueConsumer
|
||||
import AlgToAVCFlow
|
||||
|
||||
/**
|
||||
* Given a `KnownOpenSslBlockModeAlgorithmExpr`, converts this to a block family type.
|
||||
* Does not bind if there is no mapping (no mapping to 'unknown' or 'other').
|
||||
* Given a `KnownOpenSSLBlockModeAlgorithmConstant`, converts this to a block family type.
|
||||
* Does not bind if there is know mapping (no mapping to 'unknown' or 'other').
|
||||
*/
|
||||
predicate knownOpenSslConstantToBlockModeFamilyType(
|
||||
KnownOpenSslBlockModeAlgorithmExpr e, Crypto::TBlockCipherModeOfOperationType type
|
||||
predicate knownOpenSSLConstantToBlockModeFamilyType(
|
||||
KnownOpenSSLBlockModeAlgorithmConstant e, Crypto::TBlockCipherModeOfOperationType type
|
||||
) {
|
||||
exists(string name |
|
||||
name = e.(KnownOpenSslAlgorithmExpr).getNormalizedName() and
|
||||
name = e.getNormalizedName() and
|
||||
(
|
||||
name.matches("CBC") and type instanceof Crypto::CBC
|
||||
or
|
||||
@@ -39,44 +38,39 @@ predicate knownOpenSslConstantToBlockModeFamilyType(
|
||||
)
|
||||
}
|
||||
|
||||
class KnownOpenSslBlockModeConstantAlgorithmInstance extends OpenSslAlgorithmInstance,
|
||||
Crypto::ModeOfOperationAlgorithmInstance instanceof KnownOpenSslBlockModeAlgorithmExpr
|
||||
class KnownOpenSSLBlockModeConstantAlgorithmInstance extends OpenSSLAlgorithmInstance,
|
||||
Crypto::ModeOfOperationAlgorithmInstance instanceof KnownOpenSSLBlockModeAlgorithmConstant
|
||||
{
|
||||
OpenSslAlgorithmValueConsumer getterCall;
|
||||
OpenSSLAlgorithmValueConsumer getterCall;
|
||||
|
||||
KnownOpenSslBlockModeConstantAlgorithmInstance() {
|
||||
KnownOpenSSLBlockModeConstantAlgorithmInstance() {
|
||||
// Two possibilities:
|
||||
// 1) The source is a literal and flows to a getter, then we know we have an instance
|
||||
// 2) The source is a KnownOpenSslAlgorithm is call, and we know we have an instance immediately from that
|
||||
// 2) The source is a KnownOpenSSLAlgorithm is call, and we know we have an instance immediately from that
|
||||
// Possibility 1:
|
||||
this instanceof OpenSslAlgorithmLiteral and
|
||||
this instanceof Literal and
|
||||
exists(DataFlow::Node src, DataFlow::Node sink |
|
||||
// Sink is an argument to a CipherGetterCall
|
||||
sink = getterCall.getInputNode() and
|
||||
sink = getterCall.(OpenSSLAlgorithmValueConsumer).getInputNode() and
|
||||
// Source is `this`
|
||||
src.asExpr() = this and
|
||||
// This traces to a getter
|
||||
KnownOpenSslAlgorithmToAlgorithmValueConsumerFlow::flow(src, sink)
|
||||
KnownOpenSSLAlgorithmToAlgorithmValueConsumerFlow::flow(src, sink)
|
||||
)
|
||||
or
|
||||
// Possibility 2:
|
||||
this instanceof OpenSslAlgorithmCall and
|
||||
getterCall = this
|
||||
this instanceof DirectAlgorithmValueConsumer and getterCall = this
|
||||
}
|
||||
|
||||
override Crypto::TBlockCipherModeOfOperationType getModeType() {
|
||||
knownOpenSslConstantToBlockModeFamilyType(this, result)
|
||||
knownOpenSSLConstantToBlockModeFamilyType(this, result)
|
||||
or
|
||||
not knownOpenSslConstantToBlockModeFamilyType(this, _) and result = Crypto::OtherMode()
|
||||
not knownOpenSSLConstantToBlockModeFamilyType(this, _) and result = Crypto::OtherMode()
|
||||
}
|
||||
|
||||
// NOTE: I'm not going to attempt to parse out the mode specific part, so returning
|
||||
// the same as the raw name for now.
|
||||
override string getRawModeAlgorithmName() {
|
||||
result = this.(Literal).getValue().toString()
|
||||
or
|
||||
result = this.(Call).getTarget().getName()
|
||||
}
|
||||
override string getRawModeAlgorithmName() { result = this.(Literal).getValue().toString() }
|
||||
|
||||
override OpenSslAlgorithmValueConsumer getAvc() { result = getterCall }
|
||||
override OpenSSLAlgorithmValueConsumer getAVC() { result = getterCall }
|
||||
}
|
||||
|
||||
@@ -1,23 +1,22 @@
|
||||
import cpp
|
||||
private import experimental.quantum.Language
|
||||
private import KnownAlgorithmConstants
|
||||
private import Crypto::KeyOpAlg as KeyOpAlg
|
||||
private import OpenSSLAlgorithmInstanceBase
|
||||
private import PaddingAlgorithmInstance
|
||||
private import experimental.quantum.OpenSSL.AlgorithmValueConsumers.OpenSSLAlgorithmValueConsumerBase
|
||||
private import experimental.quantum.OpenSSL.AlgorithmValueConsumers.DirectAlgorithmValueConsumer
|
||||
private import AlgToAVCFlow
|
||||
private import BlockAlgorithmInstance
|
||||
import experimental.quantum.Language
|
||||
import KnownAlgorithmConstants
|
||||
import Crypto::KeyOpAlg as KeyOpAlg
|
||||
import OpenSSLAlgorithmInstanceBase
|
||||
import PaddingAlgorithmInstance
|
||||
import experimental.quantum.OpenSSL.AlgorithmValueConsumers.OpenSSLAlgorithmValueConsumers
|
||||
import AlgToAVCFlow
|
||||
import BlockAlgorithmInstance
|
||||
|
||||
/**
|
||||
* Given a `KnownOpenSslCipherAlgorithmExpr`, converts this to a cipher family type.
|
||||
* Does not bind if there is no mapping (no mapping to 'unknown' or 'other').
|
||||
* Given a `KnownOpenSSLCipherAlgorithmConstant`, converts this to a cipher family type.
|
||||
* Does not bind if there is know mapping (no mapping to 'unknown' or 'other').
|
||||
*/
|
||||
predicate knownOpenSslConstantToCipherFamilyType(
|
||||
KnownOpenSslCipherAlgorithmExpr e, Crypto::KeyOpAlg::TAlgorithm type
|
||||
predicate knownOpenSSLConstantToCipherFamilyType(
|
||||
KnownOpenSSLCipherAlgorithmConstant e, Crypto::KeyOpAlg::TAlgorithm type
|
||||
) {
|
||||
exists(string name |
|
||||
name = e.(KnownOpenSslAlgorithmExpr).getNormalizedName() and
|
||||
name = e.getNormalizedName() and
|
||||
(
|
||||
name.matches("AES%") and type = KeyOpAlg::TSymmetricCipher(KeyOpAlg::AES())
|
||||
or
|
||||
@@ -64,29 +63,28 @@ predicate knownOpenSslConstantToCipherFamilyType(
|
||||
)
|
||||
}
|
||||
|
||||
class KnownOpenSslCipherConstantAlgorithmInstance extends OpenSslAlgorithmInstance,
|
||||
Crypto::KeyOperationAlgorithmInstance instanceof KnownOpenSslCipherAlgorithmExpr
|
||||
class KnownOpenSSLCipherConstantAlgorithmInstance extends OpenSSLAlgorithmInstance,
|
||||
Crypto::KeyOperationAlgorithmInstance instanceof KnownOpenSSLCipherAlgorithmConstant
|
||||
{
|
||||
OpenSslAlgorithmValueConsumer getterCall;
|
||||
OpenSSLAlgorithmValueConsumer getterCall;
|
||||
|
||||
KnownOpenSslCipherConstantAlgorithmInstance() {
|
||||
KnownOpenSSLCipherConstantAlgorithmInstance() {
|
||||
// Two possibilities:
|
||||
// 1) The source is a literal and flows to a getter, then we know we have an instance
|
||||
// 2) The source is a KnownOpenSslAlgorithm is call, and we know we have an instance immediately from that
|
||||
// 2) The source is a KnownOpenSSLAlgorithm is call, and we know we have an instance immediately from that
|
||||
// Possibility 1:
|
||||
this instanceof OpenSslAlgorithmLiteral and
|
||||
this instanceof Literal and
|
||||
exists(DataFlow::Node src, DataFlow::Node sink |
|
||||
// Sink is an argument to a CipherGetterCall
|
||||
sink = getterCall.getInputNode() and
|
||||
sink = getterCall.(OpenSSLAlgorithmValueConsumer).getInputNode() and
|
||||
// Source is `this`
|
||||
src.asExpr() = this and
|
||||
// This traces to a getter
|
||||
KnownOpenSslAlgorithmToAlgorithmValueConsumerFlow::flow(src, sink)
|
||||
KnownOpenSSLAlgorithmToAlgorithmValueConsumerFlow::flow(src, sink)
|
||||
)
|
||||
or
|
||||
// Possibility 2:
|
||||
this instanceof OpenSslAlgorithmCall and
|
||||
getterCall = this
|
||||
this instanceof DirectAlgorithmValueConsumer and getterCall = this
|
||||
}
|
||||
|
||||
override Crypto::ModeOfOperationAlgorithmInstance getModeOfOperationAlgorithm() {
|
||||
@@ -103,24 +101,23 @@ class KnownOpenSslCipherConstantAlgorithmInstance extends OpenSslAlgorithmInstan
|
||||
// TODO or trace through getter ctx to set padding
|
||||
}
|
||||
|
||||
override string getRawAlgorithmName() {
|
||||
result = this.(Literal).getValue().toString()
|
||||
or
|
||||
result = this.(Call).getTarget().getName()
|
||||
}
|
||||
override string getRawAlgorithmName() { result = this.(Literal).getValue().toString() }
|
||||
|
||||
override int getKeySizeFixed() {
|
||||
this.(KnownOpenSslCipherAlgorithmExpr).getExplicitKeySize() = result
|
||||
override string getKeySizeFixed() {
|
||||
exists(int keySize |
|
||||
this.(KnownOpenSSLCipherAlgorithmConstant).getExplicitKeySize() = keySize and
|
||||
result = keySize.toString()
|
||||
)
|
||||
}
|
||||
|
||||
override Crypto::KeyOpAlg::Algorithm getAlgorithmType() {
|
||||
knownOpenSslConstantToCipherFamilyType(this, result)
|
||||
knownOpenSSLConstantToCipherFamilyType(this, result)
|
||||
or
|
||||
not knownOpenSslConstantToCipherFamilyType(this, _) and
|
||||
not knownOpenSSLConstantToCipherFamilyType(this, _) and
|
||||
result = Crypto::KeyOpAlg::TUnknownKeyOperationAlgorithmType()
|
||||
}
|
||||
|
||||
override OpenSslAlgorithmValueConsumer getAvc() { result = getterCall }
|
||||
override OpenSSLAlgorithmValueConsumer getAVC() { result = getterCall }
|
||||
|
||||
override Crypto::ConsumerInputDataFlowNode getKeySizeConsumer() {
|
||||
// TODO: trace to any key size initializer, symmetric and asymmetric
|
||||
|
||||
@@ -1,54 +0,0 @@
|
||||
import cpp
|
||||
private import experimental.quantum.Language
|
||||
private import KnownAlgorithmConstants
|
||||
private import OpenSSLAlgorithmInstanceBase
|
||||
private import experimental.quantum.OpenSSL.AlgorithmValueConsumers.OpenSSLAlgorithmValueConsumerBase
|
||||
private import experimental.quantum.OpenSSL.AlgorithmValueConsumers.DirectAlgorithmValueConsumer
|
||||
private import AlgToAVCFlow
|
||||
|
||||
class KnownOpenSslEllipticCurveConstantAlgorithmInstance extends OpenSslAlgorithmInstance,
|
||||
Crypto::EllipticCurveInstance instanceof KnownOpenSslEllipticCurveAlgorithmExpr
|
||||
{
|
||||
OpenSslAlgorithmValueConsumer getterCall;
|
||||
|
||||
KnownOpenSslEllipticCurveConstantAlgorithmInstance() {
|
||||
// Two possibilities:
|
||||
// 1) The source is a literal and flows to a getter, then we know we have an instance
|
||||
// 2) The source is a KnownOpenSslAlgorithm is call, and we know we have an instance immediately from that
|
||||
// Possibility 1:
|
||||
this instanceof OpenSslAlgorithmLiteral and
|
||||
exists(DataFlow::Node src, DataFlow::Node sink |
|
||||
// Sink is an argument to a CipherGetterCall
|
||||
sink = getterCall.getInputNode() and
|
||||
// Source is `this`
|
||||
src.asExpr() = this and
|
||||
// This traces to a getter
|
||||
KnownOpenSslAlgorithmToAlgorithmValueConsumerFlow::flow(src, sink)
|
||||
)
|
||||
or
|
||||
// Possibility 2:
|
||||
this instanceof OpenSslAlgorithmCall and
|
||||
getterCall = this
|
||||
}
|
||||
|
||||
override OpenSslAlgorithmValueConsumer getAvc() { result = getterCall }
|
||||
|
||||
override string getRawEllipticCurveName() {
|
||||
result = this.(Literal).getValue().toString()
|
||||
or
|
||||
result = this.(Call).getTarget().getName()
|
||||
}
|
||||
|
||||
override Crypto::TEllipticCurveType getEllipticCurveType() {
|
||||
Crypto::ellipticCurveNameToKeySizeAndFamilyMapping(this.getParsedEllipticCurveName(), _, result)
|
||||
}
|
||||
|
||||
override string getParsedEllipticCurveName() {
|
||||
result = this.(KnownOpenSslAlgorithmExpr).getNormalizedName()
|
||||
}
|
||||
|
||||
override int getKeySize() {
|
||||
Crypto::ellipticCurveNameToKeySizeAndFamilyMapping(this.(KnownOpenSslAlgorithmExpr)
|
||||
.getNormalizedName(), result, _)
|
||||
}
|
||||
}
|
||||
@@ -1,15 +1,14 @@
|
||||
import cpp
|
||||
private import experimental.quantum.Language
|
||||
private import KnownAlgorithmConstants
|
||||
private import experimental.quantum.OpenSSL.AlgorithmValueConsumers.OpenSSLAlgorithmValueConsumers
|
||||
private import experimental.quantum.OpenSSL.AlgorithmInstances.OpenSSLAlgorithmInstanceBase
|
||||
private import AlgToAVCFlow
|
||||
import experimental.quantum.Language
|
||||
import KnownAlgorithmConstants
|
||||
import experimental.quantum.OpenSSL.AlgorithmValueConsumers.OpenSSLAlgorithmValueConsumers
|
||||
import AlgToAVCFlow
|
||||
|
||||
predicate knownOpenSslConstantToHashFamilyType(
|
||||
KnownOpenSslHashAlgorithmExpr e, Crypto::THashType type
|
||||
predicate knownOpenSSLConstantToHashFamilyType(
|
||||
KnownOpenSSLHashAlgorithmConstant e, Crypto::THashType type
|
||||
) {
|
||||
exists(string name |
|
||||
name = e.(KnownOpenSslAlgorithmExpr).getNormalizedName() and
|
||||
name = e.getNormalizedName() and
|
||||
(
|
||||
name.matches("BLAKE2B") and type instanceof Crypto::BLAKE2B
|
||||
or
|
||||
@@ -29,7 +28,7 @@ predicate knownOpenSslConstantToHashFamilyType(
|
||||
or
|
||||
name.matches(["SHA", "SHA1"]) and type instanceof Crypto::SHA1
|
||||
or
|
||||
name.matches("SHA_%") and not name.matches(["SHA1", "SHA3-"]) and type instanceof Crypto::SHA2
|
||||
name.matches("SHA+%") and not name.matches(["SHA1", "SHA3-"]) and type instanceof Crypto::SHA2
|
||||
or
|
||||
name.matches("SHA3-%") and type instanceof Crypto::SHA3
|
||||
or
|
||||
@@ -44,46 +43,41 @@ predicate knownOpenSslConstantToHashFamilyType(
|
||||
)
|
||||
}
|
||||
|
||||
class KnownOpenSslHashConstantAlgorithmInstance extends OpenSslAlgorithmInstance,
|
||||
Crypto::HashAlgorithmInstance instanceof KnownOpenSslHashAlgorithmExpr
|
||||
class KnownOpenSSLHashConstantAlgorithmInstance extends OpenSSLAlgorithmInstance,
|
||||
Crypto::HashAlgorithmInstance instanceof KnownOpenSSLHashAlgorithmConstant
|
||||
{
|
||||
OpenSslAlgorithmValueConsumer getterCall;
|
||||
OpenSSLAlgorithmValueConsumer getterCall;
|
||||
|
||||
KnownOpenSslHashConstantAlgorithmInstance() {
|
||||
KnownOpenSSLHashConstantAlgorithmInstance() {
|
||||
// Two possibilities:
|
||||
// 1) The source is a literal and flows to a getter, then we know we have an instance
|
||||
// 2) The source is a KnownOpenSslAlgorithm is call, and we know we have an instance immediately from that
|
||||
// 2) The source is a KnownOpenSSLAlgorithm is call, and we know we have an instance immediately from that
|
||||
// Possibility 1:
|
||||
this instanceof OpenSslAlgorithmLiteral and
|
||||
this instanceof Literal and
|
||||
exists(DataFlow::Node src, DataFlow::Node sink |
|
||||
// Sink is an argument to a CipherGetterCall
|
||||
sink = getterCall.getInputNode() and
|
||||
sink = getterCall.(OpenSSLAlgorithmValueConsumer).getInputNode() and
|
||||
// Source is `this`
|
||||
src.asExpr() = this and
|
||||
// This traces to a getter
|
||||
KnownOpenSslAlgorithmToAlgorithmValueConsumerFlow::flow(src, sink)
|
||||
KnownOpenSSLAlgorithmToAlgorithmValueConsumerFlow::flow(src, sink)
|
||||
)
|
||||
or
|
||||
// Possibility 2:
|
||||
this instanceof OpenSslAlgorithmCall and
|
||||
getterCall = this
|
||||
this instanceof DirectAlgorithmValueConsumer and getterCall = this
|
||||
}
|
||||
|
||||
override OpenSslAlgorithmValueConsumer getAvc() { result = getterCall }
|
||||
override OpenSSLAlgorithmValueConsumer getAVC() { result = getterCall }
|
||||
|
||||
override Crypto::THashType getHashFamily() {
|
||||
knownOpenSslConstantToHashFamilyType(this, result)
|
||||
knownOpenSSLConstantToHashFamilyType(this, result)
|
||||
or
|
||||
not knownOpenSslConstantToHashFamilyType(this, _) and result = Crypto::OtherHashType()
|
||||
not knownOpenSSLConstantToHashFamilyType(this, _) and result = Crypto::OtherHashType()
|
||||
}
|
||||
|
||||
override string getRawHashAlgorithmName() {
|
||||
result = this.(Literal).getValue().toString()
|
||||
or
|
||||
result = this.(Call).getTarget().getName()
|
||||
}
|
||||
override string getRawHashAlgorithmName() { result = this.(Literal).getValue().toString() }
|
||||
|
||||
override int getFixedDigestLength() {
|
||||
this.(KnownOpenSslHashAlgorithmExpr).getExplicitDigestLength() = result
|
||||
this.(KnownOpenSSLHashAlgorithmConstant).getExplicitDigestLength() = result
|
||||
}
|
||||
}
|
||||
|
||||
@@ -1,64 +0,0 @@
|
||||
import cpp
|
||||
private import experimental.quantum.Language
|
||||
private import KnownAlgorithmConstants
|
||||
private import experimental.quantum.OpenSSL.AlgorithmValueConsumers.OpenSSLAlgorithmValueConsumers
|
||||
private import experimental.quantum.OpenSSL.AlgorithmInstances.OpenSSLAlgorithmInstanceBase
|
||||
private import AlgToAVCFlow
|
||||
|
||||
predicate knownOpenSslConstantToKeyAgreementFamilyType(
|
||||
KnownOpenSslKeyAgreementAlgorithmExpr e, Crypto::TKeyAgreementType type
|
||||
) {
|
||||
exists(string name |
|
||||
name = e.(KnownOpenSslAlgorithmExpr).getNormalizedName() and
|
||||
(
|
||||
name = "ECDH" and type = Crypto::ECDH()
|
||||
or
|
||||
name = "DH" and type = Crypto::DH()
|
||||
or
|
||||
name = "EDH" and type = Crypto::EDH()
|
||||
or
|
||||
name = "ESDH" and type = Crypto::EDH()
|
||||
)
|
||||
)
|
||||
}
|
||||
|
||||
class KnownOpenSslKeyAgreementConstantAlgorithmInstance extends OpenSslAlgorithmInstance,
|
||||
Crypto::KeyAgreementAlgorithmInstance instanceof KnownOpenSslKeyAgreementAlgorithmExpr
|
||||
{
|
||||
OpenSslAlgorithmValueConsumer getterCall;
|
||||
|
||||
KnownOpenSslKeyAgreementConstantAlgorithmInstance() {
|
||||
// Two possibilities:
|
||||
// 1) The source is a literal and flows to a getter, then we know we have an instance
|
||||
// 2) The source is a KnownOpenSslAlgorithm is call, and we know we have an instance immediately from that
|
||||
// Possibility 1:
|
||||
this instanceof OpenSslAlgorithmLiteral and
|
||||
exists(DataFlow::Node src, DataFlow::Node sink |
|
||||
// Sink is an argument to a CipherGetterCall
|
||||
sink = getterCall.getInputNode() and
|
||||
// Source is `this`
|
||||
src.asExpr() = this and
|
||||
// This traces to a getter
|
||||
KnownOpenSslAlgorithmToAlgorithmValueConsumerFlow::flow(src, sink)
|
||||
)
|
||||
or
|
||||
// Possibility 2:
|
||||
this instanceof OpenSslAlgorithmCall and
|
||||
getterCall = this
|
||||
}
|
||||
|
||||
override OpenSslAlgorithmValueConsumer getAvc() { result = getterCall }
|
||||
|
||||
override Crypto::TKeyAgreementType getKeyAgreementType() {
|
||||
knownOpenSslConstantToKeyAgreementFamilyType(this, result)
|
||||
or
|
||||
not knownOpenSslConstantToKeyAgreementFamilyType(this, _) and
|
||||
result = Crypto::OtherKeyAgreementType()
|
||||
}
|
||||
|
||||
override string getRawKeyAgreementAlgorithmName() {
|
||||
result = this.(Literal).getValue().toString()
|
||||
or
|
||||
result = this.(Call).getTarget().getName()
|
||||
}
|
||||
}
|
||||
File diff suppressed because it is too large
Load Diff
@@ -1,66 +0,0 @@
|
||||
import cpp
|
||||
private import experimental.quantum.Language
|
||||
private import KnownAlgorithmConstants
|
||||
private import experimental.quantum.OpenSSL.AlgorithmValueConsumers.OpenSSLAlgorithmValueConsumers
|
||||
private import experimental.quantum.OpenSSL.AlgorithmInstances.OpenSSLAlgorithmInstanceBase
|
||||
private import experimental.quantum.OpenSSL.Operations.OpenSSLOperations
|
||||
private import AlgToAVCFlow
|
||||
|
||||
class KnownOpenSslMacConstantAlgorithmInstance extends OpenSslAlgorithmInstance,
|
||||
Crypto::MACAlgorithmInstance instanceof KnownOpenSslMacAlgorithmExpr
|
||||
{
|
||||
OpenSslAlgorithmValueConsumer getterCall;
|
||||
|
||||
KnownOpenSslMacConstantAlgorithmInstance() {
|
||||
// Two possibilities:
|
||||
// 1) The source is a literal and flows to a getter, then we know we have an instance
|
||||
// 2) The source is a KnownOpenSslAlgorithm is call, and we know we have an instance immediately from that
|
||||
// Possibility 1:
|
||||
this instanceof OpenSslAlgorithmLiteral and
|
||||
exists(DataFlow::Node src, DataFlow::Node sink |
|
||||
// Sink is an argument to a CipherGetterCall
|
||||
sink = getterCall.getInputNode() and
|
||||
// Source is `this`
|
||||
src.asExpr() = this and
|
||||
// This traces to a getter
|
||||
KnownOpenSslAlgorithmToAlgorithmValueConsumerFlow::flow(src, sink)
|
||||
)
|
||||
or
|
||||
// Possibility 2:
|
||||
this instanceof OpenSslAlgorithmCall and
|
||||
getterCall = this
|
||||
}
|
||||
|
||||
override OpenSslAlgorithmValueConsumer getAvc() { result = getterCall }
|
||||
|
||||
override string getRawMacAlgorithmName() {
|
||||
result = this.(Literal).getValue().toString()
|
||||
or
|
||||
result = this.(Call).getTarget().getName()
|
||||
}
|
||||
|
||||
override Crypto::TMACType getMacType() {
|
||||
this instanceof KnownOpenSslHMacAlgorithmExpr and result instanceof Crypto::THMAC
|
||||
or
|
||||
this instanceof KnownOpenSslCMacAlgorithmExpr and result instanceof Crypto::TCMAC
|
||||
}
|
||||
}
|
||||
|
||||
class KnownOpenSslHMacConstantAlgorithmInstance extends Crypto::HMACAlgorithmInstance,
|
||||
KnownOpenSslMacConstantAlgorithmInstance
|
||||
{
|
||||
override Crypto::AlgorithmValueConsumer getHashAlgorithmValueConsumer() {
|
||||
if exists(this.(KnownOpenSslHMacAlgorithmExpr).getExplicitHashAlgorithm())
|
||||
then
|
||||
// ASSUMPTION: if there is an explicit hash algorithm, it is already modeled
|
||||
// and we can simply grab that model's AVC
|
||||
exists(OpenSslAlgorithmInstance inst | inst.getAvc() = result and inst = this)
|
||||
else
|
||||
// ASSUMPTION: If no explicit algorithm is given, then it is assumed to be configured by
|
||||
// a signature operation
|
||||
exists(Crypto::SignatureOperationInstance s |
|
||||
s.getHashAlgorithmValueConsumer() = result and
|
||||
s.getAnAlgorithmValueConsumer() = this.getAvc()
|
||||
)
|
||||
}
|
||||
}
|
||||
@@ -1,6 +1,6 @@
|
||||
private import experimental.quantum.Language
|
||||
private import experimental.quantum.OpenSSL.AlgorithmValueConsumers.OpenSSLAlgorithmValueConsumerBase
|
||||
import experimental.quantum.Language
|
||||
import experimental.quantum.OpenSSL.AlgorithmValueConsumers.OpenSSLAlgorithmValueConsumerBase
|
||||
|
||||
abstract class OpenSslAlgorithmInstance extends Crypto::AlgorithmInstance {
|
||||
abstract OpenSslAlgorithmValueConsumer getAvc();
|
||||
abstract class OpenSSLAlgorithmInstance extends Crypto::AlgorithmInstance {
|
||||
abstract OpenSSLAlgorithmValueConsumer getAVC();
|
||||
}
|
||||
|
||||
@@ -3,6 +3,3 @@ import CipherAlgorithmInstance
|
||||
import PaddingAlgorithmInstance
|
||||
import BlockAlgorithmInstance
|
||||
import HashAlgorithmInstance
|
||||
import EllipticCurveAlgorithmInstance
|
||||
import SignatureAlgorithmInstance
|
||||
import MACAlgorithmInstance
|
||||
|
||||
@@ -1,37 +1,19 @@
|
||||
import cpp
|
||||
private import experimental.quantum.Language
|
||||
private import OpenSSLAlgorithmInstanceBase
|
||||
private import experimental.quantum.OpenSSL.AlgorithmInstances.KnownAlgorithmConstants
|
||||
private import AlgToAVCFlow
|
||||
private import experimental.quantum.OpenSSL.AlgorithmValueConsumers.DirectAlgorithmValueConsumer
|
||||
private import experimental.quantum.OpenSSL.AlgorithmValueConsumers.OpenSSLAlgorithmValueConsumerBase
|
||||
import experimental.quantum.Language
|
||||
import OpenSSLAlgorithmInstanceBase
|
||||
import experimental.quantum.OpenSSL.AlgorithmInstances.KnownAlgorithmConstants
|
||||
import AlgToAVCFlow
|
||||
import experimental.quantum.OpenSSL.AlgorithmValueConsumers.DirectAlgorithmValueConsumer
|
||||
|
||||
/**
|
||||
* A class to define padding specific integer values.
|
||||
* from rsa.h in openssl:
|
||||
* # define RSA_PKCS1_PADDING 1
|
||||
* # define RSA_NO_PADDING 3
|
||||
* # define RSA_PKCS1_OAEP_PADDING 4
|
||||
* # define RSA_X931_PADDING 5
|
||||
* # define RSA_PKCS1_PSS_PADDING 6
|
||||
* # define RSA_PKCS1_WITH_TLS_PADDING 7
|
||||
* # define RSA_PKCS1_NO_IMPLICIT_REJECT_PADDING 8
|
||||
* Given a `KnownOpenSSLPaddingAlgorithmConstant`, converts this to a padding family type.
|
||||
* Does not bind if there is know mapping (no mapping to 'unknown' or 'other').
|
||||
*/
|
||||
class OpenSslPaddingLiteral extends Literal {
|
||||
// TODO: we can be more specific about where the literal is in a larger expression
|
||||
// to avoid literals that are clealy not representing an algorithm, e.g., array indices.
|
||||
OpenSslPaddingLiteral() { this.getValue().toInt() in [0, 1, 3, 4, 5, 6, 7, 8] }
|
||||
}
|
||||
|
||||
/**
|
||||
* Given a `KnownOpenSslPaddingAlgorithmExpr`, converts this to a padding family type.
|
||||
* Does not bind if there is no mapping (no mapping to 'unknown' or 'other').
|
||||
*/
|
||||
predicate knownOpenSslConstantToPaddingFamilyType(
|
||||
KnownOpenSslPaddingAlgorithmExpr e, Crypto::TPaddingType type
|
||||
predicate knownOpenSSLConstantToPaddingFamilyType(
|
||||
KnownOpenSSLPaddingAlgorithmConstant e, Crypto::TPaddingType type
|
||||
) {
|
||||
exists(string name |
|
||||
name = e.(KnownOpenSslAlgorithmExpr).getNormalizedName() and
|
||||
name = e.getNormalizedName() and
|
||||
(
|
||||
name.matches("OAEP") and type = Crypto::OAEP()
|
||||
or
|
||||
@@ -44,44 +26,55 @@ predicate knownOpenSslConstantToPaddingFamilyType(
|
||||
)
|
||||
}
|
||||
|
||||
//abstract class OpenSslPaddingAlgorithmInstance extends OpenSslAlgorithmInstance, Crypto::PaddingAlgorithmInstance{}
|
||||
//abstract class OpenSSLPaddingAlgorithmInstance extends OpenSSLAlgorithmInstance, Crypto::PaddingAlgorithmInstance{}
|
||||
// TODO: need to alter this to include known padding constants which don't have the
|
||||
// same mechanics as those with known nids
|
||||
class KnownOpenSslPaddingConstantAlgorithmInstance extends OpenSslAlgorithmInstance,
|
||||
class KnownOpenSSLPaddingConstantAlgorithmInstance extends OpenSSLAlgorithmInstance,
|
||||
Crypto::PaddingAlgorithmInstance instanceof Expr
|
||||
{
|
||||
OpenSslAlgorithmValueConsumer getterCall;
|
||||
OpenSSLAlgorithmValueConsumer getterCall;
|
||||
boolean isPaddingSpecificConsumer;
|
||||
|
||||
KnownOpenSslPaddingConstantAlgorithmInstance() {
|
||||
KnownOpenSSLPaddingConstantAlgorithmInstance() {
|
||||
// three possibilities:
|
||||
// 1) The source is a 'typical' literal and flows to a getter, then we know we have an instance
|
||||
// 2) The source is a KnownOpenSslAlgorithm is call, and we know we have an instance immediately from that
|
||||
// 2) The source is a KnownOpenSSLAlgorithm is call, and we know we have an instance immediately from that
|
||||
// 3) the source is a padding-specific literal flowing to a padding-specific consumer
|
||||
// Possibility 1:
|
||||
this instanceof OpenSslAlgorithmLiteral and
|
||||
this instanceof KnownOpenSslPaddingAlgorithmExpr and
|
||||
this instanceof Literal and
|
||||
this instanceof KnownOpenSSLPaddingAlgorithmConstant and
|
||||
exists(DataFlow::Node src, DataFlow::Node sink |
|
||||
// Sink is an argument to a CipherGetterCall
|
||||
sink = getterCall.getInputNode() and
|
||||
sink = getterCall.(OpenSSLAlgorithmValueConsumer).getInputNode() and
|
||||
// Source is `this`
|
||||
src.asExpr() = this and
|
||||
// This traces to a getter
|
||||
KnownOpenSslAlgorithmToAlgorithmValueConsumerFlow::flow(src, sink) and
|
||||
KnownOpenSSLAlgorithmToAlgorithmValueConsumerFlow::flow(src, sink) and
|
||||
isPaddingSpecificConsumer = false
|
||||
)
|
||||
or
|
||||
// Possibility 2:
|
||||
this instanceof OpenSslAlgorithmCall and
|
||||
this instanceof DirectAlgorithmValueConsumer and
|
||||
getterCall = this and
|
||||
this instanceof KnownOpenSslPaddingAlgorithmExpr and
|
||||
this instanceof KnownOpenSSLPaddingAlgorithmConstant and
|
||||
isPaddingSpecificConsumer = false
|
||||
or
|
||||
// Possibility 3: padding-specific literal
|
||||
this instanceof OpenSslPaddingLiteral and
|
||||
// Possibility 3:
|
||||
// from rsa.h in openssl:
|
||||
// # define RSA_PKCS1_PADDING 1
|
||||
// # define RSA_NO_PADDING 3
|
||||
// # define RSA_PKCS1_OAEP_PADDING 4
|
||||
// # define RSA_X931_PADDING 5
|
||||
// /* EVP_PKEY_ only */
|
||||
// # define RSA_PKCS1_PSS_PADDING 6
|
||||
// # define RSA_PKCS1_WITH_TLS_PADDING 7
|
||||
// /* internal RSA_ only */
|
||||
// # define RSA_PKCS1_NO_IMPLICIT_REJECT_PADDING 8
|
||||
this instanceof Literal and
|
||||
this.getValue().toInt() in [0, 1, 3, 4, 5, 6, 7, 8] and
|
||||
exists(DataFlow::Node src, DataFlow::Node sink |
|
||||
// Sink is an argument to a CipherGetterCall
|
||||
sink = getterCall.getInputNode() and
|
||||
sink = getterCall.(OpenSSLAlgorithmValueConsumer).getInputNode() and
|
||||
// Source is `this`
|
||||
src.asExpr() = this and
|
||||
// This traces to a padding-specific consumer
|
||||
@@ -90,36 +83,32 @@ class KnownOpenSslPaddingConstantAlgorithmInstance extends OpenSslAlgorithmInsta
|
||||
isPaddingSpecificConsumer = true
|
||||
}
|
||||
|
||||
override string getRawPaddingAlgorithmName() {
|
||||
result = this.(Literal).getValue().toString()
|
||||
or
|
||||
result = this.(Call).getTarget().getName()
|
||||
}
|
||||
override string getRawPaddingAlgorithmName() { result = this.(Literal).getValue().toString() }
|
||||
|
||||
override OpenSslAlgorithmValueConsumer getAvc() { result = getterCall }
|
||||
|
||||
Crypto::TPaddingType getKnownPaddingType() {
|
||||
this.(Literal).getValue().toInt() in [1, 7, 8] and result = Crypto::PKCS1_v1_5()
|
||||
or
|
||||
this.(Literal).getValue().toInt() = 3 and result = Crypto::NoPadding()
|
||||
or
|
||||
this.(Literal).getValue().toInt() = 4 and result = Crypto::OAEP()
|
||||
or
|
||||
this.(Literal).getValue().toInt() = 5 and result = Crypto::ANSI_X9_23()
|
||||
or
|
||||
this.(Literal).getValue().toInt() = 6 and result = Crypto::PSS()
|
||||
}
|
||||
override OpenSSLAlgorithmValueConsumer getAVC() { result = getterCall }
|
||||
|
||||
override Crypto::TPaddingType getPaddingType() {
|
||||
isPaddingSpecificConsumer = true and
|
||||
(
|
||||
result = this.getKnownPaddingType()
|
||||
or
|
||||
not exists(this.getKnownPaddingType()) and result = Crypto::OtherPadding()
|
||||
if this.(Literal).getValue().toInt() in [1, 7, 8]
|
||||
then result = Crypto::PKCS1_v1_5()
|
||||
else
|
||||
if this.(Literal).getValue().toInt() = 3
|
||||
then result = Crypto::NoPadding()
|
||||
else
|
||||
if this.(Literal).getValue().toInt() = 4
|
||||
then result = Crypto::OAEP()
|
||||
else
|
||||
if this.(Literal).getValue().toInt() = 5
|
||||
then result = Crypto::ANSI_X9_23()
|
||||
else
|
||||
if this.(Literal).getValue().toInt() = 6
|
||||
then result = Crypto::PSS()
|
||||
else result = Crypto::OtherPadding()
|
||||
)
|
||||
or
|
||||
isPaddingSpecificConsumer = false and
|
||||
knownOpenSslConstantToPaddingFamilyType(this, result)
|
||||
knownOpenSSLConstantToPaddingFamilyType(this, result)
|
||||
}
|
||||
}
|
||||
|
||||
@@ -127,7 +116,7 @@ class KnownOpenSslPaddingConstantAlgorithmInstance extends OpenSslAlgorithmInsta
|
||||
// // not the same as 'typical' constants found in the set of known algorithm constants
|
||||
// // they do not have an NID
|
||||
// // TODO: what about setting the padding directly?
|
||||
// class KnownRSAPaddingConstant extends OpenSslPaddingAlgorithmInstance, Crypto::PaddingAlgorithmInstance instanceof Literal
|
||||
// class KnownRSAPaddingConstant extends OpenSSLPaddingAlgorithmInstance, Crypto::PaddingAlgorithmInstance instanceof Literal
|
||||
// {
|
||||
// KnownRSAPaddingConstant() {
|
||||
// // from rsa.h in openssl:
|
||||
@@ -162,7 +151,7 @@ class KnownOpenSslPaddingConstantAlgorithmInstance extends OpenSslAlgorithmInsta
|
||||
// }
|
||||
// }
|
||||
class OAEPPaddingAlgorithmInstance extends Crypto::OAEPPaddingAlgorithmInstance,
|
||||
KnownOpenSslPaddingConstantAlgorithmInstance
|
||||
KnownOpenSSLPaddingConstantAlgorithmInstance
|
||||
{
|
||||
OAEPPaddingAlgorithmInstance() {
|
||||
this.(Crypto::PaddingAlgorithmInstance).getPaddingType() = Crypto::OAEP()
|
||||
|
||||
@@ -1,102 +0,0 @@
|
||||
import cpp
|
||||
private import experimental.quantum.Language
|
||||
private import KnownAlgorithmConstants
|
||||
private import Crypto::KeyOpAlg as KeyOpAlg
|
||||
private import OpenSSLAlgorithmInstanceBase
|
||||
private import experimental.quantum.OpenSSL.AlgorithmValueConsumers.OpenSSLAlgorithmValueConsumerBase
|
||||
private import experimental.quantum.OpenSSL.AlgorithmValueConsumers.DirectAlgorithmValueConsumer
|
||||
private import AlgToAVCFlow
|
||||
|
||||
/**
|
||||
* Gets the signature algorithm type based on the normalized algorithm name.
|
||||
*/
|
||||
private predicate knownOpenSslConstantToSignatureFamilyType(
|
||||
KnownOpenSslSignatureAlgorithmExpr e, Crypto::KeyOpAlg::TAlgorithm type
|
||||
) {
|
||||
exists(string name |
|
||||
name = e.(KnownOpenSslAlgorithmExpr).getNormalizedName() and
|
||||
(
|
||||
name.matches("RSA%") and type = KeyOpAlg::TAsymmetricCipher(KeyOpAlg::RSA())
|
||||
or
|
||||
name.matches("DSA%") and type = KeyOpAlg::TSignature(KeyOpAlg::DSA())
|
||||
or
|
||||
name.matches("ECDSA%") and type = KeyOpAlg::TSignature(KeyOpAlg::ECDSA())
|
||||
or
|
||||
name.matches("ED25519%") and type = KeyOpAlg::TSignature(KeyOpAlg::EDDSA())
|
||||
or
|
||||
name.matches("ED448%") and type = KeyOpAlg::TSignature(KeyOpAlg::EDDSA())
|
||||
)
|
||||
)
|
||||
}
|
||||
|
||||
/**
|
||||
* A signature algorithm instance derived from an OpenSsl constant.
|
||||
*/
|
||||
class KnownOpenSslSignatureConstantAlgorithmInstance extends OpenSslAlgorithmInstance,
|
||||
Crypto::KeyOperationAlgorithmInstance instanceof KnownOpenSslSignatureAlgorithmExpr
|
||||
{
|
||||
OpenSslAlgorithmValueConsumer getterCall;
|
||||
|
||||
KnownOpenSslSignatureConstantAlgorithmInstance() {
|
||||
// Two possibilities:
|
||||
// 1) The source is a literal and flows to a getter, then we know we have an instance
|
||||
// 2) The source is a KnownOpenSslAlgorithm call, and we know we have an instance immediately from that
|
||||
// Possibility 1:
|
||||
this instanceof OpenSslAlgorithmLiteral and
|
||||
exists(DataFlow::Node src, DataFlow::Node sink |
|
||||
// Sink is an argument to a signature getter call
|
||||
sink = getterCall.getInputNode() and
|
||||
// Source is `this`
|
||||
src.asExpr() = this and
|
||||
// This traces to a getter
|
||||
KnownOpenSslAlgorithmToAlgorithmValueConsumerFlow::flow(src, sink)
|
||||
)
|
||||
or
|
||||
// Possibility 2:
|
||||
this instanceof OpenSslAlgorithmCall and
|
||||
getterCall = this
|
||||
}
|
||||
|
||||
override Crypto::ModeOfOperationAlgorithmInstance getModeOfOperationAlgorithm() { none() }
|
||||
|
||||
override Crypto::PaddingAlgorithmInstance getPaddingAlgorithm() { none() }
|
||||
|
||||
override string getRawAlgorithmName() {
|
||||
result = this.(Literal).getValue().toString()
|
||||
or
|
||||
result = this.(Call).getTarget().getName()
|
||||
}
|
||||
|
||||
override int getKeySizeFixed() {
|
||||
// TODO: use ellipticCurveNameToKeySizeAndFamilyMapping or KnownOpenSslEllipticCurveConstantAlgorithmInstance
|
||||
// TODO: maybe add getExplicitKeySize to KnownOpenSslSignatureAlgorithmExpr and use it here
|
||||
none()
|
||||
}
|
||||
|
||||
override KeyOpAlg::Algorithm getAlgorithmType() {
|
||||
knownOpenSslConstantToSignatureFamilyType(this, result)
|
||||
or
|
||||
not knownOpenSslConstantToSignatureFamilyType(this, _) and
|
||||
result = KeyOpAlg::TSignature(KeyOpAlg::OtherSignatureAlgorithmType())
|
||||
}
|
||||
|
||||
override OpenSslAlgorithmValueConsumer getAvc() { result = getterCall }
|
||||
|
||||
override Crypto::ConsumerInputDataFlowNode getKeySizeConsumer() {
|
||||
// TODO: trace to any key size initializer
|
||||
// probably PKeyAlgorithmValueConsumer and SignatureAlgorithmValueConsumer
|
||||
none()
|
||||
}
|
||||
|
||||
/**
|
||||
* No mode for signatures.
|
||||
*/
|
||||
override predicate shouldHaveModeOfOperation() { none() }
|
||||
|
||||
/**
|
||||
* Padding only for RSA.
|
||||
*/
|
||||
override predicate shouldHavePaddingScheme() {
|
||||
this.getAlgorithmType() instanceof KeyOpAlg::TAsymmetricCipher
|
||||
}
|
||||
}
|
||||
@@ -1,18 +1,20 @@
|
||||
import cpp
|
||||
private import experimental.quantum.Language
|
||||
private import experimental.quantum.OpenSSL.AlgorithmInstances.KnownAlgorithmConstants
|
||||
private import experimental.quantum.OpenSSL.AlgorithmInstances.OpenSSLAlgorithmInstanceBase
|
||||
private import OpenSSLAlgorithmValueConsumerBase
|
||||
import experimental.quantum.Language
|
||||
import experimental.quantum.OpenSSL.LibraryDetector
|
||||
import experimental.quantum.OpenSSL.AlgorithmInstances.KnownAlgorithmConstants
|
||||
import experimental.quantum.OpenSSL.AlgorithmInstances.OpenSSLAlgorithmInstanceBase
|
||||
import OpenSSLAlgorithmValueConsumerBase
|
||||
|
||||
abstract class CipherAlgorithmValueConsumer extends OpenSslAlgorithmValueConsumer { }
|
||||
abstract class CipherAlgorithmValueConsumer extends OpenSSLAlgorithmValueConsumer { }
|
||||
|
||||
// https://www.openssl.org/docs/manmaster/man3/EVP_CIPHER_fetch.html
|
||||
class EvpCipherAlgorithmValueConsumer extends CipherAlgorithmValueConsumer {
|
||||
class EVPCipherAlgorithmValueConsumer extends CipherAlgorithmValueConsumer {
|
||||
DataFlow::Node valueArgNode;
|
||||
DataFlow::Node resultNode;
|
||||
|
||||
EvpCipherAlgorithmValueConsumer() {
|
||||
EVPCipherAlgorithmValueConsumer() {
|
||||
resultNode.asExpr() = this and
|
||||
isPossibleOpenSSLFunction(this.(Call).getTarget()) and
|
||||
(
|
||||
this.(Call).getTarget().getName() in [
|
||||
"EVP_get_cipherbyname", "EVP_get_cipherbyobj", "EVP_get_cipherbynid"
|
||||
@@ -30,8 +32,8 @@ class EvpCipherAlgorithmValueConsumer extends CipherAlgorithmValueConsumer {
|
||||
|
||||
// override DataFlow::Node getInputNode() { result = valueArgNode }
|
||||
override Crypto::AlgorithmInstance getAKnownAlgorithmSource() {
|
||||
exists(OpenSslAlgorithmInstance i | i.getAvc() = this and result = i)
|
||||
//TODO: As a potential alternative, for OpenSsl only, add a generic source node for literals and only create flow (flowsTo) to
|
||||
// OpenSsl AVCs... the unknown literal sources would have to be any literals not in the known set.
|
||||
exists(OpenSSLAlgorithmInstance i | i.getAVC() = this and result = i)
|
||||
//TODO: As a potential alternative, for OpenSSL only, add a generic source node for literals and only create flow (flowsTo) to
|
||||
// OpenSSL AVCs... the unknown literal sources would have to be any literals not in the known set.
|
||||
}
|
||||
}
|
||||
|
||||
@@ -1,33 +1,33 @@
|
||||
import cpp
|
||||
private import experimental.quantum.Language
|
||||
private import experimental.quantum.OpenSSL.AlgorithmInstances.KnownAlgorithmConstants
|
||||
private import experimental.quantum.OpenSSL.AlgorithmValueConsumers.OpenSSLAlgorithmValueConsumerBase
|
||||
import experimental.quantum.Language
|
||||
import experimental.quantum.OpenSSL.AlgorithmInstances.KnownAlgorithmConstants
|
||||
import experimental.quantum.OpenSSL.AlgorithmValueConsumers.OpenSSLAlgorithmValueConsumerBase
|
||||
|
||||
// TODO: can self referential to itself, which is also an algorithm (Known algorithm)
|
||||
/**
|
||||
* Cases like EVP_MD5(),
|
||||
* there is no input, rather it directly gets an algorithm
|
||||
* and returns it.
|
||||
* Also includes operations directly using an algorithm
|
||||
* like AES_encrypt().
|
||||
*/
|
||||
class DirectAlgorithmValueConsumer extends OpenSslAlgorithmValueConsumer instanceof OpenSslAlgorithmCall
|
||||
{
|
||||
class DirectAlgorithmValueConsumer extends OpenSSLAlgorithmValueConsumer {
|
||||
DataFlow::Node resultNode;
|
||||
Expr resultExpr;
|
||||
|
||||
DirectAlgorithmValueConsumer() {
|
||||
this instanceof KnownOpenSSLAlgorithmConstant and
|
||||
this instanceof Call and
|
||||
resultExpr = this and
|
||||
resultNode.asExpr() = resultExpr
|
||||
}
|
||||
|
||||
/**
|
||||
* These cases take in no explicit value (the value is implicit)
|
||||
*/
|
||||
override Crypto::ConsumerInputDataFlowNode getInputNode() { none() }
|
||||
|
||||
/**
|
||||
* Gets the DataFlow node represeting the output algorithm entity
|
||||
* created as a result of this call.
|
||||
*/
|
||||
override DataFlow::Node getResultNode() {
|
||||
this instanceof OpenSslDirectAlgorithmFetchCall and
|
||||
result.asExpr() = this
|
||||
// NOTE: if instanceof OpenSslDirectAlgorithmOperationCall then there is no algorithm generated
|
||||
// the algorithm is directly used
|
||||
}
|
||||
override DataFlow::Node getResultNode() { result = resultNode }
|
||||
|
||||
// override DataFlow::Node getOutputNode() { result = resultNode }
|
||||
override Crypto::AlgorithmInstance getAKnownAlgorithmSource() {
|
||||
// Note: algorithm source definitions enforces that
|
||||
// this class will be a known algorithm source
|
||||
|
||||
@@ -1,34 +0,0 @@
|
||||
import cpp
|
||||
private import experimental.quantum.Language
|
||||
private import experimental.quantum.OpenSSL.AlgorithmInstances.KnownAlgorithmConstants
|
||||
private import experimental.quantum.OpenSSL.AlgorithmValueConsumers.OpenSSLAlgorithmValueConsumerBase
|
||||
private import experimental.quantum.OpenSSL.AlgorithmInstances.OpenSSLAlgorithmInstances
|
||||
|
||||
abstract class EllipticCurveValueConsumer extends OpenSslAlgorithmValueConsumer { }
|
||||
|
||||
//https://docs.openssl.org/3.0/man3/EC_KEY_new/#name
|
||||
class EvpEllipticCurveAlgorithmConsumer extends EllipticCurveValueConsumer {
|
||||
DataFlow::Node valueArgNode;
|
||||
DataFlow::Node resultNode;
|
||||
|
||||
EvpEllipticCurveAlgorithmConsumer() {
|
||||
resultNode.asExpr() = this.(Call) and // in all cases the result is the return
|
||||
(
|
||||
this.(Call).getTarget().getName() in ["EVP_EC_gen", "EC_KEY_new_by_curve_name"] and
|
||||
valueArgNode.asExpr() = this.(Call).getArgument(0)
|
||||
or
|
||||
this.(Call).getTarget().getName() in [
|
||||
"EC_KEY_new_by_curve_name_ex", "EVP_PKEY_CTX_set_ec_paramgen_curve_nid"
|
||||
] and
|
||||
valueArgNode.asExpr() = this.(Call).getArgument(2)
|
||||
)
|
||||
}
|
||||
|
||||
override Crypto::AlgorithmInstance getAKnownAlgorithmSource() {
|
||||
exists(OpenSslAlgorithmInstance i | i.getAvc() = this and result = i)
|
||||
}
|
||||
|
||||
override DataFlow::Node getResultNode() { result = resultNode }
|
||||
|
||||
override Crypto::ConsumerInputDataFlowNode getInputNode() { result = valueArgNode }
|
||||
}
|
||||
@@ -1,23 +1,30 @@
|
||||
// import EVPHashInitializer
|
||||
// import EVPHashOperation
|
||||
// import EVPHashAlgorithmSource
|
||||
import cpp
|
||||
private import experimental.quantum.Language
|
||||
private import semmle.code.cpp.dataflow.new.DataFlow
|
||||
private import experimental.quantum.OpenSSL.AlgorithmValueConsumers.OpenSSLAlgorithmValueConsumerBase
|
||||
private import experimental.quantum.OpenSSL.AlgorithmInstances.OpenSSLAlgorithmInstances
|
||||
import experimental.quantum.Language
|
||||
import semmle.code.cpp.dataflow.new.DataFlow
|
||||
import experimental.quantum.OpenSSL.AlgorithmValueConsumers.OpenSSLAlgorithmValueConsumerBase
|
||||
import experimental.quantum.OpenSSL.AlgorithmInstances.OpenSSLAlgorithmInstances
|
||||
import experimental.quantum.OpenSSL.LibraryDetector
|
||||
|
||||
abstract class HashAlgorithmValueConsumer extends OpenSslAlgorithmValueConsumer { }
|
||||
abstract class HashAlgorithmValueConsumer extends OpenSSLAlgorithmValueConsumer { }
|
||||
|
||||
/**
|
||||
* EVP_Q_Digest directly consumes algorithm constant values
|
||||
*/
|
||||
class Evp_Q_Digest_Algorithm_Consumer extends HashAlgorithmValueConsumer {
|
||||
Evp_Q_Digest_Algorithm_Consumer() { this.(Call).getTarget().getName() = "EVP_Q_digest" }
|
||||
class EVP_Q_Digest_Algorithm_Consumer extends OpenSSLAlgorithmValueConsumer {
|
||||
EVP_Q_Digest_Algorithm_Consumer() {
|
||||
isPossibleOpenSSLFunction(this.(Call).getTarget()) and
|
||||
this.(Call).getTarget().getName() = "EVP_Q_digest"
|
||||
}
|
||||
|
||||
override Crypto::ConsumerInputDataFlowNode getInputNode() {
|
||||
result.asExpr() = this.(Call).getArgument(1)
|
||||
}
|
||||
|
||||
override Crypto::AlgorithmInstance getAKnownAlgorithmSource() {
|
||||
exists(OpenSslAlgorithmInstance i | i.getAvc() = this and result = i)
|
||||
exists(OpenSSLAlgorithmInstance i | i.getAVC() = this and result = i)
|
||||
}
|
||||
|
||||
override DataFlow::Node getResultNode() {
|
||||
@@ -26,64 +33,3 @@ class Evp_Q_Digest_Algorithm_Consumer extends HashAlgorithmValueConsumer {
|
||||
none()
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* An instance from https://docs.openssl.org/3.0/man3/EVP_PKEY_CTX_ctrl/
|
||||
* where the digest is directly consumed by name.
|
||||
* In these cases, the operation is not yet performed, but there is
|
||||
* these functions are treated as 'initializers' and track the algorithm through
|
||||
* `EvpInitializer` mechanics, i.e., the resultNode is considered 'none'
|
||||
*/
|
||||
class EvpPkeySetCtxALgorithmConsumer extends HashAlgorithmValueConsumer {
|
||||
DataFlow::Node valueArgNode;
|
||||
|
||||
EvpPkeySetCtxALgorithmConsumer() {
|
||||
this.(Call).getTarget().getName() in [
|
||||
"EVP_PKEY_CTX_set_rsa_mgf1_md_name", "EVP_PKEY_CTX_set_rsa_oaep_md_name",
|
||||
"EVP_PKEY_CTX_set_dsa_paramgen_md_props"
|
||||
] and
|
||||
valueArgNode.asExpr() = this.(Call).getArgument(1)
|
||||
}
|
||||
|
||||
override DataFlow::Node getResultNode() { none() }
|
||||
|
||||
override Crypto::ConsumerInputDataFlowNode getInputNode() { result = valueArgNode }
|
||||
|
||||
override Crypto::AlgorithmInstance getAKnownAlgorithmSource() {
|
||||
exists(OpenSslAlgorithmInstance i | i.getAvc() = this and result = i)
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* The EVP digest algorithm getters
|
||||
* https://docs.openssl.org/3.0/man3/EVP_DigestInit/#synopsis
|
||||
* https://docs.openssl.org/3.0/man3/EVP_DigestSignInit/#name
|
||||
*/
|
||||
class EvpDigestAlgorithmValueConsumer extends HashAlgorithmValueConsumer {
|
||||
DataFlow::Node valueArgNode;
|
||||
DataFlow::Node resultNode;
|
||||
|
||||
EvpDigestAlgorithmValueConsumer() {
|
||||
resultNode.asExpr() = this and
|
||||
(
|
||||
this.(Call).getTarget().getName() in [
|
||||
"EVP_get_digestbyname", "EVP_get_digestbynid", "EVP_get_digestbyobj"
|
||||
] and
|
||||
valueArgNode.asExpr() = this.(Call).getArgument(0)
|
||||
or
|
||||
this.(Call).getTarget().getName() = "EVP_MD_fetch" and
|
||||
valueArgNode.asExpr() = this.(Call).getArgument(1)
|
||||
or
|
||||
this.(Call).getTarget().getName() = "EVP_DigestSignInit_ex" and
|
||||
valueArgNode.asExpr() = this.(Call).getArgument(2)
|
||||
)
|
||||
}
|
||||
|
||||
override DataFlow::Node getResultNode() { result = resultNode }
|
||||
|
||||
override Crypto::ConsumerInputDataFlowNode getInputNode() { result = valueArgNode }
|
||||
|
||||
override Crypto::AlgorithmInstance getAKnownAlgorithmSource() {
|
||||
exists(OpenSslAlgorithmInstance i | i.getAvc() = this and result = i)
|
||||
}
|
||||
}
|
||||
|
||||
@@ -1,28 +0,0 @@
|
||||
import cpp
|
||||
private import experimental.quantum.Language
|
||||
private import semmle.code.cpp.dataflow.new.DataFlow
|
||||
private import experimental.quantum.OpenSSL.AlgorithmValueConsumers.OpenSSLAlgorithmValueConsumerBase
|
||||
private import experimental.quantum.OpenSSL.AlgorithmInstances.OpenSSLAlgorithmInstances
|
||||
|
||||
abstract class KemAlgorithmValueConsumer extends OpenSslAlgorithmValueConsumer { }
|
||||
|
||||
class EvpKemAlgorithmValueConsumer extends KemAlgorithmValueConsumer {
|
||||
DataFlow::Node valueArgNode;
|
||||
DataFlow::Node resultNode;
|
||||
|
||||
EvpKemAlgorithmValueConsumer() {
|
||||
resultNode.asExpr() = this and
|
||||
(
|
||||
this.(Call).getTarget().getName() = "EVP_KEM_fetch" and
|
||||
valueArgNode.asExpr() = this.(Call).getArgument(1)
|
||||
)
|
||||
}
|
||||
|
||||
override DataFlow::Node getResultNode() { result = resultNode }
|
||||
|
||||
override Crypto::ConsumerInputDataFlowNode getInputNode() { result = valueArgNode }
|
||||
|
||||
override Crypto::AlgorithmInstance getAKnownAlgorithmSource() {
|
||||
exists(OpenSslAlgorithmInstance i | i.getAvc() = this and result = i)
|
||||
}
|
||||
}
|
||||
@@ -1,28 +0,0 @@
|
||||
import cpp
|
||||
private import experimental.quantum.Language
|
||||
private import semmle.code.cpp.dataflow.new.DataFlow
|
||||
private import experimental.quantum.OpenSSL.AlgorithmValueConsumers.OpenSSLAlgorithmValueConsumerBase
|
||||
private import experimental.quantum.OpenSSL.AlgorithmInstances.OpenSSLAlgorithmInstances
|
||||
|
||||
abstract class KeyExchangeAlgorithmValueConsumer extends OpenSslAlgorithmValueConsumer { }
|
||||
|
||||
class EvpKeyExchangeAlgorithmValueConsumer extends KeyExchangeAlgorithmValueConsumer {
|
||||
DataFlow::Node valueArgNode;
|
||||
DataFlow::Node resultNode;
|
||||
|
||||
EvpKeyExchangeAlgorithmValueConsumer() {
|
||||
resultNode.asExpr() = this and
|
||||
(
|
||||
this.(Call).getTarget().getName() = "EVP_KEYEXCH_fetch" and
|
||||
valueArgNode.asExpr() = this.(Call).getArgument(1)
|
||||
)
|
||||
}
|
||||
|
||||
override DataFlow::Node getResultNode() { result = resultNode }
|
||||
|
||||
override Crypto::ConsumerInputDataFlowNode getInputNode() { result = valueArgNode }
|
||||
|
||||
override Crypto::AlgorithmInstance getAKnownAlgorithmSource() {
|
||||
exists(OpenSslAlgorithmInstance i | i.getAvc() = this and result = i)
|
||||
}
|
||||
}
|
||||
@@ -1,6 +1,7 @@
|
||||
private import experimental.quantum.Language
|
||||
import experimental.quantum.Language
|
||||
import semmle.code.cpp.dataflow.new.DataFlow
|
||||
|
||||
abstract class OpenSslAlgorithmValueConsumer extends Crypto::AlgorithmValueConsumer instanceof Call {
|
||||
abstract class OpenSSLAlgorithmValueConsumer extends Crypto::AlgorithmValueConsumer instanceof Call {
|
||||
/**
|
||||
* Returns the node representing the resulting algorithm
|
||||
*/
|
||||
|
||||
@@ -3,6 +3,3 @@ import CipherAlgorithmValueConsumer
|
||||
import DirectAlgorithmValueConsumer
|
||||
import PaddingAlgorithmValueConsumer
|
||||
import HashAlgorithmValueConsumer
|
||||
import EllipticCurveAlgorithmValueConsumer
|
||||
import PKeyAlgorithmValueConsumer
|
||||
import SignatureAlgorithmValueConsumer
|
||||
|
||||
@@ -1,56 +0,0 @@
|
||||
import cpp
|
||||
private import experimental.quantum.Language
|
||||
private import experimental.quantum.OpenSSL.AlgorithmInstances.KnownAlgorithmConstants
|
||||
private import experimental.quantum.OpenSSL.AlgorithmValueConsumers.OpenSSLAlgorithmValueConsumerBase
|
||||
private import experimental.quantum.OpenSSL.AlgorithmInstances.OpenSSLAlgorithmInstances
|
||||
|
||||
abstract class PKeyValueConsumer extends OpenSslAlgorithmValueConsumer { }
|
||||
|
||||
class EvpPKeyAlgorithmConsumer extends PKeyValueConsumer {
|
||||
DataFlow::Node valueArgNode;
|
||||
DataFlow::Node resultNode;
|
||||
|
||||
EvpPKeyAlgorithmConsumer() {
|
||||
resultNode.asExpr() = this.(Call) and // in all cases the result is the return
|
||||
(
|
||||
// NOTE: some of these consumers are themselves key gen operations,
|
||||
// in these cases, the operation will be created separately for the same function.
|
||||
this.(Call).getTarget().getName() in [
|
||||
"EVP_PKEY_CTX_new_id", "EVP_PKEY_new_raw_private_key", "EVP_PKEY_new_raw_public_key",
|
||||
"EVP_PKEY_new_mac_key"
|
||||
] and
|
||||
valueArgNode.asExpr() = this.(Call).getArgument(0)
|
||||
or
|
||||
this.(Call).getTarget().getName() in [
|
||||
"EVP_PKEY_CTX_new_from_name", "EVP_PKEY_new_raw_private_key_ex",
|
||||
"EVP_PKEY_new_raw_public_key_ex", "EVP_PKEY_CTX_ctrl", "EVP_PKEY_CTX_ctrl_uint64",
|
||||
"EVP_PKEY_CTX_ctrl_str", "EVP_PKEY_CTX_set_group_name"
|
||||
] and
|
||||
valueArgNode.asExpr() = this.(Call).getArgument(1)
|
||||
or
|
||||
// argInd 2 is 'type' which can be RSA, or EC
|
||||
// if RSA argInd 3 is the key size, else if EC argInd 3 is the curve name
|
||||
// In all other cases there is no argInd 3, and argInd 2 is the algorithm.
|
||||
// Since this is a key gen operation, handling the key size should be handled
|
||||
// when the operation is again modeled as a key gen operation.
|
||||
this.(Call).getTarget().getName() = "EVP_PKEY_Q_keygen" and
|
||||
(
|
||||
// Elliptic curve case
|
||||
// If the argInd 3 is a derived type (pointer or array) then assume it is a curve name
|
||||
if this.(Call).getArgument(3).getType().getUnderlyingType() instanceof DerivedType
|
||||
then valueArgNode.asExpr() = this.(Call).getArgument(3)
|
||||
else
|
||||
// All other cases
|
||||
valueArgNode.asExpr() = this.(Call).getArgument(2)
|
||||
)
|
||||
)
|
||||
}
|
||||
|
||||
override Crypto::AlgorithmInstance getAKnownAlgorithmSource() {
|
||||
exists(OpenSslAlgorithmInstance i | i.getAvc() = this and result = i)
|
||||
}
|
||||
|
||||
override DataFlow::Node getResultNode() { result = resultNode }
|
||||
|
||||
override Crypto::ConsumerInputDataFlowNode getInputNode() { result = valueArgNode }
|
||||
}
|
||||
Some files were not shown because too many files have changed in this diff Show More
Reference in New Issue
Block a user