mirror of
https://github.com/github/codeql.git
synced 2026-04-30 11:15:13 +02:00
Merge branch 'replace-ast-with-ir-use-usedataflow' into repair-badly-bounded-write-2
This commit is contained in:
13
.github/workflows/atm-check-queries-run.yml
vendored
Normal file
13
.github/workflows/atm-check-queries-run.yml
vendored
Normal file
@@ -0,0 +1,13 @@
|
||||
name: ATM Check Queries Run
|
||||
|
||||
# This check is required, therefore we must run it on all PRs, even if only Markdown has changed.
|
||||
on:
|
||||
workflow_dispatch:
|
||||
|
||||
jobs:
|
||||
hello-world:
|
||||
runs-on: ubuntu-latest
|
||||
|
||||
steps:
|
||||
- name: foo
|
||||
run: echo "Hello world"
|
||||
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
|
||||
|
||||
16
.github/workflows/swift-qltest.yml
vendored
16
.github/workflows/swift-qltest.yml
vendored
@@ -23,16 +23,30 @@ jobs:
|
||||
- uses: ./.github/actions/fetch-codeql
|
||||
- name: Check QL formatting
|
||||
run: find ql "(" -name "*.ql" -or -name "*.qll" ")" -print0 | xargs -0 codeql query format --check-only
|
||||
qltest-test:
|
||||
runs-on: ubuntu-latest
|
||||
steps:
|
||||
- uses: actions/checkout@v3
|
||||
- uses: bazelbuild/setup-bazelisk@v2
|
||||
- uses: actions/setup-python@v4
|
||||
with:
|
||||
python-version-file: 'swift/.python-version'
|
||||
- name: Test qltest.sh
|
||||
run: |
|
||||
bazel test //swift/tools/test/qltest
|
||||
qltest:
|
||||
runs-on: ${{ matrix.os }}
|
||||
strategy:
|
||||
fail-fast: false
|
||||
matrix:
|
||||
os : [ubuntu-20.04, macos-latest]
|
||||
os: [ ubuntu-20.04, macos-latest ]
|
||||
steps:
|
||||
- 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
|
||||
|
||||
@@ -1,3 +1,7 @@
|
||||
## 0.4.2
|
||||
|
||||
No user-facing changes.
|
||||
|
||||
## 0.4.1
|
||||
|
||||
No user-facing changes.
|
||||
|
||||
3
cpp/ql/lib/change-notes/released/0.4.2.md
Normal file
3
cpp/ql/lib/change-notes/released/0.4.2.md
Normal file
@@ -0,0 +1,3 @@
|
||||
## 0.4.2
|
||||
|
||||
No user-facing changes.
|
||||
@@ -1,2 +1,2 @@
|
||||
---
|
||||
lastReleaseVersion: 0.4.1
|
||||
lastReleaseVersion: 0.4.2
|
||||
|
||||
@@ -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 @@
|
||||
name: codeql/cpp-all
|
||||
version: 0.4.2-dev
|
||||
version: 0.4.3-dev
|
||||
groups: cpp
|
||||
dbscheme: semmlecode.cpp.dbscheme
|
||||
extractor: cpp
|
||||
|
||||
@@ -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.
|
||||
|
||||
@@ -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()
|
||||
|
||||
@@ -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,
|
||||
|
||||
@@ -371,6 +371,21 @@ predicate ssaFlow(Node nodeFrom, Node nodeTo) {
|
||||
)
|
||||
}
|
||||
|
||||
/**
|
||||
* Holds if `use` is a use of `sv` and is a next adjacent use of `phi` in
|
||||
* index `i1` in basic block `bb1`.
|
||||
*
|
||||
* This predicate exists to prevent an early join of `adjacentDefRead` with `definesAt`.
|
||||
*/
|
||||
pragma[nomagic]
|
||||
private predicate fromPhiNodeToUse(PhiNode phi, SourceVariable sv, IRBlock bb1, int i1, UseOrPhi use) {
|
||||
exists(IRBlock bb2, int i2 |
|
||||
use.asDefOrUse().hasIndexInBlock(bb2, i2, sv) and
|
||||
adjacentDefRead(pragma[only_bind_into](phi), pragma[only_bind_into](bb1),
|
||||
pragma[only_bind_into](i1), pragma[only_bind_into](bb2), pragma[only_bind_into](i2))
|
||||
)
|
||||
}
|
||||
|
||||
/** Holds if `nodeTo` receives flow from the phi node `nodeFrom`. */
|
||||
predicate fromPhiNode(SsaPhiNode nodeFrom, Node nodeTo) {
|
||||
exists(PhiNode phi, SourceVariable sv, IRBlock bb1, int i1, UseOrPhi use |
|
||||
@@ -378,10 +393,7 @@ predicate fromPhiNode(SsaPhiNode nodeFrom, Node nodeTo) {
|
||||
phi.definesAt(sv, bb1, i1) and
|
||||
useToNode(use, nodeTo)
|
||||
|
|
||||
exists(IRBlock bb2, int i2 |
|
||||
use.asDefOrUse().hasIndexInBlock(bb2, i2, sv) and
|
||||
adjacentDefRead(phi, bb1, i1, bb2, i2)
|
||||
)
|
||||
fromPhiNodeToUse(phi, sv, bb1, i1, use)
|
||||
or
|
||||
exists(PhiNode phiTo |
|
||||
lastRefRedef(phi, _, _, phiTo) and
|
||||
|
||||
@@ -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.
|
||||
*/
|
||||
|
||||
@@ -6,6 +6,7 @@ import cpp
|
||||
import semmle.code.cpp.ir.dataflow.DataFlow
|
||||
private import semmle.code.cpp.ir.IR
|
||||
import semmle.code.cpp.models.interfaces.FlowSource
|
||||
private import semmle.code.cpp.ir.dataflow.internal.ModelUtil
|
||||
|
||||
/** A data flow source of user input, whether local or remote. */
|
||||
abstract class FlowSource extends DataFlow::Node {
|
||||
@@ -19,68 +20,28 @@ abstract class RemoteFlowSource extends FlowSource { }
|
||||
/** A data flow source of local user input. */
|
||||
abstract class LocalFlowSource extends FlowSource { }
|
||||
|
||||
private class RemoteReturnSource extends RemoteFlowSource {
|
||||
private class RemoteModelSource extends RemoteFlowSource {
|
||||
string sourceType;
|
||||
|
||||
RemoteReturnSource() {
|
||||
exists(RemoteFlowSourceFunction func, CallInstruction instr, FunctionOutput output |
|
||||
this.asInstruction() = instr and
|
||||
instr.getStaticCallTarget() = func and
|
||||
RemoteModelSource() {
|
||||
exists(CallInstruction call, RemoteFlowSourceFunction func, FunctionOutput output |
|
||||
call.getStaticCallTarget() = func and
|
||||
func.hasRemoteFlowSource(output, sourceType) and
|
||||
(
|
||||
output.isReturnValue()
|
||||
or
|
||||
output.isReturnValueDeref()
|
||||
)
|
||||
this = callOutput(call, output)
|
||||
)
|
||||
}
|
||||
|
||||
override string getSourceType() { result = sourceType }
|
||||
}
|
||||
|
||||
private class RemoteParameterSource extends RemoteFlowSource {
|
||||
private class LocalModelSource extends LocalFlowSource {
|
||||
string sourceType;
|
||||
|
||||
RemoteParameterSource() {
|
||||
exists(RemoteFlowSourceFunction func, WriteSideEffectInstruction instr, FunctionOutput output |
|
||||
this.asInstruction() = instr and
|
||||
instr.getPrimaryInstruction().(CallInstruction).getStaticCallTarget() = func and
|
||||
func.hasRemoteFlowSource(output, sourceType) and
|
||||
output.isParameterDerefOrQualifierObject(instr.getIndex())
|
||||
)
|
||||
}
|
||||
|
||||
override string getSourceType() { result = sourceType }
|
||||
}
|
||||
|
||||
private class LocalReturnSource extends LocalFlowSource {
|
||||
string sourceType;
|
||||
|
||||
LocalReturnSource() {
|
||||
exists(LocalFlowSourceFunction func, CallInstruction instr, FunctionOutput output |
|
||||
this.asInstruction() = instr and
|
||||
instr.getStaticCallTarget() = func and
|
||||
LocalModelSource() {
|
||||
exists(CallInstruction call, LocalFlowSourceFunction func, FunctionOutput output |
|
||||
call.getStaticCallTarget() = func and
|
||||
func.hasLocalFlowSource(output, sourceType) and
|
||||
(
|
||||
output.isReturnValue()
|
||||
or
|
||||
output.isReturnValueDeref()
|
||||
)
|
||||
)
|
||||
}
|
||||
|
||||
override string getSourceType() { result = sourceType }
|
||||
}
|
||||
|
||||
private class LocalParameterSource extends LocalFlowSource {
|
||||
string sourceType;
|
||||
|
||||
LocalParameterSource() {
|
||||
exists(LocalFlowSourceFunction func, WriteSideEffectInstruction instr, FunctionOutput output |
|
||||
this.asInstruction() = instr and
|
||||
instr.getPrimaryInstruction().(CallInstruction).getStaticCallTarget() = func and
|
||||
func.hasLocalFlowSource(output, sourceType) and
|
||||
output.isParameterDerefOrQualifierObject(instr.getIndex())
|
||||
this = callOutput(call, output)
|
||||
)
|
||||
}
|
||||
|
||||
@@ -109,18 +70,10 @@ private class RemoteParameterSink extends RemoteFlowSink {
|
||||
string sourceType;
|
||||
|
||||
RemoteParameterSink() {
|
||||
exists(RemoteFlowSinkFunction func, FunctionInput input, CallInstruction call, int index |
|
||||
func.hasRemoteFlowSink(input, sourceType) and call.getStaticCallTarget() = func
|
||||
|
|
||||
exists(ReadSideEffectInstruction read |
|
||||
call = read.getPrimaryInstruction() and
|
||||
read.getIndex() = index and
|
||||
this.asOperand() = read.getSideEffectOperand() and
|
||||
input.isParameterDerefOrQualifierObject(index)
|
||||
)
|
||||
or
|
||||
input.isParameterOrQualifierAddress(index) and
|
||||
this.asOperand() = call.getArgumentOperand(index)
|
||||
exists(CallInstruction call, RemoteFlowSinkFunction func, FunctionInput input |
|
||||
call.getStaticCallTarget() = func and
|
||||
func.hasRemoteFlowSink(input, sourceType) and
|
||||
this = callInput(call, input)
|
||||
)
|
||||
}
|
||||
|
||||
|
||||
@@ -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) {
|
||||
|
||||
@@ -1,3 +1,14 @@
|
||||
## 0.4.2
|
||||
|
||||
### New Queries
|
||||
|
||||
* Added a new medium-precision query, `cpp/comma-before-misleading-indentation`, which detects instances of whitespace that have readability issues.
|
||||
|
||||
### Minor Analysis Improvements
|
||||
|
||||
* The "Unterminated variadic call" (`cpp/unterminated-variadic-call`) query has been tuned to produce fewer false positive results.
|
||||
* Fixed false positives from the "Unused static function" (`cpp/unused-static-function`) query in files that had errors during compilation.
|
||||
|
||||
## 0.4.1
|
||||
|
||||
### Minor Analysis Improvements
|
||||
@@ -125,7 +136,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) {
|
||||
|
||||
@@ -55,14 +55,20 @@ predicate underscoreMacro(Expr e) {
|
||||
/**
|
||||
* Holds if `t` cannot hold a character array, directly or indirectly.
|
||||
*/
|
||||
predicate cannotContainString(Type t) {
|
||||
t.getUnspecifiedType() instanceof BuiltInType
|
||||
or
|
||||
t.getUnspecifiedType() instanceof IntegralOrEnumType
|
||||
predicate cannotContainString(Type t, boolean isIndirect) {
|
||||
isIndirect = false and
|
||||
(
|
||||
t.getUnspecifiedType() instanceof BuiltInType or
|
||||
t.getUnspecifiedType() instanceof IntegralOrEnumType
|
||||
)
|
||||
}
|
||||
|
||||
predicate isNonConst(DataFlow::Node node) {
|
||||
exists(Expr e | e = node.asExpr() |
|
||||
predicate isNonConst(DataFlow::Node node, boolean isIndirect) {
|
||||
exists(Expr e |
|
||||
e = node.asExpr() and isIndirect = false
|
||||
or
|
||||
e = node.asIndirectExpr() and isIndirect = true
|
||||
|
|
||||
exists(FunctionCall fc | fc = e |
|
||||
not (
|
||||
whitelistFunction(fc.getTarget(), _) or
|
||||
@@ -106,22 +112,28 @@ predicate isNonConst(DataFlow::Node node) {
|
||||
)
|
||||
)
|
||||
or
|
||||
node instanceof DataFlow::DefinitionByReferenceNode
|
||||
node instanceof DataFlow::DefinitionByReferenceNode and
|
||||
isIndirect = true
|
||||
}
|
||||
|
||||
pragma[noinline]
|
||||
predicate isSanitizerNode(DataFlow::Node node) {
|
||||
underscoreMacro(node.asExpr())
|
||||
or
|
||||
cannotContainString(node.getType())
|
||||
not exists(node.asIndirectExpr()) and
|
||||
not exists(node.asDefiningArgument()) and
|
||||
cannotContainString(node.getType(), false)
|
||||
}
|
||||
|
||||
class NonConstFlow extends TaintTracking::Configuration {
|
||||
NonConstFlow() { this = "NonConstFlow" }
|
||||
|
||||
override predicate isSource(DataFlow::Node source) {
|
||||
isNonConst(source) and
|
||||
not cannotContainString(source.getType())
|
||||
exists(boolean isIndirect, Type t |
|
||||
isNonConst(source, isIndirect) and
|
||||
t = source.getType() and
|
||||
not cannotContainString(t, isIndirect)
|
||||
)
|
||||
}
|
||||
|
||||
override predicate isSink(DataFlow::Node sink) {
|
||||
|
||||
@@ -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 */
|
||||
|
||||
@@ -24,15 +24,6 @@ import semmle.code.cpp.security.FlowSources
|
||||
import semmle.code.cpp.models.implementations.Strcat
|
||||
import DataFlow::PathGraph
|
||||
|
||||
Expr sinkAsArgumentIndirection(DataFlow::Node sink) {
|
||||
result =
|
||||
sink.asOperand()
|
||||
.(SideEffectOperand)
|
||||
.getAddressOperand()
|
||||
.getAnyDef()
|
||||
.getUnconvertedResultExpression()
|
||||
}
|
||||
|
||||
/**
|
||||
* Holds if `fst` is a string that is used in a format or concatenation function resulting in `snd`,
|
||||
* and is *not* placed at the start of the resulting string. This indicates that the author did not
|
||||
@@ -41,7 +32,7 @@ Expr sinkAsArgumentIndirection(DataFlow::Node sink) {
|
||||
*/
|
||||
predicate interestingConcatenation(DataFlow::Node fst, DataFlow::Node snd) {
|
||||
exists(FormattingFunctionCall call, int index, FormatLiteral literal |
|
||||
sinkAsArgumentIndirection(fst) = call.getConversionArgument(index) and
|
||||
fst.asIndirectArgument() = call.getConversionArgument(index) and
|
||||
snd.asDefiningArgument() = call.getOutputArgument(false) and
|
||||
literal = call.getFormat() and
|
||||
not literal.getConvSpecOffset(index) = 0 and
|
||||
@@ -49,21 +40,18 @@ predicate interestingConcatenation(DataFlow::Node fst, DataFlow::Node snd) {
|
||||
)
|
||||
or
|
||||
// strcat and friends
|
||||
exists(StrcatFunction strcatFunc, CallInstruction call, ReadSideEffectInstruction rse |
|
||||
call.getStaticCallTarget() = strcatFunc and
|
||||
rse.getArgumentDef() = call.getArgument(strcatFunc.getParamSrc()) and
|
||||
fst.asOperand() = rse.getSideEffectOperand() and
|
||||
snd.asInstruction().(WriteSideEffectInstruction).getDestinationAddress() =
|
||||
call.getArgument(strcatFunc.getParamDest())
|
||||
exists(StrcatFunction strcatFunc, Call call |
|
||||
call.getTarget() = strcatFunc and
|
||||
fst.asIndirectArgument() = call.getArgument(strcatFunc.getParamSrc()) and
|
||||
snd.asDefiningArgument() = call.getArgument(strcatFunc.getParamDest())
|
||||
)
|
||||
or
|
||||
exists(CallInstruction call, Operator op, ReadSideEffectInstruction rse |
|
||||
call.getStaticCallTarget() = op and
|
||||
exists(Call call, Operator op |
|
||||
call.getTarget() = op and
|
||||
op.hasQualifiedName("std", "operator+") and
|
||||
op.getType().(UserType).hasQualifiedName("std", "basic_string") and
|
||||
call.getArgument(1) = rse.getArgumentOperand().getAnyDef() and // left operand
|
||||
fst.asOperand() = rse.getSideEffectOperand() and
|
||||
call = snd.asInstruction()
|
||||
fst.asIndirectArgument() = call.getArgument(1) and // left operand
|
||||
call = snd.asInstruction().getUnconvertedResultExpression()
|
||||
)
|
||||
}
|
||||
|
||||
@@ -91,6 +79,11 @@ class ExecState extends DataFlow::FlowState {
|
||||
}
|
||||
}
|
||||
|
||||
predicate isSinkImpl(DataFlow::Node sink, Expr command, string callChain) {
|
||||
command = sink.asIndirectArgument() and
|
||||
shellCommand(command, callChain)
|
||||
}
|
||||
|
||||
/**
|
||||
* A `TaintTracking` configuration that's used to find the relevant `ExecState`s for a
|
||||
* given sink. This avoids a cartesian product between all sinks and all `ExecState`s in
|
||||
@@ -103,9 +96,7 @@ class ExecStateConfiguration extends TaintTracking2::Configuration {
|
||||
exists(ExecState state | state.getSndNode() = source)
|
||||
}
|
||||
|
||||
override predicate isSink(DataFlow::Node sink) {
|
||||
shellCommand(sinkAsArgumentIndirection(sink), _)
|
||||
}
|
||||
override predicate isSink(DataFlow::Node sink) { isSinkImpl(sink, _, _) }
|
||||
|
||||
override predicate isSanitizerOut(DataFlow::Node node) {
|
||||
isSink(node, _) // Prevent duplicates along a call chain, since `shellCommand` will include wrappers
|
||||
@@ -150,13 +141,13 @@ class ExecTaintConfiguration extends TaintTracking::Configuration {
|
||||
|
||||
from
|
||||
ExecTaintConfiguration conf, DataFlow::PathNode sourceNode, DataFlow::PathNode sinkNode,
|
||||
string taintCause, string callChain, DataFlow::Node concatResult
|
||||
string taintCause, string callChain, DataFlow::Node concatResult, Expr command
|
||||
where
|
||||
conf.hasFlowPath(sourceNode, sinkNode) and
|
||||
taintCause = sourceNode.getNode().(FlowSource).getSourceType() and
|
||||
shellCommand(sinkAsArgumentIndirection(sinkNode.getNode()), callChain) and
|
||||
isSinkImpl(sinkNode.getNode(), command, callChain) and
|
||||
concatResult = sinkNode.getState().(ExecState).getSndNode()
|
||||
select sinkAsArgumentIndirection(sinkNode.getNode()), sourceNode, sinkNode,
|
||||
select command, sourceNode, sinkNode,
|
||||
"This argument to an OS command is derived from $@, dangerously concatenated into $@, and then passed to "
|
||||
+ callChain + ".", sourceNode, "user input (" + taintCause + ")", concatResult,
|
||||
concatResult.toString()
|
||||
|
||||
@@ -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()
|
||||
|
||||
@@ -1,4 +0,0 @@
|
||||
---
|
||||
category: newQuery
|
||||
---
|
||||
* Added a new medium-precision query, `cpp/comma-before-misleading-indentation`, which detects instances of whitespace that have readability issues.
|
||||
@@ -1,4 +0,0 @@
|
||||
---
|
||||
category: minorAnalysis
|
||||
---
|
||||
* The "Unterminated variadic call" (`cpp/unterminated-variadic-call`) query has been tuned to produce fewer false positive results.
|
||||
@@ -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
|
||||
|
||||
|
||||
10
cpp/ql/src/change-notes/released/0.4.2.md
Normal file
10
cpp/ql/src/change-notes/released/0.4.2.md
Normal file
@@ -0,0 +1,10 @@
|
||||
## 0.4.2
|
||||
|
||||
### New Queries
|
||||
|
||||
* Added a new medium-precision query, `cpp/comma-before-misleading-indentation`, which detects instances of whitespace that have readability issues.
|
||||
|
||||
### Minor Analysis Improvements
|
||||
|
||||
* The "Unterminated variadic call" (`cpp/unterminated-variadic-call`) query has been tuned to produce fewer false positive results.
|
||||
* Fixed false positives from the "Unused static function" (`cpp/unused-static-function`) query in files that had errors during compilation.
|
||||
@@ -1,2 +1,2 @@
|
||||
---
|
||||
lastReleaseVersion: 0.4.1
|
||||
lastReleaseVersion: 0.4.2
|
||||
|
||||
@@ -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."
|
||||
|
||||
@@ -1,5 +1,5 @@
|
||||
name: codeql/cpp-queries
|
||||
version: 0.4.2-dev
|
||||
version: 0.4.3-dev
|
||||
groups:
|
||||
- cpp
|
||||
- queries
|
||||
|
||||
@@ -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. |
|
||||
|
||||
@@ -13,6 +13,7 @@
|
||||
| test.cpp:4:26:4:26 | c<<expression>> |
|
||||
| test.cpp:4:26:4:26 | c<<unnamed>> |
|
||||
| test.cpp:5:29:5:29 | e |
|
||||
| test.cpp:6:24:6:24 | f |
|
||||
| test.cpp:6:26:6:26 | (unnamed parameter 0) |
|
||||
| test.cpp:6:29:6:31 | (unnamed parameter 1) |
|
||||
| test.cpp:7:20:7:20 | f |
|
||||
|
||||
@@ -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();
|
||||
}
|
||||
|
||||
|
||||
@@ -1 +1,20 @@
|
||||
Timeout (5m0s) in DataFlowUtil#47741e1f::simpleLocalFlowStep#2#ff
|
||||
| NonConstantFormat.c:30:10:30:16 | access to array | The format string argument to printf should be constant to prevent security issues and other potential errors. |
|
||||
| NonConstantFormat.c:41:9:41:27 | call to any_random_function | The format string argument to printf should be constant to prevent security issues and other potential errors. |
|
||||
| nested.cpp:21:23:21:26 | fmt0 | The format string argument to snprintf should be constant to prevent security issues and other potential errors. |
|
||||
| nested.cpp:79:32:79:38 | call to get_fmt | The format string argument to diagnostic should be constant to prevent security issues and other potential errors. |
|
||||
| nested.cpp:87:18:87:20 | fmt | The format string argument to diagnostic should be constant to prevent security issues and other potential errors. |
|
||||
| test.cpp:56:12:56:16 | hello | The format string argument to printf should be constant to prevent security issues and other potential errors. |
|
||||
| test.cpp:59:12:59:21 | call to const_wash | The format string argument to printf should be constant to prevent security issues and other potential errors. |
|
||||
| test.cpp:60:12:60:26 | ... + ... | The format string argument to printf should be constant to prevent security issues and other potential errors. |
|
||||
| test.cpp:61:12:61:17 | + ... | The format string argument to printf should be constant to prevent security issues and other potential errors. |
|
||||
| test.cpp:62:12:62:18 | * ... | The format string argument to printf should be constant to prevent security issues and other potential errors. |
|
||||
| test.cpp:63:12:63:18 | & ... | The format string argument to printf should be constant to prevent security issues and other potential errors. |
|
||||
| test.cpp:64:12:64:39 | ... + ... | The format string argument to printf should be constant to prevent security issues and other potential errors. |
|
||||
| test.cpp:66:10:66:35 | ... + ... | The format string argument to printf should be constant to prevent security issues and other potential errors. |
|
||||
| test.cpp:69:12:69:20 | ... + ... | The format string argument to printf should be constant to prevent security issues and other potential errors. |
|
||||
| test.cpp:81:12:81:16 | hello | The format string argument to printf should be constant to prevent security issues and other potential errors. |
|
||||
| test.cpp:92:12:92:18 | ++ ... | The format string argument to printf should be constant to prevent security issues and other potential errors. |
|
||||
| test.cpp:99:12:99:16 | hello | The format string argument to printf should be constant to prevent security issues and other potential errors. |
|
||||
| test.cpp:109:12:109:24 | new[] | The format string argument to printf should be constant to prevent security issues and other potential errors. |
|
||||
| test.cpp:114:12:114:16 | hello | The format string argument to printf should be constant to prevent security issues and other potential errors. |
|
||||
| test.cpp:129:20:129:26 | access to array | The format string argument to sprintf should be constant to prevent security issues and other potential errors. |
|
||||
|
||||
@@ -1,4 +1,16 @@
|
||||
edges
|
||||
| tests.cpp:26:15:26:23 | VariableAddress indirection | tests.cpp:51:12:51:20 | Call indirection |
|
||||
| tests.cpp:33:34:33:39 | Call indirection | tests.cpp:38:39:38:49 | environment indirection |
|
||||
| tests.cpp:38:25:38:36 | strncat output argument | tests.cpp:26:15:26:23 | VariableAddress indirection |
|
||||
| tests.cpp:38:39:38:49 | environment indirection | tests.cpp:38:25:38:36 | strncat output argument |
|
||||
| tests.cpp:51:12:51:20 | Call indirection | tests.cpp:53:16:53:19 | data indirection |
|
||||
nodes
|
||||
| tests.cpp:26:15:26:23 | VariableAddress indirection | semmle.label | VariableAddress indirection |
|
||||
| tests.cpp:33:34:33:39 | Call indirection | semmle.label | Call indirection |
|
||||
| tests.cpp:38:25:38:36 | strncat output argument | semmle.label | strncat output argument |
|
||||
| tests.cpp:38:39:38:49 | environment indirection | semmle.label | environment indirection |
|
||||
| tests.cpp:51:12:51:20 | Call indirection | semmle.label | Call indirection |
|
||||
| tests.cpp:53:16:53:19 | data indirection | semmle.label | data indirection |
|
||||
subpaths
|
||||
#select
|
||||
| tests.cpp:53:16:53:19 | data | tests.cpp:33:34:33:39 | Call indirection | tests.cpp:53:16:53:19 | data indirection | This argument to an OS command is derived from $@, dangerously concatenated into $@, and then passed to system(string). | tests.cpp:33:34:33:39 | Call indirection | user input (an environment variable) | tests.cpp:38:25:38:36 | strncat output argument | strncat output argument |
|
||||
|
||||
@@ -1,4 +1,224 @@
|
||||
edges
|
||||
| test.cpp:47:21:47:26 | Call indirection | test.cpp:50:35:50:43 | envCflags indirection |
|
||||
| test.cpp:50:11:50:17 | sprintf output argument | test.cpp:51:10:51:16 | command indirection |
|
||||
| test.cpp:50:35:50:43 | envCflags indirection | test.cpp:50:11:50:17 | sprintf output argument |
|
||||
| test.cpp:62:9:62:16 | fread output argument | test.cpp:64:20:64:27 | filename indirection |
|
||||
| test.cpp:64:11:64:17 | strncat output argument | test.cpp:65:10:65:16 | command indirection |
|
||||
| test.cpp:64:20:64:27 | filename indirection | test.cpp:64:11:64:17 | strncat output argument |
|
||||
| test.cpp:82:9:82:16 | fread output argument | test.cpp:84:20:84:27 | filename indirection |
|
||||
| test.cpp:84:11:84:17 | strncat output argument | test.cpp:85:32:85:38 | command indirection |
|
||||
| test.cpp:84:20:84:27 | filename indirection | test.cpp:84:11:84:17 | strncat output argument |
|
||||
| test.cpp:91:9:91:16 | fread output argument | test.cpp:93:17:93:24 | filename indirection |
|
||||
| test.cpp:93:11:93:14 | strncat output argument | test.cpp:94:45:94:48 | path indirection |
|
||||
| test.cpp:93:17:93:24 | filename indirection | test.cpp:93:11:93:14 | strncat output argument |
|
||||
| test.cpp:106:20:106:25 | call to getenv | test.cpp:107:33:107:36 | path indirection |
|
||||
| test.cpp:106:20:106:38 | call to getenv indirection | test.cpp:107:33:107:36 | path indirection |
|
||||
| test.cpp:107:31:107:31 | Call | test.cpp:108:18:108:22 | call to c_str indirection |
|
||||
| test.cpp:107:33:107:36 | path indirection | test.cpp:107:31:107:31 | Call |
|
||||
| test.cpp:113:20:113:25 | call to getenv | test.cpp:114:19:114:22 | path indirection |
|
||||
| test.cpp:113:20:113:38 | call to getenv indirection | test.cpp:114:19:114:22 | path indirection |
|
||||
| test.cpp:114:10:114:23 | Convert | test.cpp:114:25:114:29 | call to c_str indirection |
|
||||
| test.cpp:114:17:114:17 | call to operator+ | test.cpp:114:25:114:29 | call to c_str indirection |
|
||||
| test.cpp:114:19:114:22 | path indirection | test.cpp:114:10:114:23 | Convert |
|
||||
| test.cpp:114:19:114:22 | path indirection | test.cpp:114:17:114:17 | call to operator+ |
|
||||
| test.cpp:119:20:119:25 | call to getenv | test.cpp:120:19:120:22 | path indirection |
|
||||
| test.cpp:119:20:119:38 | call to getenv indirection | test.cpp:120:19:120:22 | path indirection |
|
||||
| test.cpp:120:17:120:17 | call to operator+ | test.cpp:120:10:120:30 | call to data indirection |
|
||||
| test.cpp:120:19:120:22 | path indirection | test.cpp:120:17:120:17 | call to operator+ |
|
||||
| test.cpp:140:9:140:11 | fread output argument | test.cpp:142:31:142:33 | str indirection |
|
||||
| test.cpp:142:11:142:17 | sprintf output argument | test.cpp:143:10:143:16 | command indirection |
|
||||
| test.cpp:142:31:142:33 | str indirection | test.cpp:142:11:142:17 | sprintf output argument |
|
||||
| test.cpp:174:9:174:16 | fread output argument | test.cpp:177:20:177:27 | filename indirection |
|
||||
| test.cpp:174:9:174:16 | fread output argument | test.cpp:178:22:178:26 | flags indirection |
|
||||
| test.cpp:174:9:174:16 | fread output argument | test.cpp:180:22:180:29 | filename indirection |
|
||||
| test.cpp:177:13:177:17 | strncat output argument | test.cpp:183:32:183:38 | command indirection |
|
||||
| test.cpp:177:20:177:27 | filename indirection | test.cpp:177:13:177:17 | strncat output argument |
|
||||
| test.cpp:178:13:178:19 | strncat output argument | test.cpp:183:32:183:38 | command indirection |
|
||||
| test.cpp:178:22:178:26 | flags indirection | test.cpp:178:13:178:19 | strncat output argument |
|
||||
| test.cpp:180:13:180:19 | strncat output argument | test.cpp:183:32:183:38 | command indirection |
|
||||
| test.cpp:180:22:180:29 | filename indirection | test.cpp:180:13:180:19 | strncat output argument |
|
||||
| test.cpp:186:34:186:38 | flags | test.cpp:187:11:187:15 | strncat output argument |
|
||||
| test.cpp:186:34:186:38 | flags | test.cpp:187:11:187:15 | strncat output argument |
|
||||
| test.cpp:186:34:186:38 | flags | test.cpp:188:11:188:17 | strncat output argument |
|
||||
| test.cpp:186:34:186:38 | flags | test.cpp:188:20:188:24 | flags indirection |
|
||||
| test.cpp:186:34:186:38 | flags indirection | test.cpp:187:11:187:15 | strncat output argument |
|
||||
| test.cpp:186:34:186:38 | flags indirection | test.cpp:187:11:187:15 | strncat output argument |
|
||||
| test.cpp:186:34:186:38 | flags indirection | test.cpp:188:11:188:17 | strncat output argument |
|
||||
| test.cpp:186:34:186:38 | flags indirection | test.cpp:188:20:188:24 | flags indirection |
|
||||
| test.cpp:186:47:186:54 | filename | test.cpp:187:11:187:15 | strncat output argument |
|
||||
| test.cpp:186:47:186:54 | filename | test.cpp:188:20:188:24 | flags indirection |
|
||||
| test.cpp:186:47:186:54 | filename indirection | test.cpp:187:11:187:15 | strncat output argument |
|
||||
| test.cpp:186:47:186:54 | filename indirection | test.cpp:187:18:187:25 | filename indirection |
|
||||
| test.cpp:186:47:186:54 | filename indirection | test.cpp:188:20:188:24 | flags indirection |
|
||||
| test.cpp:187:11:187:15 | strncat output argument | test.cpp:188:11:188:17 | strncat output argument |
|
||||
| test.cpp:187:11:187:15 | strncat output argument | test.cpp:188:11:188:17 | strncat output argument |
|
||||
| test.cpp:187:11:187:15 | strncat output argument | test.cpp:188:11:188:17 | strncat output argument |
|
||||
| test.cpp:187:11:187:15 | strncat output argument | test.cpp:188:20:188:24 | flags indirection |
|
||||
| test.cpp:187:11:187:15 | strncat output argument | test.cpp:188:20:188:24 | flags indirection |
|
||||
| test.cpp:187:11:187:15 | strncat output argument | test.cpp:188:20:188:24 | flags indirection |
|
||||
| test.cpp:187:11:187:15 | strncat output argument | test.cpp:188:20:188:24 | flags indirection |
|
||||
| test.cpp:187:18:187:25 | filename indirection | test.cpp:187:11:187:15 | strncat output argument |
|
||||
| test.cpp:188:20:188:24 | flags indirection | test.cpp:188:11:188:17 | strncat output argument |
|
||||
| test.cpp:188:20:188:24 | flags indirection | test.cpp:188:11:188:17 | strncat output argument |
|
||||
| test.cpp:188:20:188:24 | flags indirection | test.cpp:188:11:188:17 | strncat output argument |
|
||||
| test.cpp:188:20:188:24 | flags indirection | test.cpp:188:11:188:17 | strncat output argument |
|
||||
| test.cpp:194:9:194:16 | fread output argument | test.cpp:196:26:196:33 | filename |
|
||||
| test.cpp:194:9:194:16 | fread output argument | test.cpp:196:26:196:33 | filename indirection |
|
||||
| test.cpp:196:10:196:16 | concat output argument | test.cpp:198:32:198:38 | command indirection |
|
||||
| test.cpp:196:10:196:16 | concat output argument | test.cpp:198:32:198:38 | command indirection |
|
||||
| test.cpp:196:19:196:23 | concat output argument | test.cpp:196:19:196:23 | flags |
|
||||
| test.cpp:196:19:196:23 | concat output argument | test.cpp:196:19:196:23 | flags |
|
||||
| test.cpp:196:19:196:23 | concat output argument | test.cpp:196:19:196:23 | flags indirection |
|
||||
| test.cpp:196:19:196:23 | concat output argument | test.cpp:196:19:196:23 | flags indirection |
|
||||
| test.cpp:196:19:196:23 | flags | test.cpp:186:34:186:38 | flags |
|
||||
| test.cpp:196:19:196:23 | flags | test.cpp:186:34:186:38 | flags |
|
||||
| test.cpp:196:19:196:23 | flags | test.cpp:196:10:196:16 | concat output argument |
|
||||
| test.cpp:196:19:196:23 | flags | test.cpp:196:10:196:16 | concat output argument |
|
||||
| test.cpp:196:19:196:23 | flags | test.cpp:196:19:196:23 | concat output argument |
|
||||
| test.cpp:196:19:196:23 | flags | test.cpp:196:19:196:23 | concat output argument |
|
||||
| test.cpp:196:19:196:23 | flags indirection | test.cpp:186:34:186:38 | flags indirection |
|
||||
| test.cpp:196:19:196:23 | flags indirection | test.cpp:186:34:186:38 | flags indirection |
|
||||
| test.cpp:196:19:196:23 | flags indirection | test.cpp:196:10:196:16 | concat output argument |
|
||||
| test.cpp:196:19:196:23 | flags indirection | test.cpp:196:10:196:16 | concat output argument |
|
||||
| test.cpp:196:26:196:33 | filename | test.cpp:186:47:186:54 | filename |
|
||||
| test.cpp:196:26:196:33 | filename | test.cpp:196:10:196:16 | concat output argument |
|
||||
| test.cpp:196:26:196:33 | filename | test.cpp:196:19:196:23 | concat output argument |
|
||||
| test.cpp:196:26:196:33 | filename indirection | test.cpp:186:47:186:54 | filename indirection |
|
||||
| test.cpp:196:26:196:33 | filename indirection | test.cpp:196:10:196:16 | concat output argument |
|
||||
| test.cpp:196:26:196:33 | filename indirection | test.cpp:196:10:196:16 | concat output argument |
|
||||
| test.cpp:196:26:196:33 | filename indirection | test.cpp:196:19:196:23 | concat output argument |
|
||||
| test.cpp:196:26:196:33 | filename indirection | test.cpp:196:19:196:23 | concat output argument |
|
||||
| test.cpp:218:9:218:16 | fread output argument | test.cpp:220:19:220:26 | filename indirection |
|
||||
| test.cpp:218:9:218:16 | fread output argument | test.cpp:220:19:220:26 | filename indirection |
|
||||
| test.cpp:220:10:220:16 | strncat output argument | test.cpp:222:32:222:38 | command indirection |
|
||||
| test.cpp:220:10:220:16 | strncat output argument | test.cpp:222:32:222:38 | command indirection |
|
||||
| test.cpp:220:19:220:26 | filename indirection | test.cpp:220:10:220:16 | strncat output argument |
|
||||
| test.cpp:220:19:220:26 | filename indirection | test.cpp:220:10:220:16 | strncat output argument |
|
||||
| test.cpp:220:19:220:26 | filename indirection | test.cpp:220:10:220:16 | strncat output argument |
|
||||
| test.cpp:220:19:220:26 | filename indirection | test.cpp:220:10:220:16 | strncat output argument |
|
||||
nodes
|
||||
| test.cpp:47:21:47:26 | Call indirection | semmle.label | Call indirection |
|
||||
| test.cpp:50:11:50:17 | sprintf output argument | semmle.label | sprintf output argument |
|
||||
| test.cpp:50:35:50:43 | envCflags indirection | semmle.label | envCflags indirection |
|
||||
| test.cpp:51:10:51:16 | command indirection | semmle.label | command indirection |
|
||||
| test.cpp:62:9:62:16 | fread output argument | semmle.label | fread output argument |
|
||||
| test.cpp:64:11:64:17 | strncat output argument | semmle.label | strncat output argument |
|
||||
| test.cpp:64:20:64:27 | filename indirection | semmle.label | filename indirection |
|
||||
| test.cpp:65:10:65:16 | command indirection | semmle.label | command indirection |
|
||||
| test.cpp:82:9:82:16 | fread output argument | semmle.label | fread output argument |
|
||||
| test.cpp:84:11:84:17 | strncat output argument | semmle.label | strncat output argument |
|
||||
| test.cpp:84:20:84:27 | filename indirection | semmle.label | filename indirection |
|
||||
| test.cpp:85:32:85:38 | command indirection | semmle.label | command indirection |
|
||||
| test.cpp:91:9:91:16 | fread output argument | semmle.label | fread output argument |
|
||||
| test.cpp:93:11:93:14 | strncat output argument | semmle.label | strncat output argument |
|
||||
| test.cpp:93:17:93:24 | filename indirection | semmle.label | filename indirection |
|
||||
| test.cpp:94:45:94:48 | path indirection | semmle.label | path indirection |
|
||||
| test.cpp:106:20:106:25 | call to getenv | semmle.label | call to getenv |
|
||||
| test.cpp:106:20:106:38 | call to getenv indirection | semmle.label | call to getenv indirection |
|
||||
| test.cpp:107:31:107:31 | Call | semmle.label | Call |
|
||||
| test.cpp:107:33:107:36 | path indirection | semmle.label | path indirection |
|
||||
| test.cpp:108:18:108:22 | call to c_str indirection | semmle.label | call to c_str indirection |
|
||||
| test.cpp:113:20:113:25 | call to getenv | semmle.label | call to getenv |
|
||||
| test.cpp:113:20:113:38 | call to getenv indirection | semmle.label | call to getenv indirection |
|
||||
| test.cpp:114:10:114:23 | Convert | semmle.label | Convert |
|
||||
| test.cpp:114:17:114:17 | call to operator+ | semmle.label | call to operator+ |
|
||||
| test.cpp:114:19:114:22 | path indirection | semmle.label | path indirection |
|
||||
| test.cpp:114:25:114:29 | call to c_str indirection | semmle.label | call to c_str indirection |
|
||||
| test.cpp:114:25:114:29 | call to c_str indirection | semmle.label | call to c_str indirection |
|
||||
| test.cpp:119:20:119:25 | call to getenv | semmle.label | call to getenv |
|
||||
| test.cpp:119:20:119:38 | call to getenv indirection | semmle.label | call to getenv indirection |
|
||||
| test.cpp:120:10:120:30 | call to data indirection | semmle.label | call to data indirection |
|
||||
| test.cpp:120:17:120:17 | call to operator+ | semmle.label | call to operator+ |
|
||||
| test.cpp:120:19:120:22 | path indirection | semmle.label | path indirection |
|
||||
| test.cpp:140:9:140:11 | fread output argument | semmle.label | fread output argument |
|
||||
| test.cpp:142:11:142:17 | sprintf output argument | semmle.label | sprintf output argument |
|
||||
| test.cpp:142:31:142:33 | str indirection | semmle.label | str indirection |
|
||||
| test.cpp:143:10:143:16 | command indirection | semmle.label | command indirection |
|
||||
| test.cpp:174:9:174:16 | fread output argument | semmle.label | fread output argument |
|
||||
| test.cpp:177:13:177:17 | strncat output argument | semmle.label | strncat output argument |
|
||||
| test.cpp:177:20:177:27 | filename indirection | semmle.label | filename indirection |
|
||||
| test.cpp:178:13:178:19 | strncat output argument | semmle.label | strncat output argument |
|
||||
| test.cpp:178:22:178:26 | flags indirection | semmle.label | flags indirection |
|
||||
| test.cpp:180:13:180:19 | strncat output argument | semmle.label | strncat output argument |
|
||||
| test.cpp:180:22:180:29 | filename indirection | semmle.label | filename indirection |
|
||||
| test.cpp:183:32:183:38 | command indirection | semmle.label | command indirection |
|
||||
| test.cpp:183:32:183:38 | command indirection | semmle.label | command indirection |
|
||||
| test.cpp:183:32:183:38 | command indirection | semmle.label | command indirection |
|
||||
| test.cpp:186:34:186:38 | flags | semmle.label | flags |
|
||||
| test.cpp:186:34:186:38 | flags | semmle.label | flags |
|
||||
| test.cpp:186:34:186:38 | flags indirection | semmle.label | flags indirection |
|
||||
| test.cpp:186:34:186:38 | flags indirection | semmle.label | flags indirection |
|
||||
| test.cpp:186:47:186:54 | filename | semmle.label | filename |
|
||||
| test.cpp:186:47:186:54 | filename indirection | semmle.label | filename indirection |
|
||||
| test.cpp:187:11:187:15 | strncat output argument | semmle.label | strncat output argument |
|
||||
| test.cpp:187:11:187:15 | strncat output argument | semmle.label | strncat output argument |
|
||||
| test.cpp:187:11:187:15 | strncat output argument | semmle.label | strncat output argument |
|
||||
| test.cpp:187:11:187:15 | strncat output argument | semmle.label | strncat output argument |
|
||||
| test.cpp:187:11:187:15 | strncat output argument | semmle.label | strncat output argument |
|
||||
| test.cpp:187:11:187:15 | strncat output argument | semmle.label | strncat output argument |
|
||||
| test.cpp:187:11:187:15 | strncat output argument | semmle.label | strncat output argument |
|
||||
| test.cpp:187:18:187:25 | filename indirection | semmle.label | filename indirection |
|
||||
| test.cpp:188:11:188:17 | strncat output argument | semmle.label | strncat output argument |
|
||||
| test.cpp:188:11:188:17 | strncat output argument | semmle.label | strncat output argument |
|
||||
| test.cpp:188:11:188:17 | strncat output argument | semmle.label | strncat output argument |
|
||||
| test.cpp:188:11:188:17 | strncat output argument | semmle.label | strncat output argument |
|
||||
| test.cpp:188:11:188:17 | strncat output argument | semmle.label | strncat output argument |
|
||||
| test.cpp:188:11:188:17 | strncat output argument | semmle.label | strncat output argument |
|
||||
| test.cpp:188:11:188:17 | strncat output argument | semmle.label | strncat output argument |
|
||||
| test.cpp:188:20:188:24 | flags indirection | semmle.label | flags indirection |
|
||||
| test.cpp:188:20:188:24 | flags indirection | semmle.label | flags indirection |
|
||||
| test.cpp:188:20:188:24 | flags indirection | semmle.label | flags indirection |
|
||||
| test.cpp:188:20:188:24 | flags indirection | semmle.label | flags indirection |
|
||||
| test.cpp:194:9:194:16 | fread output argument | semmle.label | fread output argument |
|
||||
| test.cpp:196:10:196:16 | concat output argument | semmle.label | concat output argument |
|
||||
| test.cpp:196:10:196:16 | concat output argument | semmle.label | concat output argument |
|
||||
| test.cpp:196:19:196:23 | concat output argument | semmle.label | concat output argument |
|
||||
| test.cpp:196:19:196:23 | concat output argument | semmle.label | concat output argument |
|
||||
| test.cpp:196:19:196:23 | flags | semmle.label | flags |
|
||||
| test.cpp:196:19:196:23 | flags | semmle.label | flags |
|
||||
| test.cpp:196:19:196:23 | flags indirection | semmle.label | flags indirection |
|
||||
| test.cpp:196:19:196:23 | flags indirection | semmle.label | flags indirection |
|
||||
| test.cpp:196:26:196:33 | filename | semmle.label | filename |
|
||||
| test.cpp:196:26:196:33 | filename indirection | semmle.label | filename indirection |
|
||||
| test.cpp:198:32:198:38 | command indirection | semmle.label | command indirection |
|
||||
| test.cpp:198:32:198:38 | command indirection | semmle.label | command indirection |
|
||||
| test.cpp:218:9:218:16 | fread output argument | semmle.label | fread output argument |
|
||||
| test.cpp:220:10:220:16 | strncat output argument | semmle.label | strncat output argument |
|
||||
| test.cpp:220:10:220:16 | strncat output argument | semmle.label | strncat output argument |
|
||||
| test.cpp:220:19:220:26 | filename indirection | semmle.label | filename indirection |
|
||||
| test.cpp:220:19:220:26 | filename indirection | semmle.label | filename indirection |
|
||||
| test.cpp:222:32:222:38 | command indirection | semmle.label | command indirection |
|
||||
subpaths
|
||||
| test.cpp:196:19:196:23 | flags | test.cpp:186:34:186:38 | flags | test.cpp:187:11:187:15 | strncat output argument | test.cpp:196:19:196:23 | concat output argument |
|
||||
| test.cpp:196:19:196:23 | flags | test.cpp:186:34:186:38 | flags | test.cpp:187:11:187:15 | strncat output argument | test.cpp:196:19:196:23 | concat output argument |
|
||||
| test.cpp:196:19:196:23 | flags | test.cpp:186:34:186:38 | flags | test.cpp:188:11:188:17 | strncat output argument | test.cpp:196:10:196:16 | concat output argument |
|
||||
| test.cpp:196:19:196:23 | flags | test.cpp:186:34:186:38 | flags | test.cpp:188:11:188:17 | strncat output argument | test.cpp:196:10:196:16 | concat output argument |
|
||||
| test.cpp:196:19:196:23 | flags indirection | test.cpp:186:34:186:38 | flags indirection | test.cpp:188:11:188:17 | strncat output argument | test.cpp:196:10:196:16 | concat output argument |
|
||||
| test.cpp:196:19:196:23 | flags indirection | test.cpp:186:34:186:38 | flags indirection | test.cpp:188:11:188:17 | strncat output argument | test.cpp:196:10:196:16 | concat output argument |
|
||||
| test.cpp:196:26:196:33 | filename | test.cpp:186:47:186:54 | filename | test.cpp:187:11:187:15 | strncat output argument | test.cpp:196:19:196:23 | concat output argument |
|
||||
| test.cpp:196:26:196:33 | filename | test.cpp:186:47:186:54 | filename | test.cpp:188:11:188:17 | strncat output argument | test.cpp:196:10:196:16 | concat output argument |
|
||||
| test.cpp:196:26:196:33 | filename indirection | test.cpp:186:47:186:54 | filename indirection | test.cpp:187:11:187:15 | strncat output argument | test.cpp:196:19:196:23 | concat output argument |
|
||||
| test.cpp:196:26:196:33 | filename indirection | test.cpp:186:47:186:54 | filename indirection | test.cpp:187:11:187:15 | strncat output argument | test.cpp:196:19:196:23 | concat output argument |
|
||||
| test.cpp:196:26:196:33 | filename indirection | test.cpp:186:47:186:54 | filename indirection | test.cpp:188:11:188:17 | strncat output argument | test.cpp:196:10:196:16 | concat output argument |
|
||||
| test.cpp:196:26:196:33 | filename indirection | test.cpp:186:47:186:54 | filename indirection | test.cpp:188:11:188:17 | strncat output argument | test.cpp:196:10:196:16 | concat output argument |
|
||||
#select
|
||||
| test.cpp:51:10:51:16 | command | test.cpp:47:21:47:26 | Call indirection | test.cpp:51:10:51:16 | command indirection | This argument to an OS command is derived from $@, dangerously concatenated into $@, and then passed to system(string). | test.cpp:47:21:47:26 | Call indirection | user input (an environment variable) | test.cpp:50:11:50:17 | sprintf output argument | sprintf output argument |
|
||||
| test.cpp:65:10:65:16 | command | test.cpp:62:9:62:16 | fread output argument | test.cpp:65:10:65:16 | command indirection | This argument to an OS command is derived from $@, dangerously concatenated into $@, and then passed to system(string). | test.cpp:62:9:62:16 | fread output argument | user input (String read by fread) | test.cpp:64:11:64:17 | strncat output argument | strncat output argument |
|
||||
| test.cpp:85:32:85:38 | command | test.cpp:82:9:82:16 | fread output argument | test.cpp:85:32:85:38 | command indirection | This argument to an OS command is derived from $@, dangerously concatenated into $@, and then passed to execl. | test.cpp:82:9:82:16 | fread output argument | user input (String read by fread) | test.cpp:84:11:84:17 | strncat output argument | strncat output argument |
|
||||
| test.cpp:94:45:94:48 | path | test.cpp:91:9:91:16 | fread output argument | test.cpp:94:45:94:48 | path indirection | This argument to an OS command is derived from $@, dangerously concatenated into $@, and then passed to execl. | test.cpp:91:9:91:16 | fread output argument | user input (String read by fread) | test.cpp:93:11:93:14 | strncat output argument | strncat output argument |
|
||||
| test.cpp:108:18:108:22 | call to c_str | test.cpp:106:20:106:25 | call to getenv | test.cpp:108:18:108:22 | call to c_str indirection | This argument to an OS command is derived from $@, dangerously concatenated into $@, and then passed to system(string). | test.cpp:106:20:106:25 | call to getenv | user input (an environment variable) | test.cpp:107:31:107:31 | Call | Call |
|
||||
| test.cpp:108:18:108:22 | call to c_str | test.cpp:106:20:106:38 | call to getenv indirection | test.cpp:108:18:108:22 | call to c_str indirection | This argument to an OS command is derived from $@, dangerously concatenated into $@, and then passed to system(string). | test.cpp:106:20:106:38 | call to getenv indirection | user input (an environment variable) | test.cpp:107:31:107:31 | Call | Call |
|
||||
| test.cpp:114:25:114:29 | call to c_str | test.cpp:113:20:113:25 | call to getenv | test.cpp:114:25:114:29 | call to c_str indirection | This argument to an OS command is derived from $@, dangerously concatenated into $@, and then passed to system(string). | test.cpp:113:20:113:25 | call to getenv | user input (an environment variable) | test.cpp:114:10:114:23 | Convert | Convert |
|
||||
| test.cpp:114:25:114:29 | call to c_str | test.cpp:113:20:113:25 | call to getenv | test.cpp:114:25:114:29 | call to c_str indirection | This argument to an OS command is derived from $@, dangerously concatenated into $@, and then passed to system(string). | test.cpp:113:20:113:25 | call to getenv | user input (an environment variable) | test.cpp:114:17:114:17 | call to operator+ | call to operator+ |
|
||||
| test.cpp:114:25:114:29 | call to c_str | test.cpp:113:20:113:38 | call to getenv indirection | test.cpp:114:25:114:29 | call to c_str indirection | This argument to an OS command is derived from $@, dangerously concatenated into $@, and then passed to system(string). | test.cpp:113:20:113:38 | call to getenv indirection | user input (an environment variable) | test.cpp:114:10:114:23 | Convert | Convert |
|
||||
| test.cpp:114:25:114:29 | call to c_str | test.cpp:113:20:113:38 | call to getenv indirection | test.cpp:114:25:114:29 | call to c_str indirection | This argument to an OS command is derived from $@, dangerously concatenated into $@, and then passed to system(string). | test.cpp:113:20:113:38 | call to getenv indirection | user input (an environment variable) | test.cpp:114:17:114:17 | call to operator+ | call to operator+ |
|
||||
| test.cpp:120:25:120:28 | call to data | test.cpp:119:20:119:25 | call to getenv | test.cpp:120:10:120:30 | call to data indirection | This argument to an OS command is derived from $@, dangerously concatenated into $@, and then passed to system(string). | test.cpp:119:20:119:25 | call to getenv | user input (an environment variable) | test.cpp:120:17:120:17 | call to operator+ | call to operator+ |
|
||||
| test.cpp:120:25:120:28 | call to data | test.cpp:119:20:119:38 | call to getenv indirection | test.cpp:120:10:120:30 | call to data indirection | This argument to an OS command is derived from $@, dangerously concatenated into $@, and then passed to system(string). | test.cpp:119:20:119:38 | call to getenv indirection | user input (an environment variable) | test.cpp:120:17:120:17 | call to operator+ | call to operator+ |
|
||||
| test.cpp:143:10:143:16 | command | test.cpp:140:9:140:11 | fread output argument | test.cpp:143:10:143:16 | command indirection | This argument to an OS command is derived from $@, dangerously concatenated into $@, and then passed to system(string). | test.cpp:140:9:140:11 | fread output argument | user input (String read by fread) | test.cpp:142:11:142:17 | sprintf output argument | sprintf output argument |
|
||||
| test.cpp:183:32:183:38 | command | test.cpp:174:9:174:16 | fread output argument | test.cpp:183:32:183:38 | command indirection | This argument to an OS command is derived from $@, dangerously concatenated into $@, and then passed to execl. | test.cpp:174:9:174:16 | fread output argument | user input (String read by fread) | test.cpp:177:13:177:17 | strncat output argument | strncat output argument |
|
||||
| test.cpp:183:32:183:38 | command | test.cpp:174:9:174:16 | fread output argument | test.cpp:183:32:183:38 | command indirection | This argument to an OS command is derived from $@, dangerously concatenated into $@, and then passed to execl. | test.cpp:174:9:174:16 | fread output argument | user input (String read by fread) | test.cpp:178:13:178:19 | strncat output argument | strncat output argument |
|
||||
| test.cpp:183:32:183:38 | command | test.cpp:174:9:174:16 | fread output argument | test.cpp:183:32:183:38 | command indirection | This argument to an OS command is derived from $@, dangerously concatenated into $@, and then passed to execl. | test.cpp:174:9:174:16 | fread output argument | user input (String read by fread) | test.cpp:180:13:180:19 | strncat output argument | strncat output argument |
|
||||
| test.cpp:198:32:198:38 | command | test.cpp:194:9:194:16 | fread output argument | test.cpp:198:32:198:38 | command indirection | This argument to an OS command is derived from $@, dangerously concatenated into $@, and then passed to execl. | test.cpp:194:9:194:16 | fread output argument | user input (String read by fread) | test.cpp:187:11:187:15 | strncat output argument | strncat output argument |
|
||||
| test.cpp:198:32:198:38 | command | test.cpp:194:9:194:16 | fread output argument | test.cpp:198:32:198:38 | command indirection | This argument to an OS command is derived from $@, dangerously concatenated into $@, and then passed to execl. | test.cpp:194:9:194:16 | fread output argument | user input (String read by fread) | test.cpp:188:11:188:17 | strncat output argument | strncat output argument |
|
||||
| test.cpp:222:32:222:38 | command | test.cpp:218:9:218:16 | fread output argument | test.cpp:222:32:222:38 | command indirection | This argument to an OS command is derived from $@, dangerously concatenated into $@, and then passed to execl. | test.cpp:218:9:218:16 | fread output argument | user input (String read by fread) | test.cpp:220:10:220:16 | strncat output argument | strncat output argument |
|
||||
| test.cpp:222:32:222:38 | command | test.cpp:218:9:218:16 | fread output argument | test.cpp:222:32:222:38 | command indirection | This argument to an OS command is derived from $@, dangerously concatenated into $@, and then passed to execl. | test.cpp:218:9:218:16 | fread output argument | user input (String read by fread) | test.cpp:220:10:220:16 | strncat output argument | strncat output argument |
|
||||
|
||||
@@ -1,4 +1,8 @@
|
||||
edges
|
||||
| CWE122_Heap_Based_Buffer_Overflow__c_CWE129_fgets_01.c:30:19:30:29 | fgets output argument | CWE122_Heap_Based_Buffer_Overflow__c_CWE129_fgets_01.c:52:20:52:23 | data |
|
||||
nodes
|
||||
| CWE122_Heap_Based_Buffer_Overflow__c_CWE129_fgets_01.c:30:19:30:29 | fgets output argument | semmle.label | fgets output argument |
|
||||
| CWE122_Heap_Based_Buffer_Overflow__c_CWE129_fgets_01.c:52:20:52:23 | data | semmle.label | data |
|
||||
subpaths
|
||||
#select
|
||||
| CWE122_Heap_Based_Buffer_Overflow__c_CWE129_fgets_01.c:52:20:52:23 | data | CWE122_Heap_Based_Buffer_Overflow__c_CWE129_fgets_01.c:30:19:30:29 | fgets output argument | CWE122_Heap_Based_Buffer_Overflow__c_CWE129_fgets_01.c:52:20:52:23 | data | An array indexing expression depends on $@ that might be outside the bounds of the array. | CWE122_Heap_Based_Buffer_Overflow__c_CWE129_fgets_01.c:30:19:30:29 | fgets output argument | string read by fgets |
|
||||
|
||||
@@ -5,31 +5,57 @@ edges
|
||||
| test.cpp:40:21:40:24 | argv | test.cpp:49:32:49:35 | size |
|
||||
| test.cpp:40:21:40:24 | argv | test.cpp:50:26:50:29 | size |
|
||||
| test.cpp:40:21:40:24 | argv | test.cpp:53:35:53:60 | ... * ... |
|
||||
| test.cpp:76:25:76:29 | start | test.cpp:80:18:80:28 | ... - ... |
|
||||
| test.cpp:76:25:76:29 | start indirection | test.cpp:80:18:80:28 | ... - ... |
|
||||
| test.cpp:76:38:76:40 | end | test.cpp:80:18:80:28 | ... - ... |
|
||||
| test.cpp:76:38:76:40 | end indirection | test.cpp:80:18:80:28 | ... - ... |
|
||||
| test.cpp:98:18:98:23 | fread output argument | test.cpp:102:17:102:22 | buffer |
|
||||
| test.cpp:98:18:98:23 | fread output argument | test.cpp:102:17:102:22 | buffer indirection |
|
||||
| test.cpp:98:18:98:23 | fread output argument | test.cpp:102:25:102:39 | ... + ... |
|
||||
| test.cpp:98:18:98:23 | fread output argument | test.cpp:102:25:102:39 | ... + ... indirection |
|
||||
| test.cpp:102:17:102:22 | buffer | test.cpp:76:25:76:29 | start |
|
||||
| test.cpp:102:17:102:22 | buffer indirection | test.cpp:76:25:76:29 | start indirection |
|
||||
| test.cpp:102:25:102:39 | ... + ... | test.cpp:76:38:76:40 | end |
|
||||
| test.cpp:102:25:102:39 | ... + ... indirection | test.cpp:76:38:76:40 | end indirection |
|
||||
| test.cpp:124:18:124:23 | call to getenv | test.cpp:125:29:125:32 | size |
|
||||
| test.cpp:124:18:124:23 | call to getenv | test.cpp:128:24:128:41 | ... * ... |
|
||||
| test.cpp:124:18:124:31 | call to getenv indirection | test.cpp:125:29:125:32 | size |
|
||||
| test.cpp:124:18:124:31 | call to getenv indirection | test.cpp:128:24:128:41 | ... * ... |
|
||||
| test.cpp:125:29:125:32 | size | test.cpp:127:24:127:49 | ... * ... |
|
||||
| test.cpp:133:19:133:24 | call to getenv | test.cpp:135:10:135:27 | ... * ... |
|
||||
| test.cpp:133:19:133:32 | call to getenv indirection | test.cpp:135:10:135:27 | ... * ... |
|
||||
| test.cpp:148:20:148:25 | call to getenv | test.cpp:152:11:152:28 | ... * ... |
|
||||
| test.cpp:148:20:148:33 | call to getenv indirection | test.cpp:152:11:152:28 | ... * ... |
|
||||
| test.cpp:157:19:157:24 | call to getenv | test.cpp:161:11:161:28 | ... * ... |
|
||||
| test.cpp:157:19:157:32 | call to getenv indirection | test.cpp:161:11:161:28 | ... * ... |
|
||||
| test.cpp:184:19:184:24 | call to getenv | test.cpp:186:10:186:27 | ... * ... |
|
||||
| test.cpp:184:19:184:32 | call to getenv indirection | test.cpp:186:10:186:27 | ... * ... |
|
||||
| test.cpp:209:8:209:23 | VariableAddress indirection | test.cpp:241:9:241:24 | call to get_tainted_size |
|
||||
| test.cpp:211:14:211:19 | call to getenv | test.cpp:209:8:209:23 | VariableAddress indirection |
|
||||
| test.cpp:211:14:211:27 | call to getenv indirection | test.cpp:209:8:209:23 | VariableAddress indirection |
|
||||
| test.cpp:214:8:214:23 | VariableAddress indirection | test.cpp:242:9:242:24 | call to get_bounded_size |
|
||||
| test.cpp:216:18:216:23 | call to getenv | test.cpp:214:8:214:23 | VariableAddress indirection |
|
||||
| test.cpp:216:18:216:31 | call to getenv indirection | test.cpp:214:8:214:23 | VariableAddress indirection |
|
||||
| test.cpp:224:23:224:23 | s | test.cpp:225:21:225:21 | s |
|
||||
| test.cpp:230:21:230:21 | s | test.cpp:231:21:231:21 | s |
|
||||
| test.cpp:237:24:237:29 | call to getenv | test.cpp:239:9:239:18 | local_size |
|
||||
| test.cpp:237:24:237:29 | call to getenv | test.cpp:245:11:245:20 | local_size |
|
||||
| test.cpp:237:24:237:29 | call to getenv | test.cpp:247:10:247:19 | local_size |
|
||||
| test.cpp:237:24:237:37 | call to getenv indirection | test.cpp:239:9:239:18 | local_size |
|
||||
| test.cpp:237:24:237:37 | call to getenv indirection | test.cpp:245:11:245:20 | local_size |
|
||||
| test.cpp:237:24:237:37 | call to getenv indirection | test.cpp:247:10:247:19 | local_size |
|
||||
| test.cpp:245:11:245:20 | local_size | test.cpp:224:23:224:23 | s |
|
||||
| test.cpp:247:10:247:19 | local_size | test.cpp:230:21:230:21 | s |
|
||||
| test.cpp:250:20:250:27 | Load indirection | test.cpp:289:17:289:20 | get_size output argument |
|
||||
| test.cpp:250:20:250:27 | Load indirection | test.cpp:305:18:305:21 | get_size output argument |
|
||||
| test.cpp:251:18:251:23 | call to getenv | test.cpp:250:20:250:27 | Load indirection |
|
||||
| test.cpp:251:18:251:31 | call to getenv indirection | test.cpp:250:20:250:27 | Load indirection |
|
||||
| test.cpp:259:20:259:25 | call to getenv | test.cpp:263:11:263:29 | ... * ... |
|
||||
| test.cpp:259:20:259:33 | call to getenv indirection | test.cpp:263:11:263:29 | ... * ... |
|
||||
| test.cpp:289:17:289:20 | get_size output argument | test.cpp:291:11:291:28 | ... * ... |
|
||||
| test.cpp:305:18:305:21 | get_size output argument | test.cpp:308:10:308:27 | ... * ... |
|
||||
| test.cpp:331:15:331:20 | Call | test.cpp:334:9:334:14 | offset |
|
||||
| test.cpp:331:15:331:20 | Call indirection | test.cpp:334:9:334:14 | offset |
|
||||
nodes
|
||||
| test.cpp:40:21:40:24 | argv | semmle.label | argv |
|
||||
| test.cpp:43:38:43:44 | tainted | semmle.label | tainted |
|
||||
@@ -38,27 +64,45 @@ nodes
|
||||
| test.cpp:49:32:49:35 | size | semmle.label | size |
|
||||
| test.cpp:50:26:50:29 | size | semmle.label | size |
|
||||
| test.cpp:53:35:53:60 | ... * ... | semmle.label | ... * ... |
|
||||
| test.cpp:76:25:76:29 | start | semmle.label | start |
|
||||
| test.cpp:76:25:76:29 | start indirection | semmle.label | start indirection |
|
||||
| test.cpp:76:38:76:40 | end | semmle.label | end |
|
||||
| test.cpp:76:38:76:40 | end indirection | semmle.label | end indirection |
|
||||
| test.cpp:80:18:80:28 | ... - ... | semmle.label | ... - ... |
|
||||
| test.cpp:98:18:98:23 | fread output argument | semmle.label | fread output argument |
|
||||
| test.cpp:102:17:102:22 | buffer | semmle.label | buffer |
|
||||
| test.cpp:102:17:102:22 | buffer indirection | semmle.label | buffer indirection |
|
||||
| test.cpp:102:25:102:39 | ... + ... | semmle.label | ... + ... |
|
||||
| test.cpp:102:25:102:39 | ... + ... indirection | semmle.label | ... + ... indirection |
|
||||
| test.cpp:124:18:124:23 | call to getenv | semmle.label | call to getenv |
|
||||
| test.cpp:124:18:124:31 | call to getenv indirection | semmle.label | call to getenv indirection |
|
||||
| test.cpp:125:29:125:32 | size | semmle.label | size |
|
||||
| test.cpp:127:24:127:49 | ... * ... | semmle.label | ... * ... |
|
||||
| test.cpp:128:24:128:41 | ... * ... | semmle.label | ... * ... |
|
||||
| test.cpp:133:19:133:24 | call to getenv | semmle.label | call to getenv |
|
||||
| test.cpp:133:19:133:32 | call to getenv indirection | semmle.label | call to getenv indirection |
|
||||
| test.cpp:135:10:135:27 | ... * ... | semmle.label | ... * ... |
|
||||
| test.cpp:148:20:148:25 | call to getenv | semmle.label | call to getenv |
|
||||
| test.cpp:148:20:148:33 | call to getenv indirection | semmle.label | call to getenv indirection |
|
||||
| test.cpp:152:11:152:28 | ... * ... | semmle.label | ... * ... |
|
||||
| test.cpp:157:19:157:24 | call to getenv | semmle.label | call to getenv |
|
||||
| test.cpp:157:19:157:32 | call to getenv indirection | semmle.label | call to getenv indirection |
|
||||
| test.cpp:161:11:161:28 | ... * ... | semmle.label | ... * ... |
|
||||
| test.cpp:184:19:184:24 | call to getenv | semmle.label | call to getenv |
|
||||
| test.cpp:184:19:184:32 | call to getenv indirection | semmle.label | call to getenv indirection |
|
||||
| test.cpp:186:10:186:27 | ... * ... | semmle.label | ... * ... |
|
||||
| test.cpp:209:8:209:23 | VariableAddress indirection | semmle.label | VariableAddress indirection |
|
||||
| test.cpp:211:14:211:19 | call to getenv | semmle.label | call to getenv |
|
||||
| test.cpp:211:14:211:27 | call to getenv indirection | semmle.label | call to getenv indirection |
|
||||
| test.cpp:214:8:214:23 | VariableAddress indirection | semmle.label | VariableAddress indirection |
|
||||
| test.cpp:216:18:216:23 | call to getenv | semmle.label | call to getenv |
|
||||
| test.cpp:216:18:216:31 | call to getenv indirection | semmle.label | call to getenv indirection |
|
||||
| test.cpp:224:23:224:23 | s | semmle.label | s |
|
||||
| test.cpp:225:21:225:21 | s | semmle.label | s |
|
||||
| test.cpp:230:21:230:21 | s | semmle.label | s |
|
||||
| test.cpp:231:21:231:21 | s | semmle.label | s |
|
||||
| test.cpp:237:24:237:29 | call to getenv | semmle.label | call to getenv |
|
||||
| test.cpp:237:24:237:37 | call to getenv indirection | semmle.label | call to getenv indirection |
|
||||
| test.cpp:239:9:239:18 | local_size | semmle.label | local_size |
|
||||
| test.cpp:241:9:241:24 | call to get_tainted_size | semmle.label | call to get_tainted_size |
|
||||
| test.cpp:242:9:242:24 | call to get_bounded_size | semmle.label | call to get_bounded_size |
|
||||
@@ -66,13 +110,16 @@ nodes
|
||||
| test.cpp:247:10:247:19 | local_size | semmle.label | local_size |
|
||||
| test.cpp:250:20:250:27 | Load indirection | semmle.label | Load indirection |
|
||||
| test.cpp:251:18:251:23 | call to getenv | semmle.label | call to getenv |
|
||||
| test.cpp:251:18:251:31 | call to getenv indirection | semmle.label | call to getenv indirection |
|
||||
| test.cpp:259:20:259:25 | call to getenv | semmle.label | call to getenv |
|
||||
| test.cpp:259:20:259:33 | call to getenv indirection | semmle.label | call to getenv indirection |
|
||||
| test.cpp:263:11:263:29 | ... * ... | semmle.label | ... * ... |
|
||||
| test.cpp:289:17:289:20 | get_size output argument | semmle.label | get_size output argument |
|
||||
| test.cpp:291:11:291:28 | ... * ... | semmle.label | ... * ... |
|
||||
| test.cpp:305:18:305:21 | get_size output argument | semmle.label | get_size output argument |
|
||||
| test.cpp:308:10:308:27 | ... * ... | semmle.label | ... * ... |
|
||||
| test.cpp:331:15:331:20 | Call | semmle.label | Call |
|
||||
| test.cpp:331:15:331:20 | Call indirection | semmle.label | Call indirection |
|
||||
| test.cpp:334:9:334:14 | offset | semmle.label | offset |
|
||||
subpaths
|
||||
#select
|
||||
@@ -82,18 +129,34 @@ subpaths
|
||||
| test.cpp:49:25:49:30 | call to malloc | test.cpp:40:21:40:24 | argv | test.cpp:49:32:49:35 | size | This allocation size is derived from $@ and might overflow. | test.cpp:40:21:40:24 | argv | user input (a command-line argument) |
|
||||
| test.cpp:50:17:50:30 | new[] | test.cpp:40:21:40:24 | argv | test.cpp:50:26:50:29 | size | This allocation size is derived from $@ and might overflow. | test.cpp:40:21:40:24 | argv | user input (a command-line argument) |
|
||||
| test.cpp:53:21:53:27 | call to realloc | test.cpp:40:21:40:24 | argv | test.cpp:53:35:53:60 | ... * ... | This allocation size is derived from $@ and might overflow. | test.cpp:40:21:40:24 | argv | user input (a command-line argument) |
|
||||
| test.cpp:80:9:80:29 | new[] | test.cpp:98:18:98:23 | fread output argument | test.cpp:80:18:80:28 | ... - ... | This allocation size is derived from $@ and might overflow. | test.cpp:98:18:98:23 | fread output argument | user input (String read by fread) |
|
||||
| test.cpp:127:17:127:22 | call to malloc | test.cpp:124:18:124:23 | call to getenv | test.cpp:127:24:127:49 | ... * ... | This allocation size is derived from $@ and might overflow. | test.cpp:124:18:124:23 | call to getenv | user input (an environment variable) |
|
||||
| test.cpp:127:17:127:22 | call to malloc | test.cpp:124:18:124:31 | call to getenv indirection | test.cpp:127:24:127:49 | ... * ... | This allocation size is derived from $@ and might overflow. | test.cpp:124:18:124:31 | call to getenv indirection | user input (an environment variable) |
|
||||
| test.cpp:128:17:128:22 | call to malloc | test.cpp:124:18:124:23 | call to getenv | test.cpp:128:24:128:41 | ... * ... | This allocation size is derived from $@ and might overflow. | test.cpp:124:18:124:23 | call to getenv | user input (an environment variable) |
|
||||
| test.cpp:128:17:128:22 | call to malloc | test.cpp:124:18:124:31 | call to getenv indirection | test.cpp:128:24:128:41 | ... * ... | This allocation size is derived from $@ and might overflow. | test.cpp:124:18:124:31 | call to getenv indirection | user input (an environment variable) |
|
||||
| test.cpp:135:3:135:8 | call to malloc | test.cpp:133:19:133:24 | call to getenv | test.cpp:135:10:135:27 | ... * ... | This allocation size is derived from $@ and might overflow. | test.cpp:133:19:133:24 | call to getenv | user input (an environment variable) |
|
||||
| test.cpp:135:3:135:8 | call to malloc | test.cpp:133:19:133:32 | call to getenv indirection | test.cpp:135:10:135:27 | ... * ... | This allocation size is derived from $@ and might overflow. | test.cpp:133:19:133:32 | call to getenv indirection | user input (an environment variable) |
|
||||
| test.cpp:152:4:152:9 | call to malloc | test.cpp:148:20:148:25 | call to getenv | test.cpp:152:11:152:28 | ... * ... | This allocation size is derived from $@ and might overflow. | test.cpp:148:20:148:25 | call to getenv | user input (an environment variable) |
|
||||
| test.cpp:152:4:152:9 | call to malloc | test.cpp:148:20:148:33 | call to getenv indirection | test.cpp:152:11:152:28 | ... * ... | This allocation size is derived from $@ and might overflow. | test.cpp:148:20:148:33 | call to getenv indirection | user input (an environment variable) |
|
||||
| test.cpp:161:4:161:9 | call to malloc | test.cpp:157:19:157:24 | call to getenv | test.cpp:161:11:161:28 | ... * ... | This allocation size is derived from $@ and might overflow. | test.cpp:157:19:157:24 | call to getenv | user input (an environment variable) |
|
||||
| test.cpp:161:4:161:9 | call to malloc | test.cpp:157:19:157:32 | call to getenv indirection | test.cpp:161:11:161:28 | ... * ... | This allocation size is derived from $@ and might overflow. | test.cpp:157:19:157:32 | call to getenv indirection | user input (an environment variable) |
|
||||
| test.cpp:186:3:186:8 | call to malloc | test.cpp:184:19:184:24 | call to getenv | test.cpp:186:10:186:27 | ... * ... | This allocation size is derived from $@ and might overflow. | test.cpp:184:19:184:24 | call to getenv | user input (an environment variable) |
|
||||
| test.cpp:186:3:186:8 | call to malloc | test.cpp:184:19:184:32 | call to getenv indirection | test.cpp:186:10:186:27 | ... * ... | This allocation size is derived from $@ and might overflow. | test.cpp:184:19:184:32 | call to getenv indirection | user input (an environment variable) |
|
||||
| test.cpp:225:14:225:19 | call to malloc | test.cpp:237:24:237:29 | call to getenv | test.cpp:225:21:225:21 | s | This allocation size is derived from $@ and might overflow. | test.cpp:237:24:237:29 | call to getenv | user input (an environment variable) |
|
||||
| test.cpp:225:14:225:19 | call to malloc | test.cpp:237:24:237:37 | call to getenv indirection | test.cpp:225:21:225:21 | s | This allocation size is derived from $@ and might overflow. | test.cpp:237:24:237:37 | call to getenv indirection | user input (an environment variable) |
|
||||
| test.cpp:231:14:231:19 | call to malloc | test.cpp:237:24:237:29 | call to getenv | test.cpp:231:21:231:21 | s | This allocation size is derived from $@ and might overflow. | test.cpp:237:24:237:29 | call to getenv | user input (an environment variable) |
|
||||
| test.cpp:231:14:231:19 | call to malloc | test.cpp:237:24:237:37 | call to getenv indirection | test.cpp:231:21:231:21 | s | This allocation size is derived from $@ and might overflow. | test.cpp:237:24:237:37 | call to getenv indirection | user input (an environment variable) |
|
||||
| test.cpp:239:2:239:7 | call to malloc | test.cpp:237:24:237:29 | call to getenv | test.cpp:239:9:239:18 | local_size | This allocation size is derived from $@ and might overflow. | test.cpp:237:24:237:29 | call to getenv | user input (an environment variable) |
|
||||
| test.cpp:239:2:239:7 | call to malloc | test.cpp:237:24:237:37 | call to getenv indirection | test.cpp:239:9:239:18 | local_size | This allocation size is derived from $@ and might overflow. | test.cpp:237:24:237:37 | call to getenv indirection | user input (an environment variable) |
|
||||
| test.cpp:241:2:241:7 | call to malloc | test.cpp:211:14:211:19 | call to getenv | test.cpp:241:9:241:24 | call to get_tainted_size | This allocation size is derived from $@ and might overflow. | test.cpp:211:14:211:19 | call to getenv | user input (an environment variable) |
|
||||
| test.cpp:241:2:241:7 | call to malloc | test.cpp:211:14:211:27 | call to getenv indirection | test.cpp:241:9:241:24 | call to get_tainted_size | This allocation size is derived from $@ and might overflow. | test.cpp:211:14:211:27 | call to getenv indirection | user input (an environment variable) |
|
||||
| test.cpp:242:2:242:7 | call to malloc | test.cpp:216:18:216:23 | call to getenv | test.cpp:242:9:242:24 | call to get_bounded_size | This allocation size is derived from $@ and might overflow. | test.cpp:216:18:216:23 | call to getenv | user input (an environment variable) |
|
||||
| test.cpp:242:2:242:7 | call to malloc | test.cpp:216:18:216:31 | call to getenv indirection | test.cpp:242:9:242:24 | call to get_bounded_size | This allocation size is derived from $@ and might overflow. | test.cpp:216:18:216:31 | call to getenv indirection | user input (an environment variable) |
|
||||
| test.cpp:263:4:263:9 | call to malloc | test.cpp:259:20:259:25 | call to getenv | test.cpp:263:11:263:29 | ... * ... | This allocation size is derived from $@ and might overflow. | test.cpp:259:20:259:25 | call to getenv | user input (an environment variable) |
|
||||
| test.cpp:263:4:263:9 | call to malloc | test.cpp:259:20:259:33 | call to getenv indirection | test.cpp:263:11:263:29 | ... * ... | This allocation size is derived from $@ and might overflow. | test.cpp:259:20:259:33 | call to getenv indirection | user input (an environment variable) |
|
||||
| test.cpp:291:4:291:9 | call to malloc | test.cpp:251:18:251:23 | call to getenv | test.cpp:291:11:291:28 | ... * ... | This allocation size is derived from $@ and might overflow. | test.cpp:251:18:251:23 | call to getenv | user input (an environment variable) |
|
||||
| test.cpp:291:4:291:9 | call to malloc | test.cpp:251:18:251:31 | call to getenv indirection | test.cpp:291:11:291:28 | ... * ... | This allocation size is derived from $@ and might overflow. | test.cpp:251:18:251:31 | call to getenv indirection | user input (an environment variable) |
|
||||
| test.cpp:308:3:308:8 | call to malloc | test.cpp:251:18:251:23 | call to getenv | test.cpp:308:10:308:27 | ... * ... | This allocation size is derived from $@ and might overflow. | test.cpp:251:18:251:23 | call to getenv | user input (an environment variable) |
|
||||
| test.cpp:308:3:308:8 | call to malloc | test.cpp:251:18:251:31 | call to getenv indirection | test.cpp:308:10:308:27 | ... * ... | This allocation size is derived from $@ and might overflow. | test.cpp:251:18:251:31 | call to getenv indirection | user input (an environment variable) |
|
||||
| test.cpp:334:2:334:7 | call to malloc | test.cpp:331:15:331:20 | Call | test.cpp:334:9:334:14 | offset | This allocation size is derived from $@ and might overflow. | test.cpp:331:15:331:20 | Call | user input (an environment variable) |
|
||||
| test.cpp:334:2:334:7 | call to malloc | test.cpp:331:15:331:20 | Call indirection | test.cpp:334:9:334:14 | offset | This allocation size is derived from $@ and might overflow. | test.cpp:331:15:331:20 | Call indirection | user input (an environment variable) |
|
||||
|
||||
@@ -1,10 +1,13 @@
|
||||
edges
|
||||
| test2.cpp:110:8:110:15 | gets output argument | test2.cpp:110:3:110:6 | call to gets |
|
||||
| test.cpp:54:17:54:20 | argv | test.cpp:58:25:58:29 | input |
|
||||
nodes
|
||||
| test2.cpp:110:3:110:6 | call to gets | semmle.label | call to gets |
|
||||
| test2.cpp:110:8:110:15 | gets output argument | semmle.label | gets output argument |
|
||||
| test.cpp:54:17:54:20 | argv | semmle.label | argv |
|
||||
| test.cpp:58:25:58:29 | input | semmle.label | input |
|
||||
subpaths
|
||||
#select
|
||||
| test2.cpp:110:3:110:6 | call to gets | test2.cpp:110:3:110:6 | call to gets | test2.cpp:110:3:110:6 | call to gets | This write into buffer 'password' may contain unencrypted data from $@. | test2.cpp:110:3:110:6 | call to gets | user input (String read by gets) |
|
||||
| test2.cpp:110:3:110:6 | call to gets | test2.cpp:110:8:110:15 | gets output argument | test2.cpp:110:3:110:6 | call to gets | This write into buffer 'password' may contain unencrypted data from $@. | test2.cpp:110:8:110:15 | gets output argument | user input (String read by gets) |
|
||||
| test.cpp:58:3:58:9 | call to sprintf | test.cpp:54:17:54:20 | argv | test.cpp:58:25:58:29 | input | This write into buffer 'passwd' may contain unencrypted data from $@. | test.cpp:54:17:54:20 | argv | user input (a command-line argument) |
|
||||
|
||||
@@ -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.
|
||||
|
||||
@@ -1,3 +1,7 @@
|
||||
## 1.3.2
|
||||
|
||||
No user-facing changes.
|
||||
|
||||
## 1.3.1
|
||||
|
||||
No user-facing changes.
|
||||
|
||||
@@ -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",
|
||||
|
||||
@@ -0,0 +1,3 @@
|
||||
## 1.3.2
|
||||
|
||||
No user-facing changes.
|
||||
Some files were not shown because too many files have changed in this diff Show More
Reference in New Issue
Block a user