mirror of
https://github.com/github/codeql.git
synced 2025-12-22 03:36:30 +01:00
Merge branch 'main' into rdmarsh2/dataflow-global-vars
This commit is contained in:
9
.devcontainer/swift/Dockerfile
Normal file
9
.devcontainer/swift/Dockerfile
Normal file
@@ -0,0 +1,9 @@
|
|||||||
|
# See here for image contents: https://github.com/microsoft/vscode-dev-containers/tree/v0.236.0/containers/cpp/.devcontainer/base.Dockerfile
|
||||||
|
|
||||||
|
# [Choice] Debian / Ubuntu version (use Debian 11, Ubuntu 18.04/22.04 on local arm64/Apple Silicon): debian-11, debian-10, ubuntu-22.04, ubuntu-20.04, ubuntu-18.04
|
||||||
|
FROM mcr.microsoft.com/vscode/devcontainers/cpp:0-ubuntu-22.04
|
||||||
|
|
||||||
|
USER root
|
||||||
|
ADD root.sh /tmp/root.sh
|
||||||
|
ADD update-codeql.sh /usr/local/bin/update-codeql
|
||||||
|
RUN bash /tmp/root.sh && rm /tmp/root.sh
|
||||||
25
.devcontainer/swift/devcontainer.json
Normal file
25
.devcontainer/swift/devcontainer.json
Normal file
@@ -0,0 +1,25 @@
|
|||||||
|
{
|
||||||
|
"extensions": [
|
||||||
|
"github.vscode-codeql",
|
||||||
|
"hbenl.vscode-test-explorer",
|
||||||
|
"ms-vscode.test-adapter-converter",
|
||||||
|
"slevesque.vscode-zipexplorer",
|
||||||
|
"ms-vscode.cpptools"
|
||||||
|
],
|
||||||
|
"settings": {
|
||||||
|
"files.watcherExclude": {
|
||||||
|
"**/target/**": true
|
||||||
|
},
|
||||||
|
"codeQL.runningQueries.memory": 2048
|
||||||
|
},
|
||||||
|
"build": {
|
||||||
|
"dockerfile": "Dockerfile",
|
||||||
|
},
|
||||||
|
"runArgs": [
|
||||||
|
"--cap-add=SYS_PTRACE",
|
||||||
|
"--security-opt",
|
||||||
|
"seccomp=unconfined"
|
||||||
|
],
|
||||||
|
"remoteUser": "vscode",
|
||||||
|
"onCreateCommand": ".devcontainer/swift/user.sh"
|
||||||
|
}
|
||||||
22
.devcontainer/swift/root.sh
Normal file
22
.devcontainer/swift/root.sh
Normal file
@@ -0,0 +1,22 @@
|
|||||||
|
set -xe
|
||||||
|
|
||||||
|
BAZELISK_VERSION=v1.12.0
|
||||||
|
BAZELISK_DOWNLOAD_SHA=6b0bcb2ea15bca16fffabe6fda75803440375354c085480fe361d2cbf32501db
|
||||||
|
|
||||||
|
apt-get update
|
||||||
|
export DEBIAN_FRONTEND=noninteractive
|
||||||
|
apt-get -y install --no-install-recommends \
|
||||||
|
zlib1g-dev \
|
||||||
|
uuid-dev \
|
||||||
|
python3-distutils \
|
||||||
|
python3-pip \
|
||||||
|
bash-completion
|
||||||
|
|
||||||
|
# Install Bazel
|
||||||
|
curl -fSsL -o /usr/local/bin/bazelisk https://github.com/bazelbuild/bazelisk/releases/download/${BAZELISK_VERSION}/bazelisk-linux-amd64
|
||||||
|
echo "${BAZELISK_DOWNLOAD_SHA} */usr/local/bin/bazelisk" | sha256sum --check -
|
||||||
|
chmod 0755 /usr/local/bin/bazelisk
|
||||||
|
ln -s bazelisk /usr/local/bin/bazel
|
||||||
|
|
||||||
|
# install latest codeql
|
||||||
|
update-codeql
|
||||||
20
.devcontainer/swift/update-codeql.sh
Executable file
20
.devcontainer/swift/update-codeql.sh
Executable file
@@ -0,0 +1,20 @@
|
|||||||
|
#!/bin/bash -e
|
||||||
|
|
||||||
|
URL=https://github.com/github/codeql-cli-binaries/releases
|
||||||
|
LATEST_VERSION=$(curl -L -s -H 'Accept: application/json' $URL/latest | sed -e 's/.*"tag_name":"\([^"]*\)".*/\1/')
|
||||||
|
CURRENT_VERSION=v$(codeql version 2>/dev/null | sed -ne 's/.*release \([0-9.]*\)\./\1/p')
|
||||||
|
if [[ $CURRENT_VERSION != $LATEST_VERSION ]]; then
|
||||||
|
if [[ $UID != 0 ]]; then
|
||||||
|
echo "update required, please run this script with sudo:"
|
||||||
|
echo " sudo $0"
|
||||||
|
exit 1
|
||||||
|
fi
|
||||||
|
ZIP=$(mktemp codeql.XXXX.zip)
|
||||||
|
curl -fSqL -o $ZIP $URL/download/$LATEST_VERSION/codeql-linux64.zip
|
||||||
|
unzip -q $ZIP -d /opt
|
||||||
|
rm $ZIP
|
||||||
|
ln -sf /opt/codeql/codeql /usr/local/bin/codeql
|
||||||
|
echo installed version $LATEST_VERSION
|
||||||
|
else
|
||||||
|
echo current version $CURRENT_VERSION is up-to-date
|
||||||
|
fi
|
||||||
13
.devcontainer/swift/user.sh
Executable file
13
.devcontainer/swift/user.sh
Executable file
@@ -0,0 +1,13 @@
|
|||||||
|
set -xe
|
||||||
|
|
||||||
|
# add the workspace to the codeql search path
|
||||||
|
mkdir -p /home/vscode/.config/codeql
|
||||||
|
echo "--search-path /workspaces/codeql" > /home/vscode/.config/codeql/config
|
||||||
|
|
||||||
|
# create a swift extractor pack with the current state
|
||||||
|
cd /workspaces/codeql
|
||||||
|
bazel run swift/create-extractor-pack
|
||||||
|
|
||||||
|
#install and set up pre-commit
|
||||||
|
python3 -m pip install pre-commit --no-warn-script-location
|
||||||
|
$HOME/.local/bin/pre-commit install
|
||||||
20
.github/workflows/swift-codegen.yml
vendored
20
.github/workflows/swift-codegen.yml
vendored
@@ -15,18 +15,22 @@ jobs:
|
|||||||
- uses: actions/checkout@v3
|
- uses: actions/checkout@v3
|
||||||
- uses: ./.github/actions/fetch-codeql
|
- uses: ./.github/actions/fetch-codeql
|
||||||
- uses: bazelbuild/setup-bazelisk@v2
|
- uses: bazelbuild/setup-bazelisk@v2
|
||||||
|
- uses: actions/setup-python@v3
|
||||||
|
- uses: pre-commit/action@v3.0.0
|
||||||
|
name: Check that python code is properly formatted
|
||||||
|
with:
|
||||||
|
extra_args: autopep8 --all-files
|
||||||
- name: Run unit tests
|
- name: Run unit tests
|
||||||
run: |
|
run: |
|
||||||
bazel test //swift/codegen/test --test_output=errors
|
bazel test //swift/codegen/test --test_output=errors
|
||||||
- name: Check that QL generated code was checked in
|
- uses: pre-commit/action@v3.0.0
|
||||||
run: |
|
name: Check that QL generated code was checked in
|
||||||
bazel run //swift/codegen
|
with:
|
||||||
git add swift
|
extra_args: swift-codegen --all-files
|
||||||
git diff --exit-code --stat HEAD
|
|
||||||
- name: Generate C++ files
|
- name: Generate C++ files
|
||||||
run: |
|
run: |
|
||||||
bazel run //swift/codegen:codegen -- --generate=trap,cpp --cpp-output=$PWD/swift-generated-headers
|
bazel run //swift/codegen:codegen -- --generate=trap,cpp --cpp-output=$PWD/swift-generated-cpp-files
|
||||||
- uses: actions/upload-artifact@v3
|
- uses: actions/upload-artifact@v3
|
||||||
with:
|
with:
|
||||||
name: swift-generated-headers
|
name: swift-generated-cpp-files
|
||||||
path: swift-generated-headers/*.h
|
path: swift-generated-cpp-files/**
|
||||||
|
|||||||
3
.gitignore
vendored
3
.gitignore
vendored
@@ -58,3 +58,6 @@ go/main
|
|||||||
# node_modules folders except in the JS test suite
|
# node_modules folders except in the JS test suite
|
||||||
node_modules/
|
node_modules/
|
||||||
!/javascript/ql/test/**/node_modules/
|
!/javascript/ql/test/**/node_modules/
|
||||||
|
|
||||||
|
# Temporary folders for working with generated models
|
||||||
|
.model-temp
|
||||||
|
|||||||
@@ -15,6 +15,12 @@ repos:
|
|||||||
- id: clang-format
|
- id: clang-format
|
||||||
files: ^swift/.*\.(h|c|cpp)$
|
files: ^swift/.*\.(h|c|cpp)$
|
||||||
|
|
||||||
|
- repo: https://github.com/pre-commit/mirrors-autopep8
|
||||||
|
rev: v1.6.0
|
||||||
|
hooks:
|
||||||
|
- id: autopep8
|
||||||
|
files: ^swift/codegen/.*\.py
|
||||||
|
|
||||||
- repo: local
|
- repo: local
|
||||||
hooks:
|
hooks:
|
||||||
- id: codeql-format
|
- id: codeql-format
|
||||||
@@ -40,7 +46,7 @@ repos:
|
|||||||
name: Run Swift checked in code generation
|
name: Run Swift checked in code generation
|
||||||
files: ^swift/(codegen/|.*/generated/|ql/lib/(swift\.dbscheme$|codeql/swift/elements))
|
files: ^swift/(codegen/|.*/generated/|ql/lib/(swift\.dbscheme$|codeql/swift/elements))
|
||||||
language: system
|
language: system
|
||||||
entry: bazel run //swift/codegen
|
entry: bazel run //swift/codegen -- --quiet
|
||||||
pass_filenames: false
|
pass_filenames: false
|
||||||
|
|
||||||
- id: swift-codegen-unit-tests
|
- id: swift-codegen-unit-tests
|
||||||
|
|||||||
@@ -75,7 +75,8 @@
|
|||||||
"DataFlow Java/C# Flow Summaries": [
|
"DataFlow Java/C# Flow Summaries": [
|
||||||
"java/ql/lib/semmle/code/java/dataflow/internal/FlowSummaryImpl.qll",
|
"java/ql/lib/semmle/code/java/dataflow/internal/FlowSummaryImpl.qll",
|
||||||
"csharp/ql/lib/semmle/code/csharp/dataflow/internal/FlowSummaryImpl.qll",
|
"csharp/ql/lib/semmle/code/csharp/dataflow/internal/FlowSummaryImpl.qll",
|
||||||
"ruby/ql/lib/codeql/ruby/dataflow/internal/FlowSummaryImpl.qll"
|
"ruby/ql/lib/codeql/ruby/dataflow/internal/FlowSummaryImpl.qll",
|
||||||
|
"swift/ql/lib/codeql/swift/dataflow/internal/FlowSummaryImpl.qll"
|
||||||
],
|
],
|
||||||
"SsaReadPosition Java/C#": [
|
"SsaReadPosition Java/C#": [
|
||||||
"java/ql/lib/semmle/code/java/dataflow/internal/rangeanalysis/SsaReadPositionCommon.qll",
|
"java/ql/lib/semmle/code/java/dataflow/internal/rangeanalysis/SsaReadPositionCommon.qll",
|
||||||
@@ -527,7 +528,8 @@
|
|||||||
"java/ql/lib/semmle/code/java/dataflow/internal/AccessPathSyntax.qll",
|
"java/ql/lib/semmle/code/java/dataflow/internal/AccessPathSyntax.qll",
|
||||||
"javascript/ql/lib/semmle/javascript/frameworks/data/internal/AccessPathSyntax.qll",
|
"javascript/ql/lib/semmle/javascript/frameworks/data/internal/AccessPathSyntax.qll",
|
||||||
"ruby/ql/lib/codeql/ruby/dataflow/internal/AccessPathSyntax.qll",
|
"ruby/ql/lib/codeql/ruby/dataflow/internal/AccessPathSyntax.qll",
|
||||||
"python/ql/lib/semmle/python/frameworks/data/internal/AccessPathSyntax.qll"
|
"python/ql/lib/semmle/python/frameworks/data/internal/AccessPathSyntax.qll",
|
||||||
|
"swift/ql/lib/codeql/swift/dataflow/internal/AccessPathSyntax.qll"
|
||||||
],
|
],
|
||||||
"IncompleteUrlSubstringSanitization": [
|
"IncompleteUrlSubstringSanitization": [
|
||||||
"javascript/ql/src/Security/CWE-020/IncompleteUrlSubstringSanitization.qll",
|
"javascript/ql/src/Security/CWE-020/IncompleteUrlSubstringSanitization.qll",
|
||||||
|
|||||||
@@ -1,3 +1,9 @@
|
|||||||
|
## 0.2.3
|
||||||
|
|
||||||
|
### New Features
|
||||||
|
|
||||||
|
* An `isBraced` predicate was added to the `Initializer` class which holds when a C++ braced initializer was used in the initialization.
|
||||||
|
|
||||||
## 0.2.2
|
## 0.2.2
|
||||||
|
|
||||||
### Deprecated APIs
|
### Deprecated APIs
|
||||||
|
|||||||
@@ -0,0 +1,4 @@
|
|||||||
|
---
|
||||||
|
category: deprecated
|
||||||
|
---
|
||||||
|
* The `BarrierGuard` class has been deprecated. Such barriers and sanitizers can now instead be created using the new `BarrierGuard` parameterized module.
|
||||||
@@ -0,0 +1,4 @@
|
|||||||
|
---
|
||||||
|
category: fix
|
||||||
|
---
|
||||||
|
* `UserType.getADeclarationEntry()` now yields all forward declarations when the user type is a `class`, `struct`, or `union`.
|
||||||
5
cpp/ql/lib/change-notes/released/0.2.3.md
Normal file
5
cpp/ql/lib/change-notes/released/0.2.3.md
Normal file
@@ -0,0 +1,5 @@
|
|||||||
|
## 0.2.3
|
||||||
|
|
||||||
|
### New Features
|
||||||
|
|
||||||
|
* An `isBraced` predicate was added to the `Initializer` class which holds when a C++ braced initializer was used in the initialization.
|
||||||
@@ -1,2 +1,2 @@
|
|||||||
---
|
---
|
||||||
lastReleaseVersion: 0.2.2
|
lastReleaseVersion: 0.2.3
|
||||||
|
|||||||
@@ -1,5 +1,5 @@
|
|||||||
name: codeql/cpp-all
|
name: codeql/cpp-all
|
||||||
version: 0.2.3-dev
|
version: 0.3.0-dev
|
||||||
groups: cpp
|
groups: cpp
|
||||||
dbscheme: semmlecode.cpp.dbscheme
|
dbscheme: semmlecode.cpp.dbscheme
|
||||||
extractor: cpp
|
extractor: cpp
|
||||||
|
|||||||
@@ -48,8 +48,8 @@ class UserType extends Type, Declaration, NameQualifyingElement, AccessHolder, @
|
|||||||
}
|
}
|
||||||
|
|
||||||
override TypeDeclarationEntry getADeclarationEntry() {
|
override TypeDeclarationEntry getADeclarationEntry() {
|
||||||
if type_decls(_, underlyingElement(this), _)
|
if type_decls(_, unresolveElement(this), _)
|
||||||
then type_decls(unresolveElement(result), underlyingElement(this), _)
|
then type_decls(underlyingElement(result), unresolveElement(this), _)
|
||||||
else exists(Class t | this.(Class).isConstructedFrom(t) and result = t.getADeclarationEntry())
|
else exists(Class t | this.(Class).isConstructedFrom(t) and result = t.getADeclarationEntry())
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@@ -90,14 +90,20 @@ abstract class Configuration extends string {
|
|||||||
/** Holds if data flow out of `node` is prohibited. */
|
/** Holds if data flow out of `node` is prohibited. */
|
||||||
predicate isBarrierOut(Node node) { none() }
|
predicate isBarrierOut(Node node) { none() }
|
||||||
|
|
||||||
/** Holds if data flow through nodes guarded by `guard` is prohibited. */
|
/**
|
||||||
predicate isBarrierGuard(BarrierGuard guard) { none() }
|
* DEPRECATED: Use `isBarrier` and `BarrierGuard` module instead.
|
||||||
|
*
|
||||||
|
* Holds if data flow through nodes guarded by `guard` is prohibited.
|
||||||
|
*/
|
||||||
|
deprecated predicate isBarrierGuard(BarrierGuard guard) { none() }
|
||||||
|
|
||||||
/**
|
/**
|
||||||
|
* DEPRECATED: Use `isBarrier` and `BarrierGuard` module instead.
|
||||||
|
*
|
||||||
* Holds if data flow through nodes guarded by `guard` is prohibited when
|
* Holds if data flow through nodes guarded by `guard` is prohibited when
|
||||||
* the flow state is `state`
|
* the flow state is `state`
|
||||||
*/
|
*/
|
||||||
predicate isBarrierGuard(BarrierGuard guard, FlowState state) { none() }
|
deprecated predicate isBarrierGuard(BarrierGuard guard, FlowState state) { none() }
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Holds if data may flow from `node1` to `node2` in addition to the normal data-flow steps.
|
* Holds if data may flow from `node1` to `node2` in addition to the normal data-flow steps.
|
||||||
@@ -335,6 +341,29 @@ private predicate outBarrier(NodeEx node, Configuration config) {
|
|||||||
)
|
)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/** A bridge class to access the deprecated `isBarrierGuard`. */
|
||||||
|
private class BarrierGuardGuardedNodeBridge extends Unit {
|
||||||
|
abstract predicate guardedNode(Node n, Configuration config);
|
||||||
|
|
||||||
|
abstract predicate guardedNode(Node n, FlowState state, Configuration config);
|
||||||
|
}
|
||||||
|
|
||||||
|
private class BarrierGuardGuardedNode extends BarrierGuardGuardedNodeBridge {
|
||||||
|
deprecated override predicate guardedNode(Node n, Configuration config) {
|
||||||
|
exists(BarrierGuard g |
|
||||||
|
config.isBarrierGuard(g) and
|
||||||
|
n = g.getAGuardedNode()
|
||||||
|
)
|
||||||
|
}
|
||||||
|
|
||||||
|
deprecated override predicate guardedNode(Node n, FlowState state, Configuration config) {
|
||||||
|
exists(BarrierGuard g |
|
||||||
|
config.isBarrierGuard(g, state) and
|
||||||
|
n = g.getAGuardedNode()
|
||||||
|
)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
pragma[nomagic]
|
pragma[nomagic]
|
||||||
private predicate fullBarrier(NodeEx node, Configuration config) {
|
private predicate fullBarrier(NodeEx node, Configuration config) {
|
||||||
exists(Node n | node.asNode() = n |
|
exists(Node n | node.asNode() = n |
|
||||||
@@ -348,10 +377,7 @@ private predicate fullBarrier(NodeEx node, Configuration config) {
|
|||||||
not config.isSink(n) and
|
not config.isSink(n) and
|
||||||
not config.isSink(n, _)
|
not config.isSink(n, _)
|
||||||
or
|
or
|
||||||
exists(BarrierGuard g |
|
any(BarrierGuardGuardedNodeBridge b).guardedNode(n, config)
|
||||||
config.isBarrierGuard(g) and
|
|
||||||
n = g.getAGuardedNode()
|
|
||||||
)
|
|
||||||
)
|
)
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -360,10 +386,7 @@ private predicate stateBarrier(NodeEx node, FlowState state, Configuration confi
|
|||||||
exists(Node n | node.asNode() = n |
|
exists(Node n | node.asNode() = n |
|
||||||
config.isBarrier(n, state)
|
config.isBarrier(n, state)
|
||||||
or
|
or
|
||||||
exists(BarrierGuard g |
|
any(BarrierGuardGuardedNodeBridge b).guardedNode(n, state, config)
|
||||||
config.isBarrierGuard(g, state) and
|
|
||||||
n = g.getAGuardedNode()
|
|
||||||
)
|
|
||||||
)
|
)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@@ -90,14 +90,20 @@ abstract class Configuration extends string {
|
|||||||
/** Holds if data flow out of `node` is prohibited. */
|
/** Holds if data flow out of `node` is prohibited. */
|
||||||
predicate isBarrierOut(Node node) { none() }
|
predicate isBarrierOut(Node node) { none() }
|
||||||
|
|
||||||
/** Holds if data flow through nodes guarded by `guard` is prohibited. */
|
/**
|
||||||
predicate isBarrierGuard(BarrierGuard guard) { none() }
|
* DEPRECATED: Use `isBarrier` and `BarrierGuard` module instead.
|
||||||
|
*
|
||||||
|
* Holds if data flow through nodes guarded by `guard` is prohibited.
|
||||||
|
*/
|
||||||
|
deprecated predicate isBarrierGuard(BarrierGuard guard) { none() }
|
||||||
|
|
||||||
/**
|
/**
|
||||||
|
* DEPRECATED: Use `isBarrier` and `BarrierGuard` module instead.
|
||||||
|
*
|
||||||
* Holds if data flow through nodes guarded by `guard` is prohibited when
|
* Holds if data flow through nodes guarded by `guard` is prohibited when
|
||||||
* the flow state is `state`
|
* the flow state is `state`
|
||||||
*/
|
*/
|
||||||
predicate isBarrierGuard(BarrierGuard guard, FlowState state) { none() }
|
deprecated predicate isBarrierGuard(BarrierGuard guard, FlowState state) { none() }
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Holds if data may flow from `node1` to `node2` in addition to the normal data-flow steps.
|
* Holds if data may flow from `node1` to `node2` in addition to the normal data-flow steps.
|
||||||
@@ -335,6 +341,29 @@ private predicate outBarrier(NodeEx node, Configuration config) {
|
|||||||
)
|
)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/** A bridge class to access the deprecated `isBarrierGuard`. */
|
||||||
|
private class BarrierGuardGuardedNodeBridge extends Unit {
|
||||||
|
abstract predicate guardedNode(Node n, Configuration config);
|
||||||
|
|
||||||
|
abstract predicate guardedNode(Node n, FlowState state, Configuration config);
|
||||||
|
}
|
||||||
|
|
||||||
|
private class BarrierGuardGuardedNode extends BarrierGuardGuardedNodeBridge {
|
||||||
|
deprecated override predicate guardedNode(Node n, Configuration config) {
|
||||||
|
exists(BarrierGuard g |
|
||||||
|
config.isBarrierGuard(g) and
|
||||||
|
n = g.getAGuardedNode()
|
||||||
|
)
|
||||||
|
}
|
||||||
|
|
||||||
|
deprecated override predicate guardedNode(Node n, FlowState state, Configuration config) {
|
||||||
|
exists(BarrierGuard g |
|
||||||
|
config.isBarrierGuard(g, state) and
|
||||||
|
n = g.getAGuardedNode()
|
||||||
|
)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
pragma[nomagic]
|
pragma[nomagic]
|
||||||
private predicate fullBarrier(NodeEx node, Configuration config) {
|
private predicate fullBarrier(NodeEx node, Configuration config) {
|
||||||
exists(Node n | node.asNode() = n |
|
exists(Node n | node.asNode() = n |
|
||||||
@@ -348,10 +377,7 @@ private predicate fullBarrier(NodeEx node, Configuration config) {
|
|||||||
not config.isSink(n) and
|
not config.isSink(n) and
|
||||||
not config.isSink(n, _)
|
not config.isSink(n, _)
|
||||||
or
|
or
|
||||||
exists(BarrierGuard g |
|
any(BarrierGuardGuardedNodeBridge b).guardedNode(n, config)
|
||||||
config.isBarrierGuard(g) and
|
|
||||||
n = g.getAGuardedNode()
|
|
||||||
)
|
|
||||||
)
|
)
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -360,10 +386,7 @@ private predicate stateBarrier(NodeEx node, FlowState state, Configuration confi
|
|||||||
exists(Node n | node.asNode() = n |
|
exists(Node n | node.asNode() = n |
|
||||||
config.isBarrier(n, state)
|
config.isBarrier(n, state)
|
||||||
or
|
or
|
||||||
exists(BarrierGuard g |
|
any(BarrierGuardGuardedNodeBridge b).guardedNode(n, state, config)
|
||||||
config.isBarrierGuard(g, state) and
|
|
||||||
n = g.getAGuardedNode()
|
|
||||||
)
|
|
||||||
)
|
)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@@ -90,14 +90,20 @@ abstract class Configuration extends string {
|
|||||||
/** Holds if data flow out of `node` is prohibited. */
|
/** Holds if data flow out of `node` is prohibited. */
|
||||||
predicate isBarrierOut(Node node) { none() }
|
predicate isBarrierOut(Node node) { none() }
|
||||||
|
|
||||||
/** Holds if data flow through nodes guarded by `guard` is prohibited. */
|
/**
|
||||||
predicate isBarrierGuard(BarrierGuard guard) { none() }
|
* DEPRECATED: Use `isBarrier` and `BarrierGuard` module instead.
|
||||||
|
*
|
||||||
|
* Holds if data flow through nodes guarded by `guard` is prohibited.
|
||||||
|
*/
|
||||||
|
deprecated predicate isBarrierGuard(BarrierGuard guard) { none() }
|
||||||
|
|
||||||
/**
|
/**
|
||||||
|
* DEPRECATED: Use `isBarrier` and `BarrierGuard` module instead.
|
||||||
|
*
|
||||||
* Holds if data flow through nodes guarded by `guard` is prohibited when
|
* Holds if data flow through nodes guarded by `guard` is prohibited when
|
||||||
* the flow state is `state`
|
* the flow state is `state`
|
||||||
*/
|
*/
|
||||||
predicate isBarrierGuard(BarrierGuard guard, FlowState state) { none() }
|
deprecated predicate isBarrierGuard(BarrierGuard guard, FlowState state) { none() }
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Holds if data may flow from `node1` to `node2` in addition to the normal data-flow steps.
|
* Holds if data may flow from `node1` to `node2` in addition to the normal data-flow steps.
|
||||||
@@ -335,6 +341,29 @@ private predicate outBarrier(NodeEx node, Configuration config) {
|
|||||||
)
|
)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/** A bridge class to access the deprecated `isBarrierGuard`. */
|
||||||
|
private class BarrierGuardGuardedNodeBridge extends Unit {
|
||||||
|
abstract predicate guardedNode(Node n, Configuration config);
|
||||||
|
|
||||||
|
abstract predicate guardedNode(Node n, FlowState state, Configuration config);
|
||||||
|
}
|
||||||
|
|
||||||
|
private class BarrierGuardGuardedNode extends BarrierGuardGuardedNodeBridge {
|
||||||
|
deprecated override predicate guardedNode(Node n, Configuration config) {
|
||||||
|
exists(BarrierGuard g |
|
||||||
|
config.isBarrierGuard(g) and
|
||||||
|
n = g.getAGuardedNode()
|
||||||
|
)
|
||||||
|
}
|
||||||
|
|
||||||
|
deprecated override predicate guardedNode(Node n, FlowState state, Configuration config) {
|
||||||
|
exists(BarrierGuard g |
|
||||||
|
config.isBarrierGuard(g, state) and
|
||||||
|
n = g.getAGuardedNode()
|
||||||
|
)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
pragma[nomagic]
|
pragma[nomagic]
|
||||||
private predicate fullBarrier(NodeEx node, Configuration config) {
|
private predicate fullBarrier(NodeEx node, Configuration config) {
|
||||||
exists(Node n | node.asNode() = n |
|
exists(Node n | node.asNode() = n |
|
||||||
@@ -348,10 +377,7 @@ private predicate fullBarrier(NodeEx node, Configuration config) {
|
|||||||
not config.isSink(n) and
|
not config.isSink(n) and
|
||||||
not config.isSink(n, _)
|
not config.isSink(n, _)
|
||||||
or
|
or
|
||||||
exists(BarrierGuard g |
|
any(BarrierGuardGuardedNodeBridge b).guardedNode(n, config)
|
||||||
config.isBarrierGuard(g) and
|
|
||||||
n = g.getAGuardedNode()
|
|
||||||
)
|
|
||||||
)
|
)
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -360,10 +386,7 @@ private predicate stateBarrier(NodeEx node, FlowState state, Configuration confi
|
|||||||
exists(Node n | node.asNode() = n |
|
exists(Node n | node.asNode() = n |
|
||||||
config.isBarrier(n, state)
|
config.isBarrier(n, state)
|
||||||
or
|
or
|
||||||
exists(BarrierGuard g |
|
any(BarrierGuardGuardedNodeBridge b).guardedNode(n, state, config)
|
||||||
config.isBarrierGuard(g, state) and
|
|
||||||
n = g.getAGuardedNode()
|
|
||||||
)
|
|
||||||
)
|
)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@@ -90,14 +90,20 @@ abstract class Configuration extends string {
|
|||||||
/** Holds if data flow out of `node` is prohibited. */
|
/** Holds if data flow out of `node` is prohibited. */
|
||||||
predicate isBarrierOut(Node node) { none() }
|
predicate isBarrierOut(Node node) { none() }
|
||||||
|
|
||||||
/** Holds if data flow through nodes guarded by `guard` is prohibited. */
|
/**
|
||||||
predicate isBarrierGuard(BarrierGuard guard) { none() }
|
* DEPRECATED: Use `isBarrier` and `BarrierGuard` module instead.
|
||||||
|
*
|
||||||
|
* Holds if data flow through nodes guarded by `guard` is prohibited.
|
||||||
|
*/
|
||||||
|
deprecated predicate isBarrierGuard(BarrierGuard guard) { none() }
|
||||||
|
|
||||||
/**
|
/**
|
||||||
|
* DEPRECATED: Use `isBarrier` and `BarrierGuard` module instead.
|
||||||
|
*
|
||||||
* Holds if data flow through nodes guarded by `guard` is prohibited when
|
* Holds if data flow through nodes guarded by `guard` is prohibited when
|
||||||
* the flow state is `state`
|
* the flow state is `state`
|
||||||
*/
|
*/
|
||||||
predicate isBarrierGuard(BarrierGuard guard, FlowState state) { none() }
|
deprecated predicate isBarrierGuard(BarrierGuard guard, FlowState state) { none() }
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Holds if data may flow from `node1` to `node2` in addition to the normal data-flow steps.
|
* Holds if data may flow from `node1` to `node2` in addition to the normal data-flow steps.
|
||||||
@@ -335,6 +341,29 @@ private predicate outBarrier(NodeEx node, Configuration config) {
|
|||||||
)
|
)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/** A bridge class to access the deprecated `isBarrierGuard`. */
|
||||||
|
private class BarrierGuardGuardedNodeBridge extends Unit {
|
||||||
|
abstract predicate guardedNode(Node n, Configuration config);
|
||||||
|
|
||||||
|
abstract predicate guardedNode(Node n, FlowState state, Configuration config);
|
||||||
|
}
|
||||||
|
|
||||||
|
private class BarrierGuardGuardedNode extends BarrierGuardGuardedNodeBridge {
|
||||||
|
deprecated override predicate guardedNode(Node n, Configuration config) {
|
||||||
|
exists(BarrierGuard g |
|
||||||
|
config.isBarrierGuard(g) and
|
||||||
|
n = g.getAGuardedNode()
|
||||||
|
)
|
||||||
|
}
|
||||||
|
|
||||||
|
deprecated override predicate guardedNode(Node n, FlowState state, Configuration config) {
|
||||||
|
exists(BarrierGuard g |
|
||||||
|
config.isBarrierGuard(g, state) and
|
||||||
|
n = g.getAGuardedNode()
|
||||||
|
)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
pragma[nomagic]
|
pragma[nomagic]
|
||||||
private predicate fullBarrier(NodeEx node, Configuration config) {
|
private predicate fullBarrier(NodeEx node, Configuration config) {
|
||||||
exists(Node n | node.asNode() = n |
|
exists(Node n | node.asNode() = n |
|
||||||
@@ -348,10 +377,7 @@ private predicate fullBarrier(NodeEx node, Configuration config) {
|
|||||||
not config.isSink(n) and
|
not config.isSink(n) and
|
||||||
not config.isSink(n, _)
|
not config.isSink(n, _)
|
||||||
or
|
or
|
||||||
exists(BarrierGuard g |
|
any(BarrierGuardGuardedNodeBridge b).guardedNode(n, config)
|
||||||
config.isBarrierGuard(g) and
|
|
||||||
n = g.getAGuardedNode()
|
|
||||||
)
|
|
||||||
)
|
)
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -360,10 +386,7 @@ private predicate stateBarrier(NodeEx node, FlowState state, Configuration confi
|
|||||||
exists(Node n | node.asNode() = n |
|
exists(Node n | node.asNode() = n |
|
||||||
config.isBarrier(n, state)
|
config.isBarrier(n, state)
|
||||||
or
|
or
|
||||||
exists(BarrierGuard g |
|
any(BarrierGuardGuardedNodeBridge b).guardedNode(n, state, config)
|
||||||
config.isBarrierGuard(g, state) and
|
|
||||||
n = g.getAGuardedNode()
|
|
||||||
)
|
|
||||||
)
|
)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@@ -90,14 +90,20 @@ abstract class Configuration extends string {
|
|||||||
/** Holds if data flow out of `node` is prohibited. */
|
/** Holds if data flow out of `node` is prohibited. */
|
||||||
predicate isBarrierOut(Node node) { none() }
|
predicate isBarrierOut(Node node) { none() }
|
||||||
|
|
||||||
/** Holds if data flow through nodes guarded by `guard` is prohibited. */
|
/**
|
||||||
predicate isBarrierGuard(BarrierGuard guard) { none() }
|
* DEPRECATED: Use `isBarrier` and `BarrierGuard` module instead.
|
||||||
|
*
|
||||||
|
* Holds if data flow through nodes guarded by `guard` is prohibited.
|
||||||
|
*/
|
||||||
|
deprecated predicate isBarrierGuard(BarrierGuard guard) { none() }
|
||||||
|
|
||||||
/**
|
/**
|
||||||
|
* DEPRECATED: Use `isBarrier` and `BarrierGuard` module instead.
|
||||||
|
*
|
||||||
* Holds if data flow through nodes guarded by `guard` is prohibited when
|
* Holds if data flow through nodes guarded by `guard` is prohibited when
|
||||||
* the flow state is `state`
|
* the flow state is `state`
|
||||||
*/
|
*/
|
||||||
predicate isBarrierGuard(BarrierGuard guard, FlowState state) { none() }
|
deprecated predicate isBarrierGuard(BarrierGuard guard, FlowState state) { none() }
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Holds if data may flow from `node1` to `node2` in addition to the normal data-flow steps.
|
* Holds if data may flow from `node1` to `node2` in addition to the normal data-flow steps.
|
||||||
@@ -335,6 +341,29 @@ private predicate outBarrier(NodeEx node, Configuration config) {
|
|||||||
)
|
)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/** A bridge class to access the deprecated `isBarrierGuard`. */
|
||||||
|
private class BarrierGuardGuardedNodeBridge extends Unit {
|
||||||
|
abstract predicate guardedNode(Node n, Configuration config);
|
||||||
|
|
||||||
|
abstract predicate guardedNode(Node n, FlowState state, Configuration config);
|
||||||
|
}
|
||||||
|
|
||||||
|
private class BarrierGuardGuardedNode extends BarrierGuardGuardedNodeBridge {
|
||||||
|
deprecated override predicate guardedNode(Node n, Configuration config) {
|
||||||
|
exists(BarrierGuard g |
|
||||||
|
config.isBarrierGuard(g) and
|
||||||
|
n = g.getAGuardedNode()
|
||||||
|
)
|
||||||
|
}
|
||||||
|
|
||||||
|
deprecated override predicate guardedNode(Node n, FlowState state, Configuration config) {
|
||||||
|
exists(BarrierGuard g |
|
||||||
|
config.isBarrierGuard(g, state) and
|
||||||
|
n = g.getAGuardedNode()
|
||||||
|
)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
pragma[nomagic]
|
pragma[nomagic]
|
||||||
private predicate fullBarrier(NodeEx node, Configuration config) {
|
private predicate fullBarrier(NodeEx node, Configuration config) {
|
||||||
exists(Node n | node.asNode() = n |
|
exists(Node n | node.asNode() = n |
|
||||||
@@ -348,10 +377,7 @@ private predicate fullBarrier(NodeEx node, Configuration config) {
|
|||||||
not config.isSink(n) and
|
not config.isSink(n) and
|
||||||
not config.isSink(n, _)
|
not config.isSink(n, _)
|
||||||
or
|
or
|
||||||
exists(BarrierGuard g |
|
any(BarrierGuardGuardedNodeBridge b).guardedNode(n, config)
|
||||||
config.isBarrierGuard(g) and
|
|
||||||
n = g.getAGuardedNode()
|
|
||||||
)
|
|
||||||
)
|
)
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -360,10 +386,7 @@ private predicate stateBarrier(NodeEx node, FlowState state, Configuration confi
|
|||||||
exists(Node n | node.asNode() = n |
|
exists(Node n | node.asNode() = n |
|
||||||
config.isBarrier(n, state)
|
config.isBarrier(n, state)
|
||||||
or
|
or
|
||||||
exists(BarrierGuard g |
|
any(BarrierGuardGuardedNodeBridge b).guardedNode(n, state, config)
|
||||||
config.isBarrierGuard(g, state) and
|
|
||||||
n = g.getAGuardedNode()
|
|
||||||
)
|
|
||||||
)
|
)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@@ -850,6 +850,34 @@ class ContentSet instanceof Content {
|
|||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
|
* Holds if the guard `g` validates the expression `e` upon evaluating to `branch`.
|
||||||
|
*
|
||||||
|
* The expression `e` is expected to be a syntactic part of the guard `g`.
|
||||||
|
* For example, the guard `g` might be a call `isSafe(x)` and the expression `e`
|
||||||
|
* the argument `x`.
|
||||||
|
*/
|
||||||
|
signature predicate guardChecksSig(GuardCondition g, Expr e, boolean branch);
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Provides a set of barrier nodes for a guard that validates an expression.
|
||||||
|
*
|
||||||
|
* This is expected to be used in `isBarrier`/`isSanitizer` definitions
|
||||||
|
* in data flow and taint tracking.
|
||||||
|
*/
|
||||||
|
module BarrierGuard<guardChecksSig/3 guardChecks> {
|
||||||
|
/** Gets a node that is safely guarded by the given guard check. */
|
||||||
|
ExprNode getABarrierNode() {
|
||||||
|
exists(GuardCondition g, SsaDefinition def, Variable v, boolean branch |
|
||||||
|
result.getExpr() = def.getAUse(v) and
|
||||||
|
guardChecks(g, def.getAUse(v), branch) and
|
||||||
|
g.controls(result.getExpr().getBasicBlock(), branch)
|
||||||
|
)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* DEPRECATED: Use `BarrierGuard` module instead.
|
||||||
|
*
|
||||||
* A guard that validates some expression.
|
* A guard that validates some expression.
|
||||||
*
|
*
|
||||||
* To use this in a configuration, extend the class and provide a
|
* To use this in a configuration, extend the class and provide a
|
||||||
@@ -858,7 +886,7 @@ class ContentSet instanceof Content {
|
|||||||
*
|
*
|
||||||
* It is important that all extending classes in scope are disjoint.
|
* It is important that all extending classes in scope are disjoint.
|
||||||
*/
|
*/
|
||||||
class BarrierGuard extends GuardCondition {
|
deprecated class BarrierGuard extends GuardCondition {
|
||||||
/** Override this predicate to hold if this guard validates `e` upon evaluating to `b`. */
|
/** Override this predicate to hold if this guard validates `e` upon evaluating to `b`. */
|
||||||
abstract predicate checks(Expr e, boolean b);
|
abstract predicate checks(Expr e, boolean b);
|
||||||
|
|
||||||
|
|||||||
@@ -47,12 +47,6 @@ predicate defaultImplicitTaintRead(DataFlow::Node node, DataFlow::Content c) { n
|
|||||||
*/
|
*/
|
||||||
predicate defaultTaintSanitizer(DataFlow::Node node) { none() }
|
predicate defaultTaintSanitizer(DataFlow::Node node) { none() }
|
||||||
|
|
||||||
/**
|
|
||||||
* Holds if `guard` should be a sanitizer guard in all global taint flow configurations
|
|
||||||
* but not in local taint.
|
|
||||||
*/
|
|
||||||
predicate defaultTaintSanitizerGuard(DataFlow::BarrierGuard guard) { none() }
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Holds if taint can flow in one local step from `nodeFrom` to `nodeTo` excluding
|
* Holds if taint can flow in one local step from `nodeFrom` to `nodeTo` excluding
|
||||||
* local data flow steps. That is, `nodeFrom` and `nodeTo` are likely to represent
|
* local data flow steps. That is, `nodeFrom` and `nodeTo` are likely to represent
|
||||||
|
|||||||
@@ -116,20 +116,30 @@ abstract class Configuration extends DataFlow::Configuration {
|
|||||||
|
|
||||||
final override predicate isBarrierOut(DataFlow::Node node) { this.isSanitizerOut(node) }
|
final override predicate isBarrierOut(DataFlow::Node node) { this.isSanitizerOut(node) }
|
||||||
|
|
||||||
/** Holds if taint propagation through nodes guarded by `guard` is prohibited. */
|
/**
|
||||||
predicate isSanitizerGuard(DataFlow::BarrierGuard guard) { none() }
|
* DEPRECATED: Use `isSanitizer` and `BarrierGuard` module instead.
|
||||||
|
*
|
||||||
|
* Holds if taint propagation through nodes guarded by `guard` is prohibited.
|
||||||
|
*/
|
||||||
|
deprecated predicate isSanitizerGuard(DataFlow::BarrierGuard guard) { none() }
|
||||||
|
|
||||||
final override predicate isBarrierGuard(DataFlow::BarrierGuard guard) {
|
deprecated final override predicate isBarrierGuard(DataFlow::BarrierGuard guard) {
|
||||||
this.isSanitizerGuard(guard) or defaultTaintSanitizerGuard(guard)
|
this.isSanitizerGuard(guard)
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
|
* DEPRECATED: Use `isSanitizer` and `BarrierGuard` module instead.
|
||||||
|
*
|
||||||
* Holds if taint propagation through nodes guarded by `guard` is prohibited
|
* Holds if taint propagation through nodes guarded by `guard` is prohibited
|
||||||
* when the flow state is `state`.
|
* when the flow state is `state`.
|
||||||
*/
|
*/
|
||||||
predicate isSanitizerGuard(DataFlow::BarrierGuard guard, DataFlow::FlowState state) { none() }
|
deprecated predicate isSanitizerGuard(DataFlow::BarrierGuard guard, DataFlow::FlowState state) {
|
||||||
|
none()
|
||||||
|
}
|
||||||
|
|
||||||
final override predicate isBarrierGuard(DataFlow::BarrierGuard guard, DataFlow::FlowState state) {
|
deprecated final override predicate isBarrierGuard(
|
||||||
|
DataFlow::BarrierGuard guard, DataFlow::FlowState state
|
||||||
|
) {
|
||||||
this.isSanitizerGuard(guard, state)
|
this.isSanitizerGuard(guard, state)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@@ -116,20 +116,30 @@ abstract class Configuration extends DataFlow::Configuration {
|
|||||||
|
|
||||||
final override predicate isBarrierOut(DataFlow::Node node) { this.isSanitizerOut(node) }
|
final override predicate isBarrierOut(DataFlow::Node node) { this.isSanitizerOut(node) }
|
||||||
|
|
||||||
/** Holds if taint propagation through nodes guarded by `guard` is prohibited. */
|
/**
|
||||||
predicate isSanitizerGuard(DataFlow::BarrierGuard guard) { none() }
|
* DEPRECATED: Use `isSanitizer` and `BarrierGuard` module instead.
|
||||||
|
*
|
||||||
|
* Holds if taint propagation through nodes guarded by `guard` is prohibited.
|
||||||
|
*/
|
||||||
|
deprecated predicate isSanitizerGuard(DataFlow::BarrierGuard guard) { none() }
|
||||||
|
|
||||||
final override predicate isBarrierGuard(DataFlow::BarrierGuard guard) {
|
deprecated final override predicate isBarrierGuard(DataFlow::BarrierGuard guard) {
|
||||||
this.isSanitizerGuard(guard) or defaultTaintSanitizerGuard(guard)
|
this.isSanitizerGuard(guard)
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
|
* DEPRECATED: Use `isSanitizer` and `BarrierGuard` module instead.
|
||||||
|
*
|
||||||
* Holds if taint propagation through nodes guarded by `guard` is prohibited
|
* Holds if taint propagation through nodes guarded by `guard` is prohibited
|
||||||
* when the flow state is `state`.
|
* when the flow state is `state`.
|
||||||
*/
|
*/
|
||||||
predicate isSanitizerGuard(DataFlow::BarrierGuard guard, DataFlow::FlowState state) { none() }
|
deprecated predicate isSanitizerGuard(DataFlow::BarrierGuard guard, DataFlow::FlowState state) {
|
||||||
|
none()
|
||||||
|
}
|
||||||
|
|
||||||
final override predicate isBarrierGuard(DataFlow::BarrierGuard guard, DataFlow::FlowState state) {
|
deprecated final override predicate isBarrierGuard(
|
||||||
|
DataFlow::BarrierGuard guard, DataFlow::FlowState state
|
||||||
|
) {
|
||||||
this.isSanitizerGuard(guard, state)
|
this.isSanitizerGuard(guard, state)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@@ -4,11 +4,7 @@
|
|||||||
* qualified.
|
* qualified.
|
||||||
*
|
*
|
||||||
* This file contains classes that mirror the standard AST classes for C++, but
|
* This file contains classes that mirror the standard AST classes for C++, but
|
||||||
* these classes are only concerned with naming. The other difference is that
|
* these classes are only concerned with naming.
|
||||||
* these classes don't use the `ResolveClass.qll` mechanisms like
|
|
||||||
* `unresolveElement` because these classes should eventually be part of the
|
|
||||||
* implementation of `ResolveClass.qll`, allowing it to match up classes when
|
|
||||||
* their qualified names and parameters match.
|
|
||||||
*/
|
*/
|
||||||
|
|
||||||
private import semmle.code.cpp.Declaration as D
|
private import semmle.code.cpp.Declaration as D
|
||||||
|
|||||||
@@ -115,15 +115,13 @@ private module Cached {
|
|||||||
*/
|
*/
|
||||||
cached
|
cached
|
||||||
predicate isClass(@usertype t) {
|
predicate isClass(@usertype t) {
|
||||||
(
|
usertypes(t, _, 1) or
|
||||||
usertypes(t, _, 1) or
|
usertypes(t, _, 2) or
|
||||||
usertypes(t, _, 2) or
|
usertypes(t, _, 3) or
|
||||||
usertypes(t, _, 3) or
|
usertypes(t, _, 6) or
|
||||||
usertypes(t, _, 6) or
|
usertypes(t, _, 10) or
|
||||||
usertypes(t, _, 10) or
|
usertypes(t, _, 11) or
|
||||||
usertypes(t, _, 11) or
|
usertypes(t, _, 12)
|
||||||
usertypes(t, _, 12)
|
|
||||||
)
|
|
||||||
}
|
}
|
||||||
|
|
||||||
cached
|
cached
|
||||||
|
|||||||
@@ -90,14 +90,20 @@ abstract class Configuration extends string {
|
|||||||
/** Holds if data flow out of `node` is prohibited. */
|
/** Holds if data flow out of `node` is prohibited. */
|
||||||
predicate isBarrierOut(Node node) { none() }
|
predicate isBarrierOut(Node node) { none() }
|
||||||
|
|
||||||
/** Holds if data flow through nodes guarded by `guard` is prohibited. */
|
/**
|
||||||
predicate isBarrierGuard(BarrierGuard guard) { none() }
|
* DEPRECATED: Use `isBarrier` and `BarrierGuard` module instead.
|
||||||
|
*
|
||||||
|
* Holds if data flow through nodes guarded by `guard` is prohibited.
|
||||||
|
*/
|
||||||
|
deprecated predicate isBarrierGuard(BarrierGuard guard) { none() }
|
||||||
|
|
||||||
/**
|
/**
|
||||||
|
* DEPRECATED: Use `isBarrier` and `BarrierGuard` module instead.
|
||||||
|
*
|
||||||
* Holds if data flow through nodes guarded by `guard` is prohibited when
|
* Holds if data flow through nodes guarded by `guard` is prohibited when
|
||||||
* the flow state is `state`
|
* the flow state is `state`
|
||||||
*/
|
*/
|
||||||
predicate isBarrierGuard(BarrierGuard guard, FlowState state) { none() }
|
deprecated predicate isBarrierGuard(BarrierGuard guard, FlowState state) { none() }
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Holds if data may flow from `node1` to `node2` in addition to the normal data-flow steps.
|
* Holds if data may flow from `node1` to `node2` in addition to the normal data-flow steps.
|
||||||
@@ -335,6 +341,29 @@ private predicate outBarrier(NodeEx node, Configuration config) {
|
|||||||
)
|
)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/** A bridge class to access the deprecated `isBarrierGuard`. */
|
||||||
|
private class BarrierGuardGuardedNodeBridge extends Unit {
|
||||||
|
abstract predicate guardedNode(Node n, Configuration config);
|
||||||
|
|
||||||
|
abstract predicate guardedNode(Node n, FlowState state, Configuration config);
|
||||||
|
}
|
||||||
|
|
||||||
|
private class BarrierGuardGuardedNode extends BarrierGuardGuardedNodeBridge {
|
||||||
|
deprecated override predicate guardedNode(Node n, Configuration config) {
|
||||||
|
exists(BarrierGuard g |
|
||||||
|
config.isBarrierGuard(g) and
|
||||||
|
n = g.getAGuardedNode()
|
||||||
|
)
|
||||||
|
}
|
||||||
|
|
||||||
|
deprecated override predicate guardedNode(Node n, FlowState state, Configuration config) {
|
||||||
|
exists(BarrierGuard g |
|
||||||
|
config.isBarrierGuard(g, state) and
|
||||||
|
n = g.getAGuardedNode()
|
||||||
|
)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
pragma[nomagic]
|
pragma[nomagic]
|
||||||
private predicate fullBarrier(NodeEx node, Configuration config) {
|
private predicate fullBarrier(NodeEx node, Configuration config) {
|
||||||
exists(Node n | node.asNode() = n |
|
exists(Node n | node.asNode() = n |
|
||||||
@@ -348,10 +377,7 @@ private predicate fullBarrier(NodeEx node, Configuration config) {
|
|||||||
not config.isSink(n) and
|
not config.isSink(n) and
|
||||||
not config.isSink(n, _)
|
not config.isSink(n, _)
|
||||||
or
|
or
|
||||||
exists(BarrierGuard g |
|
any(BarrierGuardGuardedNodeBridge b).guardedNode(n, config)
|
||||||
config.isBarrierGuard(g) and
|
|
||||||
n = g.getAGuardedNode()
|
|
||||||
)
|
|
||||||
)
|
)
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -360,10 +386,7 @@ private predicate stateBarrier(NodeEx node, FlowState state, Configuration confi
|
|||||||
exists(Node n | node.asNode() = n |
|
exists(Node n | node.asNode() = n |
|
||||||
config.isBarrier(n, state)
|
config.isBarrier(n, state)
|
||||||
or
|
or
|
||||||
exists(BarrierGuard g |
|
any(BarrierGuardGuardedNodeBridge b).guardedNode(n, state, config)
|
||||||
config.isBarrierGuard(g, state) and
|
|
||||||
n = g.getAGuardedNode()
|
|
||||||
)
|
|
||||||
)
|
)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@@ -90,14 +90,20 @@ abstract class Configuration extends string {
|
|||||||
/** Holds if data flow out of `node` is prohibited. */
|
/** Holds if data flow out of `node` is prohibited. */
|
||||||
predicate isBarrierOut(Node node) { none() }
|
predicate isBarrierOut(Node node) { none() }
|
||||||
|
|
||||||
/** Holds if data flow through nodes guarded by `guard` is prohibited. */
|
/**
|
||||||
predicate isBarrierGuard(BarrierGuard guard) { none() }
|
* DEPRECATED: Use `isBarrier` and `BarrierGuard` module instead.
|
||||||
|
*
|
||||||
|
* Holds if data flow through nodes guarded by `guard` is prohibited.
|
||||||
|
*/
|
||||||
|
deprecated predicate isBarrierGuard(BarrierGuard guard) { none() }
|
||||||
|
|
||||||
/**
|
/**
|
||||||
|
* DEPRECATED: Use `isBarrier` and `BarrierGuard` module instead.
|
||||||
|
*
|
||||||
* Holds if data flow through nodes guarded by `guard` is prohibited when
|
* Holds if data flow through nodes guarded by `guard` is prohibited when
|
||||||
* the flow state is `state`
|
* the flow state is `state`
|
||||||
*/
|
*/
|
||||||
predicate isBarrierGuard(BarrierGuard guard, FlowState state) { none() }
|
deprecated predicate isBarrierGuard(BarrierGuard guard, FlowState state) { none() }
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Holds if data may flow from `node1` to `node2` in addition to the normal data-flow steps.
|
* Holds if data may flow from `node1` to `node2` in addition to the normal data-flow steps.
|
||||||
@@ -335,6 +341,29 @@ private predicate outBarrier(NodeEx node, Configuration config) {
|
|||||||
)
|
)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/** A bridge class to access the deprecated `isBarrierGuard`. */
|
||||||
|
private class BarrierGuardGuardedNodeBridge extends Unit {
|
||||||
|
abstract predicate guardedNode(Node n, Configuration config);
|
||||||
|
|
||||||
|
abstract predicate guardedNode(Node n, FlowState state, Configuration config);
|
||||||
|
}
|
||||||
|
|
||||||
|
private class BarrierGuardGuardedNode extends BarrierGuardGuardedNodeBridge {
|
||||||
|
deprecated override predicate guardedNode(Node n, Configuration config) {
|
||||||
|
exists(BarrierGuard g |
|
||||||
|
config.isBarrierGuard(g) and
|
||||||
|
n = g.getAGuardedNode()
|
||||||
|
)
|
||||||
|
}
|
||||||
|
|
||||||
|
deprecated override predicate guardedNode(Node n, FlowState state, Configuration config) {
|
||||||
|
exists(BarrierGuard g |
|
||||||
|
config.isBarrierGuard(g, state) and
|
||||||
|
n = g.getAGuardedNode()
|
||||||
|
)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
pragma[nomagic]
|
pragma[nomagic]
|
||||||
private predicate fullBarrier(NodeEx node, Configuration config) {
|
private predicate fullBarrier(NodeEx node, Configuration config) {
|
||||||
exists(Node n | node.asNode() = n |
|
exists(Node n | node.asNode() = n |
|
||||||
@@ -348,10 +377,7 @@ private predicate fullBarrier(NodeEx node, Configuration config) {
|
|||||||
not config.isSink(n) and
|
not config.isSink(n) and
|
||||||
not config.isSink(n, _)
|
not config.isSink(n, _)
|
||||||
or
|
or
|
||||||
exists(BarrierGuard g |
|
any(BarrierGuardGuardedNodeBridge b).guardedNode(n, config)
|
||||||
config.isBarrierGuard(g) and
|
|
||||||
n = g.getAGuardedNode()
|
|
||||||
)
|
|
||||||
)
|
)
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -360,10 +386,7 @@ private predicate stateBarrier(NodeEx node, FlowState state, Configuration confi
|
|||||||
exists(Node n | node.asNode() = n |
|
exists(Node n | node.asNode() = n |
|
||||||
config.isBarrier(n, state)
|
config.isBarrier(n, state)
|
||||||
or
|
or
|
||||||
exists(BarrierGuard g |
|
any(BarrierGuardGuardedNodeBridge b).guardedNode(n, state, config)
|
||||||
config.isBarrierGuard(g, state) and
|
|
||||||
n = g.getAGuardedNode()
|
|
||||||
)
|
|
||||||
)
|
)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@@ -90,14 +90,20 @@ abstract class Configuration extends string {
|
|||||||
/** Holds if data flow out of `node` is prohibited. */
|
/** Holds if data flow out of `node` is prohibited. */
|
||||||
predicate isBarrierOut(Node node) { none() }
|
predicate isBarrierOut(Node node) { none() }
|
||||||
|
|
||||||
/** Holds if data flow through nodes guarded by `guard` is prohibited. */
|
/**
|
||||||
predicate isBarrierGuard(BarrierGuard guard) { none() }
|
* DEPRECATED: Use `isBarrier` and `BarrierGuard` module instead.
|
||||||
|
*
|
||||||
|
* Holds if data flow through nodes guarded by `guard` is prohibited.
|
||||||
|
*/
|
||||||
|
deprecated predicate isBarrierGuard(BarrierGuard guard) { none() }
|
||||||
|
|
||||||
/**
|
/**
|
||||||
|
* DEPRECATED: Use `isBarrier` and `BarrierGuard` module instead.
|
||||||
|
*
|
||||||
* Holds if data flow through nodes guarded by `guard` is prohibited when
|
* Holds if data flow through nodes guarded by `guard` is prohibited when
|
||||||
* the flow state is `state`
|
* the flow state is `state`
|
||||||
*/
|
*/
|
||||||
predicate isBarrierGuard(BarrierGuard guard, FlowState state) { none() }
|
deprecated predicate isBarrierGuard(BarrierGuard guard, FlowState state) { none() }
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Holds if data may flow from `node1` to `node2` in addition to the normal data-flow steps.
|
* Holds if data may flow from `node1` to `node2` in addition to the normal data-flow steps.
|
||||||
@@ -335,6 +341,29 @@ private predicate outBarrier(NodeEx node, Configuration config) {
|
|||||||
)
|
)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/** A bridge class to access the deprecated `isBarrierGuard`. */
|
||||||
|
private class BarrierGuardGuardedNodeBridge extends Unit {
|
||||||
|
abstract predicate guardedNode(Node n, Configuration config);
|
||||||
|
|
||||||
|
abstract predicate guardedNode(Node n, FlowState state, Configuration config);
|
||||||
|
}
|
||||||
|
|
||||||
|
private class BarrierGuardGuardedNode extends BarrierGuardGuardedNodeBridge {
|
||||||
|
deprecated override predicate guardedNode(Node n, Configuration config) {
|
||||||
|
exists(BarrierGuard g |
|
||||||
|
config.isBarrierGuard(g) and
|
||||||
|
n = g.getAGuardedNode()
|
||||||
|
)
|
||||||
|
}
|
||||||
|
|
||||||
|
deprecated override predicate guardedNode(Node n, FlowState state, Configuration config) {
|
||||||
|
exists(BarrierGuard g |
|
||||||
|
config.isBarrierGuard(g, state) and
|
||||||
|
n = g.getAGuardedNode()
|
||||||
|
)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
pragma[nomagic]
|
pragma[nomagic]
|
||||||
private predicate fullBarrier(NodeEx node, Configuration config) {
|
private predicate fullBarrier(NodeEx node, Configuration config) {
|
||||||
exists(Node n | node.asNode() = n |
|
exists(Node n | node.asNode() = n |
|
||||||
@@ -348,10 +377,7 @@ private predicate fullBarrier(NodeEx node, Configuration config) {
|
|||||||
not config.isSink(n) and
|
not config.isSink(n) and
|
||||||
not config.isSink(n, _)
|
not config.isSink(n, _)
|
||||||
or
|
or
|
||||||
exists(BarrierGuard g |
|
any(BarrierGuardGuardedNodeBridge b).guardedNode(n, config)
|
||||||
config.isBarrierGuard(g) and
|
|
||||||
n = g.getAGuardedNode()
|
|
||||||
)
|
|
||||||
)
|
)
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -360,10 +386,7 @@ private predicate stateBarrier(NodeEx node, FlowState state, Configuration confi
|
|||||||
exists(Node n | node.asNode() = n |
|
exists(Node n | node.asNode() = n |
|
||||||
config.isBarrier(n, state)
|
config.isBarrier(n, state)
|
||||||
or
|
or
|
||||||
exists(BarrierGuard g |
|
any(BarrierGuardGuardedNodeBridge b).guardedNode(n, state, config)
|
||||||
config.isBarrierGuard(g, state) and
|
|
||||||
n = g.getAGuardedNode()
|
|
||||||
)
|
|
||||||
)
|
)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@@ -90,14 +90,20 @@ abstract class Configuration extends string {
|
|||||||
/** Holds if data flow out of `node` is prohibited. */
|
/** Holds if data flow out of `node` is prohibited. */
|
||||||
predicate isBarrierOut(Node node) { none() }
|
predicate isBarrierOut(Node node) { none() }
|
||||||
|
|
||||||
/** Holds if data flow through nodes guarded by `guard` is prohibited. */
|
/**
|
||||||
predicate isBarrierGuard(BarrierGuard guard) { none() }
|
* DEPRECATED: Use `isBarrier` and `BarrierGuard` module instead.
|
||||||
|
*
|
||||||
|
* Holds if data flow through nodes guarded by `guard` is prohibited.
|
||||||
|
*/
|
||||||
|
deprecated predicate isBarrierGuard(BarrierGuard guard) { none() }
|
||||||
|
|
||||||
/**
|
/**
|
||||||
|
* DEPRECATED: Use `isBarrier` and `BarrierGuard` module instead.
|
||||||
|
*
|
||||||
* Holds if data flow through nodes guarded by `guard` is prohibited when
|
* Holds if data flow through nodes guarded by `guard` is prohibited when
|
||||||
* the flow state is `state`
|
* the flow state is `state`
|
||||||
*/
|
*/
|
||||||
predicate isBarrierGuard(BarrierGuard guard, FlowState state) { none() }
|
deprecated predicate isBarrierGuard(BarrierGuard guard, FlowState state) { none() }
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Holds if data may flow from `node1` to `node2` in addition to the normal data-flow steps.
|
* Holds if data may flow from `node1` to `node2` in addition to the normal data-flow steps.
|
||||||
@@ -335,6 +341,29 @@ private predicate outBarrier(NodeEx node, Configuration config) {
|
|||||||
)
|
)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/** A bridge class to access the deprecated `isBarrierGuard`. */
|
||||||
|
private class BarrierGuardGuardedNodeBridge extends Unit {
|
||||||
|
abstract predicate guardedNode(Node n, Configuration config);
|
||||||
|
|
||||||
|
abstract predicate guardedNode(Node n, FlowState state, Configuration config);
|
||||||
|
}
|
||||||
|
|
||||||
|
private class BarrierGuardGuardedNode extends BarrierGuardGuardedNodeBridge {
|
||||||
|
deprecated override predicate guardedNode(Node n, Configuration config) {
|
||||||
|
exists(BarrierGuard g |
|
||||||
|
config.isBarrierGuard(g) and
|
||||||
|
n = g.getAGuardedNode()
|
||||||
|
)
|
||||||
|
}
|
||||||
|
|
||||||
|
deprecated override predicate guardedNode(Node n, FlowState state, Configuration config) {
|
||||||
|
exists(BarrierGuard g |
|
||||||
|
config.isBarrierGuard(g, state) and
|
||||||
|
n = g.getAGuardedNode()
|
||||||
|
)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
pragma[nomagic]
|
pragma[nomagic]
|
||||||
private predicate fullBarrier(NodeEx node, Configuration config) {
|
private predicate fullBarrier(NodeEx node, Configuration config) {
|
||||||
exists(Node n | node.asNode() = n |
|
exists(Node n | node.asNode() = n |
|
||||||
@@ -348,10 +377,7 @@ private predicate fullBarrier(NodeEx node, Configuration config) {
|
|||||||
not config.isSink(n) and
|
not config.isSink(n) and
|
||||||
not config.isSink(n, _)
|
not config.isSink(n, _)
|
||||||
or
|
or
|
||||||
exists(BarrierGuard g |
|
any(BarrierGuardGuardedNodeBridge b).guardedNode(n, config)
|
||||||
config.isBarrierGuard(g) and
|
|
||||||
n = g.getAGuardedNode()
|
|
||||||
)
|
|
||||||
)
|
)
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -360,10 +386,7 @@ private predicate stateBarrier(NodeEx node, FlowState state, Configuration confi
|
|||||||
exists(Node n | node.asNode() = n |
|
exists(Node n | node.asNode() = n |
|
||||||
config.isBarrier(n, state)
|
config.isBarrier(n, state)
|
||||||
or
|
or
|
||||||
exists(BarrierGuard g |
|
any(BarrierGuardGuardedNodeBridge b).guardedNode(n, state, config)
|
||||||
config.isBarrierGuard(g, state) and
|
|
||||||
n = g.getAGuardedNode()
|
|
||||||
)
|
|
||||||
)
|
)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@@ -1092,6 +1092,56 @@ class ContentSet instanceof Content {
|
|||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
|
* Holds if the guard `g` validates the expression `e` upon evaluating to `branch`.
|
||||||
|
*
|
||||||
|
* The expression `e` is expected to be a syntactic part of the guard `g`.
|
||||||
|
* For example, the guard `g` might be a call `isSafe(x)` and the expression `e`
|
||||||
|
* the argument `x`.
|
||||||
|
*/
|
||||||
|
signature predicate guardChecksSig(IRGuardCondition g, Expr e, boolean branch);
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Provides a set of barrier nodes for a guard that validates an expression.
|
||||||
|
*
|
||||||
|
* This is expected to be used in `isBarrier`/`isSanitizer` definitions
|
||||||
|
* in data flow and taint tracking.
|
||||||
|
*/
|
||||||
|
module BarrierGuard<guardChecksSig/3 guardChecks> {
|
||||||
|
/** Gets a node that is safely guarded by the given guard check. */
|
||||||
|
ExprNode getABarrierNode() {
|
||||||
|
exists(IRGuardCondition g, ValueNumber value, boolean edge |
|
||||||
|
guardChecks(g, value.getAnInstruction().getConvertedResultExpression(), edge) and
|
||||||
|
result.asInstruction() = value.getAnInstruction() and
|
||||||
|
g.controls(result.asInstruction().getBlock(), edge)
|
||||||
|
)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Holds if the guard `g` validates the instruction `instr` upon evaluating to `branch`.
|
||||||
|
*/
|
||||||
|
signature predicate instructionGuardChecksSig(IRGuardCondition g, Instruction instr, boolean branch);
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Provides a set of barrier nodes for a guard that validates an instruction.
|
||||||
|
*
|
||||||
|
* This is expected to be used in `isBarrier`/`isSanitizer` definitions
|
||||||
|
* in data flow and taint tracking.
|
||||||
|
*/
|
||||||
|
module InstructionBarrierGuard<instructionGuardChecksSig/3 instructionGuardChecks> {
|
||||||
|
/** Gets a node that is safely guarded by the given guard check. */
|
||||||
|
ExprNode getABarrierNode() {
|
||||||
|
exists(IRGuardCondition g, ValueNumber value, boolean edge |
|
||||||
|
instructionGuardChecks(g, value.getAnInstruction(), edge) and
|
||||||
|
result.asInstruction() = value.getAnInstruction() and
|
||||||
|
g.controls(result.asInstruction().getBlock(), edge)
|
||||||
|
)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* DEPRECATED: Use `BarrierGuard` module instead.
|
||||||
|
*
|
||||||
* A guard that validates some instruction.
|
* A guard that validates some instruction.
|
||||||
*
|
*
|
||||||
* To use this in a configuration, extend the class and provide a
|
* To use this in a configuration, extend the class and provide a
|
||||||
@@ -1100,7 +1150,7 @@ class ContentSet instanceof Content {
|
|||||||
*
|
*
|
||||||
* It is important that all extending classes in scope are disjoint.
|
* It is important that all extending classes in scope are disjoint.
|
||||||
*/
|
*/
|
||||||
class BarrierGuard extends IRGuardCondition {
|
deprecated class BarrierGuard extends IRGuardCondition {
|
||||||
/** Override this predicate to hold if this guard validates `instr` upon evaluating to `b`. */
|
/** Override this predicate to hold if this guard validates `instr` upon evaluating to `b`. */
|
||||||
predicate checksInstr(Instruction instr, boolean b) { none() }
|
predicate checksInstr(Instruction instr, boolean b) { none() }
|
||||||
|
|
||||||
|
|||||||
@@ -94,12 +94,6 @@ private string getNodeProperty(DataFlow::Node node, string key) {
|
|||||||
any(DataFlow::Configuration cfg).isBarrierIn(node) and kind = "in"
|
any(DataFlow::Configuration cfg).isBarrierIn(node) and kind = "in"
|
||||||
or
|
or
|
||||||
any(DataFlow::Configuration cfg).isBarrierOut(node) and kind = "out"
|
any(DataFlow::Configuration cfg).isBarrierOut(node) and kind = "out"
|
||||||
or
|
|
||||||
exists(DataFlow::BarrierGuard guard |
|
|
||||||
any(DataFlow::Configuration cfg).isBarrierGuard(guard) and
|
|
||||||
node = guard.getAGuardedNode() and
|
|
||||||
kind = "guard(" + guard.getResultId() + ")"
|
|
||||||
)
|
|
||||||
|
|
|
|
||||||
kind, ", "
|
kind, ", "
|
||||||
)
|
)
|
||||||
|
|||||||
@@ -163,12 +163,6 @@ predicate defaultImplicitTaintRead(DataFlow::Node node, DataFlow::Content c) { n
|
|||||||
*/
|
*/
|
||||||
predicate defaultTaintSanitizer(DataFlow::Node node) { none() }
|
predicate defaultTaintSanitizer(DataFlow::Node node) { none() }
|
||||||
|
|
||||||
/**
|
|
||||||
* Holds if `guard` should be a sanitizer guard in all global taint flow configurations
|
|
||||||
* but not in local taint.
|
|
||||||
*/
|
|
||||||
predicate defaultTaintSanitizerGuard(DataFlow::BarrierGuard guard) { none() }
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Holds if taint can flow from `instrIn` to `instrOut` through a call to a
|
* Holds if taint can flow from `instrIn` to `instrOut` through a call to a
|
||||||
* modeled function.
|
* modeled function.
|
||||||
|
|||||||
@@ -116,20 +116,30 @@ abstract class Configuration extends DataFlow::Configuration {
|
|||||||
|
|
||||||
final override predicate isBarrierOut(DataFlow::Node node) { this.isSanitizerOut(node) }
|
final override predicate isBarrierOut(DataFlow::Node node) { this.isSanitizerOut(node) }
|
||||||
|
|
||||||
/** Holds if taint propagation through nodes guarded by `guard` is prohibited. */
|
/**
|
||||||
predicate isSanitizerGuard(DataFlow::BarrierGuard guard) { none() }
|
* DEPRECATED: Use `isSanitizer` and `BarrierGuard` module instead.
|
||||||
|
*
|
||||||
|
* Holds if taint propagation through nodes guarded by `guard` is prohibited.
|
||||||
|
*/
|
||||||
|
deprecated predicate isSanitizerGuard(DataFlow::BarrierGuard guard) { none() }
|
||||||
|
|
||||||
final override predicate isBarrierGuard(DataFlow::BarrierGuard guard) {
|
deprecated final override predicate isBarrierGuard(DataFlow::BarrierGuard guard) {
|
||||||
this.isSanitizerGuard(guard) or defaultTaintSanitizerGuard(guard)
|
this.isSanitizerGuard(guard)
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
|
* DEPRECATED: Use `isSanitizer` and `BarrierGuard` module instead.
|
||||||
|
*
|
||||||
* Holds if taint propagation through nodes guarded by `guard` is prohibited
|
* Holds if taint propagation through nodes guarded by `guard` is prohibited
|
||||||
* when the flow state is `state`.
|
* when the flow state is `state`.
|
||||||
*/
|
*/
|
||||||
predicate isSanitizerGuard(DataFlow::BarrierGuard guard, DataFlow::FlowState state) { none() }
|
deprecated predicate isSanitizerGuard(DataFlow::BarrierGuard guard, DataFlow::FlowState state) {
|
||||||
|
none()
|
||||||
|
}
|
||||||
|
|
||||||
final override predicate isBarrierGuard(DataFlow::BarrierGuard guard, DataFlow::FlowState state) {
|
deprecated final override predicate isBarrierGuard(
|
||||||
|
DataFlow::BarrierGuard guard, DataFlow::FlowState state
|
||||||
|
) {
|
||||||
this.isSanitizerGuard(guard, state)
|
this.isSanitizerGuard(guard, state)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@@ -116,20 +116,30 @@ abstract class Configuration extends DataFlow::Configuration {
|
|||||||
|
|
||||||
final override predicate isBarrierOut(DataFlow::Node node) { this.isSanitizerOut(node) }
|
final override predicate isBarrierOut(DataFlow::Node node) { this.isSanitizerOut(node) }
|
||||||
|
|
||||||
/** Holds if taint propagation through nodes guarded by `guard` is prohibited. */
|
/**
|
||||||
predicate isSanitizerGuard(DataFlow::BarrierGuard guard) { none() }
|
* DEPRECATED: Use `isSanitizer` and `BarrierGuard` module instead.
|
||||||
|
*
|
||||||
|
* Holds if taint propagation through nodes guarded by `guard` is prohibited.
|
||||||
|
*/
|
||||||
|
deprecated predicate isSanitizerGuard(DataFlow::BarrierGuard guard) { none() }
|
||||||
|
|
||||||
final override predicate isBarrierGuard(DataFlow::BarrierGuard guard) {
|
deprecated final override predicate isBarrierGuard(DataFlow::BarrierGuard guard) {
|
||||||
this.isSanitizerGuard(guard) or defaultTaintSanitizerGuard(guard)
|
this.isSanitizerGuard(guard)
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
|
* DEPRECATED: Use `isSanitizer` and `BarrierGuard` module instead.
|
||||||
|
*
|
||||||
* Holds if taint propagation through nodes guarded by `guard` is prohibited
|
* Holds if taint propagation through nodes guarded by `guard` is prohibited
|
||||||
* when the flow state is `state`.
|
* when the flow state is `state`.
|
||||||
*/
|
*/
|
||||||
predicate isSanitizerGuard(DataFlow::BarrierGuard guard, DataFlow::FlowState state) { none() }
|
deprecated predicate isSanitizerGuard(DataFlow::BarrierGuard guard, DataFlow::FlowState state) {
|
||||||
|
none()
|
||||||
|
}
|
||||||
|
|
||||||
final override predicate isBarrierGuard(DataFlow::BarrierGuard guard, DataFlow::FlowState state) {
|
deprecated final override predicate isBarrierGuard(
|
||||||
|
DataFlow::BarrierGuard guard, DataFlow::FlowState state
|
||||||
|
) {
|
||||||
this.isSanitizerGuard(guard, state)
|
this.isSanitizerGuard(guard, state)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@@ -116,20 +116,30 @@ abstract class Configuration extends DataFlow::Configuration {
|
|||||||
|
|
||||||
final override predicate isBarrierOut(DataFlow::Node node) { this.isSanitizerOut(node) }
|
final override predicate isBarrierOut(DataFlow::Node node) { this.isSanitizerOut(node) }
|
||||||
|
|
||||||
/** Holds if taint propagation through nodes guarded by `guard` is prohibited. */
|
/**
|
||||||
predicate isSanitizerGuard(DataFlow::BarrierGuard guard) { none() }
|
* DEPRECATED: Use `isSanitizer` and `BarrierGuard` module instead.
|
||||||
|
*
|
||||||
|
* Holds if taint propagation through nodes guarded by `guard` is prohibited.
|
||||||
|
*/
|
||||||
|
deprecated predicate isSanitizerGuard(DataFlow::BarrierGuard guard) { none() }
|
||||||
|
|
||||||
final override predicate isBarrierGuard(DataFlow::BarrierGuard guard) {
|
deprecated final override predicate isBarrierGuard(DataFlow::BarrierGuard guard) {
|
||||||
this.isSanitizerGuard(guard) or defaultTaintSanitizerGuard(guard)
|
this.isSanitizerGuard(guard)
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
|
* DEPRECATED: Use `isSanitizer` and `BarrierGuard` module instead.
|
||||||
|
*
|
||||||
* Holds if taint propagation through nodes guarded by `guard` is prohibited
|
* Holds if taint propagation through nodes guarded by `guard` is prohibited
|
||||||
* when the flow state is `state`.
|
* when the flow state is `state`.
|
||||||
*/
|
*/
|
||||||
predicate isSanitizerGuard(DataFlow::BarrierGuard guard, DataFlow::FlowState state) { none() }
|
deprecated predicate isSanitizerGuard(DataFlow::BarrierGuard guard, DataFlow::FlowState state) {
|
||||||
|
none()
|
||||||
|
}
|
||||||
|
|
||||||
final override predicate isBarrierGuard(DataFlow::BarrierGuard guard, DataFlow::FlowState state) {
|
deprecated final override predicate isBarrierGuard(
|
||||||
|
DataFlow::BarrierGuard guard, DataFlow::FlowState state
|
||||||
|
) {
|
||||||
this.isSanitizerGuard(guard, state)
|
this.isSanitizerGuard(guard, state)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@@ -1,3 +1,5 @@
|
|||||||
|
## 0.1.4
|
||||||
|
|
||||||
## 0.1.3
|
## 0.1.3
|
||||||
|
|
||||||
### Minor Analysis Improvements
|
### Minor Analysis Improvements
|
||||||
|
|||||||
1
cpp/ql/src/change-notes/released/0.1.4.md
Normal file
1
cpp/ql/src/change-notes/released/0.1.4.md
Normal file
@@ -0,0 +1 @@
|
|||||||
|
## 0.1.4
|
||||||
@@ -1,2 +1,2 @@
|
|||||||
---
|
---
|
||||||
lastReleaseVersion: 0.1.3
|
lastReleaseVersion: 0.1.4
|
||||||
|
|||||||
@@ -0,0 +1,11 @@
|
|||||||
|
...
|
||||||
|
SSL_shutdown(ssl);
|
||||||
|
SSL_shutdown(ssl); // BAD
|
||||||
|
...
|
||||||
|
switch ((ret = SSL_shutdown(ssl))) {
|
||||||
|
case 1:
|
||||||
|
break;
|
||||||
|
case 0:
|
||||||
|
ERR_clear_error();
|
||||||
|
if (-1 != (ret = SSL_shutdown(ssl))) break; // GOOD
|
||||||
|
...
|
||||||
@@ -0,0 +1,27 @@
|
|||||||
|
<!DOCTYPE qhelp PUBLIC
|
||||||
|
"-//Semmle//qhelp//EN"
|
||||||
|
"qhelp.dtd">
|
||||||
|
<qhelp>
|
||||||
|
<overview>
|
||||||
|
<p>Incorrect closing of the connection leads to the creation of different states for the server and client, which can be exploited by an attacker.</p>
|
||||||
|
|
||||||
|
</overview>
|
||||||
|
|
||||||
|
<example>
|
||||||
|
<p>The following example shows the incorrect and correct usage of function SSL_shutdown.</p>
|
||||||
|
<sample src="DangerousUseSSL_shutdown.cpp" />
|
||||||
|
|
||||||
|
</example>
|
||||||
|
<references>
|
||||||
|
|
||||||
|
<li>
|
||||||
|
CERT Coding Standard:
|
||||||
|
<a href="https://wiki.sei.cmu.edu/confluence/display/c/EXP12-C.+Do+not+ignore+values+returned+by+functions">EXP12-C. Do not ignore values returned by functions - SEI CERT C Coding Standard - Confluence</a>.
|
||||||
|
</li>
|
||||||
|
<li>
|
||||||
|
Openssl.org:
|
||||||
|
<a href="https://www.openssl.org/docs/man3.0/man3/SSL_shutdown.html">SSL_shutdown - shut down a TLS/SSL connection</a>.
|
||||||
|
</li>
|
||||||
|
|
||||||
|
</references>
|
||||||
|
</qhelp>
|
||||||
@@ -0,0 +1,33 @@
|
|||||||
|
/**
|
||||||
|
* @name Dangerous use SSL_shutdown.
|
||||||
|
* @description Incorrect closing of the connection leads to the creation of different states for the server and client, which can be exploited by an attacker.
|
||||||
|
* @kind problem
|
||||||
|
* @id cpp/dangerous-use-of-ssl-shutdown
|
||||||
|
* @problem.severity warning
|
||||||
|
* @precision medium
|
||||||
|
* @tags correctness
|
||||||
|
* security
|
||||||
|
* external/cwe/cwe-670
|
||||||
|
*/
|
||||||
|
|
||||||
|
import cpp
|
||||||
|
import semmle.code.cpp.commons.Exclusions
|
||||||
|
import semmle.code.cpp.valuenumbering.GlobalValueNumbering
|
||||||
|
|
||||||
|
from FunctionCall fc, FunctionCall fc1
|
||||||
|
where
|
||||||
|
fc != fc1 and
|
||||||
|
fc.getASuccessor+() = fc1 and
|
||||||
|
fc.getTarget().hasName("SSL_shutdown") and
|
||||||
|
fc1.getTarget().hasName("SSL_shutdown") and
|
||||||
|
fc1 instanceof ExprInVoidContext and
|
||||||
|
(
|
||||||
|
globalValueNumber(fc.getArgument(0)) = globalValueNumber(fc1.getArgument(0)) or
|
||||||
|
fc.getArgument(0).(VariableAccess).getTarget() = fc1.getArgument(0).(VariableAccess).getTarget()
|
||||||
|
) and
|
||||||
|
not exists(FunctionCall fctmp |
|
||||||
|
fctmp.getTarget().hasName("SSL_free") and
|
||||||
|
fc.getASuccessor+() = fctmp and
|
||||||
|
fctmp.getASuccessor+() = fc1
|
||||||
|
)
|
||||||
|
select fc, "You need to handle the return value SSL_shutdown"
|
||||||
@@ -1,5 +1,5 @@
|
|||||||
name: codeql/cpp-queries
|
name: codeql/cpp-queries
|
||||||
version: 0.1.4-dev
|
version: 0.2.0-dev
|
||||||
groups:
|
groups:
|
||||||
- cpp
|
- cpp
|
||||||
- queries
|
- queries
|
||||||
|
|||||||
@@ -239,12 +239,24 @@ private string getColumnString(TColumn column) {
|
|||||||
|
|
||||||
/**
|
/**
|
||||||
* RegEx pattern to match a single expected result, not including the leading `$`. It consists of one or
|
* RegEx pattern to match a single expected result, not including the leading `$`. It consists of one or
|
||||||
* more comma-separated tags containing only letters, digits, `-` and `_` (note that the first character
|
* more comma-separated tags optionally followed by `=` and the expected value.
|
||||||
* must not be a digit), optionally followed by `=` and the expected value.
|
*
|
||||||
|
* Tags must be only letters, digits, `-` and `_` (note that the first character
|
||||||
|
* must not be a digit), but can contain anything enclosed in a single set of
|
||||||
|
* square brackets.
|
||||||
|
*
|
||||||
|
* Examples:
|
||||||
|
* - `tag`
|
||||||
|
* - `tag=value`
|
||||||
|
* - `tag,tag2=value`
|
||||||
|
* - `tag[foo bar]=value`
|
||||||
|
*
|
||||||
|
* Not allowed:
|
||||||
|
* - `tag[[[foo bar]`
|
||||||
*/
|
*/
|
||||||
private string expectationPattern() {
|
private string expectationPattern() {
|
||||||
exists(string tag, string tags, string value |
|
exists(string tag, string tags, string value |
|
||||||
tag = "[A-Za-z-_][A-Za-z-_0-9]*" and
|
tag = "[A-Za-z-_](?:[A-Za-z-_0-9]|\\[[^\\]\\]]*\\])*" and
|
||||||
tags = "((?:" + tag + ")(?:\\s*,\\s*" + tag + ")*)" and
|
tags = "((?:" + tag + ")(?:\\s*,\\s*" + tag + ")*)" and
|
||||||
// In Python, we allow both `"` and `'` for strings, as well as the prefixes `bru`.
|
// In Python, we allow both `"` and `'` for strings, as well as the prefixes `bru`.
|
||||||
// For example, `b"foo"`.
|
// For example, `b"foo"`.
|
||||||
|
|||||||
@@ -0,0 +1,2 @@
|
|||||||
|
| test.cpp:45:20:45:31 | call to SSL_shutdown | You need to handle the return value SSL_shutdown |
|
||||||
|
| test.cpp:61:11:61:22 | call to SSL_shutdown | You need to handle the return value SSL_shutdown |
|
||||||
@@ -0,0 +1 @@
|
|||||||
|
experimental/Security/CWE/CWE-670/DangerousUseSSL_shutdown.ql
|
||||||
@@ -0,0 +1,75 @@
|
|||||||
|
// it's not exact, but it's enough for an example
|
||||||
|
typedef int SSL;
|
||||||
|
|
||||||
|
|
||||||
|
int SSL_shutdown(SSL *ssl);
|
||||||
|
int SSL_get_error(const SSL *ssl, int ret);
|
||||||
|
void ERR_clear_error(void);
|
||||||
|
void print_error(char *buff,int code);
|
||||||
|
|
||||||
|
int gootTest1(SSL *ssl)
|
||||||
|
{
|
||||||
|
int ret;
|
||||||
|
switch ((ret = SSL_shutdown(ssl))) {
|
||||||
|
case 1:
|
||||||
|
break;
|
||||||
|
case 0:
|
||||||
|
ERR_clear_error();
|
||||||
|
if ((ret = SSL_shutdown(ssl)) == 1) break; // GOOD
|
||||||
|
default:
|
||||||
|
print_error("error shutdown",
|
||||||
|
SSL_get_error(ssl, ret));
|
||||||
|
return -1;
|
||||||
|
}
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
int gootTest2(SSL *ssl)
|
||||||
|
{
|
||||||
|
int ret;
|
||||||
|
switch ((ret = SSL_shutdown(ssl))) {
|
||||||
|
case 1:
|
||||||
|
break;
|
||||||
|
case 0:
|
||||||
|
ERR_clear_error();
|
||||||
|
if (-1 != (ret = SSL_shutdown(ssl))) break; // GOOD
|
||||||
|
default:
|
||||||
|
print_error("error shutdown",
|
||||||
|
SSL_get_error(ssl, ret));
|
||||||
|
return -1;
|
||||||
|
}
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
int badTest1(SSL *ssl)
|
||||||
|
{
|
||||||
|
int ret;
|
||||||
|
switch ((ret = SSL_shutdown(ssl))) {
|
||||||
|
case 1:
|
||||||
|
break;
|
||||||
|
case 0:
|
||||||
|
SSL_shutdown(ssl); // BAD
|
||||||
|
break;
|
||||||
|
default:
|
||||||
|
print_error("error shutdown",
|
||||||
|
SSL_get_error(ssl, ret));
|
||||||
|
return -1;
|
||||||
|
}
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
int badTest2(SSL *ssl)
|
||||||
|
{
|
||||||
|
int ret;
|
||||||
|
ret = SSL_shutdown(ssl);
|
||||||
|
switch (ret) {
|
||||||
|
case 1:
|
||||||
|
break;
|
||||||
|
case 0:
|
||||||
|
SSL_shutdown(ssl); // BAD
|
||||||
|
break;
|
||||||
|
default:
|
||||||
|
print_error("error shutdown",
|
||||||
|
SSL_get_error(ssl, ret));
|
||||||
|
return -1;
|
||||||
|
}
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
|
||||||
@@ -220,10 +220,10 @@ postWithInFlow
|
|||||||
| lambdas.cpp:20:11:20:11 | FieldAddress [post update] | PostUpdateNode should not be the target of local flow. |
|
| lambdas.cpp:20:11:20:11 | FieldAddress [post update] | PostUpdateNode should not be the target of local flow. |
|
||||||
| lambdas.cpp:20:11:20:11 | FieldAddress [post update] | PostUpdateNode should not be the target of local flow. |
|
| lambdas.cpp:20:11:20:11 | FieldAddress [post update] | PostUpdateNode should not be the target of local flow. |
|
||||||
| lambdas.cpp:20:11:20:11 | FieldAddress [post update] | PostUpdateNode should not be the target of local flow. |
|
| lambdas.cpp:20:11:20:11 | FieldAddress [post update] | PostUpdateNode should not be the target of local flow. |
|
||||||
|
| lambdas.cpp:23:3:23:3 | (reference dereference) [post update] | PostUpdateNode should not be the target of local flow. |
|
||||||
| lambdas.cpp:23:3:23:14 | FieldAddress [post update] | PostUpdateNode should not be the target of local flow. |
|
| lambdas.cpp:23:3:23:14 | FieldAddress [post update] | PostUpdateNode should not be the target of local flow. |
|
||||||
| lambdas.cpp:23:3:23:14 | VariableAddress [post update] | PostUpdateNode should not be the target of local flow. |
|
| lambdas.cpp:23:3:23:14 | VariableAddress [post update] | PostUpdateNode should not be the target of local flow. |
|
||||||
| lambdas.cpp:23:3:23:14 | v [post update] | PostUpdateNode should not be the target of local flow. |
|
| lambdas.cpp:23:3:23:14 | v [post update] | PostUpdateNode should not be the target of local flow. |
|
||||||
| lambdas.cpp:23:15:23:15 | (reference dereference) [post update] | PostUpdateNode should not be the target of local flow. |
|
|
||||||
| lambdas.cpp:28:7:28:7 | VariableAddress [post update] | PostUpdateNode should not be the target of local flow. |
|
| lambdas.cpp:28:7:28:7 | VariableAddress [post update] | PostUpdateNode should not be the target of local flow. |
|
||||||
| lambdas.cpp:28:10:31:2 | FieldAddress [post update] | PostUpdateNode should not be the target of local flow. |
|
| lambdas.cpp:28:10:31:2 | FieldAddress [post update] | PostUpdateNode should not be the target of local flow. |
|
||||||
| lambdas.cpp:28:10:31:2 | FieldAddress [post update] | PostUpdateNode should not be the target of local flow. |
|
| lambdas.cpp:28:10:31:2 | FieldAddress [post update] | PostUpdateNode should not be the target of local flow. |
|
||||||
|
|||||||
@@ -2,19 +2,17 @@ import TestUtilities.dataflow.FlowTestCommon
|
|||||||
|
|
||||||
module AstTest {
|
module AstTest {
|
||||||
private import semmle.code.cpp.dataflow.DataFlow
|
private import semmle.code.cpp.dataflow.DataFlow
|
||||||
|
private import semmle.code.cpp.controlflow.Guards
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* A `BarrierGuard` that stops flow to all occurrences of `x` within statement
|
* A `BarrierGuard` that stops flow to all occurrences of `x` within statement
|
||||||
* S in `if (guarded(x)) S`.
|
* S in `if (guarded(x)) S`.
|
||||||
*/
|
*/
|
||||||
// This is tested in `BarrierGuard.cpp`.
|
// This is tested in `BarrierGuard.cpp`.
|
||||||
class TestBarrierGuard extends DataFlow::BarrierGuard {
|
predicate testBarrierGuard(GuardCondition g, Expr checked, boolean isTrue) {
|
||||||
TestBarrierGuard() { this.(FunctionCall).getTarget().getName() = "guarded" }
|
g.(FunctionCall).getTarget().getName() = "guarded" and
|
||||||
|
checked = g.(FunctionCall).getArgument(0) and
|
||||||
override predicate checks(Expr checked, boolean isTrue) {
|
isTrue = true
|
||||||
checked = this.(FunctionCall).getArgument(0) and
|
|
||||||
isTrue = true
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
/** Common data flow configuration to be used by tests. */
|
/** Common data flow configuration to be used by tests. */
|
||||||
@@ -40,29 +38,26 @@ module AstTest {
|
|||||||
}
|
}
|
||||||
|
|
||||||
override predicate isBarrier(DataFlow::Node barrier) {
|
override predicate isBarrier(DataFlow::Node barrier) {
|
||||||
barrier.asExpr().(VariableAccess).getTarget().hasName("barrier")
|
barrier.asExpr().(VariableAccess).getTarget().hasName("barrier") or
|
||||||
|
barrier = DataFlow::BarrierGuard<testBarrierGuard/3>::getABarrierNode()
|
||||||
}
|
}
|
||||||
|
|
||||||
override predicate isBarrierGuard(DataFlow::BarrierGuard bg) { bg instanceof TestBarrierGuard }
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
module IRTest {
|
module IRTest {
|
||||||
private import semmle.code.cpp.ir.dataflow.DataFlow
|
private import semmle.code.cpp.ir.dataflow.DataFlow
|
||||||
private import semmle.code.cpp.ir.IR
|
private import semmle.code.cpp.ir.IR
|
||||||
|
private import semmle.code.cpp.controlflow.IRGuards
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* A `BarrierGuard` that stops flow to all occurrences of `x` within statement
|
* A `BarrierGuard` that stops flow to all occurrences of `x` within statement
|
||||||
* S in `if (guarded(x)) S`.
|
* S in `if (guarded(x)) S`.
|
||||||
*/
|
*/
|
||||||
// This is tested in `BarrierGuard.cpp`.
|
// This is tested in `BarrierGuard.cpp`.
|
||||||
class TestBarrierGuard extends DataFlow::BarrierGuard {
|
predicate testBarrierGuard(IRGuardCondition g, Instruction checked, boolean isTrue) {
|
||||||
TestBarrierGuard() { this.(CallInstruction).getStaticCallTarget().getName() = "guarded" }
|
g.(CallInstruction).getStaticCallTarget().getName() = "guarded" and
|
||||||
|
checked = g.(CallInstruction).getPositionalArgument(0) and
|
||||||
override predicate checksInstr(Instruction checked, boolean isTrue) {
|
isTrue = true
|
||||||
checked = this.(CallInstruction).getPositionalArgument(0) and
|
|
||||||
isTrue = true
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
/** Common data flow configuration to be used by tests. */
|
/** Common data flow configuration to be used by tests. */
|
||||||
@@ -93,10 +88,9 @@ module IRTest {
|
|||||||
}
|
}
|
||||||
|
|
||||||
override predicate isBarrier(DataFlow::Node barrier) {
|
override predicate isBarrier(DataFlow::Node barrier) {
|
||||||
barrier.asExpr().(VariableAccess).getTarget().hasName("barrier")
|
barrier.asExpr().(VariableAccess).getTarget().hasName("barrier") or
|
||||||
|
barrier = DataFlow::InstructionBarrierGuard<testBarrierGuard/3>::getABarrierNode()
|
||||||
}
|
}
|
||||||
|
|
||||||
override predicate isBarrierGuard(DataFlow::BarrierGuard bg) { bg instanceof TestBarrierGuard }
|
|
||||||
}
|
}
|
||||||
|
|
||||||
private predicate readsVariable(LoadInstruction load, Variable var) {
|
private predicate readsVariable(LoadInstruction load, Variable var) {
|
||||||
|
|||||||
@@ -33,3 +33,11 @@ public:
|
|||||||
|
|
||||||
myTemplateClass<int> mtc_int;
|
myTemplateClass<int> mtc_int;
|
||||||
myTemplateClass<short> mtc_short;
|
myTemplateClass<short> mtc_short;
|
||||||
|
|
||||||
|
// Class (UserType)
|
||||||
|
|
||||||
|
class myClass
|
||||||
|
{
|
||||||
|
public:
|
||||||
|
int myMemberVariable;
|
||||||
|
};
|
||||||
|
|||||||
@@ -27,5 +27,11 @@
|
|||||||
| declarationEntry.cpp:31:4:31:19 | myMemberVariable | declarationEntry.cpp:31:4:31:19 | definition of myMemberVariable | 1 | 1 |
|
| declarationEntry.cpp:31:4:31:19 | myMemberVariable | declarationEntry.cpp:31:4:31:19 | definition of myMemberVariable | 1 | 1 |
|
||||||
| declarationEntry.cpp:34:22:34:28 | mtc_int | declarationEntry.cpp:34:22:34:28 | definition of mtc_int | 1 | 1 |
|
| declarationEntry.cpp:34:22:34:28 | mtc_int | declarationEntry.cpp:34:22:34:28 | definition of mtc_int | 1 | 1 |
|
||||||
| declarationEntry.cpp:35:24:35:32 | mtc_short | declarationEntry.cpp:35:24:35:32 | definition of mtc_short | 1 | 1 |
|
| declarationEntry.cpp:35:24:35:32 | mtc_short | declarationEntry.cpp:35:24:35:32 | definition of mtc_short | 1 | 1 |
|
||||||
|
| declarationEntry.cpp:39:7:39:7 | operator= | declarationEntry.cpp:39:7:39:7 | declaration of operator= | 1 | 1 |
|
||||||
|
| declarationEntry.cpp:39:7:39:7 | operator= | declarationEntry.cpp:39:7:39:7 | declaration of operator= | 1 | 1 |
|
||||||
|
| declarationEntry.cpp:39:7:39:13 | myClass | declarationEntry.cpp:39:7:39:13 | definition of myClass | 1 | 1 |
|
||||||
|
| declarationEntry.cpp:39:7:39:13 | myClass | forwardDeclaration.cpp:1:7:1:13 | declaration of myClass | 1 | 1 |
|
||||||
|
| declarationEntry.cpp:42:6:42:21 | myMemberVariable | declarationEntry.cpp:42:6:42:21 | definition of myMemberVariable | 1 | 1 |
|
||||||
|
| forwardDeclaration.cpp:3:10:3:19 | myClassPtr | forwardDeclaration.cpp:3:10:3:19 | definition of myClassPtr | 1 | 1 |
|
||||||
| macro.c:2:1:2:3 | foo | macro.c:2:1:2:3 | declaration of foo | 1 | 1 |
|
| macro.c:2:1:2:3 | foo | macro.c:2:1:2:3 | declaration of foo | 1 | 1 |
|
||||||
| macro.c:4:5:4:8 | main | macro.c:4:5:4:8 | definition of main | 1 | 1 |
|
| macro.c:4:5:4:8 | main | macro.c:4:5:4:8 | definition of main | 1 | 1 |
|
||||||
|
|||||||
@@ -10,5 +10,7 @@
|
|||||||
| declarationEntry.cpp:28:7:28:7 | declaration of operator= | | 0 | |
|
| declarationEntry.cpp:28:7:28:7 | declaration of operator= | | 0 | |
|
||||||
| declarationEntry.cpp:28:7:28:7 | declaration of operator= | | 0 | |
|
| declarationEntry.cpp:28:7:28:7 | declaration of operator= | | 0 | |
|
||||||
| declarationEntry.cpp:28:7:28:7 | declaration of operator= | | 0 | |
|
| declarationEntry.cpp:28:7:28:7 | declaration of operator= | | 0 | |
|
||||||
|
| declarationEntry.cpp:39:7:39:7 | declaration of operator= | | 0 | |
|
||||||
|
| declarationEntry.cpp:39:7:39:7 | declaration of operator= | | 0 | |
|
||||||
| macro.c:2:1:2:3 | declaration of foo | | 2 | c_linkage, static |
|
| macro.c:2:1:2:3 | declaration of foo | | 2 | c_linkage, static |
|
||||||
| macro.c:4:5:4:8 | definition of main | | 1 | c_linkage |
|
| macro.c:4:5:4:8 | definition of main | | 1 | c_linkage |
|
||||||
|
|||||||
@@ -0,0 +1,3 @@
|
|||||||
|
class myClass;
|
||||||
|
|
||||||
|
myClass *myClassPtr;
|
||||||
@@ -0,0 +1,45 @@
|
|||||||
|
| declarationEntry.c:2:6:2:20 | declaration of myFirstFunction | declarationEntry.c:2:6:2:20 | myFirstFunction | yes |
|
||||||
|
| declarationEntry.c:4:6:4:21 | definition of mySecondFunction | declarationEntry.c:4:6:4:21 | mySecondFunction | yes |
|
||||||
|
| declarationEntry.c:8:6:8:20 | definition of myThirdFunction | declarationEntry.c:8:6:8:20 | myThirdFunction | yes |
|
||||||
|
| declarationEntry.c:13:2:13:2 | declaration of myFourthFunction | declarationEntry.c:13:2:13:2 | myFourthFunction | yes |
|
||||||
|
| declarationEntry.c:13:2:13:2 | declaration of myFourthFunction | declarationEntry.c:17:6:17:21 | myFourthFunction | yes |
|
||||||
|
| declarationEntry.c:14:2:14:2 | declaration of myFifthFunction | declarationEntry.c:14:2:14:2 | myFifthFunction | yes |
|
||||||
|
| declarationEntry.c:17:6:17:21 | declaration of myFourthFunction | declarationEntry.c:13:2:13:2 | myFourthFunction | yes |
|
||||||
|
| declarationEntry.c:17:6:17:21 | declaration of myFourthFunction | declarationEntry.c:17:6:17:21 | myFourthFunction | yes |
|
||||||
|
| declarationEntry.cpp:3:12:3:21 | declaration of myVariable | declarationEntry.cpp:5:5:5:14 | myVariable | yes |
|
||||||
|
| declarationEntry.cpp:5:5:5:14 | definition of myVariable | declarationEntry.cpp:5:5:5:14 | myVariable | yes |
|
||||||
|
| declarationEntry.cpp:9:6:9:15 | declaration of myFunction | declarationEntry.cpp:11:6:11:15 | myFunction | yes |
|
||||||
|
| declarationEntry.cpp:9:21:9:31 | declaration of myParameter | declarationEntry.cpp:11:21:11:31 | myParameter | yes |
|
||||||
|
| declarationEntry.cpp:11:6:11:15 | definition of myFunction | declarationEntry.cpp:11:6:11:15 | myFunction | yes |
|
||||||
|
| declarationEntry.cpp:11:21:11:31 | definition of myParameter | declarationEntry.cpp:11:21:11:31 | myParameter | yes |
|
||||||
|
| declarationEntry.cpp:18:6:18:11 | declaration of myEnum | declarationEntry.cpp:20:6:20:11 | myEnum | yes |
|
||||||
|
| declarationEntry.cpp:20:6:20:11 | definition of myEnum | declarationEntry.cpp:20:6:20:11 | myEnum | yes |
|
||||||
|
| declarationEntry.cpp:27:20:27:20 | definition of T | declarationEntry.cpp:27:20:27:20 | T | yes |
|
||||||
|
| declarationEntry.cpp:28:7:28:7 | declaration of operator= | declarationEntry.cpp:28:7:28:7 | operator= | yes |
|
||||||
|
| declarationEntry.cpp:28:7:28:7 | declaration of operator= | declarationEntry.cpp:28:7:28:7 | operator= | yes |
|
||||||
|
| declarationEntry.cpp:28:7:28:7 | declaration of operator= | declarationEntry.cpp:28:7:28:7 | operator= | yes |
|
||||||
|
| declarationEntry.cpp:28:7:28:7 | declaration of operator= | declarationEntry.cpp:28:7:28:7 | operator= | yes |
|
||||||
|
| declarationEntry.cpp:28:7:28:21 | definition of myTemplateClass<T> | declarationEntry.cpp:28:7:28:21 | myTemplateClass<T> | yes |
|
||||||
|
| declarationEntry.cpp:31:4:31:19 | definition of myMemberVariable | declarationEntry.cpp:31:4:31:19 | myMemberVariable | yes |
|
||||||
|
| declarationEntry.cpp:31:4:31:19 | definition of myMemberVariable | declarationEntry.cpp:31:4:31:19 | myMemberVariable | yes |
|
||||||
|
| declarationEntry.cpp:31:4:31:19 | definition of myMemberVariable | declarationEntry.cpp:31:4:31:19 | myMemberVariable | yes |
|
||||||
|
| declarationEntry.cpp:34:22:34:28 | definition of mtc_int | declarationEntry.cpp:34:22:34:28 | mtc_int | yes |
|
||||||
|
| declarationEntry.cpp:35:24:35:32 | definition of mtc_short | declarationEntry.cpp:35:24:35:32 | mtc_short | yes |
|
||||||
|
| declarationEntry.cpp:39:7:39:7 | declaration of operator= | declarationEntry.cpp:39:7:39:7 | operator= | yes |
|
||||||
|
| declarationEntry.cpp:39:7:39:7 | declaration of operator= | declarationEntry.cpp:39:7:39:7 | operator= | yes |
|
||||||
|
| declarationEntry.cpp:39:7:39:13 | definition of myClass | declarationEntry.cpp:39:7:39:13 | myClass | yes |
|
||||||
|
| declarationEntry.cpp:42:6:42:21 | definition of myMemberVariable | declarationEntry.cpp:42:6:42:21 | myMemberVariable | yes |
|
||||||
|
| file://:0:0:0:0 | declaration of 1st parameter | file://:0:0:0:0 | (unnamed parameter 0) | yes |
|
||||||
|
| file://:0:0:0:0 | declaration of 1st parameter | file://:0:0:0:0 | (unnamed parameter 0) | yes |
|
||||||
|
| file://:0:0:0:0 | declaration of 1st parameter | file://:0:0:0:0 | (unnamed parameter 0) | yes |
|
||||||
|
| file://:0:0:0:0 | declaration of 1st parameter | file://:0:0:0:0 | (unnamed parameter 0) | yes |
|
||||||
|
| file://:0:0:0:0 | declaration of 1st parameter | file://:0:0:0:0 | (unnamed parameter 0) | yes |
|
||||||
|
| file://:0:0:0:0 | declaration of 1st parameter | file://:0:0:0:0 | (unnamed parameter 0) | yes |
|
||||||
|
| file://:0:0:0:0 | definition of fp_offset | file://:0:0:0:0 | fp_offset | yes |
|
||||||
|
| file://:0:0:0:0 | definition of gp_offset | file://:0:0:0:0 | gp_offset | yes |
|
||||||
|
| file://:0:0:0:0 | definition of overflow_arg_area | file://:0:0:0:0 | overflow_arg_area | yes |
|
||||||
|
| file://:0:0:0:0 | definition of reg_save_area | file://:0:0:0:0 | reg_save_area | yes |
|
||||||
|
| forwardDeclaration.cpp:1:7:1:13 | declaration of myClass | declarationEntry.cpp:39:7:39:13 | myClass | yes |
|
||||||
|
| forwardDeclaration.cpp:3:10:3:19 | definition of myClassPtr | forwardDeclaration.cpp:3:10:3:19 | myClassPtr | yes |
|
||||||
|
| macro.c:2:1:2:3 | declaration of foo | macro.c:2:1:2:3 | foo | yes |
|
||||||
|
| macro.c:4:5:4:8 | definition of main | macro.c:4:5:4:8 | main | yes |
|
||||||
@@ -0,0 +1,7 @@
|
|||||||
|
import cpp
|
||||||
|
|
||||||
|
from DeclarationEntry de, Declaration d, string canRoundTrip
|
||||||
|
where
|
||||||
|
d = de.getDeclaration() and
|
||||||
|
if d.getADeclarationEntry() = de then canRoundTrip = "yes" else canRoundTrip = "no"
|
||||||
|
select de, d, canRoundTrip
|
||||||
@@ -4841,6 +4841,9 @@
|
|||||||
| ir.cpp:1043:24:1043:24 | SideEffect | ~m1043_20 |
|
| ir.cpp:1043:24:1043:24 | SideEffect | ~m1043_20 |
|
||||||
| ir.cpp:1043:31:1043:31 | Address | &:r1043_9 |
|
| ir.cpp:1043:31:1043:31 | Address | &:r1043_9 |
|
||||||
| ir.cpp:1043:36:1043:55 | Address | &:r1043_11 |
|
| ir.cpp:1043:36:1043:55 | Address | &:r1043_11 |
|
||||||
|
| ir.cpp:1043:43:1043:43 | Address | &:r1043_16 |
|
||||||
|
| ir.cpp:1043:43:1043:43 | Arg(this) | this:r1043_16 |
|
||||||
|
| ir.cpp:1043:43:1043:43 | SideEffect | ~m1043_20 |
|
||||||
| ir.cpp:1043:43:1043:54 | Address | &:r1043_22 |
|
| ir.cpp:1043:43:1043:54 | Address | &:r1043_22 |
|
||||||
| ir.cpp:1043:43:1043:54 | Address | &:r1043_24 |
|
| ir.cpp:1043:43:1043:54 | Address | &:r1043_24 |
|
||||||
| ir.cpp:1043:43:1043:54 | Address | &:r1043_25 |
|
| ir.cpp:1043:43:1043:54 | Address | &:r1043_25 |
|
||||||
@@ -4861,11 +4864,8 @@
|
|||||||
| ir.cpp:1043:45:1043:49 | SideEffect | ~m1043_4 |
|
| ir.cpp:1043:45:1043:49 | SideEffect | ~m1043_4 |
|
||||||
| ir.cpp:1043:45:1043:49 | Unary | r1043_13 |
|
| ir.cpp:1043:45:1043:49 | Unary | r1043_13 |
|
||||||
| ir.cpp:1043:45:1043:49 | Unary | r1043_15 |
|
| ir.cpp:1043:45:1043:49 | Unary | r1043_15 |
|
||||||
| ir.cpp:1043:52:1043:52 | Address | &:r1043_16 |
|
| ir.cpp:1043:53:1043:53 | Load | ~m1043_20 |
|
||||||
| ir.cpp:1043:52:1043:52 | Arg(this) | this:r1043_16 |
|
| ir.cpp:1043:53:1043:53 | Right | r1043_26 |
|
||||||
| ir.cpp:1043:52:1043:52 | SideEffect | ~m1043_20 |
|
|
||||||
| ir.cpp:1043:54:1043:54 | Load | ~m1043_20 |
|
|
||||||
| ir.cpp:1043:54:1043:54 | Right | r1043_26 |
|
|
||||||
| ir.cpp:1043:58:1043:58 | ChiPartial | partial:m1043_9 |
|
| ir.cpp:1043:58:1043:58 | ChiPartial | partial:m1043_9 |
|
||||||
| ir.cpp:1043:58:1043:58 | ChiTotal | total:m1043_3 |
|
| ir.cpp:1043:58:1043:58 | ChiTotal | total:m1043_3 |
|
||||||
| ir.cpp:1043:58:1043:58 | StoreValue | r1043_8 |
|
| ir.cpp:1043:58:1043:58 | StoreValue | r1043_8 |
|
||||||
@@ -4980,6 +4980,9 @@
|
|||||||
| ir.cpp:1047:34:1047:34 | SideEffect | ~m1047_20 |
|
| ir.cpp:1047:34:1047:34 | SideEffect | ~m1047_20 |
|
||||||
| ir.cpp:1047:41:1047:41 | Address | &:r1047_9 |
|
| ir.cpp:1047:41:1047:41 | Address | &:r1047_9 |
|
||||||
| ir.cpp:1047:46:1047:65 | Address | &:r1047_11 |
|
| ir.cpp:1047:46:1047:65 | Address | &:r1047_11 |
|
||||||
|
| ir.cpp:1047:53:1047:53 | Address | &:r1047_16 |
|
||||||
|
| ir.cpp:1047:53:1047:53 | Arg(this) | this:r1047_16 |
|
||||||
|
| ir.cpp:1047:53:1047:53 | SideEffect | ~m1047_20 |
|
||||||
| ir.cpp:1047:53:1047:64 | Address | &:r1047_23 |
|
| ir.cpp:1047:53:1047:64 | Address | &:r1047_23 |
|
||||||
| ir.cpp:1047:53:1047:64 | Load | ~m1047_20 |
|
| ir.cpp:1047:53:1047:64 | Load | ~m1047_20 |
|
||||||
| ir.cpp:1047:53:1047:64 | StoreValue | r1047_24 |
|
| ir.cpp:1047:53:1047:64 | StoreValue | r1047_24 |
|
||||||
@@ -4994,9 +4997,6 @@
|
|||||||
| ir.cpp:1047:55:1047:59 | SideEffect | ~m1047_4 |
|
| ir.cpp:1047:55:1047:59 | SideEffect | ~m1047_4 |
|
||||||
| ir.cpp:1047:55:1047:59 | Unary | r1047_13 |
|
| ir.cpp:1047:55:1047:59 | Unary | r1047_13 |
|
||||||
| ir.cpp:1047:55:1047:59 | Unary | r1047_15 |
|
| ir.cpp:1047:55:1047:59 | Unary | r1047_15 |
|
||||||
| ir.cpp:1047:62:1047:62 | Address | &:r1047_16 |
|
|
||||||
| ir.cpp:1047:62:1047:62 | Arg(this) | this:r1047_16 |
|
|
||||||
| ir.cpp:1047:62:1047:62 | SideEffect | ~m1047_20 |
|
|
||||||
| ir.cpp:1047:63:1047:63 | Right | r1047_22 |
|
| ir.cpp:1047:63:1047:63 | Right | r1047_22 |
|
||||||
| ir.cpp:1047:68:1047:68 | StoreValue | r1047_8 |
|
| ir.cpp:1047:68:1047:68 | StoreValue | r1047_8 |
|
||||||
| ir.cpp:1047:68:1047:68 | Unary | r1047_7 |
|
| ir.cpp:1047:68:1047:68 | Unary | r1047_7 |
|
||||||
@@ -5105,6 +5105,9 @@
|
|||||||
| ir.cpp:1051:39:1051:39 | SideEffect | ~m1051_20 |
|
| ir.cpp:1051:39:1051:39 | SideEffect | ~m1051_20 |
|
||||||
| ir.cpp:1051:46:1051:46 | Address | &:r1051_9 |
|
| ir.cpp:1051:46:1051:46 | Address | &:r1051_9 |
|
||||||
| ir.cpp:1051:51:1051:70 | Address | &:r1051_11 |
|
| ir.cpp:1051:51:1051:70 | Address | &:r1051_11 |
|
||||||
|
| ir.cpp:1051:58:1051:58 | Address | &:r1051_16 |
|
||||||
|
| ir.cpp:1051:58:1051:58 | Arg(this) | this:r1051_16 |
|
||||||
|
| ir.cpp:1051:58:1051:58 | SideEffect | ~m1051_20 |
|
||||||
| ir.cpp:1051:58:1051:69 | Address | &:r1051_22 |
|
| ir.cpp:1051:58:1051:69 | Address | &:r1051_22 |
|
||||||
| ir.cpp:1051:58:1051:69 | Address | &:r1051_24 |
|
| ir.cpp:1051:58:1051:69 | Address | &:r1051_24 |
|
||||||
| ir.cpp:1051:58:1051:69 | Address | &:r1051_26 |
|
| ir.cpp:1051:58:1051:69 | Address | &:r1051_26 |
|
||||||
@@ -5125,9 +5128,6 @@
|
|||||||
| ir.cpp:1051:60:1051:64 | SideEffect | ~m1051_4 |
|
| ir.cpp:1051:60:1051:64 | SideEffect | ~m1051_4 |
|
||||||
| ir.cpp:1051:60:1051:64 | Unary | r1051_13 |
|
| ir.cpp:1051:60:1051:64 | Unary | r1051_13 |
|
||||||
| ir.cpp:1051:60:1051:64 | Unary | r1051_15 |
|
| ir.cpp:1051:60:1051:64 | Unary | r1051_15 |
|
||||||
| ir.cpp:1051:67:1051:67 | Address | &:r1051_16 |
|
|
||||||
| ir.cpp:1051:67:1051:67 | Arg(this) | this:r1051_16 |
|
|
||||||
| ir.cpp:1051:67:1051:67 | SideEffect | ~m1051_20 |
|
|
||||||
| ir.cpp:1051:73:1051:73 | ChiPartial | partial:m1051_9 |
|
| ir.cpp:1051:73:1051:73 | ChiPartial | partial:m1051_9 |
|
||||||
| ir.cpp:1051:73:1051:73 | ChiTotal | total:m1051_3 |
|
| ir.cpp:1051:73:1051:73 | ChiTotal | total:m1051_3 |
|
||||||
| ir.cpp:1051:73:1051:73 | StoreValue | r1051_8 |
|
| ir.cpp:1051:73:1051:73 | StoreValue | r1051_8 |
|
||||||
@@ -5192,6 +5192,9 @@
|
|||||||
| ir.cpp:1054:49:1054:49 | SideEffect | ~m1054_20 |
|
| ir.cpp:1054:49:1054:49 | SideEffect | ~m1054_20 |
|
||||||
| ir.cpp:1054:56:1054:56 | Address | &:r1054_9 |
|
| ir.cpp:1054:56:1054:56 | Address | &:r1054_9 |
|
||||||
| ir.cpp:1054:61:1054:88 | Address | &:r1054_11 |
|
| ir.cpp:1054:61:1054:88 | Address | &:r1054_11 |
|
||||||
|
| ir.cpp:1054:68:1054:68 | Address | &:r1054_16 |
|
||||||
|
| ir.cpp:1054:68:1054:68 | Arg(this) | this:r1054_16 |
|
||||||
|
| ir.cpp:1054:68:1054:68 | SideEffect | ~m1054_20 |
|
||||||
| ir.cpp:1054:68:1054:87 | Address | &:r1054_37 |
|
| ir.cpp:1054:68:1054:87 | Address | &:r1054_37 |
|
||||||
| ir.cpp:1054:68:1054:87 | Load | ~m1054_20 |
|
| ir.cpp:1054:68:1054:87 | Load | ~m1054_20 |
|
||||||
| ir.cpp:1054:68:1054:87 | StoreValue | r1054_38 |
|
| ir.cpp:1054:68:1054:87 | StoreValue | r1054_38 |
|
||||||
@@ -5206,9 +5209,6 @@
|
|||||||
| ir.cpp:1054:70:1054:74 | SideEffect | ~m1054_4 |
|
| ir.cpp:1054:70:1054:74 | SideEffect | ~m1054_4 |
|
||||||
| ir.cpp:1054:70:1054:74 | Unary | r1054_13 |
|
| ir.cpp:1054:70:1054:74 | Unary | r1054_13 |
|
||||||
| ir.cpp:1054:70:1054:74 | Unary | r1054_15 |
|
| ir.cpp:1054:70:1054:74 | Unary | r1054_15 |
|
||||||
| ir.cpp:1054:77:1054:77 | Address | &:r1054_16 |
|
|
||||||
| ir.cpp:1054:77:1054:77 | Arg(this) | this:r1054_16 |
|
|
||||||
| ir.cpp:1054:77:1054:77 | SideEffect | ~m1054_20 |
|
|
||||||
| ir.cpp:1054:78:1054:82 | Address | &:r1054_22 |
|
| ir.cpp:1054:78:1054:82 | Address | &:r1054_22 |
|
||||||
| ir.cpp:1054:78:1054:82 | Address | &:r1054_24 |
|
| ir.cpp:1054:78:1054:82 | Address | &:r1054_24 |
|
||||||
| ir.cpp:1054:78:1054:82 | Left | r1054_25 |
|
| ir.cpp:1054:78:1054:82 | Left | r1054_25 |
|
||||||
|
|||||||
@@ -156,10 +156,10 @@
|
|||||||
| captures.cpp:23:12:23:16 | x |
|
| captures.cpp:23:12:23:16 | x |
|
||||||
| captures.cpp:23:12:23:16 | y |
|
| captures.cpp:23:12:23:16 | y |
|
||||||
| captures.cpp:23:12:23:20 | ... + ... |
|
| captures.cpp:23:12:23:20 | ... + ... |
|
||||||
|
| captures.cpp:23:16:23:16 | (reference dereference) |
|
||||||
| captures.cpp:23:16:23:16 | definition of y |
|
| captures.cpp:23:16:23:16 | definition of y |
|
||||||
| captures.cpp:23:16:23:16 | y |
|
| captures.cpp:23:16:23:16 | y |
|
||||||
| captures.cpp:23:16:23:16 | y |
|
| captures.cpp:23:16:23:16 | y |
|
||||||
| captures.cpp:23:18:23:18 | (reference dereference) |
|
|
||||||
| captures.cpp:23:20:23:20 | z |
|
| captures.cpp:23:20:23:20 | z |
|
||||||
| captures.cpp:26:3:26:24 | return ... |
|
| captures.cpp:26:3:26:24 | return ... |
|
||||||
| captures.cpp:26:10:26:17 | (const lambda [] type at line 22, col. 19)... |
|
| captures.cpp:26:10:26:17 | (const lambda [] type at line 22, col. 19)... |
|
||||||
|
|||||||
@@ -1,3 +1,4 @@
|
|||||||
|
|
||||||
#include "a.h"
|
#include "a.h"
|
||||||
|
|
||||||
|
#include "c.h"
|
||||||
|
|||||||
12
cpp/ql/test/library-tests/variables/global/c.c
Normal file
12
cpp/ql/test/library-tests/variables/global/c.c
Normal file
@@ -0,0 +1,12 @@
|
|||||||
|
|
||||||
|
int js[] = { 1, 2, 3, 4 };
|
||||||
|
|
||||||
|
int ks[4] = { 1, 2, 3, 4 };
|
||||||
|
|
||||||
|
int ls[4] = { 1, 2, 3, 4 };
|
||||||
|
|
||||||
|
int iss[4][2] = { { 1, 2 }, { 3, 4 }, { 1, 2 }, { 3, 4 } };
|
||||||
|
|
||||||
|
typedef int int_alias;
|
||||||
|
|
||||||
|
int_alias i;
|
||||||
10
cpp/ql/test/library-tests/variables/global/c.h
Normal file
10
cpp/ql/test/library-tests/variables/global/c.h
Normal file
@@ -0,0 +1,10 @@
|
|||||||
|
|
||||||
|
extern int js[];
|
||||||
|
|
||||||
|
extern int ks[];
|
||||||
|
|
||||||
|
extern int ls[4];
|
||||||
|
|
||||||
|
extern int iss[][2];
|
||||||
|
|
||||||
|
extern int i;
|
||||||
4
cpp/ql/test/library-tests/variables/global/d.cpp
Normal file
4
cpp/ql/test/library-tests/variables/global/d.cpp
Normal file
@@ -0,0 +1,4 @@
|
|||||||
|
|
||||||
|
namespace aNameSpace {
|
||||||
|
int xs[] = { 1, 2 };
|
||||||
|
}
|
||||||
4
cpp/ql/test/library-tests/variables/global/d.h
Normal file
4
cpp/ql/test/library-tests/variables/global/d.h
Normal file
@@ -0,0 +1,4 @@
|
|||||||
|
|
||||||
|
namespace aNameSpace {
|
||||||
|
extern int xs[2];
|
||||||
|
}
|
||||||
2
cpp/ql/test/library-tests/variables/global/e.cpp
Normal file
2
cpp/ql/test/library-tests/variables/global/e.cpp
Normal file
@@ -0,0 +1,2 @@
|
|||||||
|
|
||||||
|
#include "d.h"
|
||||||
@@ -1,5 +1,17 @@
|
|||||||
| a.c:4:5:4:6 | definition of is | array of {int} | 1 |
|
| a.c:4:5:4:6 | definition of is | array of {int} | 1 |
|
||||||
| a.h:2:12:2:13 | declaration of is | array of 4 {int} | 1 |
|
| a.h:2:12:2:13 | declaration of is | array of 4 {int} | 1 |
|
||||||
|
| c.c:2:5:2:6 | definition of js | array of {int} | 1 |
|
||||||
|
| c.c:4:5:4:6 | definition of ks | array of 4 {int} | 1 |
|
||||||
|
| c.c:6:5:6:6 | definition of ls | array of 4 {int} | 1 |
|
||||||
|
| c.c:8:5:8:7 | definition of iss | array of 4 {array of 2 {int}} | 1 |
|
||||||
|
| c.c:12:11:12:11 | definition of i | typedef {int} as "int_alias" | 1 |
|
||||||
|
| c.h:2:12:2:13 | declaration of js | array of {int} | 1 |
|
||||||
|
| c.h:4:12:4:13 | declaration of ks | array of {int} | 1 |
|
||||||
|
| c.h:6:12:6:13 | declaration of ls | array of 4 {int} | 1 |
|
||||||
|
| c.h:8:12:8:14 | declaration of iss | array of {array of 2 {int}} | 1 |
|
||||||
|
| c.h:10:12:10:12 | declaration of i | int | 1 |
|
||||||
|
| d.cpp:3:7:3:8 | definition of xs | array of {int} | 1 |
|
||||||
|
| d.h:3:14:3:15 | declaration of xs | array of 2 {int} | 1 |
|
||||||
| file://:0:0:0:0 | definition of fp_offset | unsigned int | 1 |
|
| file://:0:0:0:0 | definition of fp_offset | unsigned int | 1 |
|
||||||
| file://:0:0:0:0 | definition of gp_offset | unsigned int | 1 |
|
| file://:0:0:0:0 | definition of gp_offset | unsigned int | 1 |
|
||||||
| file://:0:0:0:0 | definition of overflow_arg_area | pointer to {void} | 1 |
|
| file://:0:0:0:0 | definition of overflow_arg_area | pointer to {void} | 1 |
|
||||||
|
|||||||
@@ -1,4 +1,16 @@
|
|||||||
| a.c:4:5:4:6 | is | array of {int} | 1 |
|
| a.c:4:5:4:6 | is | array of {int} | 1 |
|
||||||
|
| c.c:2:5:2:6 | js | array of {int} | 1 |
|
||||||
|
| c.c:4:5:4:6 | ks | array of 4 {int} | 1 |
|
||||||
|
| c.c:6:5:6:6 | ls | array of 4 {int} | 1 |
|
||||||
|
| c.c:8:5:8:7 | iss | array of 4 {array of 2 {int}} | 1 |
|
||||||
|
| c.c:12:11:12:11 | i | typedef {int} as "int_alias" | 1 |
|
||||||
|
| c.h:4:12:4:13 | ks | array of {int} | 1 |
|
||||||
|
| c.h:8:12:8:14 | iss | array of {array of 2 {int}} | 1 |
|
||||||
|
| c.h:10:12:10:12 | i | int | 1 |
|
||||||
|
| d.cpp:3:7:3:8 | xs | array of {int} | 1 |
|
||||||
|
| d.h:3:14:3:15 | xs | array of 2 {int} | 1 |
|
||||||
|
| file://:0:0:0:0 | (unnamed parameter 0) | reference to {const {struct __va_list_tag}} | 1 |
|
||||||
|
| file://:0:0:0:0 | (unnamed parameter 0) | rvalue reference to {struct __va_list_tag} | 1 |
|
||||||
| file://:0:0:0:0 | fp_offset | unsigned int | 1 |
|
| file://:0:0:0:0 | fp_offset | unsigned int | 1 |
|
||||||
| file://:0:0:0:0 | gp_offset | unsigned int | 1 |
|
| file://:0:0:0:0 | gp_offset | unsigned int | 1 |
|
||||||
| file://:0:0:0:0 | overflow_arg_area | pointer to {void} | 1 |
|
| file://:0:0:0:0 | overflow_arg_area | pointer to {void} | 1 |
|
||||||
|
|||||||
@@ -0,0 +1,36 @@
|
|||||||
|
using Microsoft.CodeAnalysis;
|
||||||
|
using Microsoft.CodeAnalysis.CSharp.Syntax;
|
||||||
|
using Semmle.Extraction.CSharp.Entities.Statements;
|
||||||
|
using System.Collections.Generic;
|
||||||
|
using System.IO;
|
||||||
|
|
||||||
|
namespace Semmle.Extraction.CSharp.Entities
|
||||||
|
{
|
||||||
|
internal class ImplicitMainMethod : OrdinaryMethod
|
||||||
|
{
|
||||||
|
private readonly List<GlobalStatementSyntax> globalStatements;
|
||||||
|
|
||||||
|
public ImplicitMainMethod(Context cx, IMethodSymbol symbol, List<GlobalStatementSyntax> globalStatements)
|
||||||
|
: base(cx, symbol)
|
||||||
|
{
|
||||||
|
this.globalStatements = globalStatements;
|
||||||
|
}
|
||||||
|
|
||||||
|
protected override void PopulateMethodBody(TextWriter trapFile)
|
||||||
|
{
|
||||||
|
GlobalStatementsBlock.Create(Context, this, globalStatements);
|
||||||
|
}
|
||||||
|
|
||||||
|
public static ImplicitMainMethod Create(Context cx, IMethodSymbol method, List<GlobalStatementSyntax> globalStatements)
|
||||||
|
{
|
||||||
|
return ImplicitMainMethodFactory.Instance.CreateEntity(cx, method, (method, globalStatements));
|
||||||
|
}
|
||||||
|
|
||||||
|
private class ImplicitMainMethodFactory : CachedEntityFactory<(IMethodSymbol, List<GlobalStatementSyntax>), ImplicitMainMethod>
|
||||||
|
{
|
||||||
|
public static ImplicitMainMethodFactory Instance { get; } = new ImplicitMainMethodFactory();
|
||||||
|
|
||||||
|
public override ImplicitMainMethod Create(Context cx, (IMethodSymbol, List<GlobalStatementSyntax>) init) => new ImplicitMainMethod(cx, init.Item1, init.Item2);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
@@ -46,7 +46,7 @@ namespace Semmle.Extraction.CSharp.Entities
|
|||||||
// so there's nothing to extract.
|
// so there's nothing to extract.
|
||||||
}
|
}
|
||||||
|
|
||||||
private void PopulateMethodBody(TextWriter trapFile)
|
protected virtual void PopulateMethodBody(TextWriter trapFile)
|
||||||
{
|
{
|
||||||
if (!IsSourceDeclaration)
|
if (!IsSourceDeclaration)
|
||||||
return;
|
return;
|
||||||
|
|||||||
@@ -8,7 +8,7 @@ namespace Semmle.Extraction.CSharp.Entities
|
|||||||
{
|
{
|
||||||
internal class OrdinaryMethod : Method
|
internal class OrdinaryMethod : Method
|
||||||
{
|
{
|
||||||
private OrdinaryMethod(Context cx, IMethodSymbol init)
|
protected OrdinaryMethod(Context cx, IMethodSymbol init)
|
||||||
: base(cx, init) { }
|
: base(cx, init) { }
|
||||||
|
|
||||||
public override string Name => Symbol.GetName();
|
public override string Name => Symbol.GetName();
|
||||||
|
|||||||
@@ -2,17 +2,22 @@ using Semmle.Extraction.Kinds;
|
|||||||
using System.Linq;
|
using System.Linq;
|
||||||
using System.IO;
|
using System.IO;
|
||||||
using Semmle.Extraction.Entities;
|
using Semmle.Extraction.Entities;
|
||||||
|
using System.Collections.Generic;
|
||||||
|
using Microsoft.CodeAnalysis.CSharp.Syntax;
|
||||||
|
using System;
|
||||||
|
|
||||||
namespace Semmle.Extraction.CSharp.Entities.Statements
|
namespace Semmle.Extraction.CSharp.Entities.Statements
|
||||||
{
|
{
|
||||||
internal class GlobalStatementsBlock : Statement
|
internal class GlobalStatementsBlock : Statement
|
||||||
{
|
{
|
||||||
private readonly Method parent;
|
private readonly Method parent;
|
||||||
|
private readonly List<GlobalStatementSyntax> globalStatements;
|
||||||
|
|
||||||
private GlobalStatementsBlock(Context cx, Method parent)
|
private GlobalStatementsBlock(Context cx, Method parent, List<GlobalStatementSyntax> globalStatements)
|
||||||
: base(cx, StmtKind.BLOCK, parent, 0)
|
: base(cx, StmtKind.BLOCK, parent, 0)
|
||||||
{
|
{
|
||||||
this.parent = parent;
|
this.parent = parent;
|
||||||
|
this.globalStatements = globalStatements;
|
||||||
}
|
}
|
||||||
|
|
||||||
public override Microsoft.CodeAnalysis.Location? ReportingLocation
|
public override Microsoft.CodeAnalysis.Location? ReportingLocation
|
||||||
@@ -27,9 +32,9 @@ namespace Semmle.Extraction.CSharp.Entities.Statements
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
public static GlobalStatementsBlock Create(Context cx, Method parent)
|
public static GlobalStatementsBlock Create(Context cx, Method parent, List<GlobalStatementSyntax> globalStatements)
|
||||||
{
|
{
|
||||||
var ret = new GlobalStatementsBlock(cx, parent);
|
var ret = new GlobalStatementsBlock(cx, parent, globalStatements);
|
||||||
ret.TryPopulate();
|
ret.TryPopulate();
|
||||||
return ret;
|
return ret;
|
||||||
}
|
}
|
||||||
@@ -37,6 +42,14 @@ namespace Semmle.Extraction.CSharp.Entities.Statements
|
|||||||
protected override void PopulateStatement(TextWriter trapFile)
|
protected override void PopulateStatement(TextWriter trapFile)
|
||||||
{
|
{
|
||||||
trapFile.stmt_location(this, Context.CreateLocation(ReportingLocation));
|
trapFile.stmt_location(this, Context.CreateLocation(ReportingLocation));
|
||||||
|
|
||||||
|
for (var i = 0; i < globalStatements.Count; i++)
|
||||||
|
{
|
||||||
|
if (globalStatements[i].Statement is not null)
|
||||||
|
{
|
||||||
|
Statement.Create(Context, globalStatements[i].Statement, this, i);
|
||||||
|
}
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -3,7 +3,6 @@ using Microsoft.CodeAnalysis.CSharp;
|
|||||||
using Microsoft.CodeAnalysis.CSharp.Syntax;
|
using Microsoft.CodeAnalysis.CSharp.Syntax;
|
||||||
using Semmle.Util.Logging;
|
using Semmle.Util.Logging;
|
||||||
using Semmle.Extraction.CSharp.Entities;
|
using Semmle.Extraction.CSharp.Entities;
|
||||||
using Semmle.Extraction.CSharp.Entities.Statements;
|
|
||||||
using System.Linq;
|
using System.Linq;
|
||||||
|
|
||||||
namespace Semmle.Extraction.CSharp.Populators
|
namespace Semmle.Extraction.CSharp.Populators
|
||||||
@@ -60,23 +59,14 @@ namespace Semmle.Extraction.CSharp.Populators
|
|||||||
}
|
}
|
||||||
|
|
||||||
var entryPoint = Cx.Compilation.GetEntryPoint(System.Threading.CancellationToken.None);
|
var entryPoint = Cx.Compilation.GetEntryPoint(System.Threading.CancellationToken.None);
|
||||||
var entryMethod = Method.Create(Cx, entryPoint);
|
if (entryPoint is null)
|
||||||
if (entryMethod is null)
|
|
||||||
{
|
{
|
||||||
Cx.ExtractionError("No entry method found. Skipping the extraction of global statements.",
|
Cx.ExtractionError("No entry method found. Skipping the extraction of global statements.",
|
||||||
null, Cx.CreateLocation(globalStatements[0].GetLocation()), null, Severity.Info);
|
null, Cx.CreateLocation(globalStatements[0].GetLocation()), null, Severity.Info);
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
var block = GlobalStatementsBlock.Create(Cx, entryMethod);
|
ImplicitMainMethod.Create(Cx, entryPoint, globalStatements);
|
||||||
|
|
||||||
for (var i = 0; i < globalStatements.Count; i++)
|
|
||||||
{
|
|
||||||
if (globalStatements[i].Statement is not null)
|
|
||||||
{
|
|
||||||
Statement.Create(Cx, globalStatements[i].Statement, block, i);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -1,3 +1,5 @@
|
|||||||
|
## 1.1.4
|
||||||
|
|
||||||
## 1.1.3
|
## 1.1.3
|
||||||
|
|
||||||
## 1.1.2
|
## 1.1.2
|
||||||
|
|||||||
@@ -0,0 +1 @@
|
|||||||
|
## 1.1.4
|
||||||
@@ -1,2 +1,2 @@
|
|||||||
---
|
---
|
||||||
lastReleaseVersion: 1.1.3
|
lastReleaseVersion: 1.1.4
|
||||||
|
|||||||
@@ -1,5 +1,5 @@
|
|||||||
name: codeql/csharp-solorigate-all
|
name: codeql/csharp-solorigate-all
|
||||||
version: 1.1.4-dev
|
version: 1.2.0-dev
|
||||||
groups:
|
groups:
|
||||||
- csharp
|
- csharp
|
||||||
- solorigate
|
- solorigate
|
||||||
|
|||||||
@@ -1,3 +1,5 @@
|
|||||||
|
## 1.1.4
|
||||||
|
|
||||||
## 1.1.3
|
## 1.1.3
|
||||||
|
|
||||||
## 1.1.2
|
## 1.1.2
|
||||||
|
|||||||
@@ -0,0 +1 @@
|
|||||||
|
## 1.1.4
|
||||||
@@ -1,2 +1,2 @@
|
|||||||
---
|
---
|
||||||
lastReleaseVersion: 1.1.3
|
lastReleaseVersion: 1.1.4
|
||||||
|
|||||||
@@ -1,5 +1,5 @@
|
|||||||
name: codeql/csharp-solorigate-queries
|
name: codeql/csharp-solorigate-queries
|
||||||
version: 1.1.4-dev
|
version: 1.2.0-dev
|
||||||
groups:
|
groups:
|
||||||
- csharp
|
- csharp
|
||||||
- solorigate
|
- solorigate
|
||||||
|
|||||||
@@ -1,3 +1,5 @@
|
|||||||
|
## 0.2.3
|
||||||
|
|
||||||
## 0.2.2
|
## 0.2.2
|
||||||
|
|
||||||
## 0.2.1
|
## 0.2.1
|
||||||
|
|||||||
@@ -0,0 +1,4 @@
|
|||||||
|
---
|
||||||
|
category: deprecated
|
||||||
|
---
|
||||||
|
* The `BarrierGuard` class has been deprecated. Such barriers and sanitizers can now instead be created using the new `BarrierGuard` parameterized module.
|
||||||
1
csharp/ql/lib/change-notes/released/0.2.3.md
Normal file
1
csharp/ql/lib/change-notes/released/0.2.3.md
Normal file
@@ -0,0 +1 @@
|
|||||||
|
## 0.2.3
|
||||||
@@ -1,2 +1,2 @@
|
|||||||
---
|
---
|
||||||
lastReleaseVersion: 0.2.2
|
lastReleaseVersion: 0.2.3
|
||||||
|
|||||||
@@ -1,5 +1,5 @@
|
|||||||
name: codeql/csharp-all
|
name: codeql/csharp-all
|
||||||
version: 0.2.3-dev
|
version: 0.3.0-dev
|
||||||
groups: csharp
|
groups: csharp
|
||||||
dbscheme: semmlecode.csharp.dbscheme
|
dbscheme: semmlecode.csharp.dbscheme
|
||||||
extractor: csharp
|
extractor: csharp
|
||||||
|
|||||||
@@ -69,6 +69,12 @@
|
|||||||
* sources "remote" indicates a default remote flow source, and for summaries
|
* sources "remote" indicates a default remote flow source, and for summaries
|
||||||
* "taint" indicates a default additional taint step and "value" indicates a
|
* "taint" indicates a default additional taint step and "value" indicates a
|
||||||
* globally applicable value-preserving step.
|
* globally applicable value-preserving step.
|
||||||
|
* 9. The `provenance` column is a tag to indicate the origin of the summary.
|
||||||
|
* There are two supported values: "generated" and "manual". "generated" means that
|
||||||
|
* the model has been emitted by the model generator tool and "manual" means
|
||||||
|
* that the model has been written by hand. This information is used in a heuristic
|
||||||
|
* for dataflow analysis to determine, if a model or source code should be used for
|
||||||
|
* determining flow.
|
||||||
*/
|
*/
|
||||||
|
|
||||||
import csharp
|
import csharp
|
||||||
@@ -163,17 +169,10 @@ private predicate sinkModel(string row) { any(SinkModelCsv s).row(row) }
|
|||||||
|
|
||||||
private predicate summaryModel(string row) { any(SummaryModelCsv s).row(row) }
|
private predicate summaryModel(string row) { any(SummaryModelCsv s).row(row) }
|
||||||
|
|
||||||
bindingset[input]
|
|
||||||
private predicate getKind(string input, string kind, boolean generated) {
|
|
||||||
input.splitAt(":", 0) = "generated" and kind = input.splitAt(":", 1) and generated = true
|
|
||||||
or
|
|
||||||
not input.matches("%:%") and kind = input and generated = false
|
|
||||||
}
|
|
||||||
|
|
||||||
/** Holds if a source model exists for the given parameters. */
|
/** Holds if a source model exists for the given parameters. */
|
||||||
predicate sourceModel(
|
predicate sourceModel(
|
||||||
string namespace, string type, boolean subtypes, string name, string signature, string ext,
|
string namespace, string type, boolean subtypes, string name, string signature, string ext,
|
||||||
string output, string kind, boolean generated
|
string output, string kind, string provenance
|
||||||
) {
|
) {
|
||||||
exists(string row |
|
exists(string row |
|
||||||
sourceModel(row) and
|
sourceModel(row) and
|
||||||
@@ -185,14 +184,15 @@ predicate sourceModel(
|
|||||||
row.splitAt(";", 4) = signature and
|
row.splitAt(";", 4) = signature and
|
||||||
row.splitAt(";", 5) = ext and
|
row.splitAt(";", 5) = ext and
|
||||||
row.splitAt(";", 6) = output and
|
row.splitAt(";", 6) = output and
|
||||||
exists(string k | row.splitAt(";", 7) = k and getKind(k, kind, generated))
|
row.splitAt(";", 7) = kind and
|
||||||
|
row.splitAt(";", 8) = provenance
|
||||||
)
|
)
|
||||||
}
|
}
|
||||||
|
|
||||||
/** Holds if a sink model exists for the given parameters. */
|
/** Holds if a sink model exists for the given parameters. */
|
||||||
predicate sinkModel(
|
predicate sinkModel(
|
||||||
string namespace, string type, boolean subtypes, string name, string signature, string ext,
|
string namespace, string type, boolean subtypes, string name, string signature, string ext,
|
||||||
string input, string kind, boolean generated
|
string input, string kind, string provenance
|
||||||
) {
|
) {
|
||||||
exists(string row |
|
exists(string row |
|
||||||
sinkModel(row) and
|
sinkModel(row) and
|
||||||
@@ -204,14 +204,15 @@ predicate sinkModel(
|
|||||||
row.splitAt(";", 4) = signature and
|
row.splitAt(";", 4) = signature and
|
||||||
row.splitAt(";", 5) = ext and
|
row.splitAt(";", 5) = ext and
|
||||||
row.splitAt(";", 6) = input and
|
row.splitAt(";", 6) = input and
|
||||||
exists(string k | row.splitAt(";", 7) = k and getKind(k, kind, generated))
|
row.splitAt(";", 7) = kind and
|
||||||
|
row.splitAt(";", 8) = provenance
|
||||||
)
|
)
|
||||||
}
|
}
|
||||||
|
|
||||||
/** Holds if a summary model exists for the given parameters. */
|
/** Holds if a summary model exists for the given parameters. */
|
||||||
predicate summaryModel(
|
predicate summaryModel(
|
||||||
string namespace, string type, boolean subtypes, string name, string signature, string ext,
|
string namespace, string type, boolean subtypes, string name, string signature, string ext,
|
||||||
string input, string output, string kind, boolean generated
|
string input, string output, string kind, string provenance
|
||||||
) {
|
) {
|
||||||
exists(string row |
|
exists(string row |
|
||||||
summaryModel(row) and
|
summaryModel(row) and
|
||||||
@@ -224,7 +225,8 @@ predicate summaryModel(
|
|||||||
row.splitAt(";", 5) = ext and
|
row.splitAt(";", 5) = ext and
|
||||||
row.splitAt(";", 6) = input and
|
row.splitAt(";", 6) = input and
|
||||||
row.splitAt(";", 7) = output and
|
row.splitAt(";", 7) = output and
|
||||||
exists(string k | row.splitAt(";", 8) = k and getKind(k, kind, generated))
|
row.splitAt(";", 8) = kind and
|
||||||
|
row.splitAt(";", 9) = provenance
|
||||||
)
|
)
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -259,25 +261,25 @@ predicate modelCoverage(string namespace, int namespaces, string kind, string pa
|
|||||||
part = "source" and
|
part = "source" and
|
||||||
n =
|
n =
|
||||||
strictcount(string subns, string type, boolean subtypes, string name, string signature,
|
strictcount(string subns, string type, boolean subtypes, string name, string signature,
|
||||||
string ext, string output, boolean generated |
|
string ext, string output, string provenance |
|
||||||
canonicalNamespaceLink(namespace, subns) and
|
canonicalNamespaceLink(namespace, subns) and
|
||||||
sourceModel(subns, type, subtypes, name, signature, ext, output, kind, generated)
|
sourceModel(subns, type, subtypes, name, signature, ext, output, kind, provenance)
|
||||||
)
|
)
|
||||||
or
|
or
|
||||||
part = "sink" and
|
part = "sink" and
|
||||||
n =
|
n =
|
||||||
strictcount(string subns, string type, boolean subtypes, string name, string signature,
|
strictcount(string subns, string type, boolean subtypes, string name, string signature,
|
||||||
string ext, string input, boolean generated |
|
string ext, string input, string provenance |
|
||||||
canonicalNamespaceLink(namespace, subns) and
|
canonicalNamespaceLink(namespace, subns) and
|
||||||
sinkModel(subns, type, subtypes, name, signature, ext, input, kind, generated)
|
sinkModel(subns, type, subtypes, name, signature, ext, input, kind, provenance)
|
||||||
)
|
)
|
||||||
or
|
or
|
||||||
part = "summary" and
|
part = "summary" and
|
||||||
n =
|
n =
|
||||||
strictcount(string subns, string type, boolean subtypes, string name, string signature,
|
strictcount(string subns, string type, boolean subtypes, string name, string signature,
|
||||||
string ext, string input, string output, boolean generated |
|
string ext, string input, string output, string provenance |
|
||||||
canonicalNamespaceLink(namespace, subns) and
|
canonicalNamespaceLink(namespace, subns) and
|
||||||
summaryModel(subns, type, subtypes, name, signature, ext, input, output, kind, generated)
|
summaryModel(subns, type, subtypes, name, signature, ext, input, output, kind, provenance)
|
||||||
)
|
)
|
||||||
)
|
)
|
||||||
}
|
}
|
||||||
@@ -286,12 +288,16 @@ predicate modelCoverage(string namespace, int namespaces, string kind, string pa
|
|||||||
module CsvValidation {
|
module CsvValidation {
|
||||||
/** Holds if some row in a CSV-based flow model appears to contain typos. */
|
/** Holds if some row in a CSV-based flow model appears to contain typos. */
|
||||||
query predicate invalidModelRow(string msg) {
|
query predicate invalidModelRow(string msg) {
|
||||||
exists(string pred, string namespace, string type, string name, string signature, string ext |
|
exists(
|
||||||
sourceModel(namespace, type, _, name, signature, ext, _, _, _) and pred = "source"
|
string pred, string namespace, string type, string name, string signature, string ext,
|
||||||
|
string provenance
|
||||||
|
|
|
||||||
|
sourceModel(namespace, type, _, name, signature, ext, _, _, provenance) and pred = "source"
|
||||||
or
|
or
|
||||||
sinkModel(namespace, type, _, name, signature, ext, _, _, _) and pred = "sink"
|
sinkModel(namespace, type, _, name, signature, ext, _, _, provenance) and pred = "sink"
|
||||||
or
|
or
|
||||||
summaryModel(namespace, type, _, name, signature, ext, _, _, _, _) and pred = "summary"
|
summaryModel(namespace, type, _, name, signature, ext, _, _, _, provenance) and
|
||||||
|
pred = "summary"
|
||||||
|
|
|
|
||||||
not namespace.regexpMatch("[a-zA-Z0-9_\\.]+") and
|
not namespace.regexpMatch("[a-zA-Z0-9_\\.]+") and
|
||||||
msg = "Dubious namespace \"" + namespace + "\" in " + pred + " model."
|
msg = "Dubious namespace \"" + namespace + "\" in " + pred + " model."
|
||||||
@@ -307,6 +313,9 @@ module CsvValidation {
|
|||||||
or
|
or
|
||||||
not ext.regexpMatch("|Attribute") and
|
not ext.regexpMatch("|Attribute") and
|
||||||
msg = "Unrecognized extra API graph element \"" + ext + "\" in " + pred + " model."
|
msg = "Unrecognized extra API graph element \"" + ext + "\" in " + pred + " model."
|
||||||
|
or
|
||||||
|
not provenance = ["manual", "generated"] and
|
||||||
|
msg = "Unrecognized provenance description \"" + provenance + "\" in " + pred + " model."
|
||||||
)
|
)
|
||||||
or
|
or
|
||||||
exists(string pred, AccessPath input, string part |
|
exists(string pred, AccessPath input, string part |
|
||||||
@@ -338,18 +347,18 @@ module CsvValidation {
|
|||||||
)
|
)
|
||||||
or
|
or
|
||||||
exists(string pred, string row, int expect |
|
exists(string pred, string row, int expect |
|
||||||
sourceModel(row) and expect = 8 and pred = "source"
|
sourceModel(row) and expect = 9 and pred = "source"
|
||||||
or
|
or
|
||||||
sinkModel(row) and expect = 8 and pred = "sink"
|
sinkModel(row) and expect = 9 and pred = "sink"
|
||||||
or
|
or
|
||||||
summaryModel(row) and expect = 9 and pred = "summary"
|
summaryModel(row) and expect = 10 and pred = "summary"
|
||||||
|
|
|
|
||||||
exists(int cols |
|
exists(int cols |
|
||||||
cols = 1 + max(int n | exists(row.splitAt(";", n))) and
|
cols = 1 + max(int n | exists(row.splitAt(";", n))) and
|
||||||
cols != expect and
|
cols != expect and
|
||||||
msg =
|
msg =
|
||||||
"Wrong number of columns in " + pred + " model row, expected " + expect + ", got " + cols +
|
"Wrong number of columns in " + pred + " model row, expected " + expect + ", got " + cols +
|
||||||
"."
|
" in " + row + "."
|
||||||
)
|
)
|
||||||
or
|
or
|
||||||
exists(string b |
|
exists(string b |
|
||||||
@@ -359,23 +368,20 @@ module CsvValidation {
|
|||||||
)
|
)
|
||||||
)
|
)
|
||||||
or
|
or
|
||||||
exists(string row, string k, string kind | summaryModel(row) |
|
exists(string row, string kind | summaryModel(row) |
|
||||||
k = row.splitAt(";", 8) and
|
kind = row.splitAt(";", 8) and
|
||||||
getKind(k, kind, _) and
|
|
||||||
not kind = ["taint", "value"] and
|
not kind = ["taint", "value"] and
|
||||||
msg = "Invalid kind \"" + kind + "\" in summary model."
|
msg = "Invalid kind \"" + kind + "\" in summary model."
|
||||||
)
|
)
|
||||||
or
|
or
|
||||||
exists(string row, string k, string kind | sinkModel(row) |
|
exists(string row, string kind | sinkModel(row) |
|
||||||
k = row.splitAt(";", 7) and
|
kind = row.splitAt(";", 7) and
|
||||||
getKind(k, kind, _) and
|
|
||||||
not kind = ["code", "sql", "xss", "remote", "html"] and
|
not kind = ["code", "sql", "xss", "remote", "html"] and
|
||||||
msg = "Invalid kind \"" + kind + "\" in sink model."
|
msg = "Invalid kind \"" + kind + "\" in sink model."
|
||||||
)
|
)
|
||||||
or
|
or
|
||||||
exists(string row, string k, string kind | sourceModel(row) |
|
exists(string row, string kind | sourceModel(row) |
|
||||||
k = row.splitAt(";", 7) and
|
kind = row.splitAt(";", 7) and
|
||||||
getKind(k, kind, _) and
|
|
||||||
not kind = "local" and
|
not kind = "local" and
|
||||||
msg = "Invalid kind \"" + kind + "\" in source model."
|
msg = "Invalid kind \"" + kind + "\" in source model."
|
||||||
)
|
)
|
||||||
|
|||||||
@@ -90,14 +90,20 @@ abstract class Configuration extends string {
|
|||||||
/** Holds if data flow out of `node` is prohibited. */
|
/** Holds if data flow out of `node` is prohibited. */
|
||||||
predicate isBarrierOut(Node node) { none() }
|
predicate isBarrierOut(Node node) { none() }
|
||||||
|
|
||||||
/** Holds if data flow through nodes guarded by `guard` is prohibited. */
|
/**
|
||||||
predicate isBarrierGuard(BarrierGuard guard) { none() }
|
* DEPRECATED: Use `isBarrier` and `BarrierGuard` module instead.
|
||||||
|
*
|
||||||
|
* Holds if data flow through nodes guarded by `guard` is prohibited.
|
||||||
|
*/
|
||||||
|
deprecated predicate isBarrierGuard(BarrierGuard guard) { none() }
|
||||||
|
|
||||||
/**
|
/**
|
||||||
|
* DEPRECATED: Use `isBarrier` and `BarrierGuard` module instead.
|
||||||
|
*
|
||||||
* Holds if data flow through nodes guarded by `guard` is prohibited when
|
* Holds if data flow through nodes guarded by `guard` is prohibited when
|
||||||
* the flow state is `state`
|
* the flow state is `state`
|
||||||
*/
|
*/
|
||||||
predicate isBarrierGuard(BarrierGuard guard, FlowState state) { none() }
|
deprecated predicate isBarrierGuard(BarrierGuard guard, FlowState state) { none() }
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Holds if data may flow from `node1` to `node2` in addition to the normal data-flow steps.
|
* Holds if data may flow from `node1` to `node2` in addition to the normal data-flow steps.
|
||||||
@@ -335,6 +341,29 @@ private predicate outBarrier(NodeEx node, Configuration config) {
|
|||||||
)
|
)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/** A bridge class to access the deprecated `isBarrierGuard`. */
|
||||||
|
private class BarrierGuardGuardedNodeBridge extends Unit {
|
||||||
|
abstract predicate guardedNode(Node n, Configuration config);
|
||||||
|
|
||||||
|
abstract predicate guardedNode(Node n, FlowState state, Configuration config);
|
||||||
|
}
|
||||||
|
|
||||||
|
private class BarrierGuardGuardedNode extends BarrierGuardGuardedNodeBridge {
|
||||||
|
deprecated override predicate guardedNode(Node n, Configuration config) {
|
||||||
|
exists(BarrierGuard g |
|
||||||
|
config.isBarrierGuard(g) and
|
||||||
|
n = g.getAGuardedNode()
|
||||||
|
)
|
||||||
|
}
|
||||||
|
|
||||||
|
deprecated override predicate guardedNode(Node n, FlowState state, Configuration config) {
|
||||||
|
exists(BarrierGuard g |
|
||||||
|
config.isBarrierGuard(g, state) and
|
||||||
|
n = g.getAGuardedNode()
|
||||||
|
)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
pragma[nomagic]
|
pragma[nomagic]
|
||||||
private predicate fullBarrier(NodeEx node, Configuration config) {
|
private predicate fullBarrier(NodeEx node, Configuration config) {
|
||||||
exists(Node n | node.asNode() = n |
|
exists(Node n | node.asNode() = n |
|
||||||
@@ -348,10 +377,7 @@ private predicate fullBarrier(NodeEx node, Configuration config) {
|
|||||||
not config.isSink(n) and
|
not config.isSink(n) and
|
||||||
not config.isSink(n, _)
|
not config.isSink(n, _)
|
||||||
or
|
or
|
||||||
exists(BarrierGuard g |
|
any(BarrierGuardGuardedNodeBridge b).guardedNode(n, config)
|
||||||
config.isBarrierGuard(g) and
|
|
||||||
n = g.getAGuardedNode()
|
|
||||||
)
|
|
||||||
)
|
)
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -360,10 +386,7 @@ private predicate stateBarrier(NodeEx node, FlowState state, Configuration confi
|
|||||||
exists(Node n | node.asNode() = n |
|
exists(Node n | node.asNode() = n |
|
||||||
config.isBarrier(n, state)
|
config.isBarrier(n, state)
|
||||||
or
|
or
|
||||||
exists(BarrierGuard g |
|
any(BarrierGuardGuardedNodeBridge b).guardedNode(n, state, config)
|
||||||
config.isBarrierGuard(g, state) and
|
|
||||||
n = g.getAGuardedNode()
|
|
||||||
)
|
|
||||||
)
|
)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@@ -90,14 +90,20 @@ abstract class Configuration extends string {
|
|||||||
/** Holds if data flow out of `node` is prohibited. */
|
/** Holds if data flow out of `node` is prohibited. */
|
||||||
predicate isBarrierOut(Node node) { none() }
|
predicate isBarrierOut(Node node) { none() }
|
||||||
|
|
||||||
/** Holds if data flow through nodes guarded by `guard` is prohibited. */
|
/**
|
||||||
predicate isBarrierGuard(BarrierGuard guard) { none() }
|
* DEPRECATED: Use `isBarrier` and `BarrierGuard` module instead.
|
||||||
|
*
|
||||||
|
* Holds if data flow through nodes guarded by `guard` is prohibited.
|
||||||
|
*/
|
||||||
|
deprecated predicate isBarrierGuard(BarrierGuard guard) { none() }
|
||||||
|
|
||||||
/**
|
/**
|
||||||
|
* DEPRECATED: Use `isBarrier` and `BarrierGuard` module instead.
|
||||||
|
*
|
||||||
* Holds if data flow through nodes guarded by `guard` is prohibited when
|
* Holds if data flow through nodes guarded by `guard` is prohibited when
|
||||||
* the flow state is `state`
|
* the flow state is `state`
|
||||||
*/
|
*/
|
||||||
predicate isBarrierGuard(BarrierGuard guard, FlowState state) { none() }
|
deprecated predicate isBarrierGuard(BarrierGuard guard, FlowState state) { none() }
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Holds if data may flow from `node1` to `node2` in addition to the normal data-flow steps.
|
* Holds if data may flow from `node1` to `node2` in addition to the normal data-flow steps.
|
||||||
@@ -335,6 +341,29 @@ private predicate outBarrier(NodeEx node, Configuration config) {
|
|||||||
)
|
)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/** A bridge class to access the deprecated `isBarrierGuard`. */
|
||||||
|
private class BarrierGuardGuardedNodeBridge extends Unit {
|
||||||
|
abstract predicate guardedNode(Node n, Configuration config);
|
||||||
|
|
||||||
|
abstract predicate guardedNode(Node n, FlowState state, Configuration config);
|
||||||
|
}
|
||||||
|
|
||||||
|
private class BarrierGuardGuardedNode extends BarrierGuardGuardedNodeBridge {
|
||||||
|
deprecated override predicate guardedNode(Node n, Configuration config) {
|
||||||
|
exists(BarrierGuard g |
|
||||||
|
config.isBarrierGuard(g) and
|
||||||
|
n = g.getAGuardedNode()
|
||||||
|
)
|
||||||
|
}
|
||||||
|
|
||||||
|
deprecated override predicate guardedNode(Node n, FlowState state, Configuration config) {
|
||||||
|
exists(BarrierGuard g |
|
||||||
|
config.isBarrierGuard(g, state) and
|
||||||
|
n = g.getAGuardedNode()
|
||||||
|
)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
pragma[nomagic]
|
pragma[nomagic]
|
||||||
private predicate fullBarrier(NodeEx node, Configuration config) {
|
private predicate fullBarrier(NodeEx node, Configuration config) {
|
||||||
exists(Node n | node.asNode() = n |
|
exists(Node n | node.asNode() = n |
|
||||||
@@ -348,10 +377,7 @@ private predicate fullBarrier(NodeEx node, Configuration config) {
|
|||||||
not config.isSink(n) and
|
not config.isSink(n) and
|
||||||
not config.isSink(n, _)
|
not config.isSink(n, _)
|
||||||
or
|
or
|
||||||
exists(BarrierGuard g |
|
any(BarrierGuardGuardedNodeBridge b).guardedNode(n, config)
|
||||||
config.isBarrierGuard(g) and
|
|
||||||
n = g.getAGuardedNode()
|
|
||||||
)
|
|
||||||
)
|
)
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -360,10 +386,7 @@ private predicate stateBarrier(NodeEx node, FlowState state, Configuration confi
|
|||||||
exists(Node n | node.asNode() = n |
|
exists(Node n | node.asNode() = n |
|
||||||
config.isBarrier(n, state)
|
config.isBarrier(n, state)
|
||||||
or
|
or
|
||||||
exists(BarrierGuard g |
|
any(BarrierGuardGuardedNodeBridge b).guardedNode(n, state, config)
|
||||||
config.isBarrierGuard(g, state) and
|
|
||||||
n = g.getAGuardedNode()
|
|
||||||
)
|
|
||||||
)
|
)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@@ -90,14 +90,20 @@ abstract class Configuration extends string {
|
|||||||
/** Holds if data flow out of `node` is prohibited. */
|
/** Holds if data flow out of `node` is prohibited. */
|
||||||
predicate isBarrierOut(Node node) { none() }
|
predicate isBarrierOut(Node node) { none() }
|
||||||
|
|
||||||
/** Holds if data flow through nodes guarded by `guard` is prohibited. */
|
/**
|
||||||
predicate isBarrierGuard(BarrierGuard guard) { none() }
|
* DEPRECATED: Use `isBarrier` and `BarrierGuard` module instead.
|
||||||
|
*
|
||||||
|
* Holds if data flow through nodes guarded by `guard` is prohibited.
|
||||||
|
*/
|
||||||
|
deprecated predicate isBarrierGuard(BarrierGuard guard) { none() }
|
||||||
|
|
||||||
/**
|
/**
|
||||||
|
* DEPRECATED: Use `isBarrier` and `BarrierGuard` module instead.
|
||||||
|
*
|
||||||
* Holds if data flow through nodes guarded by `guard` is prohibited when
|
* Holds if data flow through nodes guarded by `guard` is prohibited when
|
||||||
* the flow state is `state`
|
* the flow state is `state`
|
||||||
*/
|
*/
|
||||||
predicate isBarrierGuard(BarrierGuard guard, FlowState state) { none() }
|
deprecated predicate isBarrierGuard(BarrierGuard guard, FlowState state) { none() }
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Holds if data may flow from `node1` to `node2` in addition to the normal data-flow steps.
|
* Holds if data may flow from `node1` to `node2` in addition to the normal data-flow steps.
|
||||||
@@ -335,6 +341,29 @@ private predicate outBarrier(NodeEx node, Configuration config) {
|
|||||||
)
|
)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/** A bridge class to access the deprecated `isBarrierGuard`. */
|
||||||
|
private class BarrierGuardGuardedNodeBridge extends Unit {
|
||||||
|
abstract predicate guardedNode(Node n, Configuration config);
|
||||||
|
|
||||||
|
abstract predicate guardedNode(Node n, FlowState state, Configuration config);
|
||||||
|
}
|
||||||
|
|
||||||
|
private class BarrierGuardGuardedNode extends BarrierGuardGuardedNodeBridge {
|
||||||
|
deprecated override predicate guardedNode(Node n, Configuration config) {
|
||||||
|
exists(BarrierGuard g |
|
||||||
|
config.isBarrierGuard(g) and
|
||||||
|
n = g.getAGuardedNode()
|
||||||
|
)
|
||||||
|
}
|
||||||
|
|
||||||
|
deprecated override predicate guardedNode(Node n, FlowState state, Configuration config) {
|
||||||
|
exists(BarrierGuard g |
|
||||||
|
config.isBarrierGuard(g, state) and
|
||||||
|
n = g.getAGuardedNode()
|
||||||
|
)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
pragma[nomagic]
|
pragma[nomagic]
|
||||||
private predicate fullBarrier(NodeEx node, Configuration config) {
|
private predicate fullBarrier(NodeEx node, Configuration config) {
|
||||||
exists(Node n | node.asNode() = n |
|
exists(Node n | node.asNode() = n |
|
||||||
@@ -348,10 +377,7 @@ private predicate fullBarrier(NodeEx node, Configuration config) {
|
|||||||
not config.isSink(n) and
|
not config.isSink(n) and
|
||||||
not config.isSink(n, _)
|
not config.isSink(n, _)
|
||||||
or
|
or
|
||||||
exists(BarrierGuard g |
|
any(BarrierGuardGuardedNodeBridge b).guardedNode(n, config)
|
||||||
config.isBarrierGuard(g) and
|
|
||||||
n = g.getAGuardedNode()
|
|
||||||
)
|
|
||||||
)
|
)
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -360,10 +386,7 @@ private predicate stateBarrier(NodeEx node, FlowState state, Configuration confi
|
|||||||
exists(Node n | node.asNode() = n |
|
exists(Node n | node.asNode() = n |
|
||||||
config.isBarrier(n, state)
|
config.isBarrier(n, state)
|
||||||
or
|
or
|
||||||
exists(BarrierGuard g |
|
any(BarrierGuardGuardedNodeBridge b).guardedNode(n, state, config)
|
||||||
config.isBarrierGuard(g, state) and
|
|
||||||
n = g.getAGuardedNode()
|
|
||||||
)
|
|
||||||
)
|
)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@@ -90,14 +90,20 @@ abstract class Configuration extends string {
|
|||||||
/** Holds if data flow out of `node` is prohibited. */
|
/** Holds if data flow out of `node` is prohibited. */
|
||||||
predicate isBarrierOut(Node node) { none() }
|
predicate isBarrierOut(Node node) { none() }
|
||||||
|
|
||||||
/** Holds if data flow through nodes guarded by `guard` is prohibited. */
|
/**
|
||||||
predicate isBarrierGuard(BarrierGuard guard) { none() }
|
* DEPRECATED: Use `isBarrier` and `BarrierGuard` module instead.
|
||||||
|
*
|
||||||
|
* Holds if data flow through nodes guarded by `guard` is prohibited.
|
||||||
|
*/
|
||||||
|
deprecated predicate isBarrierGuard(BarrierGuard guard) { none() }
|
||||||
|
|
||||||
/**
|
/**
|
||||||
|
* DEPRECATED: Use `isBarrier` and `BarrierGuard` module instead.
|
||||||
|
*
|
||||||
* Holds if data flow through nodes guarded by `guard` is prohibited when
|
* Holds if data flow through nodes guarded by `guard` is prohibited when
|
||||||
* the flow state is `state`
|
* the flow state is `state`
|
||||||
*/
|
*/
|
||||||
predicate isBarrierGuard(BarrierGuard guard, FlowState state) { none() }
|
deprecated predicate isBarrierGuard(BarrierGuard guard, FlowState state) { none() }
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Holds if data may flow from `node1` to `node2` in addition to the normal data-flow steps.
|
* Holds if data may flow from `node1` to `node2` in addition to the normal data-flow steps.
|
||||||
@@ -335,6 +341,29 @@ private predicate outBarrier(NodeEx node, Configuration config) {
|
|||||||
)
|
)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/** A bridge class to access the deprecated `isBarrierGuard`. */
|
||||||
|
private class BarrierGuardGuardedNodeBridge extends Unit {
|
||||||
|
abstract predicate guardedNode(Node n, Configuration config);
|
||||||
|
|
||||||
|
abstract predicate guardedNode(Node n, FlowState state, Configuration config);
|
||||||
|
}
|
||||||
|
|
||||||
|
private class BarrierGuardGuardedNode extends BarrierGuardGuardedNodeBridge {
|
||||||
|
deprecated override predicate guardedNode(Node n, Configuration config) {
|
||||||
|
exists(BarrierGuard g |
|
||||||
|
config.isBarrierGuard(g) and
|
||||||
|
n = g.getAGuardedNode()
|
||||||
|
)
|
||||||
|
}
|
||||||
|
|
||||||
|
deprecated override predicate guardedNode(Node n, FlowState state, Configuration config) {
|
||||||
|
exists(BarrierGuard g |
|
||||||
|
config.isBarrierGuard(g, state) and
|
||||||
|
n = g.getAGuardedNode()
|
||||||
|
)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
pragma[nomagic]
|
pragma[nomagic]
|
||||||
private predicate fullBarrier(NodeEx node, Configuration config) {
|
private predicate fullBarrier(NodeEx node, Configuration config) {
|
||||||
exists(Node n | node.asNode() = n |
|
exists(Node n | node.asNode() = n |
|
||||||
@@ -348,10 +377,7 @@ private predicate fullBarrier(NodeEx node, Configuration config) {
|
|||||||
not config.isSink(n) and
|
not config.isSink(n) and
|
||||||
not config.isSink(n, _)
|
not config.isSink(n, _)
|
||||||
or
|
or
|
||||||
exists(BarrierGuard g |
|
any(BarrierGuardGuardedNodeBridge b).guardedNode(n, config)
|
||||||
config.isBarrierGuard(g) and
|
|
||||||
n = g.getAGuardedNode()
|
|
||||||
)
|
|
||||||
)
|
)
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -360,10 +386,7 @@ private predicate stateBarrier(NodeEx node, FlowState state, Configuration confi
|
|||||||
exists(Node n | node.asNode() = n |
|
exists(Node n | node.asNode() = n |
|
||||||
config.isBarrier(n, state)
|
config.isBarrier(n, state)
|
||||||
or
|
or
|
||||||
exists(BarrierGuard g |
|
any(BarrierGuardGuardedNodeBridge b).guardedNode(n, state, config)
|
||||||
config.isBarrierGuard(g, state) and
|
|
||||||
n = g.getAGuardedNode()
|
|
||||||
)
|
|
||||||
)
|
)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@@ -90,14 +90,20 @@ abstract class Configuration extends string {
|
|||||||
/** Holds if data flow out of `node` is prohibited. */
|
/** Holds if data flow out of `node` is prohibited. */
|
||||||
predicate isBarrierOut(Node node) { none() }
|
predicate isBarrierOut(Node node) { none() }
|
||||||
|
|
||||||
/** Holds if data flow through nodes guarded by `guard` is prohibited. */
|
/**
|
||||||
predicate isBarrierGuard(BarrierGuard guard) { none() }
|
* DEPRECATED: Use `isBarrier` and `BarrierGuard` module instead.
|
||||||
|
*
|
||||||
|
* Holds if data flow through nodes guarded by `guard` is prohibited.
|
||||||
|
*/
|
||||||
|
deprecated predicate isBarrierGuard(BarrierGuard guard) { none() }
|
||||||
|
|
||||||
/**
|
/**
|
||||||
|
* DEPRECATED: Use `isBarrier` and `BarrierGuard` module instead.
|
||||||
|
*
|
||||||
* Holds if data flow through nodes guarded by `guard` is prohibited when
|
* Holds if data flow through nodes guarded by `guard` is prohibited when
|
||||||
* the flow state is `state`
|
* the flow state is `state`
|
||||||
*/
|
*/
|
||||||
predicate isBarrierGuard(BarrierGuard guard, FlowState state) { none() }
|
deprecated predicate isBarrierGuard(BarrierGuard guard, FlowState state) { none() }
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Holds if data may flow from `node1` to `node2` in addition to the normal data-flow steps.
|
* Holds if data may flow from `node1` to `node2` in addition to the normal data-flow steps.
|
||||||
@@ -335,6 +341,29 @@ private predicate outBarrier(NodeEx node, Configuration config) {
|
|||||||
)
|
)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/** A bridge class to access the deprecated `isBarrierGuard`. */
|
||||||
|
private class BarrierGuardGuardedNodeBridge extends Unit {
|
||||||
|
abstract predicate guardedNode(Node n, Configuration config);
|
||||||
|
|
||||||
|
abstract predicate guardedNode(Node n, FlowState state, Configuration config);
|
||||||
|
}
|
||||||
|
|
||||||
|
private class BarrierGuardGuardedNode extends BarrierGuardGuardedNodeBridge {
|
||||||
|
deprecated override predicate guardedNode(Node n, Configuration config) {
|
||||||
|
exists(BarrierGuard g |
|
||||||
|
config.isBarrierGuard(g) and
|
||||||
|
n = g.getAGuardedNode()
|
||||||
|
)
|
||||||
|
}
|
||||||
|
|
||||||
|
deprecated override predicate guardedNode(Node n, FlowState state, Configuration config) {
|
||||||
|
exists(BarrierGuard g |
|
||||||
|
config.isBarrierGuard(g, state) and
|
||||||
|
n = g.getAGuardedNode()
|
||||||
|
)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
pragma[nomagic]
|
pragma[nomagic]
|
||||||
private predicate fullBarrier(NodeEx node, Configuration config) {
|
private predicate fullBarrier(NodeEx node, Configuration config) {
|
||||||
exists(Node n | node.asNode() = n |
|
exists(Node n | node.asNode() = n |
|
||||||
@@ -348,10 +377,7 @@ private predicate fullBarrier(NodeEx node, Configuration config) {
|
|||||||
not config.isSink(n) and
|
not config.isSink(n) and
|
||||||
not config.isSink(n, _)
|
not config.isSink(n, _)
|
||||||
or
|
or
|
||||||
exists(BarrierGuard g |
|
any(BarrierGuardGuardedNodeBridge b).guardedNode(n, config)
|
||||||
config.isBarrierGuard(g) and
|
|
||||||
n = g.getAGuardedNode()
|
|
||||||
)
|
|
||||||
)
|
)
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -360,10 +386,7 @@ private predicate stateBarrier(NodeEx node, FlowState state, Configuration confi
|
|||||||
exists(Node n | node.asNode() = n |
|
exists(Node n | node.asNode() = n |
|
||||||
config.isBarrier(n, state)
|
config.isBarrier(n, state)
|
||||||
or
|
or
|
||||||
exists(BarrierGuard g |
|
any(BarrierGuardGuardedNodeBridge b).guardedNode(n, state, config)
|
||||||
config.isBarrierGuard(g, state) and
|
|
||||||
n = g.getAGuardedNode()
|
|
||||||
)
|
|
||||||
)
|
)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@@ -90,14 +90,20 @@ abstract class Configuration extends string {
|
|||||||
/** Holds if data flow out of `node` is prohibited. */
|
/** Holds if data flow out of `node` is prohibited. */
|
||||||
predicate isBarrierOut(Node node) { none() }
|
predicate isBarrierOut(Node node) { none() }
|
||||||
|
|
||||||
/** Holds if data flow through nodes guarded by `guard` is prohibited. */
|
/**
|
||||||
predicate isBarrierGuard(BarrierGuard guard) { none() }
|
* DEPRECATED: Use `isBarrier` and `BarrierGuard` module instead.
|
||||||
|
*
|
||||||
|
* Holds if data flow through nodes guarded by `guard` is prohibited.
|
||||||
|
*/
|
||||||
|
deprecated predicate isBarrierGuard(BarrierGuard guard) { none() }
|
||||||
|
|
||||||
/**
|
/**
|
||||||
|
* DEPRECATED: Use `isBarrier` and `BarrierGuard` module instead.
|
||||||
|
*
|
||||||
* Holds if data flow through nodes guarded by `guard` is prohibited when
|
* Holds if data flow through nodes guarded by `guard` is prohibited when
|
||||||
* the flow state is `state`
|
* the flow state is `state`
|
||||||
*/
|
*/
|
||||||
predicate isBarrierGuard(BarrierGuard guard, FlowState state) { none() }
|
deprecated predicate isBarrierGuard(BarrierGuard guard, FlowState state) { none() }
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Holds if data may flow from `node1` to `node2` in addition to the normal data-flow steps.
|
* Holds if data may flow from `node1` to `node2` in addition to the normal data-flow steps.
|
||||||
@@ -335,6 +341,29 @@ private predicate outBarrier(NodeEx node, Configuration config) {
|
|||||||
)
|
)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/** A bridge class to access the deprecated `isBarrierGuard`. */
|
||||||
|
private class BarrierGuardGuardedNodeBridge extends Unit {
|
||||||
|
abstract predicate guardedNode(Node n, Configuration config);
|
||||||
|
|
||||||
|
abstract predicate guardedNode(Node n, FlowState state, Configuration config);
|
||||||
|
}
|
||||||
|
|
||||||
|
private class BarrierGuardGuardedNode extends BarrierGuardGuardedNodeBridge {
|
||||||
|
deprecated override predicate guardedNode(Node n, Configuration config) {
|
||||||
|
exists(BarrierGuard g |
|
||||||
|
config.isBarrierGuard(g) and
|
||||||
|
n = g.getAGuardedNode()
|
||||||
|
)
|
||||||
|
}
|
||||||
|
|
||||||
|
deprecated override predicate guardedNode(Node n, FlowState state, Configuration config) {
|
||||||
|
exists(BarrierGuard g |
|
||||||
|
config.isBarrierGuard(g, state) and
|
||||||
|
n = g.getAGuardedNode()
|
||||||
|
)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
pragma[nomagic]
|
pragma[nomagic]
|
||||||
private predicate fullBarrier(NodeEx node, Configuration config) {
|
private predicate fullBarrier(NodeEx node, Configuration config) {
|
||||||
exists(Node n | node.asNode() = n |
|
exists(Node n | node.asNode() = n |
|
||||||
@@ -348,10 +377,7 @@ private predicate fullBarrier(NodeEx node, Configuration config) {
|
|||||||
not config.isSink(n) and
|
not config.isSink(n) and
|
||||||
not config.isSink(n, _)
|
not config.isSink(n, _)
|
||||||
or
|
or
|
||||||
exists(BarrierGuard g |
|
any(BarrierGuardGuardedNodeBridge b).guardedNode(n, config)
|
||||||
config.isBarrierGuard(g) and
|
|
||||||
n = g.getAGuardedNode()
|
|
||||||
)
|
|
||||||
)
|
)
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -360,10 +386,7 @@ private predicate stateBarrier(NodeEx node, FlowState state, Configuration confi
|
|||||||
exists(Node n | node.asNode() = n |
|
exists(Node n | node.asNode() = n |
|
||||||
config.isBarrier(n, state)
|
config.isBarrier(n, state)
|
||||||
or
|
or
|
||||||
exists(BarrierGuard g |
|
any(BarrierGuardGuardedNodeBridge b).guardedNode(n, state, config)
|
||||||
config.isBarrierGuard(g, state) and
|
|
||||||
n = g.getAGuardedNode()
|
|
||||||
)
|
|
||||||
)
|
)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@@ -173,6 +173,33 @@ abstract class NonLocalJumpNode extends Node {
|
|||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
|
* Holds if the guard `g` validates the expression `e` upon evaluating to `v`.
|
||||||
|
*
|
||||||
|
* The expression `e` is expected to be a syntactic part of the guard `g`.
|
||||||
|
* For example, the guard `g` might be a call `isSafe(x)` and the expression `e`
|
||||||
|
* the argument `x`.
|
||||||
|
*/
|
||||||
|
signature predicate guardChecksSig(Guard g, Expr e, AbstractValue v);
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Provides a set of barrier nodes for a guard that validates an expression.
|
||||||
|
*
|
||||||
|
* This is expected to be used in `isBarrier`/`isSanitizer` definitions
|
||||||
|
* in data flow and taint tracking.
|
||||||
|
*/
|
||||||
|
module BarrierGuard<guardChecksSig/3 guardChecks> {
|
||||||
|
/** Gets a node that is safely guarded by the given guard check. */
|
||||||
|
ExprNode getABarrierNode() {
|
||||||
|
exists(Guard g, Expr e, AbstractValue v |
|
||||||
|
guardChecks(g, e, v) and
|
||||||
|
g.controlsNode(result.getControlFlowNode(), e, v)
|
||||||
|
)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* DEPRECATED: Use `BarrierGuard` module instead.
|
||||||
|
*
|
||||||
* A guard that validates some expression.
|
* A guard that validates some expression.
|
||||||
*
|
*
|
||||||
* To use this in a configuration, extend the class and provide a
|
* To use this in a configuration, extend the class and provide a
|
||||||
@@ -181,7 +208,7 @@ abstract class NonLocalJumpNode extends Node {
|
|||||||
*
|
*
|
||||||
* It is important that all extending classes in scope are disjoint.
|
* It is important that all extending classes in scope are disjoint.
|
||||||
*/
|
*/
|
||||||
class BarrierGuard extends Guard {
|
deprecated class BarrierGuard extends Guard {
|
||||||
/** Holds if this guard validates `e` upon evaluating to `v`. */
|
/** Holds if this guard validates `e` upon evaluating to `v`. */
|
||||||
abstract predicate checks(Expr e, AbstractValue v);
|
abstract predicate checks(Expr e, AbstractValue v);
|
||||||
|
|
||||||
|
|||||||
@@ -1116,13 +1116,13 @@ module Private {
|
|||||||
preservesValue = false and result = "taint"
|
preservesValue = false and result = "taint"
|
||||||
}
|
}
|
||||||
|
|
||||||
private string renderGenerated(RelevantSummarizedCallable c) {
|
private string renderProvenance(RelevantSummarizedCallable c) {
|
||||||
if c.(SummarizedCallable).isAutoGenerated() then result = "generated:" else result = ""
|
if c.(SummarizedCallable).isAutoGenerated() then result = "generated" else result = "manual"
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* A query predicate for outputting flow summaries in semi-colon separated format in QL tests.
|
* A query predicate for outputting flow summaries in semi-colon separated format in QL tests.
|
||||||
* The syntax is: "namespace;type;overrides;name;signature;ext;inputspec;outputspec;(generated:)?kind",
|
* The syntax is: "namespace;type;overrides;name;signature;ext;inputspec;outputspec;kind;provenance"",
|
||||||
* ext is hardcoded to empty.
|
* ext is hardcoded to empty.
|
||||||
*/
|
*/
|
||||||
query predicate summary(string csv) {
|
query predicate summary(string csv) {
|
||||||
@@ -1133,7 +1133,7 @@ module Private {
|
|||||||
c.relevantSummary(input, output, preservesValue) and
|
c.relevantSummary(input, output, preservesValue) and
|
||||||
csv =
|
csv =
|
||||||
c.getCallableCsv() + getComponentStackCsv(input) + ";" + getComponentStackCsv(output) +
|
c.getCallableCsv() + getComponentStackCsv(input) + ";" + getComponentStackCsv(output) +
|
||||||
";" + renderGenerated(c) + renderKind(preservesValue)
|
";" + renderKind(preservesValue) + ";" + renderProvenance(c)
|
||||||
)
|
)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -91,6 +91,13 @@ DataFlowType getCallbackReturnType(DataFlowType t, ReturnKind rk) {
|
|||||||
)
|
)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
bindingset[provenance]
|
||||||
|
private boolean isGenerated(string provenance) {
|
||||||
|
provenance = "generated" and result = true
|
||||||
|
or
|
||||||
|
provenance != "generated" and result = false
|
||||||
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Holds if an external flow summary exists for `c` with input specification
|
* Holds if an external flow summary exists for `c` with input specification
|
||||||
* `input`, output specification `output`, kind `kind`, and a flag `generated`
|
* `input`, output specification `output`, kind `kind`, and a flag `generated`
|
||||||
@@ -98,9 +105,11 @@ DataFlowType getCallbackReturnType(DataFlowType t, ReturnKind rk) {
|
|||||||
*/
|
*/
|
||||||
predicate summaryElement(Callable c, string input, string output, string kind, boolean generated) {
|
predicate summaryElement(Callable c, string input, string output, string kind, boolean generated) {
|
||||||
exists(
|
exists(
|
||||||
string namespace, string type, boolean subtypes, string name, string signature, string ext
|
string namespace, string type, boolean subtypes, string name, string signature, string ext,
|
||||||
|
string provenance
|
||||||
|
|
|
|
||||||
summaryModel(namespace, type, subtypes, name, signature, ext, input, output, kind, generated) and
|
summaryModel(namespace, type, subtypes, name, signature, ext, input, output, kind, provenance) and
|
||||||
|
generated = isGenerated(provenance) and
|
||||||
c = interpretElement(namespace, type, subtypes, name, signature, ext)
|
c = interpretElement(namespace, type, subtypes, name, signature, ext)
|
||||||
)
|
)
|
||||||
}
|
}
|
||||||
@@ -112,9 +121,11 @@ predicate summaryElement(Callable c, string input, string output, string kind, b
|
|||||||
*/
|
*/
|
||||||
predicate sourceElement(Element e, string output, string kind, boolean generated) {
|
predicate sourceElement(Element e, string output, string kind, boolean generated) {
|
||||||
exists(
|
exists(
|
||||||
string namespace, string type, boolean subtypes, string name, string signature, string ext
|
string namespace, string type, boolean subtypes, string name, string signature, string ext,
|
||||||
|
string provenance
|
||||||
|
|
|
|
||||||
sourceModel(namespace, type, subtypes, name, signature, ext, output, kind, generated) and
|
sourceModel(namespace, type, subtypes, name, signature, ext, output, kind, provenance) and
|
||||||
|
generated = isGenerated(provenance) and
|
||||||
e = interpretElement(namespace, type, subtypes, name, signature, ext)
|
e = interpretElement(namespace, type, subtypes, name, signature, ext)
|
||||||
)
|
)
|
||||||
}
|
}
|
||||||
@@ -126,9 +137,11 @@ predicate sourceElement(Element e, string output, string kind, boolean generated
|
|||||||
*/
|
*/
|
||||||
predicate sinkElement(Element e, string input, string kind, boolean generated) {
|
predicate sinkElement(Element e, string input, string kind, boolean generated) {
|
||||||
exists(
|
exists(
|
||||||
string namespace, string type, boolean subtypes, string name, string signature, string ext
|
string namespace, string type, boolean subtypes, string name, string signature, string ext,
|
||||||
|
string provenance
|
||||||
|
|
|
|
||||||
sinkModel(namespace, type, subtypes, name, signature, ext, input, kind, generated) and
|
sinkModel(namespace, type, subtypes, name, signature, ext, input, kind, provenance) and
|
||||||
|
generated = isGenerated(provenance) and
|
||||||
e = interpretElement(namespace, type, subtypes, name, signature, ext)
|
e = interpretElement(namespace, type, subtypes, name, signature, ext)
|
||||||
)
|
)
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -19,12 +19,6 @@ private import semmle.code.csharp.frameworks.WCF
|
|||||||
*/
|
*/
|
||||||
predicate defaultTaintSanitizer(DataFlow::Node node) { none() }
|
predicate defaultTaintSanitizer(DataFlow::Node node) { none() }
|
||||||
|
|
||||||
/**
|
|
||||||
* Holds if `guard` should be a sanitizer guard in all global taint flow configurations
|
|
||||||
* but not in local taint.
|
|
||||||
*/
|
|
||||||
predicate defaultTaintSanitizerGuard(DataFlow::BarrierGuard guard) { none() }
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Holds if default `TaintTracking::Configuration`s should allow implicit reads
|
* Holds if default `TaintTracking::Configuration`s should allow implicit reads
|
||||||
* of `c` at sinks and inputs to additional taint steps.
|
* of `c` at sinks and inputs to additional taint steps.
|
||||||
|
|||||||
@@ -116,20 +116,30 @@ abstract class Configuration extends DataFlow::Configuration {
|
|||||||
|
|
||||||
final override predicate isBarrierOut(DataFlow::Node node) { this.isSanitizerOut(node) }
|
final override predicate isBarrierOut(DataFlow::Node node) { this.isSanitizerOut(node) }
|
||||||
|
|
||||||
/** Holds if taint propagation through nodes guarded by `guard` is prohibited. */
|
/**
|
||||||
predicate isSanitizerGuard(DataFlow::BarrierGuard guard) { none() }
|
* DEPRECATED: Use `isSanitizer` and `BarrierGuard` module instead.
|
||||||
|
*
|
||||||
|
* Holds if taint propagation through nodes guarded by `guard` is prohibited.
|
||||||
|
*/
|
||||||
|
deprecated predicate isSanitizerGuard(DataFlow::BarrierGuard guard) { none() }
|
||||||
|
|
||||||
final override predicate isBarrierGuard(DataFlow::BarrierGuard guard) {
|
deprecated final override predicate isBarrierGuard(DataFlow::BarrierGuard guard) {
|
||||||
this.isSanitizerGuard(guard) or defaultTaintSanitizerGuard(guard)
|
this.isSanitizerGuard(guard)
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
|
* DEPRECATED: Use `isSanitizer` and `BarrierGuard` module instead.
|
||||||
|
*
|
||||||
* Holds if taint propagation through nodes guarded by `guard` is prohibited
|
* Holds if taint propagation through nodes guarded by `guard` is prohibited
|
||||||
* when the flow state is `state`.
|
* when the flow state is `state`.
|
||||||
*/
|
*/
|
||||||
predicate isSanitizerGuard(DataFlow::BarrierGuard guard, DataFlow::FlowState state) { none() }
|
deprecated predicate isSanitizerGuard(DataFlow::BarrierGuard guard, DataFlow::FlowState state) {
|
||||||
|
none()
|
||||||
|
}
|
||||||
|
|
||||||
final override predicate isBarrierGuard(DataFlow::BarrierGuard guard, DataFlow::FlowState state) {
|
deprecated final override predicate isBarrierGuard(
|
||||||
|
DataFlow::BarrierGuard guard, DataFlow::FlowState state
|
||||||
|
) {
|
||||||
this.isSanitizerGuard(guard, state)
|
this.isSanitizerGuard(guard, state)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@@ -116,20 +116,30 @@ abstract class Configuration extends DataFlow::Configuration {
|
|||||||
|
|
||||||
final override predicate isBarrierOut(DataFlow::Node node) { this.isSanitizerOut(node) }
|
final override predicate isBarrierOut(DataFlow::Node node) { this.isSanitizerOut(node) }
|
||||||
|
|
||||||
/** Holds if taint propagation through nodes guarded by `guard` is prohibited. */
|
/**
|
||||||
predicate isSanitizerGuard(DataFlow::BarrierGuard guard) { none() }
|
* DEPRECATED: Use `isSanitizer` and `BarrierGuard` module instead.
|
||||||
|
*
|
||||||
|
* Holds if taint propagation through nodes guarded by `guard` is prohibited.
|
||||||
|
*/
|
||||||
|
deprecated predicate isSanitizerGuard(DataFlow::BarrierGuard guard) { none() }
|
||||||
|
|
||||||
final override predicate isBarrierGuard(DataFlow::BarrierGuard guard) {
|
deprecated final override predicate isBarrierGuard(DataFlow::BarrierGuard guard) {
|
||||||
this.isSanitizerGuard(guard) or defaultTaintSanitizerGuard(guard)
|
this.isSanitizerGuard(guard)
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
|
* DEPRECATED: Use `isSanitizer` and `BarrierGuard` module instead.
|
||||||
|
*
|
||||||
* Holds if taint propagation through nodes guarded by `guard` is prohibited
|
* Holds if taint propagation through nodes guarded by `guard` is prohibited
|
||||||
* when the flow state is `state`.
|
* when the flow state is `state`.
|
||||||
*/
|
*/
|
||||||
predicate isSanitizerGuard(DataFlow::BarrierGuard guard, DataFlow::FlowState state) { none() }
|
deprecated predicate isSanitizerGuard(DataFlow::BarrierGuard guard, DataFlow::FlowState state) {
|
||||||
|
none()
|
||||||
|
}
|
||||||
|
|
||||||
final override predicate isBarrierGuard(DataFlow::BarrierGuard guard, DataFlow::FlowState state) {
|
deprecated final override predicate isBarrierGuard(
|
||||||
|
DataFlow::BarrierGuard guard, DataFlow::FlowState state
|
||||||
|
) {
|
||||||
this.isSanitizerGuard(guard, state)
|
this.isSanitizerGuard(guard, state)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@@ -116,20 +116,30 @@ abstract class Configuration extends DataFlow::Configuration {
|
|||||||
|
|
||||||
final override predicate isBarrierOut(DataFlow::Node node) { this.isSanitizerOut(node) }
|
final override predicate isBarrierOut(DataFlow::Node node) { this.isSanitizerOut(node) }
|
||||||
|
|
||||||
/** Holds if taint propagation through nodes guarded by `guard` is prohibited. */
|
/**
|
||||||
predicate isSanitizerGuard(DataFlow::BarrierGuard guard) { none() }
|
* DEPRECATED: Use `isSanitizer` and `BarrierGuard` module instead.
|
||||||
|
*
|
||||||
|
* Holds if taint propagation through nodes guarded by `guard` is prohibited.
|
||||||
|
*/
|
||||||
|
deprecated predicate isSanitizerGuard(DataFlow::BarrierGuard guard) { none() }
|
||||||
|
|
||||||
final override predicate isBarrierGuard(DataFlow::BarrierGuard guard) {
|
deprecated final override predicate isBarrierGuard(DataFlow::BarrierGuard guard) {
|
||||||
this.isSanitizerGuard(guard) or defaultTaintSanitizerGuard(guard)
|
this.isSanitizerGuard(guard)
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
|
* DEPRECATED: Use `isSanitizer` and `BarrierGuard` module instead.
|
||||||
|
*
|
||||||
* Holds if taint propagation through nodes guarded by `guard` is prohibited
|
* Holds if taint propagation through nodes guarded by `guard` is prohibited
|
||||||
* when the flow state is `state`.
|
* when the flow state is `state`.
|
||||||
*/
|
*/
|
||||||
predicate isSanitizerGuard(DataFlow::BarrierGuard guard, DataFlow::FlowState state) { none() }
|
deprecated predicate isSanitizerGuard(DataFlow::BarrierGuard guard, DataFlow::FlowState state) {
|
||||||
|
none()
|
||||||
|
}
|
||||||
|
|
||||||
final override predicate isBarrierGuard(DataFlow::BarrierGuard guard, DataFlow::FlowState state) {
|
deprecated final override predicate isBarrierGuard(
|
||||||
|
DataFlow::BarrierGuard guard, DataFlow::FlowState state
|
||||||
|
) {
|
||||||
this.isSanitizerGuard(guard, state)
|
this.isSanitizerGuard(guard, state)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@@ -116,20 +116,30 @@ abstract class Configuration extends DataFlow::Configuration {
|
|||||||
|
|
||||||
final override predicate isBarrierOut(DataFlow::Node node) { this.isSanitizerOut(node) }
|
final override predicate isBarrierOut(DataFlow::Node node) { this.isSanitizerOut(node) }
|
||||||
|
|
||||||
/** Holds if taint propagation through nodes guarded by `guard` is prohibited. */
|
/**
|
||||||
predicate isSanitizerGuard(DataFlow::BarrierGuard guard) { none() }
|
* DEPRECATED: Use `isSanitizer` and `BarrierGuard` module instead.
|
||||||
|
*
|
||||||
|
* Holds if taint propagation through nodes guarded by `guard` is prohibited.
|
||||||
|
*/
|
||||||
|
deprecated predicate isSanitizerGuard(DataFlow::BarrierGuard guard) { none() }
|
||||||
|
|
||||||
final override predicate isBarrierGuard(DataFlow::BarrierGuard guard) {
|
deprecated final override predicate isBarrierGuard(DataFlow::BarrierGuard guard) {
|
||||||
this.isSanitizerGuard(guard) or defaultTaintSanitizerGuard(guard)
|
this.isSanitizerGuard(guard)
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
|
* DEPRECATED: Use `isSanitizer` and `BarrierGuard` module instead.
|
||||||
|
*
|
||||||
* Holds if taint propagation through nodes guarded by `guard` is prohibited
|
* Holds if taint propagation through nodes guarded by `guard` is prohibited
|
||||||
* when the flow state is `state`.
|
* when the flow state is `state`.
|
||||||
*/
|
*/
|
||||||
predicate isSanitizerGuard(DataFlow::BarrierGuard guard, DataFlow::FlowState state) { none() }
|
deprecated predicate isSanitizerGuard(DataFlow::BarrierGuard guard, DataFlow::FlowState state) {
|
||||||
|
none()
|
||||||
|
}
|
||||||
|
|
||||||
final override predicate isBarrierGuard(DataFlow::BarrierGuard guard, DataFlow::FlowState state) {
|
deprecated final override predicate isBarrierGuard(
|
||||||
|
DataFlow::BarrierGuard guard, DataFlow::FlowState state
|
||||||
|
) {
|
||||||
this.isSanitizerGuard(guard, state)
|
this.isSanitizerGuard(guard, state)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@@ -116,20 +116,30 @@ abstract class Configuration extends DataFlow::Configuration {
|
|||||||
|
|
||||||
final override predicate isBarrierOut(DataFlow::Node node) { this.isSanitizerOut(node) }
|
final override predicate isBarrierOut(DataFlow::Node node) { this.isSanitizerOut(node) }
|
||||||
|
|
||||||
/** Holds if taint propagation through nodes guarded by `guard` is prohibited. */
|
/**
|
||||||
predicate isSanitizerGuard(DataFlow::BarrierGuard guard) { none() }
|
* DEPRECATED: Use `isSanitizer` and `BarrierGuard` module instead.
|
||||||
|
*
|
||||||
|
* Holds if taint propagation through nodes guarded by `guard` is prohibited.
|
||||||
|
*/
|
||||||
|
deprecated predicate isSanitizerGuard(DataFlow::BarrierGuard guard) { none() }
|
||||||
|
|
||||||
final override predicate isBarrierGuard(DataFlow::BarrierGuard guard) {
|
deprecated final override predicate isBarrierGuard(DataFlow::BarrierGuard guard) {
|
||||||
this.isSanitizerGuard(guard) or defaultTaintSanitizerGuard(guard)
|
this.isSanitizerGuard(guard)
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
|
* DEPRECATED: Use `isSanitizer` and `BarrierGuard` module instead.
|
||||||
|
*
|
||||||
* Holds if taint propagation through nodes guarded by `guard` is prohibited
|
* Holds if taint propagation through nodes guarded by `guard` is prohibited
|
||||||
* when the flow state is `state`.
|
* when the flow state is `state`.
|
||||||
*/
|
*/
|
||||||
predicate isSanitizerGuard(DataFlow::BarrierGuard guard, DataFlow::FlowState state) { none() }
|
deprecated predicate isSanitizerGuard(DataFlow::BarrierGuard guard, DataFlow::FlowState state) {
|
||||||
|
none()
|
||||||
|
}
|
||||||
|
|
||||||
final override predicate isBarrierGuard(DataFlow::BarrierGuard guard, DataFlow::FlowState state) {
|
deprecated final override predicate isBarrierGuard(
|
||||||
|
DataFlow::BarrierGuard guard, DataFlow::FlowState state
|
||||||
|
) {
|
||||||
this.isSanitizerGuard(guard, state)
|
this.isSanitizerGuard(guard, state)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
Some files were not shown because too many files have changed in this diff Show More
Reference in New Issue
Block a user