mirror of
https://github.com/github/codeql.git
synced 2026-04-28 02:05:14 +02:00
Merge branch 'main' into expand-ruby-ssrf-sinks-faraday-connection-new
This commit is contained in:
27
.github/workflows/swift-autobuilder.yml
vendored
Normal file
27
.github/workflows/swift-autobuilder.yml
vendored
Normal file
@@ -0,0 +1,27 @@
|
||||
name: "Swift: Build and test Xcode autobuilder"
|
||||
|
||||
on:
|
||||
pull_request:
|
||||
paths:
|
||||
- "swift/xcode-autobuilder/**"
|
||||
- "misc/bazel/**"
|
||||
- "*.bazel*"
|
||||
- .github/workflows/swift-autobuilder.yml
|
||||
branches:
|
||||
- main
|
||||
|
||||
jobs:
|
||||
autobuilder:
|
||||
runs-on: macos-latest
|
||||
steps:
|
||||
- uses: actions/checkout@v3
|
||||
- uses: bazelbuild/setup-bazelisk@v2
|
||||
- uses: actions/setup-python@v4
|
||||
with:
|
||||
python-version-file: 'swift/.python-version'
|
||||
- name: Build the Xcode autobuilder
|
||||
run: |
|
||||
bazel build //swift/xcode-autobuilder
|
||||
- name: Test the Xcode autobuilder
|
||||
run: |
|
||||
bazel test //swift/xcode-autobuilder/tests
|
||||
7
.github/workflows/swift-codegen.yml
vendored
7
.github/workflows/swift-codegen.yml
vendored
@@ -10,6 +10,9 @@ on:
|
||||
- .github/actions/fetch-codeql/action.yml
|
||||
branches:
|
||||
- main
|
||||
defaults:
|
||||
run:
|
||||
working-directory: swift
|
||||
|
||||
jobs:
|
||||
codegen:
|
||||
@@ -18,7 +21,9 @@ jobs:
|
||||
- uses: actions/checkout@v3
|
||||
- uses: ./.github/actions/fetch-codeql
|
||||
- uses: bazelbuild/setup-bazelisk@v2
|
||||
- uses: actions/setup-python@v3
|
||||
- uses: actions/setup-python@v4
|
||||
with:
|
||||
python-version-file: 'swift/.python-version'
|
||||
- uses: pre-commit/action@v3.0.0
|
||||
name: Check that python code is properly formatted
|
||||
with:
|
||||
|
||||
@@ -28,7 +28,9 @@ jobs:
|
||||
- uses: actions/checkout@v3
|
||||
- uses: ./.github/actions/fetch-codeql
|
||||
- uses: bazelbuild/setup-bazelisk@v2
|
||||
- uses: actions/setup-python@v3
|
||||
- uses: actions/setup-python@v4
|
||||
with:
|
||||
python-version-file: 'swift/.python-version'
|
||||
- name: Build Swift extractor
|
||||
run: |
|
||||
bazel run //swift:create-extractor-pack
|
||||
|
||||
3
.github/workflows/swift-qltest.yml
vendored
3
.github/workflows/swift-qltest.yml
vendored
@@ -33,6 +33,9 @@ jobs:
|
||||
- uses: actions/checkout@v3
|
||||
- uses: ./.github/actions/fetch-codeql
|
||||
- uses: bazelbuild/setup-bazelisk@v2
|
||||
- uses: actions/setup-python@v4
|
||||
with:
|
||||
python-version-file: 'swift/.python-version'
|
||||
- name: Build Swift extractor
|
||||
run: |
|
||||
bazel run //swift:create-extractor-pack
|
||||
|
||||
@@ -20,9 +20,9 @@
|
||||
/java/ql/src/semmle/code/java/dataflow/internal/tainttracking2/TaintTrackingImpl.qll @github/codeql-java @github/codeql-go
|
||||
|
||||
# CodeQL tools and associated docs
|
||||
/docs/codeql-cli/ @github/codeql-cli-reviewers
|
||||
/docs/codeql-for-visual-studio-code/ @github/codeql-vscode-reviewers
|
||||
/docs/ql-language-reference/ @github/codeql-frontend-reviewers
|
||||
/docs/codeql/codeql-cli/ @github/codeql-cli-reviewers
|
||||
/docs/codeql/codeql-for-visual-studio-code/ @github/codeql-vscode-reviewers
|
||||
/docs/codeql/ql-language-reference/ @github/codeql-frontend-reviewers
|
||||
/docs/query-*-style-guide.md @github/codeql-analysis-reviewers
|
||||
|
||||
# QL for QL reviewers
|
||||
|
||||
@@ -838,13 +838,13 @@ private module Stage1 implements StageSig {
|
||||
* by `revFlow`.
|
||||
*/
|
||||
pragma[nomagic]
|
||||
predicate revFlowIsReadAndStored(Content c, Configuration conf) {
|
||||
additional predicate revFlowIsReadAndStored(Content c, Configuration conf) {
|
||||
revFlowConsCand(c, conf) and
|
||||
revFlowStore(c, _, _, conf)
|
||||
}
|
||||
|
||||
pragma[nomagic]
|
||||
predicate viableReturnPosOutNodeCandFwd1(
|
||||
additional predicate viableReturnPosOutNodeCandFwd1(
|
||||
DataFlowCall call, ReturnPosition pos, NodeEx out, Configuration config
|
||||
) {
|
||||
fwdFlowReturnPosition(pos, _, config) and
|
||||
@@ -860,7 +860,7 @@ private module Stage1 implements StageSig {
|
||||
}
|
||||
|
||||
pragma[nomagic]
|
||||
predicate viableParamArgNodeCandFwd1(
|
||||
additional predicate viableParamArgNodeCandFwd1(
|
||||
DataFlowCall call, ParamNodeEx p, ArgNodeEx arg, Configuration config
|
||||
) {
|
||||
viableParamArgEx(call, p, arg) and
|
||||
@@ -907,7 +907,7 @@ private module Stage1 implements StageSig {
|
||||
)
|
||||
}
|
||||
|
||||
predicate revFlowState(FlowState state, Configuration config) {
|
||||
additional predicate revFlowState(FlowState state, Configuration config) {
|
||||
exists(NodeEx node |
|
||||
sinkNode(node, state, config) and
|
||||
revFlow(node, _, pragma[only_bind_into](config)) and
|
||||
@@ -999,7 +999,7 @@ private module Stage1 implements StageSig {
|
||||
)
|
||||
}
|
||||
|
||||
predicate stats(
|
||||
additional predicate stats(
|
||||
boolean fwd, int nodes, int fields, int conscand, int states, int tuples, Configuration config
|
||||
) {
|
||||
fwd = true and
|
||||
@@ -1260,7 +1260,7 @@ private module MkStage<StageSig PrevStage> {
|
||||
* argument.
|
||||
*/
|
||||
pragma[nomagic]
|
||||
predicate fwdFlow(
|
||||
additional predicate fwdFlow(
|
||||
NodeEx node, FlowState state, Cc cc, ApOption argAp, Ap ap, Configuration config
|
||||
) {
|
||||
fwdFlow0(node, state, cc, argAp, ap, config) and
|
||||
@@ -1484,7 +1484,7 @@ private module MkStage<StageSig PrevStage> {
|
||||
* the access path of the returned value.
|
||||
*/
|
||||
pragma[nomagic]
|
||||
predicate revFlow(
|
||||
additional predicate revFlow(
|
||||
NodeEx node, FlowState state, boolean toReturn, ApOption returnAp, Ap ap, Configuration config
|
||||
) {
|
||||
revFlow0(node, state, toReturn, returnAp, ap, config) and
|
||||
@@ -1662,7 +1662,7 @@ private module MkStage<StageSig PrevStage> {
|
||||
)
|
||||
}
|
||||
|
||||
predicate revFlow(NodeEx node, FlowState state, Configuration config) {
|
||||
additional predicate revFlow(NodeEx node, FlowState state, Configuration config) {
|
||||
revFlow(node, state, _, _, _, config)
|
||||
}
|
||||
|
||||
@@ -1675,11 +1675,13 @@ private module MkStage<StageSig PrevStage> {
|
||||
|
||||
// use an alias as a workaround for bad functionality-induced joins
|
||||
pragma[nomagic]
|
||||
predicate revFlowAlias(NodeEx node, Configuration config) { revFlow(node, _, _, _, _, config) }
|
||||
additional predicate revFlowAlias(NodeEx node, Configuration config) {
|
||||
revFlow(node, _, _, _, _, config)
|
||||
}
|
||||
|
||||
// use an alias as a workaround for bad functionality-induced joins
|
||||
pragma[nomagic]
|
||||
predicate revFlowAlias(NodeEx node, FlowState state, Ap ap, Configuration config) {
|
||||
additional predicate revFlowAlias(NodeEx node, FlowState state, Ap ap, Configuration config) {
|
||||
revFlow(node, state, ap, config)
|
||||
}
|
||||
|
||||
@@ -1700,7 +1702,7 @@ private module MkStage<StageSig PrevStage> {
|
||||
)
|
||||
}
|
||||
|
||||
predicate consCand(TypedContent tc, Ap ap, Configuration config) {
|
||||
additional predicate consCand(TypedContent tc, Ap ap, Configuration config) {
|
||||
revConsCand(tc, ap, config) and
|
||||
validAp(ap, config)
|
||||
}
|
||||
@@ -1742,7 +1744,7 @@ private module MkStage<StageSig PrevStage> {
|
||||
)
|
||||
}
|
||||
|
||||
predicate stats(
|
||||
additional predicate stats(
|
||||
boolean fwd, int nodes, int fields, int conscand, int states, int tuples, Configuration config
|
||||
) {
|
||||
fwd = true and
|
||||
|
||||
@@ -838,13 +838,13 @@ private module Stage1 implements StageSig {
|
||||
* by `revFlow`.
|
||||
*/
|
||||
pragma[nomagic]
|
||||
predicate revFlowIsReadAndStored(Content c, Configuration conf) {
|
||||
additional predicate revFlowIsReadAndStored(Content c, Configuration conf) {
|
||||
revFlowConsCand(c, conf) and
|
||||
revFlowStore(c, _, _, conf)
|
||||
}
|
||||
|
||||
pragma[nomagic]
|
||||
predicate viableReturnPosOutNodeCandFwd1(
|
||||
additional predicate viableReturnPosOutNodeCandFwd1(
|
||||
DataFlowCall call, ReturnPosition pos, NodeEx out, Configuration config
|
||||
) {
|
||||
fwdFlowReturnPosition(pos, _, config) and
|
||||
@@ -860,7 +860,7 @@ private module Stage1 implements StageSig {
|
||||
}
|
||||
|
||||
pragma[nomagic]
|
||||
predicate viableParamArgNodeCandFwd1(
|
||||
additional predicate viableParamArgNodeCandFwd1(
|
||||
DataFlowCall call, ParamNodeEx p, ArgNodeEx arg, Configuration config
|
||||
) {
|
||||
viableParamArgEx(call, p, arg) and
|
||||
@@ -907,7 +907,7 @@ private module Stage1 implements StageSig {
|
||||
)
|
||||
}
|
||||
|
||||
predicate revFlowState(FlowState state, Configuration config) {
|
||||
additional predicate revFlowState(FlowState state, Configuration config) {
|
||||
exists(NodeEx node |
|
||||
sinkNode(node, state, config) and
|
||||
revFlow(node, _, pragma[only_bind_into](config)) and
|
||||
@@ -999,7 +999,7 @@ private module Stage1 implements StageSig {
|
||||
)
|
||||
}
|
||||
|
||||
predicate stats(
|
||||
additional predicate stats(
|
||||
boolean fwd, int nodes, int fields, int conscand, int states, int tuples, Configuration config
|
||||
) {
|
||||
fwd = true and
|
||||
@@ -1260,7 +1260,7 @@ private module MkStage<StageSig PrevStage> {
|
||||
* argument.
|
||||
*/
|
||||
pragma[nomagic]
|
||||
predicate fwdFlow(
|
||||
additional predicate fwdFlow(
|
||||
NodeEx node, FlowState state, Cc cc, ApOption argAp, Ap ap, Configuration config
|
||||
) {
|
||||
fwdFlow0(node, state, cc, argAp, ap, config) and
|
||||
@@ -1484,7 +1484,7 @@ private module MkStage<StageSig PrevStage> {
|
||||
* the access path of the returned value.
|
||||
*/
|
||||
pragma[nomagic]
|
||||
predicate revFlow(
|
||||
additional predicate revFlow(
|
||||
NodeEx node, FlowState state, boolean toReturn, ApOption returnAp, Ap ap, Configuration config
|
||||
) {
|
||||
revFlow0(node, state, toReturn, returnAp, ap, config) and
|
||||
@@ -1662,7 +1662,7 @@ private module MkStage<StageSig PrevStage> {
|
||||
)
|
||||
}
|
||||
|
||||
predicate revFlow(NodeEx node, FlowState state, Configuration config) {
|
||||
additional predicate revFlow(NodeEx node, FlowState state, Configuration config) {
|
||||
revFlow(node, state, _, _, _, config)
|
||||
}
|
||||
|
||||
@@ -1675,11 +1675,13 @@ private module MkStage<StageSig PrevStage> {
|
||||
|
||||
// use an alias as a workaround for bad functionality-induced joins
|
||||
pragma[nomagic]
|
||||
predicate revFlowAlias(NodeEx node, Configuration config) { revFlow(node, _, _, _, _, config) }
|
||||
additional predicate revFlowAlias(NodeEx node, Configuration config) {
|
||||
revFlow(node, _, _, _, _, config)
|
||||
}
|
||||
|
||||
// use an alias as a workaround for bad functionality-induced joins
|
||||
pragma[nomagic]
|
||||
predicate revFlowAlias(NodeEx node, FlowState state, Ap ap, Configuration config) {
|
||||
additional predicate revFlowAlias(NodeEx node, FlowState state, Ap ap, Configuration config) {
|
||||
revFlow(node, state, ap, config)
|
||||
}
|
||||
|
||||
@@ -1700,7 +1702,7 @@ private module MkStage<StageSig PrevStage> {
|
||||
)
|
||||
}
|
||||
|
||||
predicate consCand(TypedContent tc, Ap ap, Configuration config) {
|
||||
additional predicate consCand(TypedContent tc, Ap ap, Configuration config) {
|
||||
revConsCand(tc, ap, config) and
|
||||
validAp(ap, config)
|
||||
}
|
||||
@@ -1742,7 +1744,7 @@ private module MkStage<StageSig PrevStage> {
|
||||
)
|
||||
}
|
||||
|
||||
predicate stats(
|
||||
additional predicate stats(
|
||||
boolean fwd, int nodes, int fields, int conscand, int states, int tuples, Configuration config
|
||||
) {
|
||||
fwd = true and
|
||||
|
||||
@@ -838,13 +838,13 @@ private module Stage1 implements StageSig {
|
||||
* by `revFlow`.
|
||||
*/
|
||||
pragma[nomagic]
|
||||
predicate revFlowIsReadAndStored(Content c, Configuration conf) {
|
||||
additional predicate revFlowIsReadAndStored(Content c, Configuration conf) {
|
||||
revFlowConsCand(c, conf) and
|
||||
revFlowStore(c, _, _, conf)
|
||||
}
|
||||
|
||||
pragma[nomagic]
|
||||
predicate viableReturnPosOutNodeCandFwd1(
|
||||
additional predicate viableReturnPosOutNodeCandFwd1(
|
||||
DataFlowCall call, ReturnPosition pos, NodeEx out, Configuration config
|
||||
) {
|
||||
fwdFlowReturnPosition(pos, _, config) and
|
||||
@@ -860,7 +860,7 @@ private module Stage1 implements StageSig {
|
||||
}
|
||||
|
||||
pragma[nomagic]
|
||||
predicate viableParamArgNodeCandFwd1(
|
||||
additional predicate viableParamArgNodeCandFwd1(
|
||||
DataFlowCall call, ParamNodeEx p, ArgNodeEx arg, Configuration config
|
||||
) {
|
||||
viableParamArgEx(call, p, arg) and
|
||||
@@ -907,7 +907,7 @@ private module Stage1 implements StageSig {
|
||||
)
|
||||
}
|
||||
|
||||
predicate revFlowState(FlowState state, Configuration config) {
|
||||
additional predicate revFlowState(FlowState state, Configuration config) {
|
||||
exists(NodeEx node |
|
||||
sinkNode(node, state, config) and
|
||||
revFlow(node, _, pragma[only_bind_into](config)) and
|
||||
@@ -999,7 +999,7 @@ private module Stage1 implements StageSig {
|
||||
)
|
||||
}
|
||||
|
||||
predicate stats(
|
||||
additional predicate stats(
|
||||
boolean fwd, int nodes, int fields, int conscand, int states, int tuples, Configuration config
|
||||
) {
|
||||
fwd = true and
|
||||
@@ -1260,7 +1260,7 @@ private module MkStage<StageSig PrevStage> {
|
||||
* argument.
|
||||
*/
|
||||
pragma[nomagic]
|
||||
predicate fwdFlow(
|
||||
additional predicate fwdFlow(
|
||||
NodeEx node, FlowState state, Cc cc, ApOption argAp, Ap ap, Configuration config
|
||||
) {
|
||||
fwdFlow0(node, state, cc, argAp, ap, config) and
|
||||
@@ -1484,7 +1484,7 @@ private module MkStage<StageSig PrevStage> {
|
||||
* the access path of the returned value.
|
||||
*/
|
||||
pragma[nomagic]
|
||||
predicate revFlow(
|
||||
additional predicate revFlow(
|
||||
NodeEx node, FlowState state, boolean toReturn, ApOption returnAp, Ap ap, Configuration config
|
||||
) {
|
||||
revFlow0(node, state, toReturn, returnAp, ap, config) and
|
||||
@@ -1662,7 +1662,7 @@ private module MkStage<StageSig PrevStage> {
|
||||
)
|
||||
}
|
||||
|
||||
predicate revFlow(NodeEx node, FlowState state, Configuration config) {
|
||||
additional predicate revFlow(NodeEx node, FlowState state, Configuration config) {
|
||||
revFlow(node, state, _, _, _, config)
|
||||
}
|
||||
|
||||
@@ -1675,11 +1675,13 @@ private module MkStage<StageSig PrevStage> {
|
||||
|
||||
// use an alias as a workaround for bad functionality-induced joins
|
||||
pragma[nomagic]
|
||||
predicate revFlowAlias(NodeEx node, Configuration config) { revFlow(node, _, _, _, _, config) }
|
||||
additional predicate revFlowAlias(NodeEx node, Configuration config) {
|
||||
revFlow(node, _, _, _, _, config)
|
||||
}
|
||||
|
||||
// use an alias as a workaround for bad functionality-induced joins
|
||||
pragma[nomagic]
|
||||
predicate revFlowAlias(NodeEx node, FlowState state, Ap ap, Configuration config) {
|
||||
additional predicate revFlowAlias(NodeEx node, FlowState state, Ap ap, Configuration config) {
|
||||
revFlow(node, state, ap, config)
|
||||
}
|
||||
|
||||
@@ -1700,7 +1702,7 @@ private module MkStage<StageSig PrevStage> {
|
||||
)
|
||||
}
|
||||
|
||||
predicate consCand(TypedContent tc, Ap ap, Configuration config) {
|
||||
additional predicate consCand(TypedContent tc, Ap ap, Configuration config) {
|
||||
revConsCand(tc, ap, config) and
|
||||
validAp(ap, config)
|
||||
}
|
||||
@@ -1742,7 +1744,7 @@ private module MkStage<StageSig PrevStage> {
|
||||
)
|
||||
}
|
||||
|
||||
predicate stats(
|
||||
additional predicate stats(
|
||||
boolean fwd, int nodes, int fields, int conscand, int states, int tuples, Configuration config
|
||||
) {
|
||||
fwd = true and
|
||||
|
||||
@@ -838,13 +838,13 @@ private module Stage1 implements StageSig {
|
||||
* by `revFlow`.
|
||||
*/
|
||||
pragma[nomagic]
|
||||
predicate revFlowIsReadAndStored(Content c, Configuration conf) {
|
||||
additional predicate revFlowIsReadAndStored(Content c, Configuration conf) {
|
||||
revFlowConsCand(c, conf) and
|
||||
revFlowStore(c, _, _, conf)
|
||||
}
|
||||
|
||||
pragma[nomagic]
|
||||
predicate viableReturnPosOutNodeCandFwd1(
|
||||
additional predicate viableReturnPosOutNodeCandFwd1(
|
||||
DataFlowCall call, ReturnPosition pos, NodeEx out, Configuration config
|
||||
) {
|
||||
fwdFlowReturnPosition(pos, _, config) and
|
||||
@@ -860,7 +860,7 @@ private module Stage1 implements StageSig {
|
||||
}
|
||||
|
||||
pragma[nomagic]
|
||||
predicate viableParamArgNodeCandFwd1(
|
||||
additional predicate viableParamArgNodeCandFwd1(
|
||||
DataFlowCall call, ParamNodeEx p, ArgNodeEx arg, Configuration config
|
||||
) {
|
||||
viableParamArgEx(call, p, arg) and
|
||||
@@ -907,7 +907,7 @@ private module Stage1 implements StageSig {
|
||||
)
|
||||
}
|
||||
|
||||
predicate revFlowState(FlowState state, Configuration config) {
|
||||
additional predicate revFlowState(FlowState state, Configuration config) {
|
||||
exists(NodeEx node |
|
||||
sinkNode(node, state, config) and
|
||||
revFlow(node, _, pragma[only_bind_into](config)) and
|
||||
@@ -999,7 +999,7 @@ private module Stage1 implements StageSig {
|
||||
)
|
||||
}
|
||||
|
||||
predicate stats(
|
||||
additional predicate stats(
|
||||
boolean fwd, int nodes, int fields, int conscand, int states, int tuples, Configuration config
|
||||
) {
|
||||
fwd = true and
|
||||
@@ -1260,7 +1260,7 @@ private module MkStage<StageSig PrevStage> {
|
||||
* argument.
|
||||
*/
|
||||
pragma[nomagic]
|
||||
predicate fwdFlow(
|
||||
additional predicate fwdFlow(
|
||||
NodeEx node, FlowState state, Cc cc, ApOption argAp, Ap ap, Configuration config
|
||||
) {
|
||||
fwdFlow0(node, state, cc, argAp, ap, config) and
|
||||
@@ -1484,7 +1484,7 @@ private module MkStage<StageSig PrevStage> {
|
||||
* the access path of the returned value.
|
||||
*/
|
||||
pragma[nomagic]
|
||||
predicate revFlow(
|
||||
additional predicate revFlow(
|
||||
NodeEx node, FlowState state, boolean toReturn, ApOption returnAp, Ap ap, Configuration config
|
||||
) {
|
||||
revFlow0(node, state, toReturn, returnAp, ap, config) and
|
||||
@@ -1662,7 +1662,7 @@ private module MkStage<StageSig PrevStage> {
|
||||
)
|
||||
}
|
||||
|
||||
predicate revFlow(NodeEx node, FlowState state, Configuration config) {
|
||||
additional predicate revFlow(NodeEx node, FlowState state, Configuration config) {
|
||||
revFlow(node, state, _, _, _, config)
|
||||
}
|
||||
|
||||
@@ -1675,11 +1675,13 @@ private module MkStage<StageSig PrevStage> {
|
||||
|
||||
// use an alias as a workaround for bad functionality-induced joins
|
||||
pragma[nomagic]
|
||||
predicate revFlowAlias(NodeEx node, Configuration config) { revFlow(node, _, _, _, _, config) }
|
||||
additional predicate revFlowAlias(NodeEx node, Configuration config) {
|
||||
revFlow(node, _, _, _, _, config)
|
||||
}
|
||||
|
||||
// use an alias as a workaround for bad functionality-induced joins
|
||||
pragma[nomagic]
|
||||
predicate revFlowAlias(NodeEx node, FlowState state, Ap ap, Configuration config) {
|
||||
additional predicate revFlowAlias(NodeEx node, FlowState state, Ap ap, Configuration config) {
|
||||
revFlow(node, state, ap, config)
|
||||
}
|
||||
|
||||
@@ -1700,7 +1702,7 @@ private module MkStage<StageSig PrevStage> {
|
||||
)
|
||||
}
|
||||
|
||||
predicate consCand(TypedContent tc, Ap ap, Configuration config) {
|
||||
additional predicate consCand(TypedContent tc, Ap ap, Configuration config) {
|
||||
revConsCand(tc, ap, config) and
|
||||
validAp(ap, config)
|
||||
}
|
||||
@@ -1742,7 +1744,7 @@ private module MkStage<StageSig PrevStage> {
|
||||
)
|
||||
}
|
||||
|
||||
predicate stats(
|
||||
additional predicate stats(
|
||||
boolean fwd, int nodes, int fields, int conscand, int states, int tuples, Configuration config
|
||||
) {
|
||||
fwd = true and
|
||||
|
||||
@@ -241,7 +241,7 @@ private Instruction getANonConversionUse(Operand operand) {
|
||||
|
||||
/**
|
||||
* Gets the operand that represents the first use of the value of `call` following
|
||||
* a sequnce of conversion-like instructions.
|
||||
* a sequence of conversion-like instructions.
|
||||
*/
|
||||
predicate operandForfullyConvertedCall(Operand operand, CallInstruction call) {
|
||||
exists(getANonConversionUse(operand)) and
|
||||
@@ -254,7 +254,7 @@ predicate operandForfullyConvertedCall(Operand operand, CallInstruction call) {
|
||||
|
||||
/**
|
||||
* Gets the instruction that represents the first use of the value of `call` following
|
||||
* a sequnce of conversion-like instructions.
|
||||
* a sequence of conversion-like instructions.
|
||||
*
|
||||
* This predicate only holds if there is no suitable operand (i.e., no operand of a non-
|
||||
* conversion instruction) to use to represent the value of `call` after conversions.
|
||||
|
||||
@@ -746,7 +746,7 @@ predicate exprNodeShouldBeOperand(Node node, Expr e) {
|
||||
|
||||
/**
|
||||
* Holds if `load` is a `LoadInstruction` that is the result of evaluating `e`
|
||||
* and `node` is an `IndirctOperandNode` that should map `node.asExpr()` to `e`.
|
||||
* and `node` is an `IndirectOperandNode` that should map `node.asExpr()` to `e`.
|
||||
*
|
||||
* We map `e` to `node.asExpr()` when `node` semantically represents the
|
||||
* same value as `load`. A subsequent flow step will flow `node` to
|
||||
|
||||
@@ -100,7 +100,7 @@ private string getNodeProperty(DataFlow::Node node, string key) {
|
||||
or
|
||||
// Is there partial flow from a source to this node?
|
||||
// This property will only be emitted if partial flow is enabled by overriding
|
||||
// `DataFlow::Configration::explorationLimit()`.
|
||||
// `DataFlow::Configuration::explorationLimit()`.
|
||||
key = "pflow" and
|
||||
result =
|
||||
strictconcat(DataFlow::PartialPathNode sourceNode, DataFlow::PartialPathNode destNode, int dist,
|
||||
|
||||
@@ -71,7 +71,7 @@ abstract class CustomSignDef extends SignDef {
|
||||
* Concrete implementations extend one of the following subclasses:
|
||||
* - `ConstantSignExpr`, for expressions with a compile-time constant value.
|
||||
* - `FlowSignExpr`, for expressions whose sign can be computed from the signs of their operands.
|
||||
* - `CustomsignExpr`, for expressions shose sign can be computed by a language-specific
|
||||
* - `CustomsignExpr`, for expressions whose sign can be computed by a language-specific
|
||||
* implementation.
|
||||
*
|
||||
* If the same expression matches more than one of the above subclasses, the sign is computed as
|
||||
|
||||
@@ -11,7 +11,7 @@ private import experimental.semmle.code.cpp.semantic.Semantic
|
||||
predicate ignoreTypeRestrictions(SemExpr e) { none() }
|
||||
|
||||
/**
|
||||
* Workaround to track the sign of cetain expressions even if the type of the expression is not
|
||||
* Workaround to track the sign of certain expressions even if the type of the expression is not
|
||||
* numeric.
|
||||
*/
|
||||
predicate trackUnknownNonNumericExpr(SemExpr e) { none() }
|
||||
|
||||
@@ -1,5 +1,5 @@
|
||||
/**
|
||||
* Proivdes the `LinkTarget` class representing linker invocations during the build process.
|
||||
* Provides the `LinkTarget` class representing linker invocations during the build process.
|
||||
*/
|
||||
|
||||
import semmle.code.cpp.Class
|
||||
|
||||
@@ -144,7 +144,7 @@ class Variable extends Declaration, @variable {
|
||||
* `Variable.getInitializer()` to get the variable's initializer,
|
||||
* or use `Variable.getAnAssignedValue()` to get an expression that
|
||||
* is the right-hand side of an assignment or an initialization of
|
||||
* the varible.
|
||||
* the variable.
|
||||
*/
|
||||
Assignment getAnAssignment() { result.getLValue() = this.getAnAccess() }
|
||||
|
||||
@@ -173,7 +173,7 @@ class Variable extends Declaration, @variable {
|
||||
}
|
||||
|
||||
/**
|
||||
* Holds if this variable is declated as part of a structured binding
|
||||
* Holds if this variable is declared as part of a structured binding
|
||||
* declaration. For example, `x` in `auto [x, y] = ...`.
|
||||
*/
|
||||
predicate isStructuredBinding() { is_structured_binding(underlyingElement(this)) }
|
||||
|
||||
@@ -76,7 +76,7 @@ class TypeBoundsAnalysis extends BufferWriteEstimationReason, TTypeBoundsAnalysi
|
||||
|
||||
/**
|
||||
* The estimation comes from non trivial bounds found via actual flow analysis,
|
||||
* but a widening aproximation might have been used for variables in loops.
|
||||
* but a widening approximation might have been used for variables in loops.
|
||||
* For example
|
||||
* ```
|
||||
* for (int i = 0; i < 10; ++i) {
|
||||
@@ -141,7 +141,7 @@ class AttributeFormattingFunction extends FormattingFunction {
|
||||
* - `""` is a `vprintf` variant, `outputParamIndex` is `-1`.
|
||||
* - `"f"` is a `vfprintf` variant, `outputParamIndex` indicates the output stream parameter.
|
||||
* - `"s"` is a `vsprintf` variant, `outputParamIndex` indicates the output buffer parameter.
|
||||
* - `"?"` if the type cannot be deteremined. `outputParamIndex` is `-1`.
|
||||
* - `"?"` if the type cannot be determined. `outputParamIndex` is `-1`.
|
||||
*/
|
||||
predicate primitiveVariadicFormatter(
|
||||
TopLevelFunction f, string type, int formatParamIndex, int outputParamIndex
|
||||
@@ -198,7 +198,7 @@ private predicate callsVariadicFormatter(
|
||||
* - `""` is a `vprintf` variant, `outputParamIndex` is `-1`.
|
||||
* - `"f"` is a `vfprintf` variant, `outputParamIndex` indicates the output stream parameter.
|
||||
* - `"s"` is a `vsprintf` variant, `outputParamIndex` indicates the output buffer parameter.
|
||||
* - `"?"` if the type cannot be deteremined. `outputParamIndex` is `-1`.
|
||||
* - `"?"` if the type cannot be determined. `outputParamIndex` is `-1`.
|
||||
*/
|
||||
predicate variadicFormatter(Function f, string type, int formatParamIndex, int outputParamIndex) {
|
||||
primitiveVariadicFormatter(f, type, formatParamIndex, outputParamIndex)
|
||||
|
||||
@@ -12,7 +12,7 @@ private import internal.ConstantExprs
|
||||
* relation). The refinement manifests itself in two changes:
|
||||
*
|
||||
* - The successor relation on `BasicBlock`s uses `successors_adapted`
|
||||
* (instead of `successors_extended` used by `PrimtiveBasicBlock`s). Consequently,
|
||||
* (instead of `successors_extended` used by `PrimitiveBasicBlock`s). Consequently,
|
||||
* some edges between `BasicBlock`s may be removed. Example:
|
||||
* ```
|
||||
* x = 1; // s1
|
||||
|
||||
@@ -149,7 +149,7 @@ private predicate bbLoopEntryConditionAlwaysTrueAt(BasicBlock bb, int i, Control
|
||||
/**
|
||||
* Basic block `pred` contains all or part of the condition belonging to a loop,
|
||||
* and there is an edge from `pred` to `succ` that concludes the condition.
|
||||
* If the edge corrseponds with the loop condition being found to be `true`, then
|
||||
* If the edge corresponds with the loop condition being found to be `true`, then
|
||||
* `skipsLoop` is `false`. Otherwise the edge corresponds with the loop condition
|
||||
* being found to be `false` and `skipsLoop` is `true`. Non-concluding edges
|
||||
* within a complex loop condition are not matched by this predicate.
|
||||
|
||||
@@ -838,13 +838,13 @@ private module Stage1 implements StageSig {
|
||||
* by `revFlow`.
|
||||
*/
|
||||
pragma[nomagic]
|
||||
predicate revFlowIsReadAndStored(Content c, Configuration conf) {
|
||||
additional predicate revFlowIsReadAndStored(Content c, Configuration conf) {
|
||||
revFlowConsCand(c, conf) and
|
||||
revFlowStore(c, _, _, conf)
|
||||
}
|
||||
|
||||
pragma[nomagic]
|
||||
predicate viableReturnPosOutNodeCandFwd1(
|
||||
additional predicate viableReturnPosOutNodeCandFwd1(
|
||||
DataFlowCall call, ReturnPosition pos, NodeEx out, Configuration config
|
||||
) {
|
||||
fwdFlowReturnPosition(pos, _, config) and
|
||||
@@ -860,7 +860,7 @@ private module Stage1 implements StageSig {
|
||||
}
|
||||
|
||||
pragma[nomagic]
|
||||
predicate viableParamArgNodeCandFwd1(
|
||||
additional predicate viableParamArgNodeCandFwd1(
|
||||
DataFlowCall call, ParamNodeEx p, ArgNodeEx arg, Configuration config
|
||||
) {
|
||||
viableParamArgEx(call, p, arg) and
|
||||
@@ -907,7 +907,7 @@ private module Stage1 implements StageSig {
|
||||
)
|
||||
}
|
||||
|
||||
predicate revFlowState(FlowState state, Configuration config) {
|
||||
additional predicate revFlowState(FlowState state, Configuration config) {
|
||||
exists(NodeEx node |
|
||||
sinkNode(node, state, config) and
|
||||
revFlow(node, _, pragma[only_bind_into](config)) and
|
||||
@@ -999,7 +999,7 @@ private module Stage1 implements StageSig {
|
||||
)
|
||||
}
|
||||
|
||||
predicate stats(
|
||||
additional predicate stats(
|
||||
boolean fwd, int nodes, int fields, int conscand, int states, int tuples, Configuration config
|
||||
) {
|
||||
fwd = true and
|
||||
@@ -1260,7 +1260,7 @@ private module MkStage<StageSig PrevStage> {
|
||||
* argument.
|
||||
*/
|
||||
pragma[nomagic]
|
||||
predicate fwdFlow(
|
||||
additional predicate fwdFlow(
|
||||
NodeEx node, FlowState state, Cc cc, ApOption argAp, Ap ap, Configuration config
|
||||
) {
|
||||
fwdFlow0(node, state, cc, argAp, ap, config) and
|
||||
@@ -1484,7 +1484,7 @@ private module MkStage<StageSig PrevStage> {
|
||||
* the access path of the returned value.
|
||||
*/
|
||||
pragma[nomagic]
|
||||
predicate revFlow(
|
||||
additional predicate revFlow(
|
||||
NodeEx node, FlowState state, boolean toReturn, ApOption returnAp, Ap ap, Configuration config
|
||||
) {
|
||||
revFlow0(node, state, toReturn, returnAp, ap, config) and
|
||||
@@ -1662,7 +1662,7 @@ private module MkStage<StageSig PrevStage> {
|
||||
)
|
||||
}
|
||||
|
||||
predicate revFlow(NodeEx node, FlowState state, Configuration config) {
|
||||
additional predicate revFlow(NodeEx node, FlowState state, Configuration config) {
|
||||
revFlow(node, state, _, _, _, config)
|
||||
}
|
||||
|
||||
@@ -1675,11 +1675,13 @@ private module MkStage<StageSig PrevStage> {
|
||||
|
||||
// use an alias as a workaround for bad functionality-induced joins
|
||||
pragma[nomagic]
|
||||
predicate revFlowAlias(NodeEx node, Configuration config) { revFlow(node, _, _, _, _, config) }
|
||||
additional predicate revFlowAlias(NodeEx node, Configuration config) {
|
||||
revFlow(node, _, _, _, _, config)
|
||||
}
|
||||
|
||||
// use an alias as a workaround for bad functionality-induced joins
|
||||
pragma[nomagic]
|
||||
predicate revFlowAlias(NodeEx node, FlowState state, Ap ap, Configuration config) {
|
||||
additional predicate revFlowAlias(NodeEx node, FlowState state, Ap ap, Configuration config) {
|
||||
revFlow(node, state, ap, config)
|
||||
}
|
||||
|
||||
@@ -1700,7 +1702,7 @@ private module MkStage<StageSig PrevStage> {
|
||||
)
|
||||
}
|
||||
|
||||
predicate consCand(TypedContent tc, Ap ap, Configuration config) {
|
||||
additional predicate consCand(TypedContent tc, Ap ap, Configuration config) {
|
||||
revConsCand(tc, ap, config) and
|
||||
validAp(ap, config)
|
||||
}
|
||||
@@ -1742,7 +1744,7 @@ private module MkStage<StageSig PrevStage> {
|
||||
)
|
||||
}
|
||||
|
||||
predicate stats(
|
||||
additional predicate stats(
|
||||
boolean fwd, int nodes, int fields, int conscand, int states, int tuples, Configuration config
|
||||
) {
|
||||
fwd = true and
|
||||
|
||||
@@ -838,13 +838,13 @@ private module Stage1 implements StageSig {
|
||||
* by `revFlow`.
|
||||
*/
|
||||
pragma[nomagic]
|
||||
predicate revFlowIsReadAndStored(Content c, Configuration conf) {
|
||||
additional predicate revFlowIsReadAndStored(Content c, Configuration conf) {
|
||||
revFlowConsCand(c, conf) and
|
||||
revFlowStore(c, _, _, conf)
|
||||
}
|
||||
|
||||
pragma[nomagic]
|
||||
predicate viableReturnPosOutNodeCandFwd1(
|
||||
additional predicate viableReturnPosOutNodeCandFwd1(
|
||||
DataFlowCall call, ReturnPosition pos, NodeEx out, Configuration config
|
||||
) {
|
||||
fwdFlowReturnPosition(pos, _, config) and
|
||||
@@ -860,7 +860,7 @@ private module Stage1 implements StageSig {
|
||||
}
|
||||
|
||||
pragma[nomagic]
|
||||
predicate viableParamArgNodeCandFwd1(
|
||||
additional predicate viableParamArgNodeCandFwd1(
|
||||
DataFlowCall call, ParamNodeEx p, ArgNodeEx arg, Configuration config
|
||||
) {
|
||||
viableParamArgEx(call, p, arg) and
|
||||
@@ -907,7 +907,7 @@ private module Stage1 implements StageSig {
|
||||
)
|
||||
}
|
||||
|
||||
predicate revFlowState(FlowState state, Configuration config) {
|
||||
additional predicate revFlowState(FlowState state, Configuration config) {
|
||||
exists(NodeEx node |
|
||||
sinkNode(node, state, config) and
|
||||
revFlow(node, _, pragma[only_bind_into](config)) and
|
||||
@@ -999,7 +999,7 @@ private module Stage1 implements StageSig {
|
||||
)
|
||||
}
|
||||
|
||||
predicate stats(
|
||||
additional predicate stats(
|
||||
boolean fwd, int nodes, int fields, int conscand, int states, int tuples, Configuration config
|
||||
) {
|
||||
fwd = true and
|
||||
@@ -1260,7 +1260,7 @@ private module MkStage<StageSig PrevStage> {
|
||||
* argument.
|
||||
*/
|
||||
pragma[nomagic]
|
||||
predicate fwdFlow(
|
||||
additional predicate fwdFlow(
|
||||
NodeEx node, FlowState state, Cc cc, ApOption argAp, Ap ap, Configuration config
|
||||
) {
|
||||
fwdFlow0(node, state, cc, argAp, ap, config) and
|
||||
@@ -1484,7 +1484,7 @@ private module MkStage<StageSig PrevStage> {
|
||||
* the access path of the returned value.
|
||||
*/
|
||||
pragma[nomagic]
|
||||
predicate revFlow(
|
||||
additional predicate revFlow(
|
||||
NodeEx node, FlowState state, boolean toReturn, ApOption returnAp, Ap ap, Configuration config
|
||||
) {
|
||||
revFlow0(node, state, toReturn, returnAp, ap, config) and
|
||||
@@ -1662,7 +1662,7 @@ private module MkStage<StageSig PrevStage> {
|
||||
)
|
||||
}
|
||||
|
||||
predicate revFlow(NodeEx node, FlowState state, Configuration config) {
|
||||
additional predicate revFlow(NodeEx node, FlowState state, Configuration config) {
|
||||
revFlow(node, state, _, _, _, config)
|
||||
}
|
||||
|
||||
@@ -1675,11 +1675,13 @@ private module MkStage<StageSig PrevStage> {
|
||||
|
||||
// use an alias as a workaround for bad functionality-induced joins
|
||||
pragma[nomagic]
|
||||
predicate revFlowAlias(NodeEx node, Configuration config) { revFlow(node, _, _, _, _, config) }
|
||||
additional predicate revFlowAlias(NodeEx node, Configuration config) {
|
||||
revFlow(node, _, _, _, _, config)
|
||||
}
|
||||
|
||||
// use an alias as a workaround for bad functionality-induced joins
|
||||
pragma[nomagic]
|
||||
predicate revFlowAlias(NodeEx node, FlowState state, Ap ap, Configuration config) {
|
||||
additional predicate revFlowAlias(NodeEx node, FlowState state, Ap ap, Configuration config) {
|
||||
revFlow(node, state, ap, config)
|
||||
}
|
||||
|
||||
@@ -1700,7 +1702,7 @@ private module MkStage<StageSig PrevStage> {
|
||||
)
|
||||
}
|
||||
|
||||
predicate consCand(TypedContent tc, Ap ap, Configuration config) {
|
||||
additional predicate consCand(TypedContent tc, Ap ap, Configuration config) {
|
||||
revConsCand(tc, ap, config) and
|
||||
validAp(ap, config)
|
||||
}
|
||||
@@ -1742,7 +1744,7 @@ private module MkStage<StageSig PrevStage> {
|
||||
)
|
||||
}
|
||||
|
||||
predicate stats(
|
||||
additional predicate stats(
|
||||
boolean fwd, int nodes, int fields, int conscand, int states, int tuples, Configuration config
|
||||
) {
|
||||
fwd = true and
|
||||
|
||||
@@ -838,13 +838,13 @@ private module Stage1 implements StageSig {
|
||||
* by `revFlow`.
|
||||
*/
|
||||
pragma[nomagic]
|
||||
predicate revFlowIsReadAndStored(Content c, Configuration conf) {
|
||||
additional predicate revFlowIsReadAndStored(Content c, Configuration conf) {
|
||||
revFlowConsCand(c, conf) and
|
||||
revFlowStore(c, _, _, conf)
|
||||
}
|
||||
|
||||
pragma[nomagic]
|
||||
predicate viableReturnPosOutNodeCandFwd1(
|
||||
additional predicate viableReturnPosOutNodeCandFwd1(
|
||||
DataFlowCall call, ReturnPosition pos, NodeEx out, Configuration config
|
||||
) {
|
||||
fwdFlowReturnPosition(pos, _, config) and
|
||||
@@ -860,7 +860,7 @@ private module Stage1 implements StageSig {
|
||||
}
|
||||
|
||||
pragma[nomagic]
|
||||
predicate viableParamArgNodeCandFwd1(
|
||||
additional predicate viableParamArgNodeCandFwd1(
|
||||
DataFlowCall call, ParamNodeEx p, ArgNodeEx arg, Configuration config
|
||||
) {
|
||||
viableParamArgEx(call, p, arg) and
|
||||
@@ -907,7 +907,7 @@ private module Stage1 implements StageSig {
|
||||
)
|
||||
}
|
||||
|
||||
predicate revFlowState(FlowState state, Configuration config) {
|
||||
additional predicate revFlowState(FlowState state, Configuration config) {
|
||||
exists(NodeEx node |
|
||||
sinkNode(node, state, config) and
|
||||
revFlow(node, _, pragma[only_bind_into](config)) and
|
||||
@@ -999,7 +999,7 @@ private module Stage1 implements StageSig {
|
||||
)
|
||||
}
|
||||
|
||||
predicate stats(
|
||||
additional predicate stats(
|
||||
boolean fwd, int nodes, int fields, int conscand, int states, int tuples, Configuration config
|
||||
) {
|
||||
fwd = true and
|
||||
@@ -1260,7 +1260,7 @@ private module MkStage<StageSig PrevStage> {
|
||||
* argument.
|
||||
*/
|
||||
pragma[nomagic]
|
||||
predicate fwdFlow(
|
||||
additional predicate fwdFlow(
|
||||
NodeEx node, FlowState state, Cc cc, ApOption argAp, Ap ap, Configuration config
|
||||
) {
|
||||
fwdFlow0(node, state, cc, argAp, ap, config) and
|
||||
@@ -1484,7 +1484,7 @@ private module MkStage<StageSig PrevStage> {
|
||||
* the access path of the returned value.
|
||||
*/
|
||||
pragma[nomagic]
|
||||
predicate revFlow(
|
||||
additional predicate revFlow(
|
||||
NodeEx node, FlowState state, boolean toReturn, ApOption returnAp, Ap ap, Configuration config
|
||||
) {
|
||||
revFlow0(node, state, toReturn, returnAp, ap, config) and
|
||||
@@ -1662,7 +1662,7 @@ private module MkStage<StageSig PrevStage> {
|
||||
)
|
||||
}
|
||||
|
||||
predicate revFlow(NodeEx node, FlowState state, Configuration config) {
|
||||
additional predicate revFlow(NodeEx node, FlowState state, Configuration config) {
|
||||
revFlow(node, state, _, _, _, config)
|
||||
}
|
||||
|
||||
@@ -1675,11 +1675,13 @@ private module MkStage<StageSig PrevStage> {
|
||||
|
||||
// use an alias as a workaround for bad functionality-induced joins
|
||||
pragma[nomagic]
|
||||
predicate revFlowAlias(NodeEx node, Configuration config) { revFlow(node, _, _, _, _, config) }
|
||||
additional predicate revFlowAlias(NodeEx node, Configuration config) {
|
||||
revFlow(node, _, _, _, _, config)
|
||||
}
|
||||
|
||||
// use an alias as a workaround for bad functionality-induced joins
|
||||
pragma[nomagic]
|
||||
predicate revFlowAlias(NodeEx node, FlowState state, Ap ap, Configuration config) {
|
||||
additional predicate revFlowAlias(NodeEx node, FlowState state, Ap ap, Configuration config) {
|
||||
revFlow(node, state, ap, config)
|
||||
}
|
||||
|
||||
@@ -1700,7 +1702,7 @@ private module MkStage<StageSig PrevStage> {
|
||||
)
|
||||
}
|
||||
|
||||
predicate consCand(TypedContent tc, Ap ap, Configuration config) {
|
||||
additional predicate consCand(TypedContent tc, Ap ap, Configuration config) {
|
||||
revConsCand(tc, ap, config) and
|
||||
validAp(ap, config)
|
||||
}
|
||||
@@ -1742,7 +1744,7 @@ private module MkStage<StageSig PrevStage> {
|
||||
)
|
||||
}
|
||||
|
||||
predicate stats(
|
||||
additional predicate stats(
|
||||
boolean fwd, int nodes, int fields, int conscand, int states, int tuples, Configuration config
|
||||
) {
|
||||
fwd = true and
|
||||
|
||||
@@ -838,13 +838,13 @@ private module Stage1 implements StageSig {
|
||||
* by `revFlow`.
|
||||
*/
|
||||
pragma[nomagic]
|
||||
predicate revFlowIsReadAndStored(Content c, Configuration conf) {
|
||||
additional predicate revFlowIsReadAndStored(Content c, Configuration conf) {
|
||||
revFlowConsCand(c, conf) and
|
||||
revFlowStore(c, _, _, conf)
|
||||
}
|
||||
|
||||
pragma[nomagic]
|
||||
predicate viableReturnPosOutNodeCandFwd1(
|
||||
additional predicate viableReturnPosOutNodeCandFwd1(
|
||||
DataFlowCall call, ReturnPosition pos, NodeEx out, Configuration config
|
||||
) {
|
||||
fwdFlowReturnPosition(pos, _, config) and
|
||||
@@ -860,7 +860,7 @@ private module Stage1 implements StageSig {
|
||||
}
|
||||
|
||||
pragma[nomagic]
|
||||
predicate viableParamArgNodeCandFwd1(
|
||||
additional predicate viableParamArgNodeCandFwd1(
|
||||
DataFlowCall call, ParamNodeEx p, ArgNodeEx arg, Configuration config
|
||||
) {
|
||||
viableParamArgEx(call, p, arg) and
|
||||
@@ -907,7 +907,7 @@ private module Stage1 implements StageSig {
|
||||
)
|
||||
}
|
||||
|
||||
predicate revFlowState(FlowState state, Configuration config) {
|
||||
additional predicate revFlowState(FlowState state, Configuration config) {
|
||||
exists(NodeEx node |
|
||||
sinkNode(node, state, config) and
|
||||
revFlow(node, _, pragma[only_bind_into](config)) and
|
||||
@@ -999,7 +999,7 @@ private module Stage1 implements StageSig {
|
||||
)
|
||||
}
|
||||
|
||||
predicate stats(
|
||||
additional predicate stats(
|
||||
boolean fwd, int nodes, int fields, int conscand, int states, int tuples, Configuration config
|
||||
) {
|
||||
fwd = true and
|
||||
@@ -1260,7 +1260,7 @@ private module MkStage<StageSig PrevStage> {
|
||||
* argument.
|
||||
*/
|
||||
pragma[nomagic]
|
||||
predicate fwdFlow(
|
||||
additional predicate fwdFlow(
|
||||
NodeEx node, FlowState state, Cc cc, ApOption argAp, Ap ap, Configuration config
|
||||
) {
|
||||
fwdFlow0(node, state, cc, argAp, ap, config) and
|
||||
@@ -1484,7 +1484,7 @@ private module MkStage<StageSig PrevStage> {
|
||||
* the access path of the returned value.
|
||||
*/
|
||||
pragma[nomagic]
|
||||
predicate revFlow(
|
||||
additional predicate revFlow(
|
||||
NodeEx node, FlowState state, boolean toReturn, ApOption returnAp, Ap ap, Configuration config
|
||||
) {
|
||||
revFlow0(node, state, toReturn, returnAp, ap, config) and
|
||||
@@ -1662,7 +1662,7 @@ private module MkStage<StageSig PrevStage> {
|
||||
)
|
||||
}
|
||||
|
||||
predicate revFlow(NodeEx node, FlowState state, Configuration config) {
|
||||
additional predicate revFlow(NodeEx node, FlowState state, Configuration config) {
|
||||
revFlow(node, state, _, _, _, config)
|
||||
}
|
||||
|
||||
@@ -1675,11 +1675,13 @@ private module MkStage<StageSig PrevStage> {
|
||||
|
||||
// use an alias as a workaround for bad functionality-induced joins
|
||||
pragma[nomagic]
|
||||
predicate revFlowAlias(NodeEx node, Configuration config) { revFlow(node, _, _, _, _, config) }
|
||||
additional predicate revFlowAlias(NodeEx node, Configuration config) {
|
||||
revFlow(node, _, _, _, _, config)
|
||||
}
|
||||
|
||||
// use an alias as a workaround for bad functionality-induced joins
|
||||
pragma[nomagic]
|
||||
predicate revFlowAlias(NodeEx node, FlowState state, Ap ap, Configuration config) {
|
||||
additional predicate revFlowAlias(NodeEx node, FlowState state, Ap ap, Configuration config) {
|
||||
revFlow(node, state, ap, config)
|
||||
}
|
||||
|
||||
@@ -1700,7 +1702,7 @@ private module MkStage<StageSig PrevStage> {
|
||||
)
|
||||
}
|
||||
|
||||
predicate consCand(TypedContent tc, Ap ap, Configuration config) {
|
||||
additional predicate consCand(TypedContent tc, Ap ap, Configuration config) {
|
||||
revConsCand(tc, ap, config) and
|
||||
validAp(ap, config)
|
||||
}
|
||||
@@ -1742,7 +1744,7 @@ private module MkStage<StageSig PrevStage> {
|
||||
)
|
||||
}
|
||||
|
||||
predicate stats(
|
||||
additional predicate stats(
|
||||
boolean fwd, int nodes, int fields, int conscand, int states, int tuples, Configuration config
|
||||
) {
|
||||
fwd = true and
|
||||
|
||||
@@ -838,13 +838,13 @@ private module Stage1 implements StageSig {
|
||||
* by `revFlow`.
|
||||
*/
|
||||
pragma[nomagic]
|
||||
predicate revFlowIsReadAndStored(Content c, Configuration conf) {
|
||||
additional predicate revFlowIsReadAndStored(Content c, Configuration conf) {
|
||||
revFlowConsCand(c, conf) and
|
||||
revFlowStore(c, _, _, conf)
|
||||
}
|
||||
|
||||
pragma[nomagic]
|
||||
predicate viableReturnPosOutNodeCandFwd1(
|
||||
additional predicate viableReturnPosOutNodeCandFwd1(
|
||||
DataFlowCall call, ReturnPosition pos, NodeEx out, Configuration config
|
||||
) {
|
||||
fwdFlowReturnPosition(pos, _, config) and
|
||||
@@ -860,7 +860,7 @@ private module Stage1 implements StageSig {
|
||||
}
|
||||
|
||||
pragma[nomagic]
|
||||
predicate viableParamArgNodeCandFwd1(
|
||||
additional predicate viableParamArgNodeCandFwd1(
|
||||
DataFlowCall call, ParamNodeEx p, ArgNodeEx arg, Configuration config
|
||||
) {
|
||||
viableParamArgEx(call, p, arg) and
|
||||
@@ -907,7 +907,7 @@ private module Stage1 implements StageSig {
|
||||
)
|
||||
}
|
||||
|
||||
predicate revFlowState(FlowState state, Configuration config) {
|
||||
additional predicate revFlowState(FlowState state, Configuration config) {
|
||||
exists(NodeEx node |
|
||||
sinkNode(node, state, config) and
|
||||
revFlow(node, _, pragma[only_bind_into](config)) and
|
||||
@@ -999,7 +999,7 @@ private module Stage1 implements StageSig {
|
||||
)
|
||||
}
|
||||
|
||||
predicate stats(
|
||||
additional predicate stats(
|
||||
boolean fwd, int nodes, int fields, int conscand, int states, int tuples, Configuration config
|
||||
) {
|
||||
fwd = true and
|
||||
@@ -1260,7 +1260,7 @@ private module MkStage<StageSig PrevStage> {
|
||||
* argument.
|
||||
*/
|
||||
pragma[nomagic]
|
||||
predicate fwdFlow(
|
||||
additional predicate fwdFlow(
|
||||
NodeEx node, FlowState state, Cc cc, ApOption argAp, Ap ap, Configuration config
|
||||
) {
|
||||
fwdFlow0(node, state, cc, argAp, ap, config) and
|
||||
@@ -1484,7 +1484,7 @@ private module MkStage<StageSig PrevStage> {
|
||||
* the access path of the returned value.
|
||||
*/
|
||||
pragma[nomagic]
|
||||
predicate revFlow(
|
||||
additional predicate revFlow(
|
||||
NodeEx node, FlowState state, boolean toReturn, ApOption returnAp, Ap ap, Configuration config
|
||||
) {
|
||||
revFlow0(node, state, toReturn, returnAp, ap, config) and
|
||||
@@ -1662,7 +1662,7 @@ private module MkStage<StageSig PrevStage> {
|
||||
)
|
||||
}
|
||||
|
||||
predicate revFlow(NodeEx node, FlowState state, Configuration config) {
|
||||
additional predicate revFlow(NodeEx node, FlowState state, Configuration config) {
|
||||
revFlow(node, state, _, _, _, config)
|
||||
}
|
||||
|
||||
@@ -1675,11 +1675,13 @@ private module MkStage<StageSig PrevStage> {
|
||||
|
||||
// use an alias as a workaround for bad functionality-induced joins
|
||||
pragma[nomagic]
|
||||
predicate revFlowAlias(NodeEx node, Configuration config) { revFlow(node, _, _, _, _, config) }
|
||||
additional predicate revFlowAlias(NodeEx node, Configuration config) {
|
||||
revFlow(node, _, _, _, _, config)
|
||||
}
|
||||
|
||||
// use an alias as a workaround for bad functionality-induced joins
|
||||
pragma[nomagic]
|
||||
predicate revFlowAlias(NodeEx node, FlowState state, Ap ap, Configuration config) {
|
||||
additional predicate revFlowAlias(NodeEx node, FlowState state, Ap ap, Configuration config) {
|
||||
revFlow(node, state, ap, config)
|
||||
}
|
||||
|
||||
@@ -1700,7 +1702,7 @@ private module MkStage<StageSig PrevStage> {
|
||||
)
|
||||
}
|
||||
|
||||
predicate consCand(TypedContent tc, Ap ap, Configuration config) {
|
||||
additional predicate consCand(TypedContent tc, Ap ap, Configuration config) {
|
||||
revConsCand(tc, ap, config) and
|
||||
validAp(ap, config)
|
||||
}
|
||||
@@ -1742,7 +1744,7 @@ private module MkStage<StageSig PrevStage> {
|
||||
)
|
||||
}
|
||||
|
||||
predicate stats(
|
||||
additional predicate stats(
|
||||
boolean fwd, int nodes, int fields, int conscand, int states, int tuples, Configuration config
|
||||
) {
|
||||
fwd = true and
|
||||
|
||||
@@ -1137,7 +1137,7 @@ class BuiltInOperationIsArray extends BuiltInOperation, @isarray {
|
||||
* A C++ `__array_rank` built-in operation (used by some implementations of the
|
||||
* `<type_traits>` header).
|
||||
*
|
||||
* If known, returns the number of dimentsions of an arrary type.
|
||||
* If known, returns the number of dimensions of an arrary type.
|
||||
* ```
|
||||
* template<typename _Tp>
|
||||
* struct rank
|
||||
|
||||
@@ -494,7 +494,7 @@ class VacuousDestructorCall extends Expr, @vacuous_destructor_call {
|
||||
* An initialization of a base class or member variable performed as part
|
||||
* of a constructor's explicit initializer list or implicit actions.
|
||||
*
|
||||
* This is a QL root class for reprenting various types of constructor
|
||||
* This is a QL root class for representing various types of constructor
|
||||
* initializations.
|
||||
*/
|
||||
class ConstructorInit extends Expr, @ctorinit {
|
||||
|
||||
@@ -779,7 +779,7 @@ class AlignofExprOperator extends AlignofOperator {
|
||||
/**
|
||||
* A C++11 `alignof` expression whose operand is a type name.
|
||||
* ```
|
||||
* bool proper_alignment = (alingof(T) == alignof(T[0]);
|
||||
* bool proper_alignment = (alignof(T) == alignof(T[0]);
|
||||
* ```
|
||||
*/
|
||||
class AlignofTypeOperator extends AlignofOperator {
|
||||
|
||||
@@ -451,7 +451,7 @@ class Expr extends StmtParent, @expr {
|
||||
// For performance, we avoid a full transitive closure over `getConversion`.
|
||||
// Since there can be several implicit conversions before and after an
|
||||
// explicit conversion, use `getImplicitlyConverted` to step over them
|
||||
// cheaply. Then, if there is an explicit conversion following the implict
|
||||
// cheaply. Then, if there is an explicit conversion following the implicit
|
||||
// conversion sequence, recurse to handle multiple explicit conversions.
|
||||
if this.getImplicitlyConverted().hasExplicitConversion()
|
||||
then result = this.getImplicitlyConverted().getConversion().getExplicitlyConverted()
|
||||
|
||||
@@ -838,13 +838,13 @@ private module Stage1 implements StageSig {
|
||||
* by `revFlow`.
|
||||
*/
|
||||
pragma[nomagic]
|
||||
predicate revFlowIsReadAndStored(Content c, Configuration conf) {
|
||||
additional predicate revFlowIsReadAndStored(Content c, Configuration conf) {
|
||||
revFlowConsCand(c, conf) and
|
||||
revFlowStore(c, _, _, conf)
|
||||
}
|
||||
|
||||
pragma[nomagic]
|
||||
predicate viableReturnPosOutNodeCandFwd1(
|
||||
additional predicate viableReturnPosOutNodeCandFwd1(
|
||||
DataFlowCall call, ReturnPosition pos, NodeEx out, Configuration config
|
||||
) {
|
||||
fwdFlowReturnPosition(pos, _, config) and
|
||||
@@ -860,7 +860,7 @@ private module Stage1 implements StageSig {
|
||||
}
|
||||
|
||||
pragma[nomagic]
|
||||
predicate viableParamArgNodeCandFwd1(
|
||||
additional predicate viableParamArgNodeCandFwd1(
|
||||
DataFlowCall call, ParamNodeEx p, ArgNodeEx arg, Configuration config
|
||||
) {
|
||||
viableParamArgEx(call, p, arg) and
|
||||
@@ -907,7 +907,7 @@ private module Stage1 implements StageSig {
|
||||
)
|
||||
}
|
||||
|
||||
predicate revFlowState(FlowState state, Configuration config) {
|
||||
additional predicate revFlowState(FlowState state, Configuration config) {
|
||||
exists(NodeEx node |
|
||||
sinkNode(node, state, config) and
|
||||
revFlow(node, _, pragma[only_bind_into](config)) and
|
||||
@@ -999,7 +999,7 @@ private module Stage1 implements StageSig {
|
||||
)
|
||||
}
|
||||
|
||||
predicate stats(
|
||||
additional predicate stats(
|
||||
boolean fwd, int nodes, int fields, int conscand, int states, int tuples, Configuration config
|
||||
) {
|
||||
fwd = true and
|
||||
@@ -1260,7 +1260,7 @@ private module MkStage<StageSig PrevStage> {
|
||||
* argument.
|
||||
*/
|
||||
pragma[nomagic]
|
||||
predicate fwdFlow(
|
||||
additional predicate fwdFlow(
|
||||
NodeEx node, FlowState state, Cc cc, ApOption argAp, Ap ap, Configuration config
|
||||
) {
|
||||
fwdFlow0(node, state, cc, argAp, ap, config) and
|
||||
@@ -1484,7 +1484,7 @@ private module MkStage<StageSig PrevStage> {
|
||||
* the access path of the returned value.
|
||||
*/
|
||||
pragma[nomagic]
|
||||
predicate revFlow(
|
||||
additional predicate revFlow(
|
||||
NodeEx node, FlowState state, boolean toReturn, ApOption returnAp, Ap ap, Configuration config
|
||||
) {
|
||||
revFlow0(node, state, toReturn, returnAp, ap, config) and
|
||||
@@ -1662,7 +1662,7 @@ private module MkStage<StageSig PrevStage> {
|
||||
)
|
||||
}
|
||||
|
||||
predicate revFlow(NodeEx node, FlowState state, Configuration config) {
|
||||
additional predicate revFlow(NodeEx node, FlowState state, Configuration config) {
|
||||
revFlow(node, state, _, _, _, config)
|
||||
}
|
||||
|
||||
@@ -1675,11 +1675,13 @@ private module MkStage<StageSig PrevStage> {
|
||||
|
||||
// use an alias as a workaround for bad functionality-induced joins
|
||||
pragma[nomagic]
|
||||
predicate revFlowAlias(NodeEx node, Configuration config) { revFlow(node, _, _, _, _, config) }
|
||||
additional predicate revFlowAlias(NodeEx node, Configuration config) {
|
||||
revFlow(node, _, _, _, _, config)
|
||||
}
|
||||
|
||||
// use an alias as a workaround for bad functionality-induced joins
|
||||
pragma[nomagic]
|
||||
predicate revFlowAlias(NodeEx node, FlowState state, Ap ap, Configuration config) {
|
||||
additional predicate revFlowAlias(NodeEx node, FlowState state, Ap ap, Configuration config) {
|
||||
revFlow(node, state, ap, config)
|
||||
}
|
||||
|
||||
@@ -1700,7 +1702,7 @@ private module MkStage<StageSig PrevStage> {
|
||||
)
|
||||
}
|
||||
|
||||
predicate consCand(TypedContent tc, Ap ap, Configuration config) {
|
||||
additional predicate consCand(TypedContent tc, Ap ap, Configuration config) {
|
||||
revConsCand(tc, ap, config) and
|
||||
validAp(ap, config)
|
||||
}
|
||||
@@ -1742,7 +1744,7 @@ private module MkStage<StageSig PrevStage> {
|
||||
)
|
||||
}
|
||||
|
||||
predicate stats(
|
||||
additional predicate stats(
|
||||
boolean fwd, int nodes, int fields, int conscand, int states, int tuples, Configuration config
|
||||
) {
|
||||
fwd = true and
|
||||
|
||||
@@ -838,13 +838,13 @@ private module Stage1 implements StageSig {
|
||||
* by `revFlow`.
|
||||
*/
|
||||
pragma[nomagic]
|
||||
predicate revFlowIsReadAndStored(Content c, Configuration conf) {
|
||||
additional predicate revFlowIsReadAndStored(Content c, Configuration conf) {
|
||||
revFlowConsCand(c, conf) and
|
||||
revFlowStore(c, _, _, conf)
|
||||
}
|
||||
|
||||
pragma[nomagic]
|
||||
predicate viableReturnPosOutNodeCandFwd1(
|
||||
additional predicate viableReturnPosOutNodeCandFwd1(
|
||||
DataFlowCall call, ReturnPosition pos, NodeEx out, Configuration config
|
||||
) {
|
||||
fwdFlowReturnPosition(pos, _, config) and
|
||||
@@ -860,7 +860,7 @@ private module Stage1 implements StageSig {
|
||||
}
|
||||
|
||||
pragma[nomagic]
|
||||
predicate viableParamArgNodeCandFwd1(
|
||||
additional predicate viableParamArgNodeCandFwd1(
|
||||
DataFlowCall call, ParamNodeEx p, ArgNodeEx arg, Configuration config
|
||||
) {
|
||||
viableParamArgEx(call, p, arg) and
|
||||
@@ -907,7 +907,7 @@ private module Stage1 implements StageSig {
|
||||
)
|
||||
}
|
||||
|
||||
predicate revFlowState(FlowState state, Configuration config) {
|
||||
additional predicate revFlowState(FlowState state, Configuration config) {
|
||||
exists(NodeEx node |
|
||||
sinkNode(node, state, config) and
|
||||
revFlow(node, _, pragma[only_bind_into](config)) and
|
||||
@@ -999,7 +999,7 @@ private module Stage1 implements StageSig {
|
||||
)
|
||||
}
|
||||
|
||||
predicate stats(
|
||||
additional predicate stats(
|
||||
boolean fwd, int nodes, int fields, int conscand, int states, int tuples, Configuration config
|
||||
) {
|
||||
fwd = true and
|
||||
@@ -1260,7 +1260,7 @@ private module MkStage<StageSig PrevStage> {
|
||||
* argument.
|
||||
*/
|
||||
pragma[nomagic]
|
||||
predicate fwdFlow(
|
||||
additional predicate fwdFlow(
|
||||
NodeEx node, FlowState state, Cc cc, ApOption argAp, Ap ap, Configuration config
|
||||
) {
|
||||
fwdFlow0(node, state, cc, argAp, ap, config) and
|
||||
@@ -1484,7 +1484,7 @@ private module MkStage<StageSig PrevStage> {
|
||||
* the access path of the returned value.
|
||||
*/
|
||||
pragma[nomagic]
|
||||
predicate revFlow(
|
||||
additional predicate revFlow(
|
||||
NodeEx node, FlowState state, boolean toReturn, ApOption returnAp, Ap ap, Configuration config
|
||||
) {
|
||||
revFlow0(node, state, toReturn, returnAp, ap, config) and
|
||||
@@ -1662,7 +1662,7 @@ private module MkStage<StageSig PrevStage> {
|
||||
)
|
||||
}
|
||||
|
||||
predicate revFlow(NodeEx node, FlowState state, Configuration config) {
|
||||
additional predicate revFlow(NodeEx node, FlowState state, Configuration config) {
|
||||
revFlow(node, state, _, _, _, config)
|
||||
}
|
||||
|
||||
@@ -1675,11 +1675,13 @@ private module MkStage<StageSig PrevStage> {
|
||||
|
||||
// use an alias as a workaround for bad functionality-induced joins
|
||||
pragma[nomagic]
|
||||
predicate revFlowAlias(NodeEx node, Configuration config) { revFlow(node, _, _, _, _, config) }
|
||||
additional predicate revFlowAlias(NodeEx node, Configuration config) {
|
||||
revFlow(node, _, _, _, _, config)
|
||||
}
|
||||
|
||||
// use an alias as a workaround for bad functionality-induced joins
|
||||
pragma[nomagic]
|
||||
predicate revFlowAlias(NodeEx node, FlowState state, Ap ap, Configuration config) {
|
||||
additional predicate revFlowAlias(NodeEx node, FlowState state, Ap ap, Configuration config) {
|
||||
revFlow(node, state, ap, config)
|
||||
}
|
||||
|
||||
@@ -1700,7 +1702,7 @@ private module MkStage<StageSig PrevStage> {
|
||||
)
|
||||
}
|
||||
|
||||
predicate consCand(TypedContent tc, Ap ap, Configuration config) {
|
||||
additional predicate consCand(TypedContent tc, Ap ap, Configuration config) {
|
||||
revConsCand(tc, ap, config) and
|
||||
validAp(ap, config)
|
||||
}
|
||||
@@ -1742,7 +1744,7 @@ private module MkStage<StageSig PrevStage> {
|
||||
)
|
||||
}
|
||||
|
||||
predicate stats(
|
||||
additional predicate stats(
|
||||
boolean fwd, int nodes, int fields, int conscand, int states, int tuples, Configuration config
|
||||
) {
|
||||
fwd = true and
|
||||
|
||||
@@ -838,13 +838,13 @@ private module Stage1 implements StageSig {
|
||||
* by `revFlow`.
|
||||
*/
|
||||
pragma[nomagic]
|
||||
predicate revFlowIsReadAndStored(Content c, Configuration conf) {
|
||||
additional predicate revFlowIsReadAndStored(Content c, Configuration conf) {
|
||||
revFlowConsCand(c, conf) and
|
||||
revFlowStore(c, _, _, conf)
|
||||
}
|
||||
|
||||
pragma[nomagic]
|
||||
predicate viableReturnPosOutNodeCandFwd1(
|
||||
additional predicate viableReturnPosOutNodeCandFwd1(
|
||||
DataFlowCall call, ReturnPosition pos, NodeEx out, Configuration config
|
||||
) {
|
||||
fwdFlowReturnPosition(pos, _, config) and
|
||||
@@ -860,7 +860,7 @@ private module Stage1 implements StageSig {
|
||||
}
|
||||
|
||||
pragma[nomagic]
|
||||
predicate viableParamArgNodeCandFwd1(
|
||||
additional predicate viableParamArgNodeCandFwd1(
|
||||
DataFlowCall call, ParamNodeEx p, ArgNodeEx arg, Configuration config
|
||||
) {
|
||||
viableParamArgEx(call, p, arg) and
|
||||
@@ -907,7 +907,7 @@ private module Stage1 implements StageSig {
|
||||
)
|
||||
}
|
||||
|
||||
predicate revFlowState(FlowState state, Configuration config) {
|
||||
additional predicate revFlowState(FlowState state, Configuration config) {
|
||||
exists(NodeEx node |
|
||||
sinkNode(node, state, config) and
|
||||
revFlow(node, _, pragma[only_bind_into](config)) and
|
||||
@@ -999,7 +999,7 @@ private module Stage1 implements StageSig {
|
||||
)
|
||||
}
|
||||
|
||||
predicate stats(
|
||||
additional predicate stats(
|
||||
boolean fwd, int nodes, int fields, int conscand, int states, int tuples, Configuration config
|
||||
) {
|
||||
fwd = true and
|
||||
@@ -1260,7 +1260,7 @@ private module MkStage<StageSig PrevStage> {
|
||||
* argument.
|
||||
*/
|
||||
pragma[nomagic]
|
||||
predicate fwdFlow(
|
||||
additional predicate fwdFlow(
|
||||
NodeEx node, FlowState state, Cc cc, ApOption argAp, Ap ap, Configuration config
|
||||
) {
|
||||
fwdFlow0(node, state, cc, argAp, ap, config) and
|
||||
@@ -1484,7 +1484,7 @@ private module MkStage<StageSig PrevStage> {
|
||||
* the access path of the returned value.
|
||||
*/
|
||||
pragma[nomagic]
|
||||
predicate revFlow(
|
||||
additional predicate revFlow(
|
||||
NodeEx node, FlowState state, boolean toReturn, ApOption returnAp, Ap ap, Configuration config
|
||||
) {
|
||||
revFlow0(node, state, toReturn, returnAp, ap, config) and
|
||||
@@ -1662,7 +1662,7 @@ private module MkStage<StageSig PrevStage> {
|
||||
)
|
||||
}
|
||||
|
||||
predicate revFlow(NodeEx node, FlowState state, Configuration config) {
|
||||
additional predicate revFlow(NodeEx node, FlowState state, Configuration config) {
|
||||
revFlow(node, state, _, _, _, config)
|
||||
}
|
||||
|
||||
@@ -1675,11 +1675,13 @@ private module MkStage<StageSig PrevStage> {
|
||||
|
||||
// use an alias as a workaround for bad functionality-induced joins
|
||||
pragma[nomagic]
|
||||
predicate revFlowAlias(NodeEx node, Configuration config) { revFlow(node, _, _, _, _, config) }
|
||||
additional predicate revFlowAlias(NodeEx node, Configuration config) {
|
||||
revFlow(node, _, _, _, _, config)
|
||||
}
|
||||
|
||||
// use an alias as a workaround for bad functionality-induced joins
|
||||
pragma[nomagic]
|
||||
predicate revFlowAlias(NodeEx node, FlowState state, Ap ap, Configuration config) {
|
||||
additional predicate revFlowAlias(NodeEx node, FlowState state, Ap ap, Configuration config) {
|
||||
revFlow(node, state, ap, config)
|
||||
}
|
||||
|
||||
@@ -1700,7 +1702,7 @@ private module MkStage<StageSig PrevStage> {
|
||||
)
|
||||
}
|
||||
|
||||
predicate consCand(TypedContent tc, Ap ap, Configuration config) {
|
||||
additional predicate consCand(TypedContent tc, Ap ap, Configuration config) {
|
||||
revConsCand(tc, ap, config) and
|
||||
validAp(ap, config)
|
||||
}
|
||||
@@ -1742,7 +1744,7 @@ private module MkStage<StageSig PrevStage> {
|
||||
)
|
||||
}
|
||||
|
||||
predicate stats(
|
||||
additional predicate stats(
|
||||
boolean fwd, int nodes, int fields, int conscand, int states, int tuples, Configuration config
|
||||
) {
|
||||
fwd = true and
|
||||
|
||||
@@ -838,13 +838,13 @@ private module Stage1 implements StageSig {
|
||||
* by `revFlow`.
|
||||
*/
|
||||
pragma[nomagic]
|
||||
predicate revFlowIsReadAndStored(Content c, Configuration conf) {
|
||||
additional predicate revFlowIsReadAndStored(Content c, Configuration conf) {
|
||||
revFlowConsCand(c, conf) and
|
||||
revFlowStore(c, _, _, conf)
|
||||
}
|
||||
|
||||
pragma[nomagic]
|
||||
predicate viableReturnPosOutNodeCandFwd1(
|
||||
additional predicate viableReturnPosOutNodeCandFwd1(
|
||||
DataFlowCall call, ReturnPosition pos, NodeEx out, Configuration config
|
||||
) {
|
||||
fwdFlowReturnPosition(pos, _, config) and
|
||||
@@ -860,7 +860,7 @@ private module Stage1 implements StageSig {
|
||||
}
|
||||
|
||||
pragma[nomagic]
|
||||
predicate viableParamArgNodeCandFwd1(
|
||||
additional predicate viableParamArgNodeCandFwd1(
|
||||
DataFlowCall call, ParamNodeEx p, ArgNodeEx arg, Configuration config
|
||||
) {
|
||||
viableParamArgEx(call, p, arg) and
|
||||
@@ -907,7 +907,7 @@ private module Stage1 implements StageSig {
|
||||
)
|
||||
}
|
||||
|
||||
predicate revFlowState(FlowState state, Configuration config) {
|
||||
additional predicate revFlowState(FlowState state, Configuration config) {
|
||||
exists(NodeEx node |
|
||||
sinkNode(node, state, config) and
|
||||
revFlow(node, _, pragma[only_bind_into](config)) and
|
||||
@@ -999,7 +999,7 @@ private module Stage1 implements StageSig {
|
||||
)
|
||||
}
|
||||
|
||||
predicate stats(
|
||||
additional predicate stats(
|
||||
boolean fwd, int nodes, int fields, int conscand, int states, int tuples, Configuration config
|
||||
) {
|
||||
fwd = true and
|
||||
@@ -1260,7 +1260,7 @@ private module MkStage<StageSig PrevStage> {
|
||||
* argument.
|
||||
*/
|
||||
pragma[nomagic]
|
||||
predicate fwdFlow(
|
||||
additional predicate fwdFlow(
|
||||
NodeEx node, FlowState state, Cc cc, ApOption argAp, Ap ap, Configuration config
|
||||
) {
|
||||
fwdFlow0(node, state, cc, argAp, ap, config) and
|
||||
@@ -1484,7 +1484,7 @@ private module MkStage<StageSig PrevStage> {
|
||||
* the access path of the returned value.
|
||||
*/
|
||||
pragma[nomagic]
|
||||
predicate revFlow(
|
||||
additional predicate revFlow(
|
||||
NodeEx node, FlowState state, boolean toReturn, ApOption returnAp, Ap ap, Configuration config
|
||||
) {
|
||||
revFlow0(node, state, toReturn, returnAp, ap, config) and
|
||||
@@ -1662,7 +1662,7 @@ private module MkStage<StageSig PrevStage> {
|
||||
)
|
||||
}
|
||||
|
||||
predicate revFlow(NodeEx node, FlowState state, Configuration config) {
|
||||
additional predicate revFlow(NodeEx node, FlowState state, Configuration config) {
|
||||
revFlow(node, state, _, _, _, config)
|
||||
}
|
||||
|
||||
@@ -1675,11 +1675,13 @@ private module MkStage<StageSig PrevStage> {
|
||||
|
||||
// use an alias as a workaround for bad functionality-induced joins
|
||||
pragma[nomagic]
|
||||
predicate revFlowAlias(NodeEx node, Configuration config) { revFlow(node, _, _, _, _, config) }
|
||||
additional predicate revFlowAlias(NodeEx node, Configuration config) {
|
||||
revFlow(node, _, _, _, _, config)
|
||||
}
|
||||
|
||||
// use an alias as a workaround for bad functionality-induced joins
|
||||
pragma[nomagic]
|
||||
predicate revFlowAlias(NodeEx node, FlowState state, Ap ap, Configuration config) {
|
||||
additional predicate revFlowAlias(NodeEx node, FlowState state, Ap ap, Configuration config) {
|
||||
revFlow(node, state, ap, config)
|
||||
}
|
||||
|
||||
@@ -1700,7 +1702,7 @@ private module MkStage<StageSig PrevStage> {
|
||||
)
|
||||
}
|
||||
|
||||
predicate consCand(TypedContent tc, Ap ap, Configuration config) {
|
||||
additional predicate consCand(TypedContent tc, Ap ap, Configuration config) {
|
||||
revConsCand(tc, ap, config) and
|
||||
validAp(ap, config)
|
||||
}
|
||||
@@ -1742,7 +1744,7 @@ private module MkStage<StageSig PrevStage> {
|
||||
)
|
||||
}
|
||||
|
||||
predicate stats(
|
||||
additional predicate stats(
|
||||
boolean fwd, int nodes, int fields, int conscand, int states, int tuples, Configuration config
|
||||
) {
|
||||
fwd = true and
|
||||
|
||||
@@ -100,7 +100,7 @@ private string getNodeProperty(DataFlow::Node node, string key) {
|
||||
or
|
||||
// Is there partial flow from a source to this node?
|
||||
// This property will only be emitted if partial flow is enabled by overriding
|
||||
// `DataFlow::Configration::explorationLimit()`.
|
||||
// `DataFlow::Configuration::explorationLimit()`.
|
||||
key = "pflow" and
|
||||
result =
|
||||
strictconcat(DataFlow::PartialPathNode sourceNode, DataFlow::PartialPathNode destNode, int dist,
|
||||
|
||||
@@ -742,7 +742,7 @@ class NoOpInstruction extends Instruction {
|
||||
* The `ReturnInstruction` for a function will have a control-flow successor edge to a block
|
||||
* containing the `ExitFunction` instruction for that function.
|
||||
*
|
||||
* There are two differet return instructions: `ReturnValueInstruction`, for returning a value from
|
||||
* There are two different return instructions: `ReturnValueInstruction`, for returning a value from
|
||||
* a non-`void`-returning function, and `ReturnVoidInstruction`, for returning from a
|
||||
* `void`-returning function.
|
||||
*/
|
||||
@@ -1331,7 +1331,7 @@ class CheckedConvertOrThrowInstruction extends UnaryInstruction {
|
||||
*
|
||||
* If the operand holds a null address, the result is a null address.
|
||||
*
|
||||
* This instruction is used to represent `dyanmic_cast<void*>` in C++, which returns the pointer to
|
||||
* This instruction is used to represent `dynamic_cast<void*>` in C++, which returns the pointer to
|
||||
* the most-derived object.
|
||||
*/
|
||||
class CompleteObjectAddressInstruction extends UnaryInstruction {
|
||||
|
||||
@@ -64,7 +64,7 @@ private module Cached {
|
||||
or
|
||||
instr = reusedPhiInstruction(_) and
|
||||
// Check that the phi instruction is *not* degenerate, but we can't use
|
||||
// getDegeneratePhiOperand in the first stage with phi instyructions
|
||||
// getDegeneratePhiOperand in the first stage with phi instructions
|
||||
not exists(
|
||||
unique(OldIR::PhiInputOperand operand |
|
||||
operand = instr.(OldIR::PhiInstruction).getAnInputOperand() and
|
||||
@@ -718,7 +718,7 @@ module DefUse {
|
||||
}
|
||||
|
||||
/**
|
||||
* Gets the rank index of a hyphothetical use one instruction past the end of
|
||||
* Gets the rank index of a hypothetical use one instruction past the end of
|
||||
* the block. This index can be used to determine if a definition reaches the
|
||||
* end of the block, even if the definition is the last instruction in the
|
||||
* block.
|
||||
|
||||
@@ -172,7 +172,7 @@ deprecated module UnaliasedSSAOperands = UnaliasedSsaOperands;
|
||||
|
||||
/**
|
||||
* Provides wrappers for the constructors of each branch of `TOperand` that is used by the
|
||||
* asliased SSA stage.
|
||||
* aliased SSA stage.
|
||||
* These wrappers are not parameterized because it is not possible to invoke an IPA constructor via
|
||||
* a class alias.
|
||||
*/
|
||||
|
||||
@@ -742,7 +742,7 @@ class NoOpInstruction extends Instruction {
|
||||
* The `ReturnInstruction` for a function will have a control-flow successor edge to a block
|
||||
* containing the `ExitFunction` instruction for that function.
|
||||
*
|
||||
* There are two differet return instructions: `ReturnValueInstruction`, for returning a value from
|
||||
* There are two different return instructions: `ReturnValueInstruction`, for returning a value from
|
||||
* a non-`void`-returning function, and `ReturnVoidInstruction`, for returning from a
|
||||
* `void`-returning function.
|
||||
*/
|
||||
@@ -1331,7 +1331,7 @@ class CheckedConvertOrThrowInstruction extends UnaryInstruction {
|
||||
*
|
||||
* If the operand holds a null address, the result is a null address.
|
||||
*
|
||||
* This instruction is used to represent `dyanmic_cast<void*>` in C++, which returns the pointer to
|
||||
* This instruction is used to represent `dynamic_cast<void*>` in C++, which returns the pointer to
|
||||
* the most-derived object.
|
||||
*/
|
||||
class CompleteObjectAddressInstruction extends UnaryInstruction {
|
||||
|
||||
@@ -542,7 +542,7 @@ class TranslatedArgumentExprSideEffect extends TranslatedArgumentSideEffect,
|
||||
* The IR translation of an argument side effect for `*this` on a call, where there is no `Expr`
|
||||
* object that represents the `this` argument.
|
||||
*
|
||||
* The applies only to constructor calls, as the AST has explioit qualifier `Expr`s for all other
|
||||
* The applies only to constructor calls, as the AST has exploit qualifier `Expr`s for all other
|
||||
* calls to non-static member functions.
|
||||
*/
|
||||
class TranslatedStructorQualifierSideEffect extends TranslatedArgumentSideEffect,
|
||||
|
||||
@@ -2177,7 +2177,7 @@ abstract class TranslatedConditionalExpr extends TranslatedNonConstantExpr {
|
||||
/**
|
||||
* The IR translation of the ternary conditional operator (`a ? b : c`).
|
||||
* For this version, we expand the condition as a `TranslatedCondition`, rather than a
|
||||
* `TranslatedExpr`, to simplify the control flow in the presence of short-ciruit logical operators.
|
||||
* `TranslatedExpr`, to simplify the control flow in the presence of short-circuit logical operators.
|
||||
*/
|
||||
class TranslatedTernaryConditionalExpr extends TranslatedConditionalExpr, ConditionContext {
|
||||
TranslatedTernaryConditionalExpr() { not expr.isTwoOperand() }
|
||||
|
||||
@@ -742,7 +742,7 @@ class NoOpInstruction extends Instruction {
|
||||
* The `ReturnInstruction` for a function will have a control-flow successor edge to a block
|
||||
* containing the `ExitFunction` instruction for that function.
|
||||
*
|
||||
* There are two differet return instructions: `ReturnValueInstruction`, for returning a value from
|
||||
* There are two different return instructions: `ReturnValueInstruction`, for returning a value from
|
||||
* a non-`void`-returning function, and `ReturnVoidInstruction`, for returning from a
|
||||
* `void`-returning function.
|
||||
*/
|
||||
@@ -1331,7 +1331,7 @@ class CheckedConvertOrThrowInstruction extends UnaryInstruction {
|
||||
*
|
||||
* If the operand holds a null address, the result is a null address.
|
||||
*
|
||||
* This instruction is used to represent `dyanmic_cast<void*>` in C++, which returns the pointer to
|
||||
* This instruction is used to represent `dynamic_cast<void*>` in C++, which returns the pointer to
|
||||
* the most-derived object.
|
||||
*/
|
||||
class CompleteObjectAddressInstruction extends UnaryInstruction {
|
||||
|
||||
@@ -64,7 +64,7 @@ private module Cached {
|
||||
or
|
||||
instr = reusedPhiInstruction(_) and
|
||||
// Check that the phi instruction is *not* degenerate, but we can't use
|
||||
// getDegeneratePhiOperand in the first stage with phi instyructions
|
||||
// getDegeneratePhiOperand in the first stage with phi instructions
|
||||
not exists(
|
||||
unique(OldIR::PhiInputOperand operand |
|
||||
operand = instr.(OldIR::PhiInstruction).getAnInputOperand() and
|
||||
@@ -718,7 +718,7 @@ module DefUse {
|
||||
}
|
||||
|
||||
/**
|
||||
* Gets the rank index of a hyphothetical use one instruction past the end of
|
||||
* Gets the rank index of a hypothetical use one instruction past the end of
|
||||
* the block. This index can be used to determine if a definition reaches the
|
||||
* end of the block, even if the definition is the last instruction in the
|
||||
* block.
|
||||
|
||||
@@ -12,7 +12,7 @@ private Type getDecayedType(Type type) {
|
||||
}
|
||||
|
||||
/**
|
||||
* Holds if the sepcified variable is a structured binding with a non-reference
|
||||
* Holds if the specified variable is a structured binding with a non-reference
|
||||
* type.
|
||||
*/
|
||||
predicate isNonReferenceStructuredBinding(Variable v) {
|
||||
|
||||
@@ -209,7 +209,7 @@ private predicate aClassFile(Class c, File file) { c.getDefinitionLocation().get
|
||||
|
||||
pragma[noopt]
|
||||
private predicate dependsOnFileSimple(MetricFile source, MetricFile dest) {
|
||||
// class derives from classs
|
||||
// class derives from another class
|
||||
exists(Class fromClass, Class toClass |
|
||||
aClassFile(fromClass, source) and
|
||||
fromClass.derivesFrom(toClass) and
|
||||
|
||||
@@ -173,7 +173,7 @@ predicate eqOpWithSwapAndNegate(EqualityOperation cmp, Expr a, Expr b, boolean i
|
||||
|
||||
/**
|
||||
* Holds if `cmp` is an unconverted conversion of `a` to a Boolean that
|
||||
* evalutes to `isEQ` iff `a` is 0.
|
||||
* evaluates to `isEQ` iff `a` is 0.
|
||||
*
|
||||
* Note that `a` can be `cmp` itself or a conversion thereof.
|
||||
*/
|
||||
|
||||
@@ -51,14 +51,14 @@ string getInsecureAlgorithmRegex() {
|
||||
|
||||
/**
|
||||
* Holds if `name` looks like it might be related to operations with an
|
||||
* insecure encyption algorithm.
|
||||
* insecure encryption algorithm.
|
||||
*/
|
||||
bindingset[name]
|
||||
predicate isInsecureEncryption(string name) { name.regexpMatch(getInsecureAlgorithmRegex()) }
|
||||
|
||||
/**
|
||||
* Holds if there is additional evidence that `name` looks like it might be
|
||||
* related to operations with an encyption algorithm, besides the name of a
|
||||
* related to operations with an encryption algorithm, besides the name of a
|
||||
* specific algorithm. This can be used in conjunction with
|
||||
* `isInsecureEncryption` to produce a stronger heuristic.
|
||||
*/
|
||||
|
||||
@@ -1,7 +1,7 @@
|
||||
/**
|
||||
* DEPRECATED: we now use `semmle.code.cpp.ir.dataflow.DefaultTaintTracking`,
|
||||
* which is based on the IR but designed to behave similarly to this old
|
||||
* libarary.
|
||||
* library.
|
||||
*
|
||||
* Provides the implementation of `semmle.code.cpp.security.TaintTracking`. Do
|
||||
* not import this file directly.
|
||||
|
||||
@@ -104,7 +104,7 @@ private newtype HC_Alloc =
|
||||
HC_HasAlloc(HashCons hc) { mk_HasAlloc(hc, _) }
|
||||
|
||||
/**
|
||||
* Used to implement optional extent expression on `new[]` exprtessions
|
||||
* Used to implement optional extent expression on `new[]` expressions
|
||||
*/
|
||||
private newtype HC_Extent =
|
||||
HC_NoExtent() or
|
||||
@@ -116,7 +116,7 @@ private newtype HC_Args =
|
||||
HC_ArgCons(HashCons hc, int i, HC_Args list) { mk_ArgCons(hc, i, list, _) }
|
||||
|
||||
/**
|
||||
* Used to implement hash-consing of struct initizializers.
|
||||
* Used to implement hash-consing of struct initializers.
|
||||
*/
|
||||
private newtype HC_Fields =
|
||||
HC_EmptyFields(Class c) { exists(ClassAggregateLiteral cal | c = cal.getUnspecifiedType()) } or
|
||||
|
||||
@@ -13,16 +13,32 @@
|
||||
|
||||
import cpp
|
||||
|
||||
pragma[noinline]
|
||||
predicate possiblyIncompleteFile(File f) {
|
||||
exists(Diagnostic d | d.getFile() = f and d.getSeverity() >= 3)
|
||||
}
|
||||
|
||||
predicate immediatelyReachableFunction(Function f) {
|
||||
not f.isStatic() or
|
||||
exists(BlockExpr be | be.getFunction() = f) or
|
||||
f instanceof MemberFunction or
|
||||
f instanceof TemplateFunction or
|
||||
f.getFile() instanceof HeaderFile or
|
||||
f.getAnAttribute().hasName("constructor") or
|
||||
f.getAnAttribute().hasName("destructor") or
|
||||
f.getAnAttribute().hasName("used") or
|
||||
not f.isStatic()
|
||||
or
|
||||
exists(BlockExpr be | be.getFunction() = f)
|
||||
or
|
||||
f instanceof MemberFunction
|
||||
or
|
||||
f instanceof TemplateFunction
|
||||
or
|
||||
f.getFile() instanceof HeaderFile
|
||||
or
|
||||
f.getAnAttribute().hasName("constructor")
|
||||
or
|
||||
f.getAnAttribute().hasName("destructor")
|
||||
or
|
||||
f.getAnAttribute().hasName("used")
|
||||
or
|
||||
f.getAnAttribute().hasName("unused")
|
||||
or
|
||||
// a compiler error in the same file suggests we may be missing data
|
||||
possiblyIncompleteFile(f.getFile())
|
||||
}
|
||||
|
||||
predicate immediatelyReachableVariable(Variable v) {
|
||||
|
||||
@@ -125,7 +125,7 @@
|
||||
|
||||
* The `security` tag has been added to the `cpp/return-stack-allocated-memory` query. As a result, its results will now appear by default.
|
||||
* The "Uncontrolled data in arithmetic expression" (cpp/uncontrolled-arithmetic) query has been enhanced to reduce false positive results and its @precision increased to high.
|
||||
* A new `cpp/very-likely-overruning-write` query has been added to the default query suite for C/C++. The query reports some results that were formerly flagged by `cpp/overruning-write`.
|
||||
* A new `cpp/very-likely-overrunning-write` query has been added to the default query suite for C/C++. The query reports some results that were formerly flagged by `cpp/overrunning-write`.
|
||||
|
||||
### Minor Analysis Improvements
|
||||
|
||||
|
||||
@@ -63,7 +63,7 @@ predicate verifiedRealloc(FunctionCall reallocCall, Variable v, ControlFlowNode
|
||||
node.(AnalysedExpr).getNonNullSuccessor(newV) = verified and
|
||||
// note: this case uses naive flow logic (getAnAssignedValue).
|
||||
// special case: if the result of the 'realloc' is assigned to the
|
||||
// same variable, we don't descriminate properly between the old
|
||||
// same variable, we don't discriminate properly between the old
|
||||
// and the new allocation; better to not consider this a free at
|
||||
// all in that case.
|
||||
newV != v
|
||||
|
||||
@@ -23,7 +23,7 @@ DoStmt getAFalseLoop() {
|
||||
/**
|
||||
* Gets a `do` ... `while` loop surrounding a statement. This is blocked by a
|
||||
* `switch` statement, since a `continue` inside a `switch` inside a loop may be
|
||||
* jusitifed (`continue` breaks out of the loop whereas `break` only escapes the
|
||||
* justified (`continue` breaks out of the loop whereas `break` only escapes the
|
||||
* `switch`).
|
||||
*/
|
||||
DoStmt enclosingLoop(Stmt s) {
|
||||
|
||||
@@ -17,7 +17,7 @@ import cpp
|
||||
/**
|
||||
* It's common in some projects to use "a double negation" to normalize the boolean
|
||||
* result to either 1 or 0.
|
||||
* This predciate is intended to filter explicit usage of a double negation as it typically
|
||||
* This predicate is intended to filter explicit usage of a double negation as it typically
|
||||
* indicates the explicit purpose to normalize the result for bit-wise or arithmetic purposes.
|
||||
*/
|
||||
predicate doubleNegationNormalization(NotExpr notexpr) { notexpr.getAnOperand() instanceof NotExpr }
|
||||
|
||||
@@ -3,7 +3,7 @@
|
||||
* @name Untrusted network-to-host usage
|
||||
* @description Using the result of a network-to-host byte order function, such as ntohl, as an
|
||||
* array bound or length value without checking it may result in buffer overflows or
|
||||
* other vulnerabilties.
|
||||
* other vulnerabilities.
|
||||
* @kind problem
|
||||
* @problem.severity error
|
||||
*/
|
||||
|
||||
@@ -44,7 +44,7 @@ class ReturnStackAllocatedMemoryConfig extends MustFlowConfiguration {
|
||||
// Holds if `sink` is a node that represents the `StoreInstruction` that is subsequently used in
|
||||
// a `ReturnValueInstruction`.
|
||||
// We use the `StoreInstruction` instead of the instruction that defines the
|
||||
// `ReturnValueInstruction`'s source value oprand because the former has better location information.
|
||||
// `ReturnValueInstruction`'s source value operand because the former has better location information.
|
||||
exists(StoreInstruction store |
|
||||
store.getDestinationAddress().(VariableAddressInstruction).getIRVariable() instanceof
|
||||
IRReturnVariable and
|
||||
|
||||
@@ -24,7 +24,7 @@ import semmle.code.cpp.valuenumbering.GlobalValueNumbering
|
||||
* Holds if `call` is a call to `strncat` such that `sizeArg` and `destArg` are the size and
|
||||
* destination arguments, respectively.
|
||||
*/
|
||||
predicate interestringCallWithArgs(Call call, Expr sizeArg, Expr destArg) {
|
||||
predicate interestingCallWithArgs(Call call, Expr sizeArg, Expr destArg) {
|
||||
exists(StrcatFunction strcat |
|
||||
strcat = call.getTarget() and
|
||||
sizeArg = call.getArgument(strcat.getParamSize()) and
|
||||
@@ -37,7 +37,7 @@ predicate interestringCallWithArgs(Call call, Expr sizeArg, Expr destArg) {
|
||||
* argument `destArg`, and `destArg` is the size of the buffer pointed to by `destArg`.
|
||||
*/
|
||||
predicate case1(FunctionCall fc, Expr sizeArg, VariableAccess destArg) {
|
||||
interestringCallWithArgs(fc, sizeArg, destArg) and
|
||||
interestingCallWithArgs(fc, sizeArg, destArg) and
|
||||
exists(VariableAccess va |
|
||||
va = sizeArg.(BufferSizeExpr).getArg() and
|
||||
destArg.getTarget() = va.getTarget()
|
||||
@@ -49,7 +49,7 @@ predicate case1(FunctionCall fc, Expr sizeArg, VariableAccess destArg) {
|
||||
* argument `destArg`, and `sizeArg` computes the value `sizeof (dest) - strlen (dest)`.
|
||||
*/
|
||||
predicate case2(FunctionCall fc, Expr sizeArg, VariableAccess destArg) {
|
||||
interestringCallWithArgs(fc, sizeArg, destArg) and
|
||||
interestingCallWithArgs(fc, sizeArg, destArg) and
|
||||
exists(SubExpr sub, int n |
|
||||
// The destination buffer is an array of size n
|
||||
destArg.getUnspecifiedType().(ArrayType).getSize() = n and
|
||||
|
||||
@@ -1,4 +1,4 @@
|
||||
/* '#include <stdlib.h>' was forgotton */
|
||||
/* '#include <stdlib.h>' was forgotten */
|
||||
|
||||
int main(void) {
|
||||
/* 'int malloc()' assumed */
|
||||
|
||||
@@ -26,7 +26,7 @@ where
|
||||
dest = bw.getDest() and
|
||||
destSize = getBufferSize(dest, _) and
|
||||
estimated = bw.getMaxDataLimited(reason) and
|
||||
// we exclude ValueFlowAnalysis as it is reported in cpp/very-likely-overruning-write
|
||||
// we exclude ValueFlowAnalysis as it is reported in cpp/very-likely-overrunning-write
|
||||
not reason instanceof ValueFlowAnalysis and
|
||||
// we can deduce that too much data may be copied (even without
|
||||
// long '%f' conversions)
|
||||
|
||||
@@ -31,7 +31,7 @@ predicate bounded(Expr e) {
|
||||
) and
|
||||
not convertedExprMightOverflow(e)
|
||||
or
|
||||
// Optimitically assume that a remainder expression always yields a much smaller value.
|
||||
// Optimistically assume that a remainder expression always yields a much smaller value.
|
||||
e = any(RemExpr rem).getLeftOperand()
|
||||
or
|
||||
e = any(AssignRemExpr rem).getLValue()
|
||||
@@ -44,7 +44,7 @@ predicate bounded(Expr e) {
|
||||
boundedBitwiseAnd(e, andExpr, andExpr.getAnOperand(), andExpr.getAnOperand())
|
||||
)
|
||||
or
|
||||
// Optimitically assume that a division always yields a much smaller value.
|
||||
// Optimistically assume that a division always yields a much smaller value.
|
||||
e = any(DivExpr div).getLeftOperand()
|
||||
or
|
||||
e = any(AssignDivExpr div).getLValue()
|
||||
|
||||
@@ -0,0 +1,4 @@
|
||||
---
|
||||
category: minorAnalysis
|
||||
---
|
||||
* Fixed false positives from the "Unused static function" (`cpp/unused-static-function`) query in files that had errors during compilation.
|
||||
@@ -4,7 +4,7 @@
|
||||
|
||||
* The `security` tag has been added to the `cpp/return-stack-allocated-memory` query. As a result, its results will now appear by default.
|
||||
* The "Uncontrolled data in arithmetic expression" (cpp/uncontrolled-arithmetic) query has been enhanced to reduce false positive results and its @precision increased to high.
|
||||
* A new `cpp/very-likely-overruning-write` query has been added to the default query suite for C/C++. The query reports some results that were formerly flagged by `cpp/overruning-write`.
|
||||
* A new `cpp/very-likely-overrunning-write` query has been added to the default query suite for C/C++. The query reports some results that were formerly flagged by `cpp/overrunning-write`.
|
||||
|
||||
### Minor Analysis Improvements
|
||||
|
||||
|
||||
@@ -13,6 +13,6 @@ where
|
||||
def = definitionOf(e, kind) and
|
||||
// We need to exclude definitions for elements inside template instantiations,
|
||||
// as these often lead to multiple links to definitions from the same source location.
|
||||
// LGTM does not support this bevaviour.
|
||||
// LGTM does not support this behaviour.
|
||||
not e.isFromTemplateInstantiation(_)
|
||||
select e, def, kind
|
||||
|
||||
@@ -1,7 +1,7 @@
|
||||
/**
|
||||
* @id cpp/wrong-uint-access
|
||||
* @name Wrong Uint
|
||||
* @descripion Acess an array of size lower than 256 with a uint16.
|
||||
* @description Access an array of size lower than 256 with a uint16.
|
||||
* @kind problem
|
||||
* @problem.severity recommendation
|
||||
* @tags efficiency
|
||||
@@ -21,5 +21,5 @@ where
|
||||
) and
|
||||
defLine.getArraySize() <= 256
|
||||
select useExpr,
|
||||
"Using a " + useExpr.getArrayOffset().getType() + " to acess the array $@ of size " +
|
||||
"Using a " + useExpr.getArrayOffset().getType() + " to access the array $@ of size " +
|
||||
defLine.getArraySize() + ".", var, var.getName()
|
||||
|
||||
@@ -0,0 +1,19 @@
|
||||
|
||||
int main(int argc, char** argv) {
|
||||
char *filePath = argv[2];
|
||||
|
||||
{
|
||||
// BAD: the user-controlled string is injected
|
||||
// directly into `wordexp` which performs command substitution
|
||||
|
||||
wordexp_t we;
|
||||
wordexp(filePath, &we, 0);
|
||||
}
|
||||
|
||||
{
|
||||
// GOOD: command substitution is disabled
|
||||
|
||||
wordexp_t we;
|
||||
wordexp(filePath, &we, WRDE_NOCMD);
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,42 @@
|
||||
<!DOCTYPE qhelp PUBLIC
|
||||
"-//Semmle//qhelp//EN"
|
||||
"qhelp.dtd">
|
||||
<qhelp>
|
||||
<overview>
|
||||
<p>The code passes user input to <code>wordexp</code>. This leaves the code
|
||||
vulnerable to attack by command injection, because <code>wordexp</code> performs command substitution.
|
||||
Command substitution is a feature that replaces <code>$(command)</code> or <code>`command`</code> with the
|
||||
output of the given command, allowing the user to run arbitrary code on the system.
|
||||
</p>
|
||||
|
||||
</overview>
|
||||
<recommendation>
|
||||
|
||||
<p>When calling <code>wordexp</code>, pass the <code>WRDE_NOCMD</code> flag to prevent command substitution.</p>
|
||||
|
||||
</recommendation>
|
||||
<example>
|
||||
<p>The following example passes a user-supplied file path to <code>wordexp</code> in two ways. The
|
||||
first way uses <code>wordexp</code> with no specified flags. As such, it is vulnerable to command
|
||||
injection.
|
||||
The second way uses <code>wordexp</code> with the <code>WRDE_NOCMD</code> flag. As such, no command substitution
|
||||
is performed, making this safe from command injection.</p>
|
||||
<sample src="WordexpTainted.c" />
|
||||
|
||||
</example>
|
||||
<references>
|
||||
|
||||
<li>CERT C Coding Standard:
|
||||
<a href="https://www.securecoding.cert.org/confluence/display/c/STR02-C.+Sanitize+data+passed+to+complex+subsystems">STR02-C.
|
||||
Sanitize data passed to complex subsystems</a>.</li>
|
||||
<li>
|
||||
OWASP:
|
||||
<a href="https://www.owasp.org/index.php/Command_Injection">Command Injection</a>.
|
||||
</li>
|
||||
|
||||
|
||||
<!-- LocalWords: CWE STR
|
||||
-->
|
||||
|
||||
</references>
|
||||
</qhelp>
|
||||
@@ -0,0 +1,57 @@
|
||||
/**
|
||||
* @name Uncontrolled data used in `wordexp` command
|
||||
* @description Using user-supplied data in a `wordexp` command, without
|
||||
* disabling command substitution, can make code vulnerable
|
||||
* to command injection.
|
||||
* @kind path-problem
|
||||
* @problem.severity error
|
||||
* @precision high
|
||||
* @id cpp/wordexp-injection
|
||||
* @tags security
|
||||
* external/cwe/cwe-078
|
||||
*/
|
||||
|
||||
import cpp
|
||||
import semmle.code.cpp.ir.dataflow.TaintTracking
|
||||
import semmle.code.cpp.security.FlowSources
|
||||
import DataFlow::PathGraph
|
||||
|
||||
/**
|
||||
* The `wordexp` function, which can perform command substitution.
|
||||
*/
|
||||
private class WordexpFunction extends Function {
|
||||
WordexpFunction() { hasGlobalName("wordexp") }
|
||||
}
|
||||
|
||||
/**
|
||||
* Holds if `fc` disables command substitution by containing `WRDE_NOCMD` as a flag argument.
|
||||
*/
|
||||
private predicate isCommandSubstitutionDisabled(FunctionCall fc) {
|
||||
fc.getArgument(2).getValue().toInt().bitAnd(4) = 4
|
||||
/* 4 = WRDE_NOCMD. Check whether the flag is set. */
|
||||
}
|
||||
|
||||
/**
|
||||
* A configuration to track user-supplied data to the `wordexp` function.
|
||||
*/
|
||||
class WordexpTaintConfiguration extends TaintTracking::Configuration {
|
||||
WordexpTaintConfiguration() { this = "WordexpTaintConfiguration" }
|
||||
|
||||
override predicate isSource(DataFlow::Node source) { source instanceof FlowSource }
|
||||
|
||||
override predicate isSink(DataFlow::Node sink) {
|
||||
exists(FunctionCall fc | fc.getTarget() instanceof WordexpFunction |
|
||||
fc.getArgument(0) = sink.asExpr() and
|
||||
not isCommandSubstitutionDisabled(fc)
|
||||
)
|
||||
}
|
||||
|
||||
override predicate isSanitizer(DataFlow::Node node) {
|
||||
node.asExpr().getUnspecifiedType() instanceof IntegralType
|
||||
}
|
||||
}
|
||||
|
||||
from WordexpTaintConfiguration conf, DataFlow::PathNode sourceNode, DataFlow::PathNode sinkNode
|
||||
where conf.hasFlowPath(sourceNode, sinkNode)
|
||||
select sinkNode.getNode(), sourceNode, sinkNode,
|
||||
"Using user-supplied data in a `wordexp` command, without disabling command substitution, can make code vulnerable to command injection."
|
||||
@@ -1,7 +1,7 @@
|
||||
/**
|
||||
* @name LinuxPrivilegeDroppingOutoforder
|
||||
* @description A syscall commonly associated with privilege dropping is being called out of order.
|
||||
* Normally a process drops group ID and sets supplimental groups for the target user
|
||||
* Normally a process drops group ID and sets supplemental groups for the target user
|
||||
* before setting the target user ID. This can have security impact if the return code
|
||||
* from these methods is not checked.
|
||||
* @kind problem
|
||||
|
||||
@@ -2,7 +2,7 @@
|
||||
* @name Linux kernel double-fetch vulnerability detection
|
||||
* @description Double-fetch is a very common vulnerability pattern
|
||||
* in linux kernel, attacker can exploit double-fetch
|
||||
* issues to obatain root privilege.
|
||||
* issues to obtain root privilege.
|
||||
* Double-fetch is caused by fetching data from user
|
||||
* mode by calling copy_from_user twice, CVE-2016-6480
|
||||
* is quite a good example for your information.
|
||||
|
||||
@@ -84,7 +84,7 @@ predicate isConditionBig(SwitchStmt swtmp) {
|
||||
}
|
||||
|
||||
/** Holds if there are labels inside the block with names similar to `default` or `case`. */
|
||||
predicate isWrongLableName(SwitchStmt swtmp) {
|
||||
predicate isWrongLabelName(SwitchStmt swtmp) {
|
||||
not swtmp.hasDefaultCase() and
|
||||
exists(LabelStmt lb |
|
||||
(
|
||||
@@ -147,7 +147,7 @@ where
|
||||
isConditionBig(sw) and msg = "The range of condition values is wider than the choices."
|
||||
)
|
||||
or
|
||||
isWrongLableName(sw) and msg = "Possibly erroneous label name."
|
||||
isWrongLabelName(sw) and msg = "Possibly erroneous label name."
|
||||
or
|
||||
isCodeBeforeCase(sw) and msg = "Code before case will not be executed."
|
||||
select sw, msg
|
||||
|
||||
@@ -24,7 +24,7 @@ where
|
||||
texp.getEnclosingStmt().getParentStmt*() = ts.getStmt() and
|
||||
not ts.getACatchClause().isEmpty()
|
||||
) and
|
||||
msg = "DllMain contains an exeption not wrapped in a try..catch block."
|
||||
msg = "DllMain contains an exception not wrapped in a try..catch block."
|
||||
or
|
||||
texp.getExpr().isParenthesised() and
|
||||
texp.getExpr().(CommaExpr).getLeftOperand().isConstant() and
|
||||
|
||||
4
cpp/ql/src/external/CodeDuplication.qll
vendored
4
cpp/ql/src/external/CodeDuplication.qll
vendored
@@ -292,7 +292,7 @@ deprecated predicate duplicateFiles(File f, File other, int percent) {
|
||||
}
|
||||
|
||||
/**
|
||||
* DEPRECATED: Information on duplciate classes is no longer available.
|
||||
* DEPRECATED: Information on duplicate classes is no longer available.
|
||||
*
|
||||
* Holds if most member functions of `c` (`numDup` out of `total`) are
|
||||
* duplicates of member functions in `other`.
|
||||
@@ -313,7 +313,7 @@ deprecated predicate mostlyDuplicateClassBase(Class c, Class other, int numDup,
|
||||
}
|
||||
|
||||
/**
|
||||
* DEPRECATED: Information on duplciate classes is no longer available.
|
||||
* DEPRECATED: Information on duplicate classes is no longer available.
|
||||
*
|
||||
* Holds if most member functions of `c` are duplicates of member functions in
|
||||
* `other`. Provides the human-readable `message` to describe the amount of
|
||||
|
||||
@@ -14,4 +14,4 @@ from Function f
|
||||
where
|
||||
f.fromSource() and
|
||||
f.calls+(f)
|
||||
select f, "Functions shall not call theselves, either directly or indirectly."
|
||||
select f, "Functions shall not call themselves, either directly or indirectly."
|
||||
|
||||
@@ -41,4 +41,4 @@ where
|
||||
not ae.getParent() instanceof ExprStmt and
|
||||
not ae instanceof ForStmtSideEffectExpr
|
||||
select ae,
|
||||
"AV Rule 160: An assignment expression shall be used only as the exprression in an expression statement."
|
||||
"AV Rule 160: An assignment expression shall be used only as the expression in an expression statement."
|
||||
|
||||
@@ -0,0 +1,11 @@
|
||||
edges
|
||||
| test.cpp:23:20:23:23 | argv | test.cpp:29:13:29:20 | (const char *)... |
|
||||
| test.cpp:23:20:23:23 | argv | test.cpp:29:13:29:20 | filePath |
|
||||
nodes
|
||||
| test.cpp:23:20:23:23 | argv | semmle.label | argv |
|
||||
| test.cpp:29:13:29:20 | (const char *)... | semmle.label | (const char *)... |
|
||||
| test.cpp:29:13:29:20 | filePath | semmle.label | filePath |
|
||||
subpaths
|
||||
#select
|
||||
| test.cpp:29:13:29:20 | (const char *)... | test.cpp:23:20:23:23 | argv | test.cpp:29:13:29:20 | (const char *)... | Using user-supplied data in a `wordexp` command, without disabling command substitution, can make code vulnerable to command injection. |
|
||||
| test.cpp:29:13:29:20 | filePath | test.cpp:23:20:23:23 | argv | test.cpp:29:13:29:20 | filePath | Using user-supplied data in a `wordexp` command, without disabling command substitution, can make code vulnerable to command injection. |
|
||||
@@ -0,0 +1 @@
|
||||
experimental/Security/CWE/CWE-078/WordexpTainted.ql
|
||||
@@ -0,0 +1,45 @@
|
||||
#ifdef _MSC_VER
|
||||
#define restrict __restrict
|
||||
#else
|
||||
#define restrict __restrict__
|
||||
#endif
|
||||
|
||||
typedef unsigned long size_t;
|
||||
|
||||
typedef struct {
|
||||
size_t we_wordc;
|
||||
char **we_wordv;
|
||||
size_t we_offs;
|
||||
} wordexp_t;
|
||||
|
||||
enum {
|
||||
WRDE_APPEND = (1 << 1),
|
||||
WRDE_NOCMD = (1 << 2)
|
||||
};
|
||||
|
||||
int wordexp(const char *restrict s, wordexp_t *restrict p, int flags);
|
||||
|
||||
int main(int argc, char** argv) {
|
||||
char *filePath = argv[2];
|
||||
|
||||
{
|
||||
// BAD: the user string is injected directly into `wordexp` which performs command substitution
|
||||
|
||||
wordexp_t we;
|
||||
wordexp(filePath, &we, 0);
|
||||
}
|
||||
|
||||
{
|
||||
// GOOD: command substitution is disabled
|
||||
|
||||
wordexp_t we;
|
||||
wordexp(filePath, &we, WRDE_NOCMD);
|
||||
}
|
||||
|
||||
{
|
||||
// GOOD: command substitution is disabled
|
||||
|
||||
wordexp_t we;
|
||||
wordexp(filePath, &we, WRDE_NOCMD | WRDE_APPEND);
|
||||
}
|
||||
}
|
||||
@@ -1,3 +1,3 @@
|
||||
| test.cpp:35:3:35:33 | call to runtime_error | Object creation of exception type on stack. Did you forget the throw keyword? |
|
||||
| test.cpp:41:3:41:11 | call to funcTest1 | There is an exception in the function that requires your attention. |
|
||||
| test.cpp:42:3:42:9 | call to DllMain | DllMain contains an exeption not wrapped in a try..catch block. |
|
||||
| test.cpp:42:3:42:9 | call to DllMain | DllMain contains an exception not wrapped in a try..catch block. |
|
||||
|
||||
@@ -0,0 +1,15 @@
|
||||
// semmle-extractor-options: --expect_errors
|
||||
|
||||
static void my_function1_called() {} // GOOD
|
||||
static void my_function2_called_after_error() {} // GOOD
|
||||
static void my_function3_not_called() {} // BAD [NOT DETECTED]
|
||||
|
||||
int main(void) {
|
||||
my_function1_called();
|
||||
|
||||
--- compilation stops here because this line is not valid C code ---
|
||||
|
||||
my_function2_called_after_error();
|
||||
|
||||
return 0;
|
||||
}
|
||||
@@ -33,3 +33,16 @@ static void f6(void);
|
||||
static void f5(void) { f6(); }
|
||||
static void f6(void) { f5(); }
|
||||
|
||||
// f7 and f8 are reachable from `function_caller`
|
||||
static int f7() { return 1; } // GOOD
|
||||
static void f8() { } // GOOD
|
||||
|
||||
void function_caller()
|
||||
{
|
||||
auto my_lambda = []() {
|
||||
return f7();
|
||||
}();
|
||||
|
||||
f8();
|
||||
}
|
||||
|
||||
|
||||
@@ -218,7 +218,7 @@ namespace Semmle.Extraction.CIL
|
||||
public PdbSourceFile CreateSourceFile(PDB.ISourceFile file) => sourceFiles[file];
|
||||
|
||||
/// <summary>
|
||||
/// Creates a folder entitiy with the given path.
|
||||
/// Creates a folder entity with the given path.
|
||||
/// </summary>
|
||||
/// <param name="path">The path of the folder.</param>
|
||||
/// <returns>A folder entity.</returns>
|
||||
|
||||
@@ -5,7 +5,7 @@ namespace Semmle.Extraction.CIL
|
||||
{
|
||||
/// <summary>
|
||||
/// An entity that has contents to extract. There is no need to populate
|
||||
/// a key as it's done in the contructor.
|
||||
/// a key as it's done in the constructor.
|
||||
/// </summary>
|
||||
internal abstract class UnlabelledEntity : Extraction.UnlabelledEntity, IExtractedEntity
|
||||
{
|
||||
|
||||
@@ -1,7 +1,7 @@
|
||||
namespace Semmle.Extraction.CIL.Entities
|
||||
{
|
||||
/// <summary>
|
||||
/// An entity represting a member.
|
||||
/// An entity representing a member.
|
||||
/// Used to type tuples correctly.
|
||||
/// </summary>
|
||||
internal interface IMember : IExtractedEntity
|
||||
|
||||
@@ -66,7 +66,7 @@ namespace Semmle.Extraction.CSharp.Entities
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// The location which is stored in the database and is used when highlighing source code.
|
||||
/// The location which is stored in the database and is used when highlighting source code.
|
||||
/// It's generally short, e.g. a method name.
|
||||
/// </summary>
|
||||
public override Microsoft.CodeAnalysis.Location? ReportingLocation => Symbol.Locations.FirstOrDefault();
|
||||
|
||||
@@ -42,7 +42,7 @@ namespace Semmle.Extraction.CSharp.Entities
|
||||
}
|
||||
else
|
||||
{
|
||||
Context.ModelError(Symbol, $"Undhandled event accessor kind {Symbol.ToDisplayString()}");
|
||||
Context.ModelError(Symbol, $"Unhandled event accessor kind {Symbol.ToDisplayString()}");
|
||||
return;
|
||||
}
|
||||
|
||||
|
||||
@@ -74,7 +74,7 @@ namespace Semmle.Extraction.CSharp.Entities
|
||||
bool IExpressionParentEntity.IsTopLevelParent => false;
|
||||
|
||||
/// <summary>
|
||||
/// Gets a string represention of a constant value.
|
||||
/// Gets a string representation of a constant value.
|
||||
/// </summary>
|
||||
/// <param name="obj">The value.</param>
|
||||
/// <returns>The string representation.</returns>
|
||||
|
||||
@@ -23,7 +23,7 @@ namespace Semmle.Extraction.CSharp.Entities
|
||||
trapFile.modifiers(Label, Symbol);
|
||||
}
|
||||
|
||||
public static string AccessbilityModifier(Accessibility access)
|
||||
public static string AccessibilityModifier(Accessibility access)
|
||||
{
|
||||
switch (access)
|
||||
{
|
||||
@@ -48,7 +48,7 @@ namespace Semmle.Extraction.CSharp.Entities
|
||||
case Accessibility.Public:
|
||||
case Accessibility.Protected:
|
||||
case Accessibility.Internal:
|
||||
HasModifier(cx, trapFile, type, Modifier.AccessbilityModifier(access));
|
||||
HasModifier(cx, trapFile, type, Modifier.AccessibilityModifier(access));
|
||||
break;
|
||||
case Accessibility.NotApplicable:
|
||||
break;
|
||||
@@ -131,7 +131,7 @@ namespace Semmle.Extraction.CSharp.Entities
|
||||
|
||||
public static Modifier Create(Context cx, Accessibility access)
|
||||
{
|
||||
var modifier = AccessbilityModifier(access);
|
||||
var modifier = AccessibilityModifier(access);
|
||||
return ModifierFactory.Instance.CreateEntity(cx, (typeof(Modifier), modifier), modifier);
|
||||
}
|
||||
|
||||
|
||||
@@ -10,7 +10,7 @@ namespace Semmle.Extraction.CSharp
|
||||
{
|
||||
/// <summary>
|
||||
/// An ITypeSymbol with nullability annotations.
|
||||
/// Although a similar class has been implemented in Rolsyn,
|
||||
/// Although a similar class has been implemented in Roslyn,
|
||||
/// https://github.com/dotnet/roslyn/blob/090e52e27c38ad8f1ea4d033114c2a107604ddaa/src/Compilers/CSharp/Portable/Symbols/TypeWithAnnotations.cs
|
||||
/// it is an internal struct that has not yet been exposed on the public interface.
|
||||
/// </summary>
|
||||
@@ -80,8 +80,8 @@ namespace Semmle.Extraction.CSharp
|
||||
public static IEnumerable<string> GetSourceLevelModifiers(this ISymbol symbol)
|
||||
{
|
||||
var methodModifiers = symbol.GetModifiers<Microsoft.CodeAnalysis.CSharp.Syntax.BaseMethodDeclarationSyntax>(md => md.Modifiers);
|
||||
var typeModifers = symbol.GetModifiers<Microsoft.CodeAnalysis.CSharp.Syntax.TypeDeclarationSyntax>(cd => cd.Modifiers);
|
||||
return methodModifiers.Concat(typeModifers).Select(m => m.Text);
|
||||
var typeModifiers = symbol.GetModifiers<Microsoft.CodeAnalysis.CSharp.Syntax.TypeDeclarationSyntax>(cd => cd.Modifiers);
|
||||
return methodModifiers.Concat(typeModifiers).Select(m => m.Text);
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
|
||||
@@ -26,7 +26,7 @@ namespace Semmle.Extraction
|
||||
Label Label { get; set; }
|
||||
|
||||
/// <summary>
|
||||
/// Writes the unique identifier of this entitiy to a trap file.
|
||||
/// Writes the unique identifier of this entity to a trap file.
|
||||
/// </summary>
|
||||
/// <param name="trapFile">The trapfile to write to.</param>
|
||||
void WriteId(EscapingTextWriter trapFile);
|
||||
|
||||
@@ -8,7 +8,7 @@ namespace Semmle.Util
|
||||
/// Create an enumerable with a single element.
|
||||
/// </summary>
|
||||
///
|
||||
/// <typeparam name="T">The type of the enumerble/element.</typeparam>
|
||||
/// <typeparam name="T">The type of the enumerable/element.</typeparam>
|
||||
/// <param name="t">The element.</param>
|
||||
/// <returns>An enumerable containing a single element.</returns>
|
||||
public static IEnumerable<T> Singleton<T>(T t)
|
||||
|
||||
@@ -17,7 +17,7 @@ namespace Semmle.Util
|
||||
/// The algorithm locates the closest match to a string based on a "distance function".
|
||||
///
|
||||
/// Whilst many distance functions are possible, a bespoke algorithm is used here,
|
||||
/// for efficiency and suitablility for the domain.
|
||||
/// for efficiency and suitability for the domain.
|
||||
///
|
||||
/// The distance is defined as the Hamming Distance of the numbers in the string.
|
||||
/// Each string is split into the base "form" (stripped of numbers) and a vector of
|
||||
|
||||
@@ -1,5 +1,5 @@
|
||||
lgtm,codescanning
|
||||
* Inferring the lengths of implicitely sized arrays is fixed. Previously, multi
|
||||
* Inferring the lengths of implicitly sized arrays is fixed. Previously, multi
|
||||
dimensional arrays were always extracted with the same length for each dimension.
|
||||
With the fix, the array sizes `2` and `1` are extracted for `new int[,]{{1},{2}}`.
|
||||
Previously `2` and `2` were extracted.
|
||||
|
||||
@@ -124,7 +124,7 @@ string solorigateSuspiciousLiterals() {
|
||||
"fc00::", "fe00::", "fec0::", "ffc0::", "ff00::", "HKCC", "HKCR", "HKCU", "HKDD",
|
||||
"HKEY_CLASSES_ROOT", "HKEY_CURRENT_CONFIG", "HKEY_CURRENT_USER", "HKEY_DYN_DATA",
|
||||
"HKEY_LOCAL_MACHINE", "HKEY_LOCAL_MACHINE\\SOFTWARE\\Microsoft\\Cryptography",
|
||||
"HKEY_PERFOMANCE_DATA", "HKEY_USERS", "HKLM", "HKPD", "HKU", "If-None-Match",
|
||||
"HKEY_PERFORMANCE_DATA", "HKEY_USERS", "HKLM", "HKPD", "HKU", "If-None-Match",
|
||||
"Microsoft-CryptoAPI/", "Nodes", "Volumes", "Interfaces", "Components", "opensans",
|
||||
"Organization", "OSArchitecture", "ParentProcessID", "PathName", "ReportWatcherPostpone",
|
||||
"ReportWatcherRetry", "S-1-5-", "SeRestorePrivilege", "SeShutdownPrivilege",
|
||||
|
||||
@@ -10,7 +10,9 @@ import csharp
|
||||
private import DataFlow
|
||||
private import semmle.code.csharp.dataflow.TaintTracking2
|
||||
|
||||
predicate maybeANonCryptogrphicHash(Callable callable, Variable v, Expr xor, Expr mul, LoopStmt loop) {
|
||||
predicate maybeANonCryptographicHash(
|
||||
Callable callable, Variable v, Expr xor, Expr mul, LoopStmt loop
|
||||
) {
|
||||
callable = loop.getEnclosingCallable() and
|
||||
(
|
||||
maybeUsedInFnvFunction(v, xor, mul, loop) or
|
||||
@@ -75,7 +77,7 @@ private predicate maybeUsedInElfHashFunction(Variable v, Operation xor, Operatio
|
||||
*/
|
||||
predicate isCallableAPotentialNonCryptographicHashFunction(Callable callable, Parameter param) {
|
||||
exists(Variable v, Expr op1, Expr op2, LoopStmt loop |
|
||||
maybeANonCryptogrphicHash(callable, v, op1, op2, loop) and
|
||||
maybeANonCryptographicHash(callable, v, op1, op2, loop) and
|
||||
callable.getAParameter() = param and
|
||||
exists(ParameterNode p, ExprNode n |
|
||||
p.getParameter() = param and
|
||||
|
||||
@@ -20,16 +20,18 @@ class DataFlowNode extends @cil_dataflow_node {
|
||||
* Holds if this node flows to `sink` in one step.
|
||||
* `tt` is the tainting that occurs during this step.
|
||||
*/
|
||||
predicate getALocalFlowSucc(DataFlowNode sink, TaintType tt) {
|
||||
deprecated predicate getALocalFlowSucc(DataFlowNode sink, TaintType tt) {
|
||||
localExactStep(this, sink) and tt = TExactValue()
|
||||
or
|
||||
localTaintStep(this, sink) and tt = TTaintedValue()
|
||||
}
|
||||
|
||||
private predicate flowsToStep(DataFlowNode sink) { this.getALocalFlowSucc(sink, TExactValue()) }
|
||||
deprecated private predicate flowsToStep(DataFlowNode sink) {
|
||||
this.getALocalFlowSucc(sink, TExactValue())
|
||||
}
|
||||
|
||||
/** Holds if this node flows to `sink` in zero or more steps. */
|
||||
predicate flowsTo(DataFlowNode sink) { this.flowsToStep*(sink) }
|
||||
deprecated predicate flowsTo(DataFlowNode sink) { this.flowsToStep*(sink) }
|
||||
|
||||
/** Gets the method that contains this dataflow node. */
|
||||
Method getMethod() { none() }
|
||||
@@ -38,12 +40,12 @@ class DataFlowNode extends @cil_dataflow_node {
|
||||
Location getLocation() { none() }
|
||||
}
|
||||
|
||||
private newtype TTaintType =
|
||||
deprecated private newtype TTaintType =
|
||||
TExactValue() or
|
||||
TTaintedValue()
|
||||
|
||||
/** Describes how data is tainted. */
|
||||
class TaintType extends TTaintType {
|
||||
deprecated class TaintType extends TTaintType {
|
||||
string toString() {
|
||||
this = TExactValue() and result = "exact"
|
||||
or
|
||||
@@ -52,12 +54,12 @@ class TaintType extends TTaintType {
|
||||
}
|
||||
|
||||
/** A taint type where the data is untainted. */
|
||||
class Untainted extends TaintType, TExactValue { }
|
||||
deprecated class Untainted extends TaintType, TExactValue { }
|
||||
|
||||
/** A taint type where the data is tainted. */
|
||||
class Tainted extends TaintType, TTaintedValue { }
|
||||
deprecated class Tainted extends TaintType, TTaintedValue { }
|
||||
|
||||
private predicate localFlowPhiInput(DataFlowNode input, Ssa::PhiNode phi) {
|
||||
deprecated private predicate localFlowPhiInput(DataFlowNode input, Ssa::PhiNode phi) {
|
||||
exists(Ssa::Definition def, BasicBlock bb, int i | phi.hasLastInputRef(def, bb, i) |
|
||||
def.definesAt(_, bb, i) and
|
||||
input = def.getVariableUpdate().getSource()
|
||||
@@ -76,7 +78,7 @@ private predicate localFlowPhiInput(DataFlowNode input, Ssa::PhiNode phi) {
|
||||
)
|
||||
}
|
||||
|
||||
private predicate localExactStep(DataFlowNode src, DataFlowNode sink) {
|
||||
deprecated private predicate localExactStep(DataFlowNode src, DataFlowNode sink) {
|
||||
src = sink.(Opcodes::Dup).getAnOperand()
|
||||
or
|
||||
exists(Ssa::Definition def, VariableUpdate vu |
|
||||
@@ -103,7 +105,7 @@ private predicate localExactStep(DataFlowNode src, DataFlowNode sink) {
|
||||
src = sink.(ConditionalBranch).getAnOperand()
|
||||
}
|
||||
|
||||
private predicate localTaintStep(DataFlowNode src, DataFlowNode sink) {
|
||||
deprecated private predicate localTaintStep(DataFlowNode src, DataFlowNode sink) {
|
||||
src = sink.(BinaryArithmeticExpr).getAnOperand() or
|
||||
src = sink.(Opcodes::Neg).getOperand() or
|
||||
src = sink.(UnaryBitwiseOperation).getOperand()
|
||||
|
||||
@@ -270,7 +270,7 @@ class Setter extends Accessor {
|
||||
*/
|
||||
class TrivialSetter extends Method {
|
||||
TrivialSetter() {
|
||||
exists(MethodImplementation impl | impl = this.getImplementation() |
|
||||
exists(MethodImplementation impl | impl = this.getAnImplementation() |
|
||||
impl.getInstruction(0) instanceof ThisAccess and
|
||||
impl.getInstruction(1).(ParameterReadAccess).getTarget().getIndex() = 1 and
|
||||
impl.getInstruction(2) instanceof FieldWriteAccess
|
||||
|
||||
@@ -24,10 +24,10 @@ module Ssa {
|
||||
}
|
||||
|
||||
/** Gets a first read of this SSA definition. */
|
||||
final ReadAccess getAFirstRead() { result = SsaImpl::getAFirstRead(this) }
|
||||
deprecated final ReadAccess getAFirstRead() { result = SsaImpl::getAFirstRead(this) }
|
||||
|
||||
/** Holds if `first` and `second` are adjacent reads of this SSA definition. */
|
||||
final predicate hasAdjacentReads(ReadAccess first, ReadAccess second) {
|
||||
deprecated final predicate hasAdjacentReads(ReadAccess first, ReadAccess second) {
|
||||
SsaImpl::hasAdjacentReads(this, first, second)
|
||||
}
|
||||
|
||||
@@ -58,8 +58,9 @@ module Ssa {
|
||||
* index `i` in basic block `bb` can reach this phi node without going through
|
||||
* other references.
|
||||
*/
|
||||
final predicate hasLastInputRef(Definition def, BasicBlock bb, int i) {
|
||||
SsaImpl::hasLastInputRef(this, def, bb, i)
|
||||
deprecated final predicate hasLastInputRef(Definition def, BasicBlock bb, int i) {
|
||||
SsaImpl::lastRefRedef(def, bb, i, this) and
|
||||
def = SsaImpl::getAPhiInput(this)
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -29,14 +29,17 @@ private module Cached {
|
||||
|
||||
cached
|
||||
predicate bestImplementation(MethodImplementation mi) {
|
||||
not assemblyIsStubImpl(mi.getLocation()) and
|
||||
not exists(MethodImplementation better | mi.getMethod() = better.getMethod() |
|
||||
mi.getNumberOfInstructions() < better.getNumberOfInstructions()
|
||||
or
|
||||
mi.getNumberOfInstructions() = better.getNumberOfInstructions() and
|
||||
mi.getLocation().getFile().toString() > better.getLocation().getFile().toString()
|
||||
) and
|
||||
exists(mi.getAnInstruction())
|
||||
exists(Assembly asm |
|
||||
asm = mi.getLocation() and
|
||||
(assemblyIsStubImpl(asm) implies asm.getFile().extractedQlTest()) and
|
||||
not exists(MethodImplementation better | mi.getMethod() = better.getMethod() |
|
||||
mi.getNumberOfInstructions() < better.getNumberOfInstructions()
|
||||
or
|
||||
mi.getNumberOfInstructions() = better.getNumberOfInstructions() and
|
||||
asm.getFile().toString() > better.getLocation().getFile().toString()
|
||||
) and
|
||||
exists(mi.getAnInstruction())
|
||||
)
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
@@ -68,9 +68,8 @@ private module Cached {
|
||||
Definition getAPhiInput(PhiNode phi) { phiHasInputFromBlock(phi, result, _) }
|
||||
|
||||
cached
|
||||
predicate hasLastInputRef(Definition phi, Definition def, BasicBlock bb, int i) {
|
||||
lastRefRedef(def, bb, i, phi) and
|
||||
def = getAPhiInput(phi)
|
||||
predicate lastRefBeforeRedef(Definition def, BasicBlock bb, int i, Definition next) {
|
||||
lastRefRedef(def, bb, i, next)
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
@@ -191,7 +191,7 @@ private module Annotations {
|
||||
NoNullability() { not nullability_parent(_, _, nullability) }
|
||||
}
|
||||
|
||||
/** A type with annotated nullablity, `?`. */
|
||||
/** A type with annotated nullability, `?`. */
|
||||
class AnnotatedNullability extends Nullability {
|
||||
AnnotatedNullability() { nullability instanceof @annotated }
|
||||
|
||||
|
||||
@@ -111,6 +111,7 @@ class AssignableRead extends AssignableAccess {
|
||||
* - The reads of `i` on lines 7 and 8 are next to the read on line 6.
|
||||
* - The read of `this.Field` on line 11 is next to the read on line 10.
|
||||
*/
|
||||
pragma[nomagic]
|
||||
AssignableRead getANextRead() {
|
||||
forex(ControlFlow::Node cfn | cfn = result.getAControlFlowNode() |
|
||||
cfn = this.getAnAdjacentReadSameVar()
|
||||
@@ -124,7 +125,7 @@ class AssignableRead extends AssignableAccess {
|
||||
*
|
||||
* This is the transitive closure of `getANextRead()`.
|
||||
*/
|
||||
AssignableRead getAReachableRead() { result = this.getANextRead+() }
|
||||
deprecated AssignableRead getAReachableRead() { result = this.getANextRead+() }
|
||||
}
|
||||
|
||||
/**
|
||||
@@ -479,6 +480,7 @@ class AssignableDefinition extends TAssignableDefinition {
|
||||
* Subsequent reads can be found by following the steps defined by
|
||||
* `AssignableRead.getANextRead()`.
|
||||
*/
|
||||
pragma[nomagic]
|
||||
AssignableRead getAFirstRead() {
|
||||
forex(ControlFlow::Node cfn | cfn = result.getAControlFlowNode() |
|
||||
exists(Ssa::ExplicitDefinition def | result = def.getAFirstReadAtNode(cfn) |
|
||||
@@ -494,7 +496,7 @@ class AssignableDefinition extends TAssignableDefinition {
|
||||
*
|
||||
* This is the equivalent with `getAFirstRead().getANextRead*()`.
|
||||
*/
|
||||
AssignableRead getAReachableRead() { result = this.getAFirstRead().getANextRead*() }
|
||||
deprecated AssignableRead getAReachableRead() { result = this.getAFirstRead().getANextRead*() }
|
||||
|
||||
/** Gets a textual representation of this assignable definition. */
|
||||
string toString() { none() }
|
||||
|
||||
@@ -517,7 +517,7 @@ predicate convNullableType(ValueOrRefType fromType, NullableType toType) {
|
||||
/**
|
||||
* Holds if `fromType` is `NullType`, and `toType` is a type that can represent
|
||||
* the `null` value, such as a reference type, `Nullable<T>` or a type parameter
|
||||
* with contraints that restrict it to a reference type.
|
||||
* with constraints that restrict it to a reference type.
|
||||
*/
|
||||
// This is a deliberate, small Cartesian product, so we have manually lifted it to force the
|
||||
// evaluator to evaluate it in its entirety, rather than trying to optimize it in context.
|
||||
|
||||
Some files were not shown because too many files have changed in this diff Show More
Reference in New Issue
Block a user