mirror of
https://github.com/github/codeql.git
synced 2025-12-23 12:16:33 +01:00
Merge branch 'main' of https://github.com/microsoft/codeql
This commit is contained in:
10
.github/workflows/go-tests-other-os.yml
vendored
10
.github/workflows/go-tests-other-os.yml
vendored
@@ -7,15 +7,17 @@ on:
|
|||||||
- .github/workflows/go-tests-other-os.yml
|
- .github/workflows/go-tests-other-os.yml
|
||||||
- .github/actions/**
|
- .github/actions/**
|
||||||
- codeql-workspace.yml
|
- codeql-workspace.yml
|
||||||
|
env:
|
||||||
|
GO_VERSION: '~1.21.0'
|
||||||
jobs:
|
jobs:
|
||||||
test-mac:
|
test-mac:
|
||||||
name: Test MacOS
|
name: Test MacOS
|
||||||
runs-on: macos-latest
|
runs-on: macos-latest
|
||||||
steps:
|
steps:
|
||||||
- name: Set up Go 1.20
|
- name: Set up Go ${{ env.GO_VERSION }}
|
||||||
uses: actions/setup-go@v4
|
uses: actions/setup-go@v4
|
||||||
with:
|
with:
|
||||||
go-version: '1.20'
|
go-version: ${{ env.GO_VERSION }}
|
||||||
id: go
|
id: go
|
||||||
|
|
||||||
- name: Check out code
|
- name: Check out code
|
||||||
@@ -47,10 +49,10 @@ jobs:
|
|||||||
name: Test Windows
|
name: Test Windows
|
||||||
runs-on: windows-latest-xl
|
runs-on: windows-latest-xl
|
||||||
steps:
|
steps:
|
||||||
- name: Set up Go 1.20
|
- name: Set up Go ${{ env.GO_VERSION }}
|
||||||
uses: actions/setup-go@v4
|
uses: actions/setup-go@v4
|
||||||
with:
|
with:
|
||||||
go-version: '1.20'
|
go-version: ${{ env.GO_VERSION }}
|
||||||
id: go
|
id: go
|
||||||
|
|
||||||
- name: Check out code
|
- name: Check out code
|
||||||
|
|||||||
6
.github/workflows/go-tests.yml
vendored
6
.github/workflows/go-tests.yml
vendored
@@ -15,15 +15,17 @@ on:
|
|||||||
- .github/workflows/go-tests.yml
|
- .github/workflows/go-tests.yml
|
||||||
- .github/actions/**
|
- .github/actions/**
|
||||||
- codeql-workspace.yml
|
- codeql-workspace.yml
|
||||||
|
env:
|
||||||
|
GO_VERSION: '~1.21.0'
|
||||||
jobs:
|
jobs:
|
||||||
test-linux:
|
test-linux:
|
||||||
name: Test Linux (Ubuntu)
|
name: Test Linux (Ubuntu)
|
||||||
runs-on: ubuntu-latest-xl
|
runs-on: ubuntu-latest-xl
|
||||||
steps:
|
steps:
|
||||||
- name: Set up Go 1.20
|
- name: Set up Go ${{ env.GO_VERSION }}
|
||||||
uses: actions/setup-go@v4
|
uses: actions/setup-go@v4
|
||||||
with:
|
with:
|
||||||
go-version: '1.20'
|
go-version: ${{ env.GO_VERSION }}
|
||||||
id: go
|
id: go
|
||||||
|
|
||||||
- name: Check out code
|
- name: Check out code
|
||||||
|
|||||||
@@ -22,7 +22,6 @@
|
|||||||
"csharp/ql/lib/semmle/code/csharp/dataflow/internal/DataFlowImpl5.qll",
|
"csharp/ql/lib/semmle/code/csharp/dataflow/internal/DataFlowImpl5.qll",
|
||||||
"go/ql/lib/semmle/go/dataflow/internal/DataFlowImpl1.qll",
|
"go/ql/lib/semmle/go/dataflow/internal/DataFlowImpl1.qll",
|
||||||
"go/ql/lib/semmle/go/dataflow/internal/DataFlowImpl2.qll",
|
"go/ql/lib/semmle/go/dataflow/internal/DataFlowImpl2.qll",
|
||||||
"go/ql/lib/semmle/go/dataflow/internal/DataFlowImplForStringsNewReplacer.qll",
|
|
||||||
"python/ql/lib/semmle/python/dataflow/new/internal/DataFlowImpl1.qll",
|
"python/ql/lib/semmle/python/dataflow/new/internal/DataFlowImpl1.qll",
|
||||||
"python/ql/lib/semmle/python/dataflow/new/internal/DataFlowImpl2.qll",
|
"python/ql/lib/semmle/python/dataflow/new/internal/DataFlowImpl2.qll",
|
||||||
"python/ql/lib/semmle/python/dataflow/new/internal/DataFlowImpl3.qll",
|
"python/ql/lib/semmle/python/dataflow/new/internal/DataFlowImpl3.qll",
|
||||||
@@ -33,16 +32,6 @@
|
|||||||
"ruby/ql/lib/codeql/ruby/dataflow/internal/DataFlowImplForPathname.qll",
|
"ruby/ql/lib/codeql/ruby/dataflow/internal/DataFlowImplForPathname.qll",
|
||||||
"swift/ql/lib/codeql/swift/dataflow/internal/DataFlowImpl1.qll"
|
"swift/ql/lib/codeql/swift/dataflow/internal/DataFlowImpl1.qll"
|
||||||
],
|
],
|
||||||
"TaintTracking Java/C++/C#/Go/Python/Ruby/Swift": [
|
|
||||||
"cpp/ql/lib/semmle/code/cpp/dataflow/internal/tainttracking1/TaintTracking.qll",
|
|
||||||
"cpp/ql/lib/semmle/code/cpp/ir/dataflow/internal/tainttracking1/TaintTracking.qll",
|
|
||||||
"csharp/ql/lib/semmle/code/csharp/dataflow/internal/tainttracking1/TaintTracking.qll",
|
|
||||||
"go/ql/lib/semmle/go/dataflow/internal/tainttracking1/TaintTracking.qll",
|
|
||||||
"java/ql/lib/semmle/code/java/dataflow/internal/tainttracking1/TaintTracking.qll",
|
|
||||||
"python/ql/lib/semmle/python/dataflow/new/internal/tainttracking1/TaintTracking.qll",
|
|
||||||
"ruby/ql/lib/codeql/ruby/dataflow/internal/tainttracking1/TaintTracking.qll",
|
|
||||||
"swift/ql/lib/codeql/swift/dataflow/internal/tainttracking1/TaintTracking.qll"
|
|
||||||
],
|
|
||||||
"TaintTracking Legacy Configuration Java/C++/C#/Go/Python/Ruby/Swift": [
|
"TaintTracking Legacy Configuration Java/C++/C#/Go/Python/Ruby/Swift": [
|
||||||
"cpp/ql/lib/semmle/code/cpp/dataflow/internal/tainttracking1/TaintTrackingImpl.qll",
|
"cpp/ql/lib/semmle/code/cpp/dataflow/internal/tainttracking1/TaintTrackingImpl.qll",
|
||||||
"cpp/ql/lib/semmle/code/cpp/dataflow/internal/tainttracking2/TaintTrackingImpl.qll",
|
"cpp/ql/lib/semmle/code/cpp/dataflow/internal/tainttracking2/TaintTrackingImpl.qll",
|
||||||
@@ -484,10 +473,6 @@
|
|||||||
"ruby/ql/lib/codeql/ruby/security/internal/SensitiveDataHeuristics.qll",
|
"ruby/ql/lib/codeql/ruby/security/internal/SensitiveDataHeuristics.qll",
|
||||||
"swift/ql/lib/codeql/swift/security/internal/SensitiveDataHeuristics.qll"
|
"swift/ql/lib/codeql/swift/security/internal/SensitiveDataHeuristics.qll"
|
||||||
],
|
],
|
||||||
"CFG": [
|
|
||||||
"csharp/ql/lib/semmle/code/csharp/controlflow/internal/ControlFlowGraphImplShared.qll",
|
|
||||||
"swift/ql/lib/codeql/swift/controlflow/internal/ControlFlowGraphImplShared.qll"
|
|
||||||
],
|
|
||||||
"TypeTracker": [
|
"TypeTracker": [
|
||||||
"python/ql/lib/semmle/python/dataflow/new/internal/TypeTracker.qll",
|
"python/ql/lib/semmle/python/dataflow/new/internal/TypeTracker.qll",
|
||||||
"ruby/ql/lib/codeql/ruby/typetracking/TypeTracker.qll"
|
"ruby/ql/lib/codeql/ruby/typetracking/TypeTracker.qll"
|
||||||
|
|||||||
@@ -327,7 +327,7 @@ namespace Semmle.Autobuild.Cpp.Tests
|
|||||||
{
|
{
|
||||||
Actions.RunProcess[@"cmd.exe /C nuget restore C:\Project\test.sln -DisableParallelProcessing"] = 1;
|
Actions.RunProcess[@"cmd.exe /C nuget restore C:\Project\test.sln -DisableParallelProcessing"] = 1;
|
||||||
Actions.RunProcess[@"cmd.exe /C C:\Project\.nuget\nuget.exe restore C:\Project\test.sln -DisableParallelProcessing"] = 0;
|
Actions.RunProcess[@"cmd.exe /C C:\Project\.nuget\nuget.exe restore C:\Project\test.sln -DisableParallelProcessing"] = 0;
|
||||||
Actions.RunProcess[@"cmd.exe /C CALL ^""C:\Program Files ^(x86^)\Microsoft Visual Studio 14.0\VC\vcvarsall.bat^"" && set Platform=&& type NUL && msbuild C:\Project\test.sln /t:rebuild /p:Platform=""x86"" /p:Configuration=""Release"""] = 0;
|
Actions.RunProcess[@"cmd.exe /C CALL ^""C:\Program^ Files^ ^(x86^)\Microsoft^ Visual^ Studio^ 14.0\VC\vcvarsall.bat^"" && set Platform=&& type NUL && msbuild C:\Project\test.sln /t:rebuild /p:Platform=""x86"" /p:Configuration=""Release"""] = 0;
|
||||||
Actions.RunProcessOut[@"C:\Program Files (x86)\Microsoft Visual Studio\Installer\vswhere.exe -prerelease -legacy -property installationPath"] = "";
|
Actions.RunProcessOut[@"C:\Program Files (x86)\Microsoft Visual Studio\Installer\vswhere.exe -prerelease -legacy -property installationPath"] = "";
|
||||||
Actions.RunProcess[@"C:\Program Files (x86)\Microsoft Visual Studio\Installer\vswhere.exe -prerelease -legacy -property installationPath"] = 1;
|
Actions.RunProcess[@"C:\Program Files (x86)\Microsoft Visual Studio\Installer\vswhere.exe -prerelease -legacy -property installationPath"] = 1;
|
||||||
Actions.RunProcess[@"C:\Program Files (x86)\Microsoft Visual Studio\Installer\vswhere.exe -prerelease -legacy -property installationVersion"] = 0;
|
Actions.RunProcess[@"C:\Program Files (x86)\Microsoft Visual Studio\Installer\vswhere.exe -prerelease -legacy -property installationVersion"] = 0;
|
||||||
|
|||||||
@@ -0,0 +1,4 @@
|
|||||||
|
---
|
||||||
|
category: minorAnalysis
|
||||||
|
---
|
||||||
|
* Only the 2 level indirection of `argv` (corresponding to `**argv`) is consided for `FlowSource`.
|
||||||
@@ -1,5 +1,5 @@
|
|||||||
name: codeql/cpp-all
|
name: codeql/cpp-all
|
||||||
version: 0.9.0
|
version: 0.9.1-dev
|
||||||
groups: cpp
|
groups: cpp
|
||||||
dbscheme: semmlecode.cpp.dbscheme
|
dbscheme: semmlecode.cpp.dbscheme
|
||||||
extractor: cpp
|
extractor: cpp
|
||||||
|
|||||||
@@ -25,6 +25,10 @@ import semmle.code.cpp.dataflow.DataFlow2
|
|||||||
* global (inter-procedural) taint-tracking analyses.
|
* global (inter-procedural) taint-tracking analyses.
|
||||||
*/
|
*/
|
||||||
deprecated module TaintTracking {
|
deprecated module TaintTracking {
|
||||||
import semmle.code.cpp.dataflow.internal.tainttracking1.TaintTracking
|
import semmle.code.cpp.dataflow.internal.tainttracking1.TaintTrackingParameter::Public
|
||||||
|
private import semmle.code.cpp.dataflow.internal.DataFlowImplSpecific
|
||||||
|
private import semmle.code.cpp.dataflow.internal.TaintTrackingImplSpecific
|
||||||
|
private import codeql.dataflow.TaintTracking
|
||||||
|
import TaintFlowMake<CppOldDataFlow, CppOldTaintTracking>
|
||||||
import semmle.code.cpp.dataflow.internal.tainttracking1.TaintTrackingImpl
|
import semmle.code.cpp.dataflow.internal.tainttracking1.TaintTrackingImpl
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -0,0 +1,10 @@
|
|||||||
|
/**
|
||||||
|
* Provides C++-specific definitions for use in the taint tracking library.
|
||||||
|
*/
|
||||||
|
|
||||||
|
private import codeql.dataflow.TaintTracking
|
||||||
|
private import DataFlowImplSpecific
|
||||||
|
|
||||||
|
module CppOldTaintTracking implements InputSig<CppOldDataFlow> {
|
||||||
|
import TaintTrackingUtil
|
||||||
|
}
|
||||||
@@ -39,7 +39,7 @@ predicate defaultAdditionalTaintStep(DataFlow::Node src, DataFlow::Node sink) {
|
|||||||
* of `c` at sinks and inputs to additional taint steps.
|
* of `c` at sinks and inputs to additional taint steps.
|
||||||
*/
|
*/
|
||||||
bindingset[node]
|
bindingset[node]
|
||||||
predicate defaultImplicitTaintRead(DataFlow::Node node, DataFlow::Content c) { none() }
|
predicate defaultImplicitTaintRead(DataFlow::Node node, DataFlow::ContentSet c) { none() }
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Holds if `node` should be a sanitizer in all global taint flow configurations
|
* Holds if `node` should be a sanitizer in all global taint flow configurations
|
||||||
|
|||||||
@@ -1,75 +0,0 @@
|
|||||||
/**
|
|
||||||
* Provides classes for performing local (intra-procedural) and
|
|
||||||
* global (inter-procedural) taint-tracking analyses.
|
|
||||||
*/
|
|
||||||
|
|
||||||
import TaintTrackingParameter::Public
|
|
||||||
private import TaintTrackingParameter::Private
|
|
||||||
|
|
||||||
private module AddTaintDefaults<DataFlowInternal::FullStateConfigSig Config> implements
|
|
||||||
DataFlowInternal::FullStateConfigSig
|
|
||||||
{
|
|
||||||
import Config
|
|
||||||
|
|
||||||
predicate isBarrier(DataFlow::Node node) {
|
|
||||||
Config::isBarrier(node) or defaultTaintSanitizer(node)
|
|
||||||
}
|
|
||||||
|
|
||||||
predicate isAdditionalFlowStep(DataFlow::Node node1, DataFlow::Node node2) {
|
|
||||||
Config::isAdditionalFlowStep(node1, node2) or
|
|
||||||
defaultAdditionalTaintStep(node1, node2)
|
|
||||||
}
|
|
||||||
|
|
||||||
predicate allowImplicitRead(DataFlow::Node node, DataFlow::ContentSet c) {
|
|
||||||
Config::allowImplicitRead(node, c)
|
|
||||||
or
|
|
||||||
(
|
|
||||||
Config::isSink(node) or
|
|
||||||
Config::isSink(node, _) or
|
|
||||||
Config::isAdditionalFlowStep(node, _) or
|
|
||||||
Config::isAdditionalFlowStep(node, _, _, _)
|
|
||||||
) and
|
|
||||||
defaultImplicitTaintRead(node, c)
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Constructs a global taint tracking computation.
|
|
||||||
*/
|
|
||||||
module Global<DataFlow::ConfigSig Config> implements DataFlow::GlobalFlowSig {
|
|
||||||
private module Config0 implements DataFlowInternal::FullStateConfigSig {
|
|
||||||
import DataFlowInternal::DefaultState<Config>
|
|
||||||
import Config
|
|
||||||
}
|
|
||||||
|
|
||||||
private module C implements DataFlowInternal::FullStateConfigSig {
|
|
||||||
import AddTaintDefaults<Config0>
|
|
||||||
}
|
|
||||||
|
|
||||||
import DataFlowInternal::Impl<C>
|
|
||||||
}
|
|
||||||
|
|
||||||
/** DEPRECATED: Use `Global` instead. */
|
|
||||||
deprecated module Make<DataFlow::ConfigSig Config> implements DataFlow::GlobalFlowSig {
|
|
||||||
import Global<Config>
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Constructs a global taint tracking computation using flow state.
|
|
||||||
*/
|
|
||||||
module GlobalWithState<DataFlow::StateConfigSig Config> implements DataFlow::GlobalFlowSig {
|
|
||||||
private module Config0 implements DataFlowInternal::FullStateConfigSig {
|
|
||||||
import Config
|
|
||||||
}
|
|
||||||
|
|
||||||
private module C implements DataFlowInternal::FullStateConfigSig {
|
|
||||||
import AddTaintDefaults<Config0>
|
|
||||||
}
|
|
||||||
|
|
||||||
import DataFlowInternal::Impl<C>
|
|
||||||
}
|
|
||||||
|
|
||||||
/** DEPRECATED: Use `GlobalWithState` instead. */
|
|
||||||
deprecated module MakeWithState<DataFlow::StateConfigSig Config> implements DataFlow::GlobalFlowSig {
|
|
||||||
import GlobalWithState<Config>
|
|
||||||
}
|
|
||||||
@@ -23,6 +23,10 @@ import semmle.code.cpp.dataflow.new.DataFlow2
|
|||||||
* global (inter-procedural) taint-tracking analyses.
|
* global (inter-procedural) taint-tracking analyses.
|
||||||
*/
|
*/
|
||||||
module TaintTracking {
|
module TaintTracking {
|
||||||
import semmle.code.cpp.ir.dataflow.internal.tainttracking1.TaintTracking
|
import semmle.code.cpp.ir.dataflow.internal.tainttracking1.TaintTrackingParameter::Public
|
||||||
|
private import semmle.code.cpp.ir.dataflow.internal.DataFlowImplSpecific
|
||||||
|
private import semmle.code.cpp.ir.dataflow.internal.TaintTrackingImplSpecific
|
||||||
|
private import codeql.dataflow.TaintTracking
|
||||||
|
import TaintFlowMake<CppDataFlow, CppTaintTracking>
|
||||||
import semmle.code.cpp.ir.dataflow.internal.tainttracking1.TaintTrackingImpl
|
import semmle.code.cpp.ir.dataflow.internal.tainttracking1.TaintTrackingImpl
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -19,6 +19,10 @@ import semmle.code.cpp.ir.dataflow.DataFlow
|
|||||||
import semmle.code.cpp.ir.dataflow.DataFlow2
|
import semmle.code.cpp.ir.dataflow.DataFlow2
|
||||||
|
|
||||||
module TaintTracking {
|
module TaintTracking {
|
||||||
import semmle.code.cpp.ir.dataflow.internal.tainttracking1.TaintTracking
|
import semmle.code.cpp.ir.dataflow.internal.tainttracking1.TaintTrackingParameter::Public
|
||||||
|
private import semmle.code.cpp.ir.dataflow.internal.DataFlowImplSpecific
|
||||||
|
private import semmle.code.cpp.ir.dataflow.internal.TaintTrackingImplSpecific
|
||||||
|
private import codeql.dataflow.TaintTracking
|
||||||
|
import TaintFlowMake<CppDataFlow, CppTaintTracking>
|
||||||
import semmle.code.cpp.ir.dataflow.internal.tainttracking1.TaintTrackingImpl
|
import semmle.code.cpp.ir.dataflow.internal.tainttracking1.TaintTrackingImpl
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -1078,7 +1078,7 @@ private IRVariable getIRVariableForParameterNode(ParameterNode p) {
|
|||||||
|
|
||||||
/** Holds if `v` is the source variable corresponding to the parameter represented by `p`. */
|
/** Holds if `v` is the source variable corresponding to the parameter represented by `p`. */
|
||||||
pragma[nomagic]
|
pragma[nomagic]
|
||||||
private predicate parameterNodeHasSourceVariable(ParameterNode p, Ssa::SourceIRVariable v) {
|
private predicate parameterNodeHasSourceVariable(ParameterNode p, Ssa::SourceVariable v) {
|
||||||
v.getIRVariable() = getIRVariableForParameterNode(p) and
|
v.getIRVariable() = getIRVariableForParameterNode(p) and
|
||||||
exists(Position pos | p.isParameterOf(_, pos) |
|
exists(Position pos | p.isParameterOf(_, pos) |
|
||||||
pos instanceof DirectPosition and
|
pos instanceof DirectPosition and
|
||||||
|
|||||||
@@ -781,26 +781,12 @@ class IndirectArgumentOutNode extends Node, TIndirectArgumentOutNode, PartialDef
|
|||||||
override Expr getDefinedExpr() { result = operand.getDef().getUnconvertedResultExpression() }
|
override Expr getDefinedExpr() { result = operand.getDef().getUnconvertedResultExpression() }
|
||||||
}
|
}
|
||||||
|
|
||||||
pragma[nomagic]
|
|
||||||
predicate indirectReturnOutNodeOperand0(CallInstruction call, Operand operand, int indirectionIndex) {
|
|
||||||
Ssa::hasRawIndirectInstruction(call, indirectionIndex) and
|
|
||||||
operandForFullyConvertedCall(operand, call)
|
|
||||||
}
|
|
||||||
|
|
||||||
pragma[nomagic]
|
|
||||||
predicate indirectReturnOutNodeInstruction0(
|
|
||||||
CallInstruction call, Instruction instr, int indirectionIndex
|
|
||||||
) {
|
|
||||||
Ssa::hasRawIndirectInstruction(call, indirectionIndex) and
|
|
||||||
instructionForFullyConvertedCall(instr, call)
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Holds if `node` is an indirect operand with columns `(operand, indirectionIndex)`, and
|
* Holds if `node` is an indirect operand with columns `(operand, indirectionIndex)`, and
|
||||||
* `operand` represents a use of the fully converted value of `call`.
|
* `operand` represents a use of the fully converted value of `call`.
|
||||||
*/
|
*/
|
||||||
private predicate hasOperand(Node node, CallInstruction call, int indirectionIndex, Operand operand) {
|
private predicate hasOperand(Node node, CallInstruction call, int indirectionIndex, Operand operand) {
|
||||||
indirectReturnOutNodeOperand0(call, operand, indirectionIndex) and
|
operandForFullyConvertedCall(operand, call) and
|
||||||
hasOperandAndIndex(node, operand, indirectionIndex)
|
hasOperandAndIndex(node, operand, indirectionIndex)
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -813,7 +799,7 @@ private predicate hasOperand(Node node, CallInstruction call, int indirectionInd
|
|||||||
private predicate hasInstruction(
|
private predicate hasInstruction(
|
||||||
Node node, CallInstruction call, int indirectionIndex, Instruction instr
|
Node node, CallInstruction call, int indirectionIndex, Instruction instr
|
||||||
) {
|
) {
|
||||||
indirectReturnOutNodeInstruction0(call, instr, indirectionIndex) and
|
instructionForFullyConvertedCall(instr, call) and
|
||||||
hasInstructionAndIndex(node, instr, indirectionIndex)
|
hasInstructionAndIndex(node, instr, indirectionIndex)
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -1534,6 +1520,25 @@ private module Cached {
|
|||||||
)
|
)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Holds if `operand.getDef() = instr`, but there exists a `StoreInstruction` that
|
||||||
|
* writes to an address that is equivalent to the value computed by `instr` in
|
||||||
|
* between `instr` and `operand`, and therefore there should not be flow from `*instr`
|
||||||
|
* to `*operand`.
|
||||||
|
*/
|
||||||
|
pragma[nomagic]
|
||||||
|
private predicate isStoredToBetween(Instruction instr, Operand operand) {
|
||||||
|
simpleOperandLocalFlowStep(pragma[only_bind_into](instr), pragma[only_bind_into](operand)) and
|
||||||
|
exists(StoreInstruction store, IRBlock block, int storeIndex, int instrIndex, int operandIndex |
|
||||||
|
store.getDestinationAddress() = instr and
|
||||||
|
block.getInstruction(storeIndex) = store and
|
||||||
|
block.getInstruction(instrIndex) = instr and
|
||||||
|
block.getInstruction(operandIndex) = operand.getUse() and
|
||||||
|
instrIndex < storeIndex and
|
||||||
|
storeIndex < operandIndex
|
||||||
|
)
|
||||||
|
}
|
||||||
|
|
||||||
private predicate indirectionInstructionFlow(
|
private predicate indirectionInstructionFlow(
|
||||||
RawIndirectInstruction nodeFrom, IndirectOperand nodeTo
|
RawIndirectInstruction nodeFrom, IndirectOperand nodeTo
|
||||||
) {
|
) {
|
||||||
@@ -1543,7 +1548,8 @@ private module Cached {
|
|||||||
simpleOperandLocalFlowStep(pragma[only_bind_into](instr), pragma[only_bind_into](operand))
|
simpleOperandLocalFlowStep(pragma[only_bind_into](instr), pragma[only_bind_into](operand))
|
||||||
|
|
|
|
||||||
hasOperandAndIndex(nodeTo, operand, pragma[only_bind_into](indirectionIndex)) and
|
hasOperandAndIndex(nodeTo, operand, pragma[only_bind_into](indirectionIndex)) and
|
||||||
hasInstructionAndIndex(nodeFrom, instr, pragma[only_bind_into](indirectionIndex))
|
hasInstructionAndIndex(nodeFrom, instr, pragma[only_bind_into](indirectionIndex)) and
|
||||||
|
not isStoredToBetween(instr, operand)
|
||||||
)
|
)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@@ -10,32 +10,35 @@ private import ssa0.SsaInternals as SsaInternals0
|
|||||||
import SsaInternalsCommon
|
import SsaInternalsCommon
|
||||||
|
|
||||||
private module SourceVariables {
|
private module SourceVariables {
|
||||||
int getMaxIndirectionForIRVariable(IRVariable var) {
|
|
||||||
exists(Type type, boolean isGLValue |
|
|
||||||
var.getLanguageType().hasType(type, isGLValue) and
|
|
||||||
if isGLValue = true
|
|
||||||
then result = 1 + getMaxIndirectionsForType(type)
|
|
||||||
else result = getMaxIndirectionsForType(type)
|
|
||||||
)
|
|
||||||
}
|
|
||||||
|
|
||||||
cached
|
cached
|
||||||
private newtype TSourceVariable =
|
private newtype TSourceVariable =
|
||||||
TSourceIRVariable(BaseIRVariable baseVar, int ind) {
|
TMkSourceVariable(SsaInternals0::SourceVariable base, int ind) {
|
||||||
ind = [0 .. getMaxIndirectionForIRVariable(baseVar.getIRVariable())]
|
ind = [0 .. countIndirectionsForCppType(base.getLanguageType()) + 1]
|
||||||
} or
|
|
||||||
TCallVariable(AllocationInstruction call, int ind) {
|
|
||||||
ind = [0 .. countIndirectionsForCppType(getResultLanguageType(call))]
|
|
||||||
}
|
}
|
||||||
|
|
||||||
abstract class SourceVariable extends TSourceVariable {
|
class SourceVariable extends TSourceVariable {
|
||||||
|
SsaInternals0::SourceVariable base;
|
||||||
int ind;
|
int ind;
|
||||||
|
|
||||||
bindingset[ind]
|
SourceVariable() { this = TMkSourceVariable(base, ind) }
|
||||||
SourceVariable() { any() }
|
|
||||||
|
/** Gets the IR variable associated with this `SourceVariable`, if any. */
|
||||||
|
IRVariable getIRVariable() { result = base.(BaseIRVariable).getIRVariable() }
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Gets the base source variable (i.e., the variable without any
|
||||||
|
* indirections) of this source variable.
|
||||||
|
*/
|
||||||
|
SsaInternals0::SourceVariable getBaseVariable() { result = base }
|
||||||
|
|
||||||
/** Gets a textual representation of this element. */
|
/** Gets a textual representation of this element. */
|
||||||
abstract string toString();
|
string toString() {
|
||||||
|
ind = 0 and
|
||||||
|
result = this.getBaseVariable().toString()
|
||||||
|
or
|
||||||
|
ind > 0 and
|
||||||
|
result = this.getBaseVariable().toString() + " indirection"
|
||||||
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Gets the number of loads performed on the base source variable
|
* Gets the number of loads performed on the base source variable
|
||||||
@@ -43,65 +46,19 @@ private module SourceVariables {
|
|||||||
*/
|
*/
|
||||||
int getIndirection() { result = ind }
|
int getIndirection() { result = ind }
|
||||||
|
|
||||||
/**
|
|
||||||
* Gets the base source variable (i.e., the variable without any
|
|
||||||
* indirections) of this source variable.
|
|
||||||
*/
|
|
||||||
abstract BaseSourceVariable getBaseVariable();
|
|
||||||
|
|
||||||
/** Holds if this variable is a glvalue. */
|
/** Holds if this variable is a glvalue. */
|
||||||
predicate isGLValue() { none() }
|
predicate isGLValue() { ind = 0 }
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Gets the type of this source variable. If `isGLValue()` holds, then
|
* Gets the type of this source variable. If `isGLValue()` holds, then
|
||||||
* the type of this source variable should be thought of as "pointer
|
* the type of this source variable should be thought of as "pointer
|
||||||
* to `getType()`".
|
* to `getType()`".
|
||||||
*/
|
*/
|
||||||
abstract DataFlowType getType();
|
DataFlowType getType() {
|
||||||
}
|
if this.isGLValue()
|
||||||
|
then result = base.getType()
|
||||||
class SourceIRVariable extends SourceVariable, TSourceIRVariable {
|
else result = getTypeImpl(base.getType(), ind - 1)
|
||||||
BaseIRVariable var;
|
|
||||||
|
|
||||||
SourceIRVariable() { this = TSourceIRVariable(var, ind) }
|
|
||||||
|
|
||||||
IRVariable getIRVariable() { result = var.getIRVariable() }
|
|
||||||
|
|
||||||
override BaseIRVariable getBaseVariable() { result.getIRVariable() = this.getIRVariable() }
|
|
||||||
|
|
||||||
override string toString() {
|
|
||||||
ind = 0 and
|
|
||||||
result = this.getIRVariable().toString()
|
|
||||||
or
|
|
||||||
ind > 0 and
|
|
||||||
result = this.getIRVariable().toString() + " indirection"
|
|
||||||
}
|
}
|
||||||
|
|
||||||
override predicate isGLValue() { ind = 0 }
|
|
||||||
|
|
||||||
override DataFlowType getType() {
|
|
||||||
if ind = 0 then result = var.getType() else result = getTypeImpl(var.getType(), ind - 1)
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
class CallVariable extends SourceVariable, TCallVariable {
|
|
||||||
AllocationInstruction call;
|
|
||||||
|
|
||||||
CallVariable() { this = TCallVariable(call, ind) }
|
|
||||||
|
|
||||||
AllocationInstruction getCall() { result = call }
|
|
||||||
|
|
||||||
override BaseCallVariable getBaseVariable() { result.getCallInstruction() = call }
|
|
||||||
|
|
||||||
override string toString() {
|
|
||||||
ind = 0 and
|
|
||||||
result = "Call"
|
|
||||||
or
|
|
||||||
ind > 0 and
|
|
||||||
result = "Call indirection"
|
|
||||||
}
|
|
||||||
|
|
||||||
override DataFlowType getType() { result = getTypeImpl(call.getResultType(), ind) }
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -137,8 +94,9 @@ predicate hasRawIndirectInstruction(Instruction instr, int indirectionIndex) {
|
|||||||
|
|
||||||
cached
|
cached
|
||||||
private newtype TDefOrUseImpl =
|
private newtype TDefOrUseImpl =
|
||||||
TDefImpl(Operand address, int indirectionIndex) {
|
TDefImpl(BaseSourceVariableInstruction base, Operand address, int indirectionIndex) {
|
||||||
exists(Instruction base | isDef(_, _, address, base, _, indirectionIndex) |
|
isDef(_, _, address, base, _, indirectionIndex) and
|
||||||
|
(
|
||||||
// We only include the definition if the SSA pruning stage
|
// We only include the definition if the SSA pruning stage
|
||||||
// concluded that the definition is live after the write.
|
// concluded that the definition is live after the write.
|
||||||
any(SsaInternals0::Def def).getAddressOperand() = address
|
any(SsaInternals0::Def def).getAddressOperand() = address
|
||||||
@@ -148,8 +106,8 @@ private newtype TDefOrUseImpl =
|
|||||||
base.(VariableAddressInstruction).getAstVariable() instanceof GlobalLikeVariable
|
base.(VariableAddressInstruction).getAstVariable() instanceof GlobalLikeVariable
|
||||||
)
|
)
|
||||||
} or
|
} or
|
||||||
TUseImpl(Operand operand, int indirectionIndex) {
|
TUseImpl(BaseSourceVariableInstruction base, Operand operand, int indirectionIndex) {
|
||||||
isUse(_, operand, _, _, indirectionIndex) and
|
isUse(_, operand, base, _, indirectionIndex) and
|
||||||
not isDef(_, _, operand, _, _, _)
|
not isDef(_, _, operand, _, _, _)
|
||||||
} or
|
} or
|
||||||
TGlobalUse(GlobalLikeVariable v, IRFunction f, int indirectionIndex) {
|
TGlobalUse(GlobalLikeVariable v, IRFunction f, int indirectionIndex) {
|
||||||
@@ -236,7 +194,7 @@ abstract private class DefOrUseImpl extends TDefOrUseImpl {
|
|||||||
|
|
||||||
/**
|
/**
|
||||||
* Gets the instruction that computes the base of this definition or use.
|
* Gets the instruction that computes the base of this definition or use.
|
||||||
* This is always a `VariableAddressInstruction` or an `AllocationInstruction`.
|
* This is always a `VariableAddressInstruction` or an `CallInstruction`.
|
||||||
*/
|
*/
|
||||||
abstract BaseSourceVariableInstruction getBase();
|
abstract BaseSourceVariableInstruction getBase();
|
||||||
|
|
||||||
@@ -308,15 +266,17 @@ abstract class DefImpl extends DefOrUseImpl {
|
|||||||
}
|
}
|
||||||
|
|
||||||
private class DirectDef extends DefImpl, TDefImpl {
|
private class DirectDef extends DefImpl, TDefImpl {
|
||||||
DirectDef() { this = TDefImpl(address, ind) }
|
BaseSourceVariableInstruction base;
|
||||||
|
|
||||||
override BaseSourceVariableInstruction getBase() { isDef(_, _, address, result, _, _) }
|
DirectDef() { this = TDefImpl(base, address, ind) }
|
||||||
|
|
||||||
override int getIndirection() { isDef(_, _, address, _, result, ind) }
|
override BaseSourceVariableInstruction getBase() { result = base }
|
||||||
|
|
||||||
override Node0Impl getValue() { isDef(_, result, address, _, _, _) }
|
override int getIndirection() { isDef(_, _, address, base, result, ind) }
|
||||||
|
|
||||||
override predicate isCertain() { isDef(true, _, address, _, _, ind) }
|
override Node0Impl getValue() { isDef(_, result, address, base, _, _) }
|
||||||
|
|
||||||
|
override predicate isCertain() { isDef(true, _, address, base, _, ind) }
|
||||||
}
|
}
|
||||||
|
|
||||||
private class IteratorDef extends DefImpl, TIteratorDef {
|
private class IteratorDef extends DefImpl, TIteratorDef {
|
||||||
@@ -359,6 +319,7 @@ abstract class UseImpl extends DefOrUseImpl {
|
|||||||
|
|
||||||
abstract private class OperandBasedUse extends UseImpl {
|
abstract private class OperandBasedUse extends UseImpl {
|
||||||
Operand operand;
|
Operand operand;
|
||||||
|
BaseSourceVariableInstruction base;
|
||||||
|
|
||||||
bindingset[ind]
|
bindingset[ind]
|
||||||
OperandBasedUse() { any() }
|
OperandBasedUse() { any() }
|
||||||
@@ -366,50 +327,44 @@ abstract private class OperandBasedUse extends UseImpl {
|
|||||||
final override predicate hasIndexInBlock(IRBlock block, int index) {
|
final override predicate hasIndexInBlock(IRBlock block, int index) {
|
||||||
// See the comment in `ssa0`'s `OperandBasedUse` for an explanation of this
|
// See the comment in `ssa0`'s `OperandBasedUse` for an explanation of this
|
||||||
// predicate's implementation.
|
// predicate's implementation.
|
||||||
exists(BaseSourceVariableInstruction base | base = this.getBase() |
|
if base.getAst() = any(Cpp::PostfixCrementOperation c).getOperand()
|
||||||
if base.getAst() = any(Cpp::PostfixCrementOperation c).getOperand()
|
then
|
||||||
then
|
exists(Operand op, int indirectionIndex, int indirection |
|
||||||
exists(Operand op, int indirectionIndex, int indirection |
|
indirectionIndex = this.getIndirectionIndex() and
|
||||||
indirectionIndex = this.getIndirectionIndex() and
|
indirection = this.getIndirection() and
|
||||||
indirection = this.getIndirection() and
|
op =
|
||||||
op =
|
min(Operand cand, int i |
|
||||||
min(Operand cand, int i |
|
isUse(_, cand, base, indirection, indirectionIndex) and
|
||||||
isUse(_, cand, base, indirection, indirectionIndex) and
|
block.getInstruction(i) = cand.getUse()
|
||||||
block.getInstruction(i) = cand.getUse()
|
|
|
||||||
|
|
cand order by i
|
||||||
cand order by i
|
) and
|
||||||
) and
|
block.getInstruction(index) = op.getUse()
|
||||||
block.getInstruction(index) = op.getUse()
|
)
|
||||||
)
|
else operand.getUse() = block.getInstruction(index)
|
||||||
else operand.getUse() = block.getInstruction(index)
|
|
||||||
)
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
final override BaseSourceVariableInstruction getBase() { result = base }
|
||||||
|
|
||||||
final Operand getOperand() { result = operand }
|
final Operand getOperand() { result = operand }
|
||||||
|
|
||||||
final override Cpp::Location getLocation() { result = operand.getLocation() }
|
final override Cpp::Location getLocation() { result = operand.getLocation() }
|
||||||
}
|
}
|
||||||
|
|
||||||
private class DirectUse extends OperandBasedUse, TUseImpl {
|
private class DirectUse extends OperandBasedUse, TUseImpl {
|
||||||
DirectUse() { this = TUseImpl(operand, ind) }
|
DirectUse() { this = TUseImpl(base, operand, ind) }
|
||||||
|
|
||||||
override int getIndirection() { isUse(_, operand, _, result, ind) }
|
override int getIndirection() { isUse(_, operand, base, result, ind) }
|
||||||
|
|
||||||
override BaseSourceVariableInstruction getBase() { isUse(_, operand, result, _, ind) }
|
override predicate isCertain() { isUse(true, operand, base, _, ind) }
|
||||||
|
|
||||||
override predicate isCertain() { isUse(true, operand, _, _, ind) }
|
|
||||||
|
|
||||||
override Node getNode() { nodeHasOperand(result, operand, ind) }
|
override Node getNode() { nodeHasOperand(result, operand, ind) }
|
||||||
}
|
}
|
||||||
|
|
||||||
private class IteratorUse extends OperandBasedUse, TIteratorUse {
|
private class IteratorUse extends OperandBasedUse, TIteratorUse {
|
||||||
BaseSourceVariableInstruction container;
|
IteratorUse() { this = TIteratorUse(operand, base, ind) }
|
||||||
|
|
||||||
IteratorUse() { this = TIteratorUse(operand, container, ind) }
|
override int getIndirection() { isIteratorUse(base, operand, result, ind) }
|
||||||
|
|
||||||
override int getIndirection() { isIteratorUse(container, operand, result, ind) }
|
|
||||||
|
|
||||||
override BaseSourceVariableInstruction getBase() { result = container }
|
|
||||||
|
|
||||||
override predicate isCertain() { none() }
|
override predicate isCertain() { none() }
|
||||||
|
|
||||||
|
|||||||
@@ -6,6 +6,7 @@ private import DataFlowImplCommon as DataFlowImplCommon
|
|||||||
private import DataFlowUtil
|
private import DataFlowUtil
|
||||||
private import semmle.code.cpp.models.interfaces.PointerWrapper
|
private import semmle.code.cpp.models.interfaces.PointerWrapper
|
||||||
private import DataFlowPrivate
|
private import DataFlowPrivate
|
||||||
|
private import semmle.code.cpp.ir.ValueNumbering
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Holds if `operand` is an operand that is not used by the dataflow library.
|
* Holds if `operand` is an operand that is not used by the dataflow library.
|
||||||
@@ -146,14 +147,6 @@ int countIndirectionsForCppType(LanguageType langType) {
|
|||||||
)
|
)
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
|
||||||
* A `CallInstruction` that calls an allocation function such
|
|
||||||
* as `malloc` or `operator new`.
|
|
||||||
*/
|
|
||||||
class AllocationInstruction extends CallInstruction {
|
|
||||||
AllocationInstruction() { this.getStaticCallTarget() instanceof Cpp::AllocationFunction }
|
|
||||||
}
|
|
||||||
|
|
||||||
private predicate isIndirectionType(Type t) { t instanceof Indirection }
|
private predicate isIndirectionType(Type t) { t instanceof Indirection }
|
||||||
|
|
||||||
private predicate hasUnspecifiedBaseType(Indirection t, Type base) {
|
private predicate hasUnspecifiedBaseType(Indirection t, Type base) {
|
||||||
@@ -368,17 +361,22 @@ newtype TBaseSourceVariable =
|
|||||||
// Each IR variable gets its own source variable
|
// Each IR variable gets its own source variable
|
||||||
TBaseIRVariable(IRVariable var) or
|
TBaseIRVariable(IRVariable var) or
|
||||||
// Each allocation gets its own source variable
|
// Each allocation gets its own source variable
|
||||||
TBaseCallVariable(AllocationInstruction call)
|
TBaseCallVariable(CallInstruction call) { not call.getResultIRType() instanceof IRVoidType }
|
||||||
|
|
||||||
abstract class BaseSourceVariable extends TBaseSourceVariable {
|
abstract private class AbstractBaseSourceVariable extends TBaseSourceVariable {
|
||||||
/** Gets a textual representation of this element. */
|
/** Gets a textual representation of this element. */
|
||||||
abstract string toString();
|
abstract string toString();
|
||||||
|
|
||||||
/** Gets the type of this base source variable. */
|
/** Gets the type of this base source variable. */
|
||||||
abstract DataFlowType getType();
|
final DataFlowType getType() { this.getLanguageType().hasUnspecifiedType(result, _) }
|
||||||
|
|
||||||
|
/** Gets the `CppType` of this base source variable. */
|
||||||
|
abstract CppType getLanguageType();
|
||||||
}
|
}
|
||||||
|
|
||||||
class BaseIRVariable extends BaseSourceVariable, TBaseIRVariable {
|
final class BaseSourceVariable = AbstractBaseSourceVariable;
|
||||||
|
|
||||||
|
class BaseIRVariable extends AbstractBaseSourceVariable, TBaseIRVariable {
|
||||||
IRVariable var;
|
IRVariable var;
|
||||||
|
|
||||||
IRVariable getIRVariable() { result = var }
|
IRVariable getIRVariable() { result = var }
|
||||||
@@ -387,19 +385,19 @@ class BaseIRVariable extends BaseSourceVariable, TBaseIRVariable {
|
|||||||
|
|
||||||
override string toString() { result = var.toString() }
|
override string toString() { result = var.toString() }
|
||||||
|
|
||||||
override DataFlowType getType() { result = var.getType() }
|
override CppType getLanguageType() { result = var.getLanguageType() }
|
||||||
}
|
}
|
||||||
|
|
||||||
class BaseCallVariable extends BaseSourceVariable, TBaseCallVariable {
|
class BaseCallVariable extends AbstractBaseSourceVariable, TBaseCallVariable {
|
||||||
AllocationInstruction call;
|
CallInstruction call;
|
||||||
|
|
||||||
BaseCallVariable() { this = TBaseCallVariable(call) }
|
BaseCallVariable() { this = TBaseCallVariable(call) }
|
||||||
|
|
||||||
AllocationInstruction getCallInstruction() { result = call }
|
CallInstruction getCallInstruction() { result = call }
|
||||||
|
|
||||||
override string toString() { result = call.toString() }
|
override string toString() { result = call.toString() }
|
||||||
|
|
||||||
override DataFlowType getType() { result = call.getResultType() }
|
override CppType getLanguageType() { result = getResultLanguageType(call) }
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
@@ -499,8 +497,7 @@ private class BaseIRVariableInstruction extends BaseSourceVariableInstruction,
|
|||||||
override BaseIRVariable getBaseSourceVariable() { result.getIRVariable() = this.getIRVariable() }
|
override BaseIRVariable getBaseSourceVariable() { result.getIRVariable() = this.getIRVariable() }
|
||||||
}
|
}
|
||||||
|
|
||||||
private class BaseAllocationInstruction extends BaseSourceVariableInstruction, AllocationInstruction
|
private class BaseCallInstruction extends BaseSourceVariableInstruction, CallInstruction {
|
||||||
{
|
|
||||||
override BaseCallVariable getBaseSourceVariable() { result.getCallInstruction() = this }
|
override BaseCallVariable getBaseSourceVariable() { result.getCallInstruction() = this }
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -868,7 +865,7 @@ private module Cached {
|
|||||||
* to a specific address.
|
* to a specific address.
|
||||||
*/
|
*/
|
||||||
private predicate isCertainAddress(Operand operand) {
|
private predicate isCertainAddress(Operand operand) {
|
||||||
operand.getDef() instanceof VariableAddressInstruction
|
valueNumberOfOperand(operand).getAnInstruction() instanceof VariableAddressInstruction
|
||||||
or
|
or
|
||||||
operand.getType() instanceof Cpp::ReferenceType
|
operand.getType() instanceof Cpp::ReferenceType
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -0,0 +1,10 @@
|
|||||||
|
/**
|
||||||
|
* Provides C++-specific definitions for use in the taint tracking library.
|
||||||
|
*/
|
||||||
|
|
||||||
|
private import codeql.dataflow.TaintTracking
|
||||||
|
private import DataFlowImplSpecific
|
||||||
|
|
||||||
|
module CppTaintTracking implements InputSig<CppDataFlow> {
|
||||||
|
import TaintTrackingUtil
|
||||||
|
}
|
||||||
@@ -112,7 +112,7 @@ predicate defaultAdditionalTaintStep(DataFlow::Node src, DataFlow::Node sink) {
|
|||||||
* of `c` at sinks and inputs to additional taint steps.
|
* of `c` at sinks and inputs to additional taint steps.
|
||||||
*/
|
*/
|
||||||
bindingset[node]
|
bindingset[node]
|
||||||
predicate defaultImplicitTaintRead(DataFlow::Node node, DataFlow::Content c) { none() }
|
predicate defaultImplicitTaintRead(DataFlow::Node node, DataFlow::ContentSet c) { none() }
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Holds if `node` should be a sanitizer in all global taint flow configurations
|
* Holds if `node` should be a sanitizer in all global taint flow configurations
|
||||||
|
|||||||
@@ -15,15 +15,12 @@ private import semmle.code.cpp.ir.dataflow.internal.DataFlowUtil
|
|||||||
private import semmle.code.cpp.ir.dataflow.internal.SsaInternalsCommon
|
private import semmle.code.cpp.ir.dataflow.internal.SsaInternalsCommon
|
||||||
|
|
||||||
private module SourceVariables {
|
private module SourceVariables {
|
||||||
class SourceVariable instanceof BaseSourceVariable {
|
class SourceVariable extends BaseSourceVariable {
|
||||||
string toString() { result = BaseSourceVariable.super.toString() }
|
/**
|
||||||
|
* Gets the base source variable of this `SourceVariable`.
|
||||||
|
*/
|
||||||
BaseSourceVariable getBaseVariable() { result = this }
|
BaseSourceVariable getBaseVariable() { result = this }
|
||||||
}
|
}
|
||||||
|
|
||||||
class SourceIRVariable = BaseIRVariable;
|
|
||||||
|
|
||||||
class CallVariable = BaseCallVariable;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
import SourceVariables
|
import SourceVariables
|
||||||
|
|||||||
@@ -1,75 +0,0 @@
|
|||||||
/**
|
|
||||||
* Provides classes for performing local (intra-procedural) and
|
|
||||||
* global (inter-procedural) taint-tracking analyses.
|
|
||||||
*/
|
|
||||||
|
|
||||||
import TaintTrackingParameter::Public
|
|
||||||
private import TaintTrackingParameter::Private
|
|
||||||
|
|
||||||
private module AddTaintDefaults<DataFlowInternal::FullStateConfigSig Config> implements
|
|
||||||
DataFlowInternal::FullStateConfigSig
|
|
||||||
{
|
|
||||||
import Config
|
|
||||||
|
|
||||||
predicate isBarrier(DataFlow::Node node) {
|
|
||||||
Config::isBarrier(node) or defaultTaintSanitizer(node)
|
|
||||||
}
|
|
||||||
|
|
||||||
predicate isAdditionalFlowStep(DataFlow::Node node1, DataFlow::Node node2) {
|
|
||||||
Config::isAdditionalFlowStep(node1, node2) or
|
|
||||||
defaultAdditionalTaintStep(node1, node2)
|
|
||||||
}
|
|
||||||
|
|
||||||
predicate allowImplicitRead(DataFlow::Node node, DataFlow::ContentSet c) {
|
|
||||||
Config::allowImplicitRead(node, c)
|
|
||||||
or
|
|
||||||
(
|
|
||||||
Config::isSink(node) or
|
|
||||||
Config::isSink(node, _) or
|
|
||||||
Config::isAdditionalFlowStep(node, _) or
|
|
||||||
Config::isAdditionalFlowStep(node, _, _, _)
|
|
||||||
) and
|
|
||||||
defaultImplicitTaintRead(node, c)
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Constructs a global taint tracking computation.
|
|
||||||
*/
|
|
||||||
module Global<DataFlow::ConfigSig Config> implements DataFlow::GlobalFlowSig {
|
|
||||||
private module Config0 implements DataFlowInternal::FullStateConfigSig {
|
|
||||||
import DataFlowInternal::DefaultState<Config>
|
|
||||||
import Config
|
|
||||||
}
|
|
||||||
|
|
||||||
private module C implements DataFlowInternal::FullStateConfigSig {
|
|
||||||
import AddTaintDefaults<Config0>
|
|
||||||
}
|
|
||||||
|
|
||||||
import DataFlowInternal::Impl<C>
|
|
||||||
}
|
|
||||||
|
|
||||||
/** DEPRECATED: Use `Global` instead. */
|
|
||||||
deprecated module Make<DataFlow::ConfigSig Config> implements DataFlow::GlobalFlowSig {
|
|
||||||
import Global<Config>
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Constructs a global taint tracking computation using flow state.
|
|
||||||
*/
|
|
||||||
module GlobalWithState<DataFlow::StateConfigSig Config> implements DataFlow::GlobalFlowSig {
|
|
||||||
private module Config0 implements DataFlowInternal::FullStateConfigSig {
|
|
||||||
import Config
|
|
||||||
}
|
|
||||||
|
|
||||||
private module C implements DataFlowInternal::FullStateConfigSig {
|
|
||||||
import AddTaintDefaults<Config0>
|
|
||||||
}
|
|
||||||
|
|
||||||
import DataFlowInternal::Impl<C>
|
|
||||||
}
|
|
||||||
|
|
||||||
/** DEPRECATED: Use `GlobalWithState` instead. */
|
|
||||||
deprecated module MakeWithState<DataFlow::StateConfigSig Config> implements DataFlow::GlobalFlowSig {
|
|
||||||
import GlobalWithState<Config>
|
|
||||||
}
|
|
||||||
@@ -574,16 +574,6 @@ module RangeStage<
|
|||||||
)
|
)
|
||||||
}
|
}
|
||||||
|
|
||||||
/** Holds if `e >= 1` as determined by sign analysis. */
|
|
||||||
private predicate strictlyPositiveIntegralExpr(SemExpr e) {
|
|
||||||
semStrictlyPositive(e) and getTrackedType(e) instanceof SemIntegerType
|
|
||||||
}
|
|
||||||
|
|
||||||
/** Holds if `e <= -1` as determined by sign analysis. */
|
|
||||||
private predicate strictlyNegativeIntegralExpr(SemExpr e) {
|
|
||||||
semStrictlyNegative(e) and getTrackedType(e) instanceof SemIntegerType
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Holds if `e1 + delta` is a valid bound for `e2`.
|
* Holds if `e1 + delta` is a valid bound for `e2`.
|
||||||
* - `upper = true` : `e2 <= e1 + delta`
|
* - `upper = true` : `e2 <= e1 + delta`
|
||||||
@@ -597,27 +587,6 @@ module RangeStage<
|
|||||||
delta = D::fromInt(0) and
|
delta = D::fromInt(0) and
|
||||||
(upper = true or upper = false)
|
(upper = true or upper = false)
|
||||||
or
|
or
|
||||||
exists(SemExpr x, SemSubExpr sub |
|
|
||||||
e2 = sub and
|
|
||||||
sub.getLeftOperand() = e1 and
|
|
||||||
sub.getRightOperand() = x
|
|
||||||
|
|
|
||||||
// `x instanceof ConstantIntegerExpr` is covered by valueFlowStep
|
|
||||||
not x instanceof SemConstantIntegerExpr and
|
|
||||||
if strictlyPositiveIntegralExpr(x)
|
|
||||||
then upper = true and delta = D::fromInt(-1)
|
|
||||||
else
|
|
||||||
if semPositive(x)
|
|
||||||
then upper = true and delta = D::fromInt(0)
|
|
||||||
else
|
|
||||||
if strictlyNegativeIntegralExpr(x)
|
|
||||||
then upper = false and delta = D::fromInt(1)
|
|
||||||
else
|
|
||||||
if semNegative(x)
|
|
||||||
then upper = false and delta = D::fromInt(0)
|
|
||||||
else none()
|
|
||||||
)
|
|
||||||
or
|
|
||||||
e2.(SemRemExpr).getRightOperand() = e1 and
|
e2.(SemRemExpr).getRightOperand() = e1 and
|
||||||
semPositive(e1) and
|
semPositive(e1) and
|
||||||
delta = D::fromInt(-1) and
|
delta = D::fromInt(-1) and
|
||||||
@@ -1137,6 +1106,23 @@ module RangeStage<
|
|||||||
b = bRight and origdelta = odRight and reason = rRight and bLeft instanceof SemZeroBound
|
b = bRight and origdelta = odRight and reason = rRight and bLeft instanceof SemZeroBound
|
||||||
)
|
)
|
||||||
or
|
or
|
||||||
|
exists(D::Delta dLeft, D::Delta dRight, boolean fbeLeft, boolean fbeRight |
|
||||||
|
boundedSubOperandLeft(e, upper, b, dLeft, fbeLeft, origdelta, reason) and
|
||||||
|
boundedSubOperandRight(e, upper, dRight, fbeRight) and
|
||||||
|
// when `upper` is `true` we have:
|
||||||
|
// left <= b + dLeft
|
||||||
|
// right >= 0 + dRight
|
||||||
|
// left - right <= b + dLeft - (0 + dRight)
|
||||||
|
// = b + (dLeft - dRight)
|
||||||
|
// and when `upper` is `false` we have:
|
||||||
|
// left >= b + dLeft
|
||||||
|
// right <= 0 + dRight
|
||||||
|
// left - right >= b + dLeft - (0 + dRight)
|
||||||
|
// = b + (dLeft - dRight)
|
||||||
|
delta = D::fromFloat(D::toFloat(dLeft) - D::toFloat(dRight)) and
|
||||||
|
fromBackEdge = fbeLeft.booleanOr(fbeRight)
|
||||||
|
)
|
||||||
|
or
|
||||||
exists(
|
exists(
|
||||||
SemRemExpr rem, D::Delta d_max, D::Delta d1, D::Delta d2, boolean fbe1, boolean fbe2,
|
SemRemExpr rem, D::Delta d_max, D::Delta d1, D::Delta d2, boolean fbe1, boolean fbe2,
|
||||||
D::Delta od1, D::Delta od2, SemReason r1, SemReason r2
|
D::Delta od1, D::Delta od2, SemReason r1, SemReason r2
|
||||||
@@ -1201,6 +1187,37 @@ module RangeStage<
|
|||||||
)
|
)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Holds if `sub = left - right` and `left <= b + delta` if `upper` is `true`
|
||||||
|
* and `left >= b + delta` is `upper` is `false`.
|
||||||
|
*/
|
||||||
|
pragma[nomagic]
|
||||||
|
private predicate boundedSubOperandLeft(
|
||||||
|
SemSubExpr sub, boolean upper, SemBound b, D::Delta delta, boolean fromBackEdge,
|
||||||
|
D::Delta origdelta, SemReason reason
|
||||||
|
) {
|
||||||
|
// `semValueFlowStep` already handles the case where one of the operands is a constant.
|
||||||
|
not semValueFlowStep(sub, _, _) and
|
||||||
|
bounded(sub.getLeftOperand(), b, delta, upper, fromBackEdge, origdelta, reason)
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Holds if `sub = left - right` and `right <= 0 + delta` if `upper` is `false`
|
||||||
|
* and `right >= 0 + delta` is `upper` is `true`.
|
||||||
|
*
|
||||||
|
* Note that the boolean value of `upper` is flipped compared to many other predicates in
|
||||||
|
* this file. This ensures a clean join at the call-site.
|
||||||
|
*/
|
||||||
|
pragma[nomagic]
|
||||||
|
private predicate boundedSubOperandRight(
|
||||||
|
SemSubExpr sub, boolean upper, D::Delta delta, boolean fromBackEdge
|
||||||
|
) {
|
||||||
|
// `semValueFlowStep` already handles the case where one of the operands is a constant.
|
||||||
|
not semValueFlowStep(sub, _, _) and
|
||||||
|
bounded(sub.getRightOperand(), any(SemZeroBound zb), delta, upper.booleanNot(), fromBackEdge, _,
|
||||||
|
_)
|
||||||
|
}
|
||||||
|
|
||||||
pragma[nomagic]
|
pragma[nomagic]
|
||||||
private predicate boundedRemExpr(
|
private predicate boundedRemExpr(
|
||||||
SemRemExpr rem, boolean upper, D::Delta delta, boolean fromBackEdge, D::Delta origdelta,
|
SemRemExpr rem, boolean upper, D::Delta delta, boolean fromBackEdge, D::Delta origdelta,
|
||||||
|
|||||||
@@ -53,7 +53,7 @@ private class ArgvSource extends LocalFlowSource {
|
|||||||
exists(Function main, Parameter argv |
|
exists(Function main, Parameter argv |
|
||||||
main.hasGlobalName("main") and
|
main.hasGlobalName("main") and
|
||||||
main.getParameter(1) = argv and
|
main.getParameter(1) = argv and
|
||||||
this.asParameter(_) = argv
|
this.asParameter(2) = argv
|
||||||
)
|
)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@@ -96,7 +96,7 @@ predicate hasSize(HeuristicAllocationExpr alloc, DataFlow::Node n, int state) {
|
|||||||
* but because there's a strict comparison that compares `n` against the size of the allocation this
|
* but because there's a strict comparison that compares `n` against the size of the allocation this
|
||||||
* snippet is fine.
|
* snippet is fine.
|
||||||
*/
|
*/
|
||||||
module SizeBarrier {
|
private module SizeBarrier {
|
||||||
private module SizeBarrierConfig implements DataFlow::ConfigSig {
|
private module SizeBarrierConfig implements DataFlow::ConfigSig {
|
||||||
predicate isSource(DataFlow::Node source) {
|
predicate isSource(DataFlow::Node source) {
|
||||||
// The sources is the same as in the sources for the second
|
// The sources is the same as in the sources for the second
|
||||||
@@ -104,35 +104,60 @@ module SizeBarrier {
|
|||||||
hasSize(_, source, _)
|
hasSize(_, source, _)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Holds if `small <= large + k` holds if `g` evaluates to `testIsTrue`.
|
||||||
|
*/
|
||||||
additional predicate isSink(
|
additional predicate isSink(
|
||||||
DataFlow::Node left, DataFlow::Node right, IRGuardCondition g, int k, boolean testIsTrue
|
DataFlow::Node small, DataFlow::Node large, IRGuardCondition g, int k, boolean testIsTrue
|
||||||
) {
|
) {
|
||||||
// The sink is any "large" side of a relational comparison. i.e., the `right` expression
|
// The sink is any "large" side of a relational comparison. i.e., the `large` expression
|
||||||
// in a guard such as `left < right + k`.
|
// in a guard such as `small <= large + k`.
|
||||||
g.comparesLt(left.asOperand(), right.asOperand(), k, true, testIsTrue)
|
g.comparesLt(small.asOperand(), large.asOperand(), k + 1, true, testIsTrue)
|
||||||
}
|
}
|
||||||
|
|
||||||
predicate isSink(DataFlow::Node sink) { isSink(_, sink, _, _, _) }
|
predicate isSink(DataFlow::Node sink) { isSink(_, sink, _, _, _) }
|
||||||
}
|
}
|
||||||
|
|
||||||
private import DataFlow::Global<SizeBarrierConfig>
|
module SizeBarrierFlow = DataFlow::Global<SizeBarrierConfig>;
|
||||||
|
|
||||||
private int getAFlowStateForNode(DataFlow::Node node) {
|
private int getASizeAddend(DataFlow::Node node) {
|
||||||
exists(DataFlow::Node source |
|
exists(DataFlow::Node source |
|
||||||
flow(source, node) and
|
SizeBarrierFlow::flow(source, node) and
|
||||||
hasSize(_, source, result)
|
hasSize(_, source, result)
|
||||||
)
|
)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Holds if `small <= large + k` holds if `g` evaluates to `edge`.
|
||||||
|
*/
|
||||||
private predicate operandGuardChecks(
|
private predicate operandGuardChecks(
|
||||||
IRGuardCondition g, Operand left, Operand right, int state, boolean edge
|
IRGuardCondition g, Operand small, DataFlow::Node large, int k, boolean edge
|
||||||
) {
|
) {
|
||||||
exists(DataFlow::Node nLeft, DataFlow::Node nRight, int k |
|
SizeBarrierFlow::flowTo(large) and
|
||||||
nRight.asOperand() = right and
|
SizeBarrierConfig::isSink(DataFlow::operandNode(small), large, g, k, edge)
|
||||||
nLeft.asOperand() = left and
|
}
|
||||||
SizeBarrierConfig::isSink(nLeft, nRight, g, k, edge) and
|
|
||||||
state = getAFlowStateForNode(nRight) and
|
/**
|
||||||
k <= state
|
* Gets an instruction `instr` that is guarded by a check such as `instr <= small + delta` where
|
||||||
|
* `small <= _ + k` and `small` is the "small side" of of a relational comparison that checks
|
||||||
|
* whether `small <= size` where `size` is the size of an allocation.
|
||||||
|
*/
|
||||||
|
Instruction getABarrierInstruction0(int delta, int k) {
|
||||||
|
exists(
|
||||||
|
IRGuardCondition g, ValueNumber value, Operand small, boolean edge, DataFlow::Node large
|
||||||
|
|
|
||||||
|
// We know:
|
||||||
|
// 1. result <= value + delta (by `bounded`)
|
||||||
|
// 2. value <= large + k (by `operandGuardChecks`).
|
||||||
|
// So:
|
||||||
|
// result <= value + delta (by 1.)
|
||||||
|
// <= large + k + delta (by 2.)
|
||||||
|
small = value.getAUse() and
|
||||||
|
operandGuardChecks(pragma[only_bind_into](g), pragma[only_bind_into](small), large,
|
||||||
|
pragma[only_bind_into](k), pragma[only_bind_into](edge)) and
|
||||||
|
bounded(result, value.getAnInstruction(), delta) and
|
||||||
|
g.controls(result.getBlock(), edge) and
|
||||||
|
k < getASizeAddend(large)
|
||||||
)
|
)
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -140,13 +165,14 @@ module SizeBarrier {
|
|||||||
* Gets an instruction that is guarded by a guard condition which ensures that
|
* Gets an instruction that is guarded by a guard condition which ensures that
|
||||||
* the value of the instruction is upper-bounded by size of some allocation.
|
* the value of the instruction is upper-bounded by size of some allocation.
|
||||||
*/
|
*/
|
||||||
|
bindingset[state]
|
||||||
|
pragma[inline_late]
|
||||||
Instruction getABarrierInstruction(int state) {
|
Instruction getABarrierInstruction(int state) {
|
||||||
exists(IRGuardCondition g, ValueNumber value, Operand use, boolean edge |
|
exists(int delta, int k |
|
||||||
use = value.getAUse() and
|
state > k + delta and
|
||||||
operandGuardChecks(pragma[only_bind_into](g), pragma[only_bind_into](use), _,
|
// result <= "size of allocation" + delta + k
|
||||||
pragma[only_bind_into](state), pragma[only_bind_into](edge)) and
|
// < "size of allocation" + state
|
||||||
result = value.getAnInstruction() and
|
result = getABarrierInstruction0(delta, k)
|
||||||
g.controls(result.getBlock(), edge)
|
|
||||||
)
|
)
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -155,14 +181,16 @@ module SizeBarrier {
|
|||||||
* the value of the node is upper-bounded by size of some allocation.
|
* the value of the node is upper-bounded by size of some allocation.
|
||||||
*/
|
*/
|
||||||
DataFlow::Node getABarrierNode(int state) {
|
DataFlow::Node getABarrierNode(int state) {
|
||||||
result.asOperand() = getABarrierInstruction(state).getAUse()
|
exists(DataFlow::Node source, int delta, int k |
|
||||||
|
SizeBarrierFlow::flow(source, result) and
|
||||||
|
hasSize(_, source, state) and
|
||||||
|
result.asInstruction() = SizeBarrier::getABarrierInstruction0(delta, k) and
|
||||||
|
state > k + delta
|
||||||
|
// so now we have:
|
||||||
|
// result <= "size of allocation" + delta + k
|
||||||
|
// < "size of allocation" + state
|
||||||
|
)
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
|
||||||
* Gets the block of a node that is guarded (see `getABarrierInstruction` or
|
|
||||||
* `getABarrierNode` for the definition of what it means to be guarded).
|
|
||||||
*/
|
|
||||||
IRBlock getABarrierBlock(int state) { result.getAnInstruction() = getABarrierInstruction(state) }
|
|
||||||
}
|
}
|
||||||
|
|
||||||
private module InterestingPointerAddInstruction {
|
private module InterestingPointerAddInstruction {
|
||||||
|
|||||||
@@ -66,11 +66,14 @@
|
|||||||
* module. Since the node we are tracking is not necessarily _equal_ to the pointer-arithmetic instruction, but rather satisfies
|
* module. Since the node we are tracking is not necessarily _equal_ to the pointer-arithmetic instruction, but rather satisfies
|
||||||
* `node.asInstruction() <= pai + deltaDerefSourceAndPai`, we need to account for the delta when checking if a guard is sufficiently
|
* `node.asInstruction() <= pai + deltaDerefSourceAndPai`, we need to account for the delta when checking if a guard is sufficiently
|
||||||
* strong to infer that a future dereference is safe. To do this, we check that the guard guarantees that a node `n` satisfies
|
* strong to infer that a future dereference is safe. To do this, we check that the guard guarantees that a node `n` satisfies
|
||||||
* `n < node + k` where `node` is a node we know is equal to the value of the dereference source (i.e., it satisfies
|
* `n < node + k` where `node` is a node such that `node <= pai`. Thus, we know that any node `m` such that `m <= n + delta` where
|
||||||
* `node.asInstruction() <= pai + deltaDerefSourceAndPai`) and `k <= deltaDerefSourceAndPai`. Combining this we have
|
* `delta + k <= 0` will be safe because:
|
||||||
* `n < node + k <= node + deltaDerefSourceAndPai <= pai + 2*deltaDerefSourceAndPai` (TODO: Oops. This math doesn't quite work out.
|
* ```
|
||||||
* I think this is because we need to redefine the `BarrierConfig` to start flow at the pointer-arithmetic instruction instead of
|
* m <= n + delta
|
||||||
* at the dereference source. When combined with TODO above it's easy to show that this guard ensures that the dereference is safe).
|
* < node + k + delta
|
||||||
|
* <= pai + k + delta
|
||||||
|
* <= pai
|
||||||
|
* ```
|
||||||
*/
|
*/
|
||||||
|
|
||||||
private import cpp
|
private import cpp
|
||||||
@@ -82,16 +85,19 @@ private import RangeAnalysisUtil
|
|||||||
|
|
||||||
private module InvalidPointerToDerefBarrier {
|
private module InvalidPointerToDerefBarrier {
|
||||||
private module BarrierConfig implements DataFlow::ConfigSig {
|
private module BarrierConfig implements DataFlow::ConfigSig {
|
||||||
predicate isSource(DataFlow::Node source) {
|
additional predicate isSource(DataFlow::Node source, PointerArithmeticInstruction pai) {
|
||||||
// The sources is the same as in the sources for `InvalidPointerToDerefConfig`.
|
invalidPointerToDerefSource(_, pai, _, _) and
|
||||||
invalidPointerToDerefSource(_, _, source, _)
|
// source <= pai
|
||||||
|
bounded2(source.asInstruction(), pai, any(int d | d <= 0))
|
||||||
}
|
}
|
||||||
|
|
||||||
|
predicate isSource(DataFlow::Node source) { isSource(source, _) }
|
||||||
|
|
||||||
additional predicate isSink(
|
additional predicate isSink(
|
||||||
DataFlow::Node left, DataFlow::Node right, IRGuardCondition g, int k, boolean testIsTrue
|
DataFlow::Node small, DataFlow::Node large, IRGuardCondition g, int k, boolean testIsTrue
|
||||||
) {
|
) {
|
||||||
// The sink is any "large" side of a relational comparison.
|
// The sink is any "large" side of a relational comparison.
|
||||||
g.comparesLt(left.asOperand(), right.asOperand(), k, true, testIsTrue)
|
g.comparesLt(small.asOperand(), large.asOperand(), k, true, testIsTrue)
|
||||||
}
|
}
|
||||||
|
|
||||||
predicate isSink(DataFlow::Node sink) { isSink(_, sink, _, _, _) }
|
predicate isSink(DataFlow::Node sink) { isSink(_, sink, _, _, _) }
|
||||||
@@ -99,59 +105,82 @@ private module InvalidPointerToDerefBarrier {
|
|||||||
|
|
||||||
private module BarrierFlow = DataFlow::Global<BarrierConfig>;
|
private module BarrierFlow = DataFlow::Global<BarrierConfig>;
|
||||||
|
|
||||||
private int getInvalidPointerToDerefSourceDelta(DataFlow::Node node) {
|
/**
|
||||||
exists(DataFlow::Node source |
|
* Holds if `g` ensures that `small < large + k` if `g` evaluates to `edge`.
|
||||||
BarrierFlow::flow(source, node) and
|
*
|
||||||
invalidPointerToDerefSource(_, _, source, result)
|
* Additionally, it also holds that `large <= pai`. Thus, when `g` evaluates to `edge`
|
||||||
)
|
* it holds that `small < pai + k`.
|
||||||
}
|
*/
|
||||||
|
|
||||||
private predicate operandGuardChecks(
|
private predicate operandGuardChecks(
|
||||||
IRGuardCondition g, Operand left, Operand right, int state, boolean edge
|
PointerArithmeticInstruction pai, IRGuardCondition g, Operand small, int k, boolean edge
|
||||||
) {
|
) {
|
||||||
exists(DataFlow::Node nLeft, DataFlow::Node nRight, int k |
|
exists(DataFlow::Node source, DataFlow::Node nSmall, DataFlow::Node nLarge |
|
||||||
nRight.asOperand() = right and
|
nSmall.asOperand() = small and
|
||||||
nLeft.asOperand() = left and
|
BarrierConfig::isSource(source, pai) and
|
||||||
BarrierConfig::isSink(nLeft, nRight, g, k, edge) and
|
BarrierFlow::flow(source, nLarge) and
|
||||||
state = getInvalidPointerToDerefSourceDelta(nRight) and
|
BarrierConfig::isSink(nSmall, nLarge, g, k, edge)
|
||||||
k <= state
|
|
||||||
)
|
)
|
||||||
}
|
}
|
||||||
|
|
||||||
Instruction getABarrierInstruction(int state) {
|
/**
|
||||||
exists(IRGuardCondition g, ValueNumber value, Operand use, boolean edge |
|
* Gets an instruction `instr` such that `instr < pai`.
|
||||||
|
*/
|
||||||
|
Instruction getABarrierInstruction(PointerArithmeticInstruction pai) {
|
||||||
|
exists(IRGuardCondition g, ValueNumber value, Operand use, boolean edge, int delta, int k |
|
||||||
use = value.getAUse() and
|
use = value.getAUse() and
|
||||||
operandGuardChecks(pragma[only_bind_into](g), pragma[only_bind_into](use), _, state,
|
// value < pai + k
|
||||||
pragma[only_bind_into](edge)) and
|
operandGuardChecks(pai, pragma[only_bind_into](g), pragma[only_bind_into](use),
|
||||||
result = value.getAnInstruction() and
|
pragma[only_bind_into](k), pragma[only_bind_into](edge)) and
|
||||||
g.controls(result.getBlock(), edge)
|
// result <= value + delta
|
||||||
|
bounded(result, value.getAnInstruction(), delta) and
|
||||||
|
g.controls(result.getBlock(), edge) and
|
||||||
|
delta + k <= 0
|
||||||
|
// combining the above we have: result < pai + k + delta <= pai
|
||||||
)
|
)
|
||||||
}
|
}
|
||||||
|
|
||||||
DataFlow::Node getABarrierNode() { result.asOperand() = getABarrierInstruction(_).getAUse() }
|
DataFlow::Node getABarrierNode(PointerArithmeticInstruction pai) {
|
||||||
|
result.asOperand() = getABarrierInstruction(pai).getAUse()
|
||||||
|
}
|
||||||
|
|
||||||
pragma[nomagic]
|
/**
|
||||||
IRBlock getABarrierBlock(int state) { result.getAnInstruction() = getABarrierInstruction(state) }
|
* Gets an address operand whose definition `instr` satisfies `instr < pai`.
|
||||||
|
*/
|
||||||
|
AddressOperand getABarrierAddressOperand(PointerArithmeticInstruction pai) {
|
||||||
|
result.getDef() = getABarrierInstruction(pai)
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* A configuration to track flow from a pointer-arithmetic operation found
|
* A configuration to track flow from a pointer-arithmetic operation found
|
||||||
* by `AllocToInvalidPointerConfig` to a dereference of the pointer.
|
* by `AllocToInvalidPointerConfig` to a dereference of the pointer.
|
||||||
*/
|
*/
|
||||||
private module InvalidPointerToDerefConfig implements DataFlow::ConfigSig {
|
private module InvalidPointerToDerefConfig implements DataFlow::StateConfigSig {
|
||||||
predicate isSource(DataFlow::Node source) { invalidPointerToDerefSource(_, _, source, _) }
|
class FlowState extends PointerArithmeticInstruction {
|
||||||
|
FlowState() { invalidPointerToDerefSource(_, this, _, _) }
|
||||||
|
}
|
||||||
|
|
||||||
|
predicate isSource(DataFlow::Node source, FlowState pai) {
|
||||||
|
invalidPointerToDerefSource(_, pai, source, _)
|
||||||
|
}
|
||||||
|
|
||||||
pragma[inline]
|
pragma[inline]
|
||||||
predicate isSink(DataFlow::Node sink) { isInvalidPointerDerefSink(sink, _, _, _) }
|
predicate isSink(DataFlow::Node sink) { isInvalidPointerDerefSink(sink, _, _, _, _) }
|
||||||
|
|
||||||
|
predicate isSink(DataFlow::Node sink, FlowState pai) { none() }
|
||||||
|
|
||||||
predicate isBarrier(DataFlow::Node node) {
|
predicate isBarrier(DataFlow::Node node) {
|
||||||
node = any(DataFlow::SsaPhiNode phi | not phi.isPhiRead()).getAnInput(true)
|
node = any(DataFlow::SsaPhiNode phi | not phi.isPhiRead()).getAnInput(true)
|
||||||
or
|
}
|
||||||
node = InvalidPointerToDerefBarrier::getABarrierNode()
|
|
||||||
|
predicate isBarrier(DataFlow::Node node, FlowState pai) {
|
||||||
|
// `node = getABarrierNode(pai)` ensures that node < pai, so this node is safe to dereference.
|
||||||
|
// Note that this is the only place where the `FlowState` is used in this configuration.
|
||||||
|
node = InvalidPointerToDerefBarrier::getABarrierNode(pai)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
private import DataFlow::Global<InvalidPointerToDerefConfig>
|
private import DataFlow::GlobalWithState<InvalidPointerToDerefConfig>
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Holds if `allocSource` is dataflow node that represents an allocation that flows to the
|
* Holds if `allocSource` is dataflow node that represents an allocation that flows to the
|
||||||
@@ -165,19 +194,14 @@ private predicate invalidPointerToDerefSource(
|
|||||||
DataFlow::Node allocSource, PointerArithmeticInstruction pai, DataFlow::Node derefSource,
|
DataFlow::Node allocSource, PointerArithmeticInstruction pai, DataFlow::Node derefSource,
|
||||||
int deltaDerefSourceAndPai
|
int deltaDerefSourceAndPai
|
||||||
) {
|
) {
|
||||||
exists(int rhsSizeDelta |
|
// Note that `deltaDerefSourceAndPai` is not necessarily equal to `rhsSizeDelta`:
|
||||||
// Note that `deltaDerefSourceAndPai` is not necessarily equal to `rhsSizeDelta`:
|
// `rhsSizeDelta` is the constant offset added to the size of the allocation, and
|
||||||
// `rhsSizeDelta` is the constant offset added to the size of the allocation, and
|
// `deltaDerefSourceAndPai` is the constant difference between the pointer-arithmetic instruction
|
||||||
// `deltaDerefSourceAndPai` is the constant difference between the pointer-arithmetic instruction
|
// and the instruction computing the address for which we will search for a dereference.
|
||||||
// and the instruction computing the address for which we will search for a dereference.
|
AllocToInvalidPointer::pointerAddInstructionHasBounds(allocSource, pai, _, _) and
|
||||||
AllocToInvalidPointer::pointerAddInstructionHasBounds(allocSource, pai, _, rhsSizeDelta) and
|
// derefSource <= pai + deltaDerefSourceAndPai
|
||||||
bounded2(derefSource.asInstruction(), pai, deltaDerefSourceAndPai) and
|
bounded2(derefSource.asInstruction(), pai, deltaDerefSourceAndPai) and
|
||||||
deltaDerefSourceAndPai >= 0 and
|
deltaDerefSourceAndPai >= 0
|
||||||
// TODO: This condition will go away once #13725 is merged, and then we can make `SizeBarrier`
|
|
||||||
// private to `AllocationToInvalidPointer.qll`.
|
|
||||||
not derefSource.getBasicBlock() =
|
|
||||||
AllocToInvalidPointer::SizeBarrier::getABarrierBlock(rhsSizeDelta)
|
|
||||||
)
|
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
@@ -187,15 +211,14 @@ private predicate invalidPointerToDerefSource(
|
|||||||
*/
|
*/
|
||||||
pragma[inline]
|
pragma[inline]
|
||||||
private predicate isInvalidPointerDerefSink(
|
private predicate isInvalidPointerDerefSink(
|
||||||
DataFlow::Node sink, Instruction i, string operation, int deltaDerefSinkAndDerefAddress
|
DataFlow::Node sink, AddressOperand addr, Instruction i, string operation,
|
||||||
|
int deltaDerefSinkAndDerefAddress
|
||||||
) {
|
) {
|
||||||
exists(AddressOperand addr, Instruction s, IRBlock b |
|
exists(Instruction s |
|
||||||
s = sink.asInstruction() and
|
s = sink.asInstruction() and
|
||||||
bounded(addr.getDef(), s, deltaDerefSinkAndDerefAddress) and
|
bounded(addr.getDef(), s, deltaDerefSinkAndDerefAddress) and
|
||||||
deltaDerefSinkAndDerefAddress >= 0 and
|
deltaDerefSinkAndDerefAddress >= 0 and
|
||||||
i.getAnOperand() = addr and
|
i.getAnOperand() = addr
|
||||||
b = i.getBlock() and
|
|
||||||
not b = InvalidPointerToDerefBarrier::getABarrierBlock(deltaDerefSinkAndDerefAddress)
|
|
||||||
|
|
|
|
||||||
i instanceof StoreInstruction and
|
i instanceof StoreInstruction and
|
||||||
operation = "write"
|
operation = "write"
|
||||||
@@ -221,9 +244,11 @@ private Instruction getASuccessor(Instruction instr) {
|
|||||||
instr.getBlock().getASuccessor+() = result.getBlock()
|
instr.getBlock().getASuccessor+() = result.getBlock()
|
||||||
}
|
}
|
||||||
|
|
||||||
private predicate paiForDereferenceSink(PointerArithmeticInstruction pai, DataFlow::Node derefSink) {
|
private predicate paiForDereferenceSink(
|
||||||
|
PointerArithmeticInstruction pai, DataFlow::Node derefSink, int deltaDerefSourceAndPai
|
||||||
|
) {
|
||||||
exists(DataFlow::Node derefSource |
|
exists(DataFlow::Node derefSource |
|
||||||
invalidPointerToDerefSource(_, pai, derefSource, _) and
|
invalidPointerToDerefSource(_, pai, derefSource, deltaDerefSourceAndPai) and
|
||||||
flow(derefSource, derefSink)
|
flow(derefSource, derefSink)
|
||||||
)
|
)
|
||||||
}
|
}
|
||||||
@@ -235,13 +260,15 @@ private predicate paiForDereferenceSink(PointerArithmeticInstruction pai, DataFl
|
|||||||
*/
|
*/
|
||||||
private predicate derefSinkToOperation(
|
private predicate derefSinkToOperation(
|
||||||
DataFlow::Node derefSink, PointerArithmeticInstruction pai, DataFlow::Node operation,
|
DataFlow::Node derefSink, PointerArithmeticInstruction pai, DataFlow::Node operation,
|
||||||
string description, int deltaDerefSinkAndDerefAddress
|
string description, int deltaDerefSourceAndPai, int deltaDerefSinkAndDerefAddress
|
||||||
) {
|
) {
|
||||||
exists(Instruction operationInstr |
|
exists(Instruction operationInstr, AddressOperand addr |
|
||||||
paiForDereferenceSink(pai, pragma[only_bind_into](derefSink)) and
|
paiForDereferenceSink(pai, pragma[only_bind_into](derefSink), deltaDerefSourceAndPai) and
|
||||||
isInvalidPointerDerefSink(derefSink, operationInstr, description, deltaDerefSinkAndDerefAddress) and
|
isInvalidPointerDerefSink(derefSink, addr, operationInstr, description,
|
||||||
|
deltaDerefSinkAndDerefAddress) and
|
||||||
operationInstr = getASuccessor(derefSink.asInstruction()) and
|
operationInstr = getASuccessor(derefSink.asInstruction()) and
|
||||||
operation.asInstruction() = operationInstr
|
operation.asInstruction() = operationInstr and
|
||||||
|
not addr = InvalidPointerToDerefBarrier::getABarrierAddressOperand(pai)
|
||||||
)
|
)
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -260,7 +287,8 @@ predicate operationIsOffBy(
|
|||||||
exists(int deltaDerefSourceAndPai, int deltaDerefSinkAndDerefAddress |
|
exists(int deltaDerefSourceAndPai, int deltaDerefSinkAndDerefAddress |
|
||||||
invalidPointerToDerefSource(allocation, pai, derefSource, deltaDerefSourceAndPai) and
|
invalidPointerToDerefSource(allocation, pai, derefSource, deltaDerefSourceAndPai) and
|
||||||
flow(derefSource, derefSink) and
|
flow(derefSource, derefSink) and
|
||||||
derefSinkToOperation(derefSink, pai, operation, description, deltaDerefSinkAndDerefAddress) and
|
derefSinkToOperation(derefSink, pai, operation, description, deltaDerefSourceAndPai,
|
||||||
|
deltaDerefSinkAndDerefAddress) and
|
||||||
delta = deltaDerefSourceAndPai + deltaDerefSinkAndDerefAddress
|
delta = deltaDerefSourceAndPai + deltaDerefSinkAndDerefAddress
|
||||||
)
|
)
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -18,7 +18,7 @@ private Instruction getABoundIn(SemBound b, IRFunction func) {
|
|||||||
* Holds if `i <= b + delta`.
|
* Holds if `i <= b + delta`.
|
||||||
*/
|
*/
|
||||||
pragma[inline]
|
pragma[inline]
|
||||||
private predicate boundedImpl(Instruction i, Instruction b, int delta) {
|
private predicate boundedImplCand(Instruction i, Instruction b, int delta) {
|
||||||
exists(SemBound bound, IRFunction func |
|
exists(SemBound bound, IRFunction func |
|
||||||
semBounded(getSemanticExpr(i), bound, delta, true, _) and
|
semBounded(getSemanticExpr(i), bound, delta, true, _) and
|
||||||
b = getABoundIn(bound, func) and
|
b = getABoundIn(bound, func) and
|
||||||
@@ -26,6 +26,15 @@ private predicate boundedImpl(Instruction i, Instruction b, int delta) {
|
|||||||
)
|
)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Holds if `i <= b + delta` and `delta` is the smallest integer that satisfies
|
||||||
|
* this condition.
|
||||||
|
*/
|
||||||
|
pragma[inline]
|
||||||
|
private predicate boundedImpl(Instruction i, Instruction b, int delta) {
|
||||||
|
delta = min(int cand | boundedImplCand(i, b, cand))
|
||||||
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Holds if `i <= b + delta`.
|
* Holds if `i <= b + delta`.
|
||||||
*
|
*
|
||||||
|
|||||||
@@ -105,8 +105,6 @@ predicate isNonConst(DataFlow::Node node, boolean isIndirect) {
|
|||||||
or
|
or
|
||||||
e instanceof NewArrayExpr
|
e instanceof NewArrayExpr
|
||||||
or
|
or
|
||||||
e instanceof AssignExpr
|
|
||||||
or
|
|
||||||
exists(Variable v | v = e.(VariableAccess).getTarget() |
|
exists(Variable v | v = e.(VariableAccess).getTarget() |
|
||||||
v.getType().(ArrayType).getBaseType() instanceof CharType and
|
v.getType().(ArrayType).getBaseType() instanceof CharType and
|
||||||
exists(AssignExpr ae |
|
exists(AssignExpr ae |
|
||||||
|
|||||||
@@ -14,9 +14,11 @@
|
|||||||
|
|
||||||
import cpp
|
import cpp
|
||||||
import semmle.code.cpp.security.Security
|
import semmle.code.cpp.security.Security
|
||||||
|
import semmle.code.cpp.security.FlowSources
|
||||||
import semmle.code.cpp.security.FunctionWithWrappers
|
import semmle.code.cpp.security.FunctionWithWrappers
|
||||||
import semmle.code.cpp.ir.dataflow.internal.DefaultTaintTrackingImpl
|
import semmle.code.cpp.ir.IR
|
||||||
import TaintedWithPath
|
import semmle.code.cpp.ir.dataflow.TaintTracking
|
||||||
|
import SqlTainted::PathGraph
|
||||||
|
|
||||||
class SqlLikeFunction extends FunctionWithWrappers {
|
class SqlLikeFunction extends FunctionWithWrappers {
|
||||||
SqlLikeFunction() { sqlArgument(this.getName(), _) }
|
SqlLikeFunction() { sqlArgument(this.getName(), _) }
|
||||||
@@ -24,31 +26,43 @@ class SqlLikeFunction extends FunctionWithWrappers {
|
|||||||
override predicate interestingArg(int arg) { sqlArgument(this.getName(), arg) }
|
override predicate interestingArg(int arg) { sqlArgument(this.getName(), arg) }
|
||||||
}
|
}
|
||||||
|
|
||||||
class Configuration extends TaintTrackingConfiguration {
|
Expr asSinkExpr(DataFlow::Node node) {
|
||||||
override predicate isSink(Element tainted) {
|
result = node.asIndirectArgument()
|
||||||
exists(SqlLikeFunction runSql | runSql.outermostWrapperFunctionCall(tainted, _))
|
or
|
||||||
|
// We want the conversion so we only get one node for the expression
|
||||||
|
result = node.asConvertedExpr()
|
||||||
|
}
|
||||||
|
|
||||||
|
module SqlTaintedConfig implements DataFlow::ConfigSig {
|
||||||
|
predicate isSource(DataFlow::Node node) { node instanceof FlowSource }
|
||||||
|
|
||||||
|
predicate isSink(DataFlow::Node node) {
|
||||||
|
exists(SqlLikeFunction runSql | runSql.outermostWrapperFunctionCall(asSinkExpr(node), _))
|
||||||
}
|
}
|
||||||
|
|
||||||
override predicate isBarrier(Expr e) {
|
predicate isBarrier(DataFlow::Node node) {
|
||||||
super.isBarrier(e)
|
node.asExpr().getUnspecifiedType() instanceof IntegralType
|
||||||
or
|
}
|
||||||
e.getUnspecifiedType() instanceof IntegralType
|
|
||||||
or
|
predicate isBarrierIn(DataFlow::Node node) {
|
||||||
exists(SqlBarrierFunction sql, int arg, FunctionInput input |
|
exists(SqlBarrierFunction sql, int arg, FunctionInput input |
|
||||||
e = sql.getACallToThisFunction().getArgument(arg) and
|
node.asIndirectArgument() = sql.getACallToThisFunction().getArgument(arg) and
|
||||||
input.isParameterDeref(arg) and
|
input.isParameterDeref(arg) and
|
||||||
sql.barrierSqlArgument(input, _)
|
sql.barrierSqlArgument(input, _)
|
||||||
)
|
)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
module SqlTainted = TaintTracking::Global<SqlTaintedConfig>;
|
||||||
|
|
||||||
from
|
from
|
||||||
SqlLikeFunction runSql, Expr taintedArg, Expr taintSource, PathNode sourceNode, PathNode sinkNode,
|
SqlLikeFunction runSql, Expr taintedArg, FlowSource taintSource, SqlTainted::PathNode sourceNode,
|
||||||
string taintCause, string callChain
|
SqlTainted::PathNode sinkNode, string callChain
|
||||||
where
|
where
|
||||||
runSql.outermostWrapperFunctionCall(taintedArg, callChain) and
|
runSql.outermostWrapperFunctionCall(taintedArg, callChain) and
|
||||||
taintedWithPath(taintSource, taintedArg, sourceNode, sinkNode) and
|
SqlTainted::flowPath(sourceNode, sinkNode) and
|
||||||
isUserInput(taintSource, taintCause)
|
taintedArg = asSinkExpr(sinkNode.getNode()) and
|
||||||
|
taintSource = sourceNode.getNode()
|
||||||
select taintedArg, sourceNode, sinkNode,
|
select taintedArg, sourceNode, sinkNode,
|
||||||
"This argument to a SQL query function is derived from $@ and then passed to " + callChain + ".",
|
"This argument to a SQL query function is derived from $@ and then passed to " + callChain + ".",
|
||||||
taintSource, "user input (" + taintCause + ")"
|
taintSource, "user input (" + taintSource.getSourceType() + ")"
|
||||||
|
|||||||
@@ -0,0 +1,4 @@
|
|||||||
|
---
|
||||||
|
category: minorAnalysis
|
||||||
|
---
|
||||||
|
* Some queries that had repeated results corresponding to different levels of indirection for `argv` now only have a single result.
|
||||||
@@ -0,0 +1,4 @@
|
|||||||
|
---
|
||||||
|
category: minorAnalysis
|
||||||
|
---
|
||||||
|
* The `cpp/non-constant-format` query no longer considers an assignment on the right-hand side of another assignment to be a source of non-constant format strings. As a result, the query may now produce fewer results.
|
||||||
@@ -40,7 +40,7 @@ module WordexpTaintConfig implements DataFlow::ConfigSig {
|
|||||||
|
|
||||||
predicate isSink(DataFlow::Node sink) {
|
predicate isSink(DataFlow::Node sink) {
|
||||||
exists(FunctionCall fc | fc.getTarget() instanceof WordexpFunction |
|
exists(FunctionCall fc | fc.getTarget() instanceof WordexpFunction |
|
||||||
fc.getArgument(0) = sink.asExpr() and
|
fc.getArgument(0) = sink.asIndirectArgument(1) and
|
||||||
not isCommandSubstitutionDisabled(fc)
|
not isCommandSubstitutionDisabled(fc)
|
||||||
)
|
)
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -1,5 +1,5 @@
|
|||||||
name: codeql/cpp-queries
|
name: codeql/cpp-queries
|
||||||
version: 0.7.2
|
version: 0.7.3-dev
|
||||||
groups:
|
groups:
|
||||||
- cpp
|
- cpp
|
||||||
- queries
|
- queries
|
||||||
|
|||||||
@@ -1,16 +1,8 @@
|
|||||||
edges
|
edges
|
||||||
| test.cpp:22:27:22:30 | argv | test.cpp:29:13:29:20 | filePath |
|
| test.cpp:22:27:22:30 | argv indirection | test.cpp:29:13:29:20 | filePath indirection |
|
||||||
| test.cpp:22:27:22:30 | argv | test.cpp:29:13:29:20 | filePath |
|
|
||||||
| test.cpp:22:27:22:30 | argv indirection | test.cpp:29:13:29:20 | filePath |
|
|
||||||
| test.cpp:22:27:22:30 | argv indirection | test.cpp:29:13:29:20 | filePath |
|
|
||||||
nodes
|
nodes
|
||||||
| test.cpp:22:27:22:30 | argv | semmle.label | argv |
|
|
||||||
| test.cpp:22:27:22:30 | argv indirection | semmle.label | argv indirection |
|
| test.cpp:22:27:22:30 | argv indirection | semmle.label | argv indirection |
|
||||||
| test.cpp:29:13:29:20 | filePath | semmle.label | filePath |
|
| test.cpp:29:13:29:20 | filePath indirection | semmle.label | filePath indirection |
|
||||||
| test.cpp:29:13:29:20 | filePath | semmle.label | filePath |
|
|
||||||
subpaths
|
subpaths
|
||||||
#select
|
#select
|
||||||
| test.cpp:29:13:29:20 | filePath | test.cpp:22:27:22:30 | 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. |
|
| test.cpp:29:13:29:20 | filePath indirection | test.cpp:22:27:22:30 | argv indirection | test.cpp:29:13:29:20 | filePath indirection | 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:22:27:22:30 | 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. |
|
|
||||||
| test.cpp:29:13:29:20 | filePath | test.cpp:22:27:22:30 | argv indirection | 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. |
|
|
||||||
| test.cpp:29:13:29:20 | filePath | test.cpp:22:27:22:30 | argv indirection | 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. |
|
|
||||||
|
|||||||
@@ -69,12 +69,6 @@ edges
|
|||||||
| test.cpp:322:19:322:27 | ... + ... | test.cpp:325:24:325:26 | end |
|
| test.cpp:322:19:322:27 | ... + ... | test.cpp:325:24:325:26 | end |
|
||||||
| test.cpp:324:23:324:26 | temp | test.cpp:324:23:324:32 | ... + ... |
|
| test.cpp:324:23:324:26 | temp | test.cpp:324:23:324:32 | ... + ... |
|
||||||
| test.cpp:324:23:324:32 | ... + ... | test.cpp:325:15:325:19 | temp2 |
|
| test.cpp:324:23:324:32 | ... + ... | test.cpp:325:15:325:19 | temp2 |
|
||||||
| test.cpp:351:9:351:11 | arr | test.cpp:351:9:351:14 | access to array |
|
|
||||||
| test.cpp:351:9:351:11 | arr | test.cpp:351:18:351:25 | access to array |
|
|
||||||
| test.cpp:351:18:351:20 | arr | test.cpp:351:9:351:14 | access to array |
|
|
||||||
| test.cpp:351:18:351:20 | arr | test.cpp:351:18:351:25 | access to array |
|
|
||||||
| test.cpp:351:29:351:31 | arr | test.cpp:351:9:351:14 | access to array |
|
|
||||||
| test.cpp:351:29:351:31 | arr | test.cpp:351:18:351:25 | access to array |
|
|
||||||
nodes
|
nodes
|
||||||
| test.cpp:34:5:34:24 | access to array | semmle.label | access to array |
|
| test.cpp:34:5:34:24 | access to array | semmle.label | access to array |
|
||||||
| test.cpp:34:10:34:12 | buf | semmle.label | buf |
|
| test.cpp:34:10:34:12 | buf | semmle.label | buf |
|
||||||
@@ -167,11 +161,6 @@ nodes
|
|||||||
| test.cpp:325:15:325:19 | temp2 | semmle.label | temp2 |
|
| test.cpp:325:15:325:19 | temp2 | semmle.label | temp2 |
|
||||||
| test.cpp:325:24:325:26 | end | semmle.label | end |
|
| test.cpp:325:24:325:26 | end | semmle.label | end |
|
||||||
| test.cpp:325:24:325:26 | end | semmle.label | end |
|
| test.cpp:325:24:325:26 | end | semmle.label | end |
|
||||||
| test.cpp:351:9:351:11 | arr | semmle.label | arr |
|
|
||||||
| test.cpp:351:9:351:14 | access to array | semmle.label | access to array |
|
|
||||||
| test.cpp:351:18:351:20 | arr | semmle.label | arr |
|
|
||||||
| test.cpp:351:18:351:25 | access to array | semmle.label | access to array |
|
|
||||||
| test.cpp:351:29:351:31 | arr | semmle.label | arr |
|
|
||||||
subpaths
|
subpaths
|
||||||
#select
|
#select
|
||||||
| test.cpp:35:5:35:22 | PointerAdd: access to array | test.cpp:35:10:35:12 | buf | test.cpp:35:5:35:22 | access to array | This pointer arithmetic may have an off-by-1 error allowing it to overrun $@ at this $@. | test.cpp:15:9:15:11 | buf | buf | test.cpp:35:5:35:26 | Store: ... = ... | write |
|
| test.cpp:35:5:35:22 | PointerAdd: access to array | test.cpp:35:10:35:12 | buf | test.cpp:35:5:35:22 | access to array | This pointer arithmetic may have an off-by-1 error allowing it to overrun $@ at this $@. | test.cpp:15:9:15:11 | buf | buf | test.cpp:35:5:35:26 | Store: ... = ... | write |
|
||||||
@@ -194,6 +183,3 @@ subpaths
|
|||||||
| test.cpp:322:19:322:27 | PointerAdd: ... + ... | test.cpp:322:19:322:22 | temp | test.cpp:325:24:325:26 | end | This pointer arithmetic may have an off-by-1 error allowing it to overrun $@ at this $@. | test.cpp:314:10:314:13 | temp | temp | test.cpp:330:13:330:24 | Store: ... = ... | write |
|
| test.cpp:322:19:322:27 | PointerAdd: ... + ... | test.cpp:322:19:322:22 | temp | test.cpp:325:24:325:26 | end | This pointer arithmetic may have an off-by-1 error allowing it to overrun $@ at this $@. | test.cpp:314:10:314:13 | temp | temp | test.cpp:330:13:330:24 | Store: ... = ... | write |
|
||||||
| test.cpp:322:19:322:27 | PointerAdd: ... + ... | test.cpp:322:19:322:22 | temp | test.cpp:325:24:325:26 | end | This pointer arithmetic may have an off-by-1 error allowing it to overrun $@ at this $@. | test.cpp:314:10:314:13 | temp | temp | test.cpp:331:13:331:24 | Store: ... = ... | write |
|
| test.cpp:322:19:322:27 | PointerAdd: ... + ... | test.cpp:322:19:322:22 | temp | test.cpp:325:24:325:26 | end | This pointer arithmetic may have an off-by-1 error allowing it to overrun $@ at this $@. | test.cpp:314:10:314:13 | temp | temp | test.cpp:331:13:331:24 | Store: ... = ... | write |
|
||||||
| test.cpp:322:19:322:27 | PointerAdd: ... + ... | test.cpp:322:19:322:22 | temp | test.cpp:325:24:325:26 | end | This pointer arithmetic may have an off-by-1 error allowing it to overrun $@ at this $@. | test.cpp:314:10:314:13 | temp | temp | test.cpp:333:13:333:24 | Store: ... = ... | write |
|
| test.cpp:322:19:322:27 | PointerAdd: ... + ... | test.cpp:322:19:322:22 | temp | test.cpp:325:24:325:26 | end | This pointer arithmetic may have an off-by-1 error allowing it to overrun $@ at this $@. | test.cpp:314:10:314:13 | temp | temp | test.cpp:333:13:333:24 | Store: ... = ... | write |
|
||||||
| test.cpp:351:18:351:25 | PointerAdd: access to array | test.cpp:351:9:351:11 | arr | test.cpp:351:18:351:25 | access to array | This pointer arithmetic may have an off-by-1 error allowing it to overrun $@ at this $@. | test.cpp:348:9:348:11 | arr | arr | test.cpp:351:18:351:25 | Load: access to array | read |
|
|
||||||
| test.cpp:351:18:351:25 | PointerAdd: access to array | test.cpp:351:18:351:20 | arr | test.cpp:351:18:351:25 | access to array | This pointer arithmetic may have an off-by-1 error allowing it to overrun $@ at this $@. | test.cpp:348:9:348:11 | arr | arr | test.cpp:351:18:351:25 | Load: access to array | read |
|
|
||||||
| test.cpp:351:18:351:25 | PointerAdd: access to array | test.cpp:351:29:351:31 | arr | test.cpp:351:18:351:25 | access to array | This pointer arithmetic may have an off-by-1 error allowing it to overrun $@ at this $@. | test.cpp:348:9:348:11 | arr | arr | test.cpp:351:18:351:25 | Load: access to array | read |
|
|
||||||
|
|||||||
@@ -348,7 +348,7 @@ int positiveRange(int x) {
|
|||||||
int arr[128];
|
int arr[128];
|
||||||
|
|
||||||
for(int i=127-offset; i>= 0; i--) {
|
for(int i=127-offset; i>= 0; i--) {
|
||||||
arr[i] = arr[i+1] + arr[i+offset]; // GOOD [FALSE POSITIVE]
|
arr[i] = arr[i+1] + arr[i+offset]; // GOOD
|
||||||
}
|
}
|
||||||
return arr[0];
|
return arr[0];
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -129,7 +129,6 @@ edges
|
|||||||
| test.cpp:271:14:271:21 | ... + ... | test.cpp:271:14:271:21 | ... + ... |
|
| test.cpp:271:14:271:21 | ... + ... | test.cpp:271:14:271:21 | ... + ... |
|
||||||
| test.cpp:271:14:271:21 | ... + ... | test.cpp:274:5:274:10 | ... = ... |
|
| test.cpp:271:14:271:21 | ... + ... | test.cpp:274:5:274:10 | ... = ... |
|
||||||
| test.cpp:271:14:271:21 | ... + ... | test.cpp:274:5:274:10 | ... = ... |
|
| test.cpp:271:14:271:21 | ... + ... | test.cpp:274:5:274:10 | ... = ... |
|
||||||
| test.cpp:304:15:304:26 | new[] | test.cpp:308:5:308:29 | ... = ... |
|
|
||||||
| test.cpp:355:14:355:27 | new[] | test.cpp:356:15:356:23 | ... + ... |
|
| test.cpp:355:14:355:27 | new[] | test.cpp:356:15:356:23 | ... + ... |
|
||||||
| test.cpp:355:14:355:27 | new[] | test.cpp:356:15:356:23 | ... + ... |
|
| test.cpp:355:14:355:27 | new[] | test.cpp:356:15:356:23 | ... + ... |
|
||||||
| test.cpp:355:14:355:27 | new[] | test.cpp:357:24:357:30 | ... + ... |
|
| test.cpp:355:14:355:27 | new[] | test.cpp:357:24:357:30 | ... + ... |
|
||||||
@@ -214,20 +213,26 @@ edges
|
|||||||
| test.cpp:543:14:543:27 | new[] | test.cpp:548:5:548:19 | ... = ... |
|
| test.cpp:543:14:543:27 | new[] | test.cpp:548:5:548:19 | ... = ... |
|
||||||
| test.cpp:554:14:554:27 | new[] | test.cpp:559:5:559:19 | ... = ... |
|
| test.cpp:554:14:554:27 | new[] | test.cpp:559:5:559:19 | ... = ... |
|
||||||
| test.cpp:642:14:642:31 | new[] | test.cpp:647:5:647:19 | ... = ... |
|
| test.cpp:642:14:642:31 | new[] | test.cpp:647:5:647:19 | ... = ... |
|
||||||
| test.cpp:652:14:652:27 | new[] | test.cpp:656:3:656:6 | ... ++ |
|
|
||||||
| test.cpp:652:14:652:27 | new[] | test.cpp:656:3:656:6 | ... ++ |
|
|
||||||
| test.cpp:652:14:652:27 | new[] | test.cpp:662:3:662:11 | ... = ... |
|
|
||||||
| test.cpp:656:3:656:6 | ... ++ | test.cpp:656:3:656:6 | ... ++ |
|
|
||||||
| test.cpp:656:3:656:6 | ... ++ | test.cpp:662:3:662:11 | ... = ... |
|
|
||||||
| test.cpp:656:3:656:6 | ... ++ | test.cpp:662:3:662:11 | ... = ... |
|
|
||||||
| test.cpp:667:14:667:31 | new[] | test.cpp:675:7:675:23 | ... = ... |
|
|
||||||
| test.cpp:695:13:695:26 | new[] | test.cpp:698:5:698:10 | ... += ... |
|
| test.cpp:695:13:695:26 | new[] | test.cpp:698:5:698:10 | ... += ... |
|
||||||
|
| test.cpp:695:13:695:26 | new[] | test.cpp:698:5:698:10 | ... += ... |
|
||||||
|
| test.cpp:698:5:698:10 | ... += ... | test.cpp:698:5:698:10 | ... += ... |
|
||||||
| test.cpp:698:5:698:10 | ... += ... | test.cpp:701:15:701:16 | * ... |
|
| test.cpp:698:5:698:10 | ... += ... | test.cpp:701:15:701:16 | * ... |
|
||||||
| test.cpp:705:18:705:18 | q | test.cpp:705:18:705:18 | q |
|
| test.cpp:705:18:705:18 | q | test.cpp:705:18:705:18 | q |
|
||||||
| test.cpp:705:18:705:18 | q | test.cpp:706:12:706:13 | * ... |
|
| test.cpp:705:18:705:18 | q | test.cpp:706:12:706:13 | * ... |
|
||||||
| test.cpp:705:18:705:18 | q | test.cpp:706:12:706:13 | * ... |
|
| test.cpp:705:18:705:18 | q | test.cpp:706:12:706:13 | * ... |
|
||||||
| test.cpp:711:13:711:26 | new[] | test.cpp:714:11:714:11 | q |
|
| test.cpp:711:13:711:26 | new[] | test.cpp:714:11:714:11 | q |
|
||||||
| test.cpp:714:11:714:11 | q | test.cpp:705:18:705:18 | q |
|
| test.cpp:714:11:714:11 | q | test.cpp:705:18:705:18 | q |
|
||||||
|
| test.cpp:730:12:730:28 | new[] | test.cpp:732:16:732:26 | ... + ... |
|
||||||
|
| test.cpp:730:12:730:28 | new[] | test.cpp:732:16:732:26 | ... + ... |
|
||||||
|
| test.cpp:730:12:730:28 | new[] | test.cpp:733:5:733:12 | ... = ... |
|
||||||
|
| test.cpp:732:16:732:26 | ... + ... | test.cpp:732:16:732:26 | ... + ... |
|
||||||
|
| test.cpp:732:16:732:26 | ... + ... | test.cpp:733:5:733:12 | ... = ... |
|
||||||
|
| test.cpp:732:16:732:26 | ... + ... | test.cpp:733:5:733:12 | ... = ... |
|
||||||
|
| test.cpp:754:18:754:31 | new[] | test.cpp:767:16:767:29 | access to array |
|
||||||
|
| test.cpp:754:18:754:31 | new[] | test.cpp:767:16:767:29 | access to array |
|
||||||
|
| test.cpp:754:18:754:31 | new[] | test.cpp:772:16:772:29 | access to array |
|
||||||
|
| test.cpp:754:18:754:31 | new[] | test.cpp:772:16:772:29 | access to array |
|
||||||
|
| test.cpp:781:14:781:27 | new[] | test.cpp:786:18:786:27 | access to array |
|
||||||
nodes
|
nodes
|
||||||
| test.cpp:4:15:4:20 | call to malloc | semmle.label | call to malloc |
|
| test.cpp:4:15:4:20 | call to malloc | semmle.label | call to malloc |
|
||||||
| test.cpp:5:15:5:22 | ... + ... | semmle.label | ... + ... |
|
| test.cpp:5:15:5:22 | ... + ... | semmle.label | ... + ... |
|
||||||
@@ -320,8 +325,6 @@ nodes
|
|||||||
| test.cpp:271:14:271:21 | ... + ... | semmle.label | ... + ... |
|
| test.cpp:271:14:271:21 | ... + ... | semmle.label | ... + ... |
|
||||||
| test.cpp:271:14:271:21 | ... + ... | semmle.label | ... + ... |
|
| test.cpp:271:14:271:21 | ... + ... | semmle.label | ... + ... |
|
||||||
| test.cpp:274:5:274:10 | ... = ... | semmle.label | ... = ... |
|
| test.cpp:274:5:274:10 | ... = ... | semmle.label | ... = ... |
|
||||||
| test.cpp:304:15:304:26 | new[] | semmle.label | new[] |
|
|
||||||
| test.cpp:308:5:308:29 | ... = ... | semmle.label | ... = ... |
|
|
||||||
| test.cpp:355:14:355:27 | new[] | semmle.label | new[] |
|
| test.cpp:355:14:355:27 | new[] | semmle.label | new[] |
|
||||||
| test.cpp:356:15:356:23 | ... + ... | semmle.label | ... + ... |
|
| test.cpp:356:15:356:23 | ... + ... | semmle.label | ... + ... |
|
||||||
| test.cpp:356:15:356:23 | ... + ... | semmle.label | ... + ... |
|
| test.cpp:356:15:356:23 | ... + ... | semmle.label | ... + ... |
|
||||||
@@ -371,20 +374,26 @@ nodes
|
|||||||
| test.cpp:559:5:559:19 | ... = ... | semmle.label | ... = ... |
|
| test.cpp:559:5:559:19 | ... = ... | semmle.label | ... = ... |
|
||||||
| test.cpp:642:14:642:31 | new[] | semmle.label | new[] |
|
| test.cpp:642:14:642:31 | new[] | semmle.label | new[] |
|
||||||
| test.cpp:647:5:647:19 | ... = ... | semmle.label | ... = ... |
|
| test.cpp:647:5:647:19 | ... = ... | semmle.label | ... = ... |
|
||||||
| test.cpp:652:14:652:27 | new[] | semmle.label | new[] |
|
|
||||||
| test.cpp:656:3:656:6 | ... ++ | semmle.label | ... ++ |
|
|
||||||
| test.cpp:656:3:656:6 | ... ++ | semmle.label | ... ++ |
|
|
||||||
| test.cpp:662:3:662:11 | ... = ... | semmle.label | ... = ... |
|
|
||||||
| test.cpp:667:14:667:31 | new[] | semmle.label | new[] |
|
|
||||||
| test.cpp:675:7:675:23 | ... = ... | semmle.label | ... = ... |
|
|
||||||
| test.cpp:695:13:695:26 | new[] | semmle.label | new[] |
|
| test.cpp:695:13:695:26 | new[] | semmle.label | new[] |
|
||||||
| test.cpp:698:5:698:10 | ... += ... | semmle.label | ... += ... |
|
| test.cpp:698:5:698:10 | ... += ... | semmle.label | ... += ... |
|
||||||
|
| test.cpp:698:5:698:10 | ... += ... | semmle.label | ... += ... |
|
||||||
| test.cpp:701:15:701:16 | * ... | semmle.label | * ... |
|
| test.cpp:701:15:701:16 | * ... | semmle.label | * ... |
|
||||||
| test.cpp:705:18:705:18 | q | semmle.label | q |
|
| test.cpp:705:18:705:18 | q | semmle.label | q |
|
||||||
| test.cpp:705:18:705:18 | q | semmle.label | q |
|
| test.cpp:705:18:705:18 | q | semmle.label | q |
|
||||||
| test.cpp:706:12:706:13 | * ... | semmle.label | * ... |
|
| test.cpp:706:12:706:13 | * ... | semmle.label | * ... |
|
||||||
| test.cpp:711:13:711:26 | new[] | semmle.label | new[] |
|
| test.cpp:711:13:711:26 | new[] | semmle.label | new[] |
|
||||||
| test.cpp:714:11:714:11 | q | semmle.label | q |
|
| test.cpp:714:11:714:11 | q | semmle.label | q |
|
||||||
|
| test.cpp:730:12:730:28 | new[] | semmle.label | new[] |
|
||||||
|
| test.cpp:732:16:732:26 | ... + ... | semmle.label | ... + ... |
|
||||||
|
| test.cpp:732:16:732:26 | ... + ... | semmle.label | ... + ... |
|
||||||
|
| test.cpp:733:5:733:12 | ... = ... | semmle.label | ... = ... |
|
||||||
|
| test.cpp:754:18:754:31 | new[] | semmle.label | new[] |
|
||||||
|
| test.cpp:767:16:767:29 | access to array | semmle.label | access to array |
|
||||||
|
| test.cpp:767:16:767:29 | access to array | semmle.label | access to array |
|
||||||
|
| test.cpp:772:16:772:29 | access to array | semmle.label | access to array |
|
||||||
|
| test.cpp:772:16:772:29 | access to array | semmle.label | access to array |
|
||||||
|
| test.cpp:781:14:781:27 | new[] | semmle.label | new[] |
|
||||||
|
| test.cpp:786:18:786:27 | access to array | semmle.label | access to array |
|
||||||
subpaths
|
subpaths
|
||||||
#select
|
#select
|
||||||
| test.cpp:6:14:6:15 | * ... | test.cpp:4:15:4:20 | call to malloc | test.cpp:6:14:6:15 | * ... | This read might be out of bounds, as the pointer might be equal to $@ + $@. | test.cpp:4:15:4:20 | call to malloc | call to malloc | test.cpp:5:19:5:22 | size | size |
|
| test.cpp:6:14:6:15 | * ... | test.cpp:4:15:4:20 | call to malloc | test.cpp:6:14:6:15 | * ... | This read might be out of bounds, as the pointer might be equal to $@ + $@. | test.cpp:4:15:4:20 | call to malloc | call to malloc | test.cpp:5:19:5:22 | size | size |
|
||||||
@@ -406,7 +415,6 @@ subpaths
|
|||||||
| test.cpp:254:9:254:16 | ... = ... | test.cpp:248:24:248:30 | call to realloc | test.cpp:254:9:254:16 | ... = ... | This write might be out of bounds, as the pointer might be equal to $@ + $@. | test.cpp:248:24:248:30 | call to realloc | call to realloc | test.cpp:254:11:254:11 | i | i |
|
| test.cpp:254:9:254:16 | ... = ... | test.cpp:248:24:248:30 | call to realloc | test.cpp:254:9:254:16 | ... = ... | This write might be out of bounds, as the pointer might be equal to $@ + $@. | test.cpp:248:24:248:30 | call to realloc | call to realloc | test.cpp:254:11:254:11 | i | i |
|
||||||
| test.cpp:264:13:264:14 | * ... | test.cpp:260:13:260:24 | new[] | test.cpp:264:13:264:14 | * ... | This read might be out of bounds, as the pointer might be equal to $@ + $@. | test.cpp:260:13:260:24 | new[] | new[] | test.cpp:261:19:261:21 | len | len |
|
| test.cpp:264:13:264:14 | * ... | test.cpp:260:13:260:24 | new[] | test.cpp:264:13:264:14 | * ... | This read might be out of bounds, as the pointer might be equal to $@ + $@. | test.cpp:260:13:260:24 | new[] | new[] | test.cpp:261:19:261:21 | len | len |
|
||||||
| test.cpp:274:5:274:10 | ... = ... | test.cpp:270:13:270:24 | new[] | test.cpp:274:5:274:10 | ... = ... | This write might be out of bounds, as the pointer might be equal to $@ + $@. | test.cpp:270:13:270:24 | new[] | new[] | test.cpp:271:19:271:21 | len | len |
|
| test.cpp:274:5:274:10 | ... = ... | test.cpp:270:13:270:24 | new[] | test.cpp:274:5:274:10 | ... = ... | This write might be out of bounds, as the pointer might be equal to $@ + $@. | test.cpp:270:13:270:24 | new[] | new[] | test.cpp:271:19:271:21 | len | len |
|
||||||
| test.cpp:308:5:308:29 | ... = ... | test.cpp:304:15:304:26 | new[] | test.cpp:308:5:308:29 | ... = ... | This write might be out of bounds, as the pointer might be equal to $@ + $@. | test.cpp:304:15:304:26 | new[] | new[] | test.cpp:308:8:308:10 | ... + ... | ... + ... |
|
|
||||||
| test.cpp:358:14:358:26 | * ... | test.cpp:355:14:355:27 | new[] | test.cpp:358:14:358:26 | * ... | This read might be out of bounds, as the pointer might be equal to $@ + $@ + 1. | test.cpp:355:14:355:27 | new[] | new[] | test.cpp:356:20:356:23 | size | size |
|
| test.cpp:358:14:358:26 | * ... | test.cpp:355:14:355:27 | new[] | test.cpp:358:14:358:26 | * ... | This read might be out of bounds, as the pointer might be equal to $@ + $@ + 1. | test.cpp:355:14:355:27 | new[] | new[] | test.cpp:356:20:356:23 | size | size |
|
||||||
| test.cpp:359:14:359:32 | * ... | test.cpp:355:14:355:27 | new[] | test.cpp:359:14:359:32 | * ... | This read might be out of bounds, as the pointer might be equal to $@ + $@ + 2. | test.cpp:355:14:355:27 | new[] | new[] | test.cpp:356:20:356:23 | size | size |
|
| test.cpp:359:14:359:32 | * ... | test.cpp:355:14:355:27 | new[] | test.cpp:359:14:359:32 | * ... | This read might be out of bounds, as the pointer might be equal to $@ + $@ + 2. | test.cpp:355:14:355:27 | new[] | new[] | test.cpp:356:20:356:23 | size | size |
|
||||||
| test.cpp:384:13:384:16 | * ... | test.cpp:377:14:377:27 | new[] | test.cpp:384:13:384:16 | * ... | This read might be out of bounds, as the pointer might be equal to $@ + $@. | test.cpp:377:14:377:27 | new[] | new[] | test.cpp:378:20:378:23 | size | size |
|
| test.cpp:384:13:384:16 | * ... | test.cpp:377:14:377:27 | new[] | test.cpp:384:13:384:16 | * ... | This read might be out of bounds, as the pointer might be equal to $@ + $@. | test.cpp:377:14:377:27 | new[] | new[] | test.cpp:378:20:378:23 | size | size |
|
||||||
@@ -418,7 +426,11 @@ subpaths
|
|||||||
| test.cpp:548:5:548:19 | ... = ... | test.cpp:543:14:543:27 | new[] | test.cpp:548:5:548:19 | ... = ... | This write might be out of bounds, as the pointer might be equal to $@ + $@. | test.cpp:543:14:543:27 | new[] | new[] | test.cpp:548:8:548:14 | src_pos | src_pos |
|
| test.cpp:548:5:548:19 | ... = ... | test.cpp:543:14:543:27 | new[] | test.cpp:548:5:548:19 | ... = ... | This write might be out of bounds, as the pointer might be equal to $@ + $@. | test.cpp:543:14:543:27 | new[] | new[] | test.cpp:548:8:548:14 | src_pos | src_pos |
|
||||||
| test.cpp:559:5:559:19 | ... = ... | test.cpp:554:14:554:27 | new[] | test.cpp:559:5:559:19 | ... = ... | This write might be out of bounds, as the pointer might be equal to $@ + $@. | test.cpp:554:14:554:27 | new[] | new[] | test.cpp:559:8:559:14 | src_pos | src_pos |
|
| test.cpp:559:5:559:19 | ... = ... | test.cpp:554:14:554:27 | new[] | test.cpp:559:5:559:19 | ... = ... | This write might be out of bounds, as the pointer might be equal to $@ + $@. | test.cpp:554:14:554:27 | new[] | new[] | test.cpp:559:8:559:14 | src_pos | src_pos |
|
||||||
| test.cpp:647:5:647:19 | ... = ... | test.cpp:642:14:642:31 | new[] | test.cpp:647:5:647:19 | ... = ... | This write might be out of bounds, as the pointer might be equal to $@ + $@. | test.cpp:642:14:642:31 | new[] | new[] | test.cpp:647:8:647:14 | src_pos | src_pos |
|
| test.cpp:647:5:647:19 | ... = ... | test.cpp:642:14:642:31 | new[] | test.cpp:647:5:647:19 | ... = ... | This write might be out of bounds, as the pointer might be equal to $@ + $@. | test.cpp:642:14:642:31 | new[] | new[] | test.cpp:647:8:647:14 | src_pos | src_pos |
|
||||||
| test.cpp:662:3:662:11 | ... = ... | test.cpp:652:14:652:27 | new[] | test.cpp:662:3:662:11 | ... = ... | This write might be out of bounds, as the pointer might be equal to $@ + $@ + 1. | test.cpp:652:14:652:27 | new[] | new[] | test.cpp:653:19:653:22 | size | size |
|
|
||||||
| test.cpp:675:7:675:23 | ... = ... | test.cpp:667:14:667:31 | new[] | test.cpp:675:7:675:23 | ... = ... | This write might be out of bounds, as the pointer might be equal to $@ + $@. | test.cpp:667:14:667:31 | new[] | new[] | test.cpp:675:10:675:18 | ... ++ | ... ++ |
|
|
||||||
| test.cpp:701:15:701:16 | * ... | test.cpp:695:13:695:26 | new[] | test.cpp:701:15:701:16 | * ... | This read might be out of bounds, as the pointer might be equal to $@ + $@. | test.cpp:695:13:695:26 | new[] | new[] | test.cpp:696:19:696:22 | size | size |
|
| test.cpp:701:15:701:16 | * ... | test.cpp:695:13:695:26 | new[] | test.cpp:701:15:701:16 | * ... | This read might be out of bounds, as the pointer might be equal to $@ + $@. | test.cpp:695:13:695:26 | new[] | new[] | test.cpp:696:19:696:22 | size | size |
|
||||||
| test.cpp:706:12:706:13 | * ... | test.cpp:711:13:711:26 | new[] | test.cpp:706:12:706:13 | * ... | This read might be out of bounds, as the pointer might be equal to $@ + $@. | test.cpp:711:13:711:26 | new[] | new[] | test.cpp:712:19:712:22 | size | size |
|
| test.cpp:706:12:706:13 | * ... | test.cpp:711:13:711:26 | new[] | test.cpp:706:12:706:13 | * ... | This read might be out of bounds, as the pointer might be equal to $@ + $@. | test.cpp:711:13:711:26 | new[] | new[] | test.cpp:712:19:712:22 | size | size |
|
||||||
|
| test.cpp:733:5:733:12 | ... = ... | test.cpp:730:12:730:28 | new[] | test.cpp:733:5:733:12 | ... = ... | This write might be out of bounds, as the pointer might be equal to $@ + $@. | test.cpp:730:12:730:28 | new[] | new[] | test.cpp:732:21:732:25 | ... + ... | ... + ... |
|
||||||
|
| test.cpp:767:16:767:29 | access to array | test.cpp:754:18:754:31 | new[] | test.cpp:767:16:767:29 | access to array | This read might be out of bounds, as the pointer might be equal to $@ + $@. | test.cpp:754:18:754:31 | new[] | new[] | test.cpp:767:22:767:28 | ... + ... | ... + ... |
|
||||||
|
| test.cpp:767:16:767:29 | access to array | test.cpp:754:18:754:31 | new[] | test.cpp:767:16:767:29 | access to array | This read might be out of bounds, as the pointer might be equal to $@ + $@. | test.cpp:754:18:754:31 | new[] | new[] | test.cpp:772:22:772:28 | ... + ... | ... + ... |
|
||||||
|
| test.cpp:772:16:772:29 | access to array | test.cpp:754:18:754:31 | new[] | test.cpp:772:16:772:29 | access to array | This read might be out of bounds, as the pointer might be equal to $@ + $@. | test.cpp:754:18:754:31 | new[] | new[] | test.cpp:767:22:767:28 | ... + ... | ... + ... |
|
||||||
|
| test.cpp:772:16:772:29 | access to array | test.cpp:754:18:754:31 | new[] | test.cpp:772:16:772:29 | access to array | This read might be out of bounds, as the pointer might be equal to $@ + $@. | test.cpp:754:18:754:31 | new[] | new[] | test.cpp:772:22:772:28 | ... + ... | ... + ... |
|
||||||
|
| test.cpp:786:18:786:27 | access to array | test.cpp:781:14:781:27 | new[] | test.cpp:786:18:786:27 | access to array | This read might be out of bounds, as the pointer might be equal to $@ + $@. | test.cpp:781:14:781:27 | new[] | new[] | test.cpp:786:20:786:26 | ... + ... | ... + ... |
|
||||||
|
|||||||
@@ -305,7 +305,7 @@ void test21() {
|
|||||||
|
|
||||||
for (int i = 0; i < n; i += 2) {
|
for (int i = 0; i < n; i += 2) {
|
||||||
xs[i] = test21_get(i); // GOOD
|
xs[i] = test21_get(i); // GOOD
|
||||||
xs[i+1] = test21_get(i+1); // $ alloc=L304 alloc=L304-1 deref=L308 // GOOD [FALSE POSITIVE]
|
xs[i+1] = test21_get(i+1); // GOOD
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -659,7 +659,7 @@ void test32(unsigned size) {
|
|||||||
xs++;
|
xs++;
|
||||||
if (xs >= end)
|
if (xs >= end)
|
||||||
return;
|
return;
|
||||||
xs[0] = 0; // $ deref=L656->L662+1 deref=L657->L662+1 GOOD [FALSE POSITIVE]
|
xs[0] = 0; // GOOD
|
||||||
}
|
}
|
||||||
|
|
||||||
void test33(unsigned size, unsigned src_pos)
|
void test33(unsigned size, unsigned src_pos)
|
||||||
@@ -672,7 +672,7 @@ void test33(unsigned size, unsigned src_pos)
|
|||||||
while (dst_pos < size - 1) {
|
while (dst_pos < size - 1) {
|
||||||
dst_pos++;
|
dst_pos++;
|
||||||
if (true)
|
if (true)
|
||||||
xs[dst_pos++] = 0; // $ alloc=L667+1 deref=L675 // GOOD [FALSE POSITIVE]
|
xs[dst_pos++] = 0; // GOOD
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -714,3 +714,77 @@ void test35(unsigned long size, char* q)
|
|||||||
deref(q);
|
deref(q);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
void test21_simple(bool b) {
|
||||||
|
int n = 0;
|
||||||
|
if (b) n = 2;
|
||||||
|
|
||||||
|
int* xs = new int[n];
|
||||||
|
|
||||||
|
for (int i = 0; i < n; i += 2) {
|
||||||
|
xs[i+1] = 0; // GOOD
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
void test36(unsigned size, unsigned n) {
|
||||||
|
int* p = new int[size + 2];
|
||||||
|
if(n < size + 1) {
|
||||||
|
int* end = p + (n + 2); // $ alloc=L730+2
|
||||||
|
*end = 0; // $ deref=L733 // BAD
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
void test37(unsigned long n)
|
||||||
|
{
|
||||||
|
int *p = new int[n];
|
||||||
|
for (unsigned long i = n; i != 0u; i--)
|
||||||
|
{
|
||||||
|
p[n - i] = 0; // GOOD
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
unsigned get(char);
|
||||||
|
void exit(int);
|
||||||
|
|
||||||
|
void error(const char * msg) {
|
||||||
|
exit(1);
|
||||||
|
}
|
||||||
|
|
||||||
|
void test38(unsigned size) {
|
||||||
|
char * alloc = new char[size];
|
||||||
|
|
||||||
|
unsigned pos = 0;
|
||||||
|
while (pos < size) {
|
||||||
|
char kind = alloc[pos];
|
||||||
|
unsigned n = get(alloc[pos]);
|
||||||
|
if (pos + n >= size) {
|
||||||
|
error("");
|
||||||
|
}
|
||||||
|
switch (kind) {
|
||||||
|
case '0':
|
||||||
|
if (n != 1)
|
||||||
|
error("");
|
||||||
|
char x = alloc[pos + 1]; // $ alloc=L754 deref=L767 // GOOD [FALSE POSITIVE]
|
||||||
|
break;
|
||||||
|
case '1':
|
||||||
|
if (n != 2)
|
||||||
|
error("");
|
||||||
|
char a = alloc[pos + 1]; // $ alloc=L754 deref=L772 // GOOD [FALSE POSITIVE]
|
||||||
|
char b = alloc[pos + 2];
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
pos += 1 + n;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
void test38_simple(unsigned size, unsigned pos, unsigned numParams) {
|
||||||
|
char * p = new char[size];
|
||||||
|
|
||||||
|
if (pos < size) {
|
||||||
|
if (pos + numParams < size) {
|
||||||
|
if (numParams == 1) {
|
||||||
|
char x = p[pos + 1]; // $ alloc=L781 deref=L786 // GOOD [FALSE POSITIVE]
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
@@ -732,7 +732,7 @@ void test_does_not_write_source_to_dereference()
|
|||||||
{
|
{
|
||||||
int x;
|
int x;
|
||||||
does_not_write_source_to_dereference(&x);
|
does_not_write_source_to_dereference(&x);
|
||||||
sink(x); // $ ast,ir=733:7 SPURIOUS: ast,ir=726:11
|
sink(x); // $ ast=733:7 ir SPURIOUS: ast=726:11
|
||||||
}
|
}
|
||||||
|
|
||||||
void sometimes_calls_sink_eq(int x, int n) {
|
void sometimes_calls_sink_eq(int x, int n) {
|
||||||
|
|||||||
@@ -134,7 +134,7 @@ void pointer_test() {
|
|||||||
sink(*p3); // $ ast,ir
|
sink(*p3); // $ ast,ir
|
||||||
|
|
||||||
*p3 = 0;
|
*p3 = 0;
|
||||||
sink(*p3); // $ SPURIOUS: ast,ir
|
sink(*p3); // $ SPURIOUS: ast
|
||||||
}
|
}
|
||||||
|
|
||||||
// --- return values ---
|
// --- return values ---
|
||||||
|
|||||||
@@ -1,3 +0,0 @@
|
|||||||
| file://:0:0:0:0 | There was an error during this compilation |
|
|
||||||
| float128.cpp:1:39:1:39 | 128-bit floating-point types are not supported in this configuration |
|
|
||||||
| float128.cpp:2:30:2:30 | 128-bit floating-point types are not supported in this configuration |
|
|
||||||
@@ -1,4 +0,0 @@
|
|||||||
import cpp
|
|
||||||
|
|
||||||
from Diagnostic d
|
|
||||||
select d
|
|
||||||
@@ -1,5 +1,5 @@
|
|||||||
typedef _Complex float __attribute__((mode(TC))) _Complex128; // [COMPILER ERROR AND ERROR-TYPE DUE TO __float128 BEING DISABLED]
|
typedef _Complex float __attribute__((mode(TC))) _Complex128;
|
||||||
typedef float __attribute__((mode(TF))) _Float128; // [COMPILER ERROR AND ERROR-TYPE DUE TO __float128 BEING DISABLED]
|
typedef float __attribute__((mode(TF))) _Float128;
|
||||||
|
|
||||||
int main() {
|
int main() {
|
||||||
__float128 f = 1.0f;
|
__float128 f = 1.0f;
|
||||||
@@ -25,4 +25,3 @@ __float128 id(__float128 q)
|
|||||||
{
|
{
|
||||||
return q;
|
return q;
|
||||||
}
|
}
|
||||||
// semmle-extractor-options: --expect_errors
|
|
||||||
|
|||||||
@@ -1,5 +1,5 @@
|
|||||||
| float128.cpp:1:50:1:60 | _Complex128 | file://:0:0:0:0 | <error-type> |
|
| float128.cpp:1:50:1:60 | _Complex128 | file://:0:0:0:0 | float __complex__ |
|
||||||
| float128.cpp:2:41:2:49 | _Float128 | file://:0:0:0:0 | <error-type> |
|
| float128.cpp:2:41:2:49 | _Float128 | file://:0:0:0:0 | __float128 |
|
||||||
| float128.cpp:13:29:13:54 | __is_floating_point_helper<T> | float128.cpp:10:8:10:17 | false_type |
|
| float128.cpp:13:29:13:54 | __is_floating_point_helper<T> | float128.cpp:10:8:10:17 | false_type |
|
||||||
| float128.cpp:14:19:14:51 | __is_floating_point_helper<float> | float128.cpp:11:8:11:16 | true_type |
|
| float128.cpp:14:19:14:51 | __is_floating_point_helper<float> | float128.cpp:11:8:11:16 | true_type |
|
||||||
| float128.cpp:15:19:15:52 | __is_floating_point_helper<double> | float128.cpp:11:8:11:16 | true_type |
|
| float128.cpp:15:19:15:52 | __is_floating_point_helper<double> | float128.cpp:11:8:11:16 | true_type |
|
||||||
|
|||||||
@@ -1798,6 +1798,23 @@ ir.c:
|
|||||||
# 10| Type = [CTypedefType] MyCoords
|
# 10| Type = [CTypedefType] MyCoords
|
||||||
# 10| ValueCategory = lvalue
|
# 10| ValueCategory = lvalue
|
||||||
# 11| getStmt(3): [ReturnStmt] return ...
|
# 11| getStmt(3): [ReturnStmt] return ...
|
||||||
|
# 13| [TopLevelFunction] void CStyleCast(void*)
|
||||||
|
# 13| <params>:
|
||||||
|
# 13| getParameter(0): [Parameter] src
|
||||||
|
# 13| Type = [VoidPointerType] void *
|
||||||
|
# 14| getEntryPoint(): [BlockStmt] { ... }
|
||||||
|
# 15| getStmt(0): [DeclStmt] declaration
|
||||||
|
# 15| getDeclarationEntry(0): [VariableDeclarationEntry] definition of dst
|
||||||
|
# 15| Type = [CharPointerType] char *
|
||||||
|
# 15| getVariable().getInitializer(): [Initializer] initializer for dst
|
||||||
|
# 15| getExpr(): [VariableAccess] src
|
||||||
|
# 15| Type = [VoidPointerType] void *
|
||||||
|
# 15| ValueCategory = prvalue(load)
|
||||||
|
# 15| getExpr().getFullyConverted(): [CStyleCast] (char *)...
|
||||||
|
# 15| Conversion = [PointerConversion] pointer conversion
|
||||||
|
# 15| Type = [CharPointerType] char *
|
||||||
|
# 15| ValueCategory = prvalue
|
||||||
|
# 16| getStmt(1): [ReturnStmt] return ...
|
||||||
ir.cpp:
|
ir.cpp:
|
||||||
# 1| [TopLevelFunction] void Constants()
|
# 1| [TopLevelFunction] void Constants()
|
||||||
# 1| <params>:
|
# 1| <params>:
|
||||||
|
|||||||
@@ -9,3 +9,10 @@ void MyCoordsTest(int pos) {
|
|||||||
coords.x = coords.y = pos + 1;
|
coords.x = coords.y = pos + 1;
|
||||||
coords.x = getX(&coords);
|
coords.x = getX(&coords);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
void CStyleCast(void *src)
|
||||||
|
{
|
||||||
|
char *dst = (char*)src;
|
||||||
|
}
|
||||||
|
|
||||||
|
// semmle-extractor-options: --microsoft
|
||||||
|
|||||||
@@ -978,6 +978,20 @@
|
|||||||
| ir.c:10:19:10:25 | ChiTotal | total:m9_13 |
|
| ir.c:10:19:10:25 | ChiTotal | total:m9_13 |
|
||||||
| ir.c:10:19:10:25 | SideEffect | ~m9_13 |
|
| ir.c:10:19:10:25 | SideEffect | ~m9_13 |
|
||||||
| ir.c:10:20:10:25 | Unary | r10_2 |
|
| ir.c:10:20:10:25 | Unary | r10_2 |
|
||||||
|
| ir.c:13:6:13:15 | ChiPartial | partial:m13_3 |
|
||||||
|
| ir.c:13:6:13:15 | ChiTotal | total:m13_2 |
|
||||||
|
| ir.c:13:6:13:15 | SideEffect | m13_3 |
|
||||||
|
| ir.c:13:23:13:25 | Address | &:r13_5 |
|
||||||
|
| ir.c:13:23:13:25 | Address | &:r13_5 |
|
||||||
|
| ir.c:13:23:13:25 | Address | &:r13_7 |
|
||||||
|
| ir.c:13:23:13:25 | Address | &:r13_7 |
|
||||||
|
| ir.c:13:23:13:25 | Load | m13_6 |
|
||||||
|
| ir.c:13:23:13:25 | SideEffect | m13_8 |
|
||||||
|
| ir.c:15:11:15:13 | Address | &:r15_1 |
|
||||||
|
| ir.c:15:17:15:26 | StoreValue | r15_4 |
|
||||||
|
| ir.c:15:24:15:26 | Address | &:r15_2 |
|
||||||
|
| ir.c:15:24:15:26 | Load | m13_6 |
|
||||||
|
| ir.c:15:24:15:26 | Unary | r15_3 |
|
||||||
| ir.cpp:1:6:1:14 | ChiPartial | partial:m1_3 |
|
| ir.cpp:1:6:1:14 | ChiPartial | partial:m1_3 |
|
||||||
| ir.cpp:1:6:1:14 | ChiTotal | total:m1_2 |
|
| ir.cpp:1:6:1:14 | ChiTotal | total:m1_2 |
|
||||||
| ir.cpp:1:6:1:14 | SideEffect | m1_3 |
|
| ir.cpp:1:6:1:14 | SideEffect | m1_3 |
|
||||||
|
|||||||
@@ -766,6 +766,26 @@ ir.c:
|
|||||||
# 7| v7_7(void) = AliasedUse : ~m?
|
# 7| v7_7(void) = AliasedUse : ~m?
|
||||||
# 7| v7_8(void) = ExitFunction :
|
# 7| v7_8(void) = ExitFunction :
|
||||||
|
|
||||||
|
# 13| void CStyleCast(void*)
|
||||||
|
# 13| Block 0
|
||||||
|
# 13| v13_1(void) = EnterFunction :
|
||||||
|
# 13| mu13_2(unknown) = AliasedDefinition :
|
||||||
|
# 13| mu13_3(unknown) = InitializeNonLocal :
|
||||||
|
# 13| r13_4(glval<void *>) = VariableAddress[src] :
|
||||||
|
# 13| mu13_5(void *) = InitializeParameter[src] : &:r13_4
|
||||||
|
# 13| r13_6(void *) = Load[src] : &:r13_4, ~m?
|
||||||
|
# 13| mu13_7(unknown) = InitializeIndirection[src] : &:r13_6
|
||||||
|
# 15| r15_1(glval<char *>) = VariableAddress[dst] :
|
||||||
|
# 15| r15_2(glval<void *>) = VariableAddress[src] :
|
||||||
|
# 15| r15_3(void *) = Load[src] : &:r15_2, ~m?
|
||||||
|
# 15| r15_4(char *) = Convert : r15_3
|
||||||
|
# 15| mu15_5(char *) = Store[dst] : &:r15_1, r15_4
|
||||||
|
# 16| v16_1(void) = NoOp :
|
||||||
|
# 13| v13_8(void) = ReturnIndirection[src] : &:r13_6, ~m?
|
||||||
|
# 13| v13_9(void) = ReturnVoid :
|
||||||
|
# 13| v13_10(void) = AliasedUse : ~m?
|
||||||
|
# 13| v13_11(void) = ExitFunction :
|
||||||
|
|
||||||
ir.cpp:
|
ir.cpp:
|
||||||
# 1| void Constants()
|
# 1| void Constants()
|
||||||
# 1| Block 0
|
# 1| Block 0
|
||||||
|
|||||||
@@ -95,3 +95,25 @@ void gotoLoop(bool b1, bool b2)
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
void test_sub(int x, int y, int n) {
|
||||||
|
if(x > 0 && x < 500) {
|
||||||
|
if(y > 0 && y < 10) {
|
||||||
|
range(x - y); // $ range=<=498 range=>=-8
|
||||||
|
}
|
||||||
|
|
||||||
|
if(n > 0 && n < 100) {
|
||||||
|
for (int i = 0; i < n; i++)
|
||||||
|
{
|
||||||
|
range(n - i); // $ range=">=Phi: i-97" range=<=99 range=>=-97
|
||||||
|
range(i - n); // $ range="<=Phi: i-1" range=">=Phi: i-99" range=<=97 range=>=-99
|
||||||
|
}
|
||||||
|
|
||||||
|
for (int i = n; i != 0; i--)
|
||||||
|
{
|
||||||
|
range(n - i); // $ SPURIOUS: overflow=+
|
||||||
|
range(i - n); // $ range=">=Phi: i-99"
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|||||||
@@ -156,3 +156,10 @@ void fmt_via_strcpy(char *data) {
|
|||||||
strcpy(data, "some string");
|
strcpy(data, "some string");
|
||||||
printf(data); // BAD
|
printf(data); // BAD
|
||||||
}
|
}
|
||||||
|
|
||||||
|
void fmt_with_assignment() {
|
||||||
|
const char *x, *y;
|
||||||
|
|
||||||
|
x = y = "a";
|
||||||
|
printf(y); // GOOD
|
||||||
|
}
|
||||||
|
|||||||
@@ -1,16 +1,10 @@
|
|||||||
edges
|
edges
|
||||||
| test.c:8:27:8:30 | argv | test.c:17:11:17:18 | fileName indirection |
|
|
||||||
| test.c:8:27:8:30 | argv indirection | test.c:17:11:17:18 | fileName indirection |
|
|
||||||
| test.c:8:27:8:30 | argv indirection | test.c:17:11:17:18 | fileName indirection |
|
| test.c:8:27:8:30 | argv indirection | test.c:17:11:17:18 | fileName indirection |
|
||||||
| test.c:8:27:8:30 | argv indirection | test.c:32:11:32:18 | fileName indirection |
|
| test.c:8:27:8:30 | argv indirection | test.c:32:11:32:18 | fileName indirection |
|
||||||
| test.c:8:27:8:30 | argv indirection | test.c:32:11:32:18 | fileName indirection |
|
|
||||||
| test.c:8:27:8:30 | argv indirection | test.c:57:10:57:16 | access to array indirection |
|
|
||||||
| test.c:8:27:8:30 | argv indirection | test.c:57:10:57:16 | access to array indirection |
|
| test.c:8:27:8:30 | argv indirection | test.c:57:10:57:16 | access to array indirection |
|
||||||
| test.c:37:17:37:24 | scanf output argument | test.c:38:11:38:18 | fileName indirection |
|
| test.c:37:17:37:24 | scanf output argument | test.c:38:11:38:18 | fileName indirection |
|
||||||
| test.c:43:17:43:24 | scanf output argument | test.c:44:11:44:18 | fileName indirection |
|
| test.c:43:17:43:24 | scanf output argument | test.c:44:11:44:18 | fileName indirection |
|
||||||
nodes
|
nodes
|
||||||
| test.c:8:27:8:30 | argv | semmle.label | argv |
|
|
||||||
| test.c:8:27:8:30 | argv indirection | semmle.label | argv indirection |
|
|
||||||
| test.c:8:27:8:30 | argv indirection | semmle.label | argv indirection |
|
| test.c:8:27:8:30 | argv indirection | semmle.label | argv indirection |
|
||||||
| test.c:17:11:17:18 | fileName indirection | semmle.label | fileName indirection |
|
| test.c:17:11:17:18 | fileName indirection | semmle.label | fileName indirection |
|
||||||
| test.c:32:11:32:18 | fileName indirection | semmle.label | fileName indirection |
|
| test.c:32:11:32:18 | fileName indirection | semmle.label | fileName indirection |
|
||||||
@@ -21,12 +15,8 @@ nodes
|
|||||||
| test.c:57:10:57:16 | access to array indirection | semmle.label | access to array indirection |
|
| test.c:57:10:57:16 | access to array indirection | semmle.label | access to array indirection |
|
||||||
subpaths
|
subpaths
|
||||||
#select
|
#select
|
||||||
| test.c:17:11:17:18 | fileName | test.c:8:27:8:30 | argv | test.c:17:11:17:18 | fileName indirection | This argument to a file access function is derived from $@ and then passed to fopen(filename). | test.c:8:27:8:30 | argv | user input (a command-line argument) |
|
|
||||||
| test.c:17:11:17:18 | fileName | test.c:8:27:8:30 | argv indirection | test.c:17:11:17:18 | fileName indirection | This argument to a file access function is derived from $@ and then passed to fopen(filename). | test.c:8:27:8:30 | argv indirection | user input (a command-line argument) |
|
| test.c:17:11:17:18 | fileName | test.c:8:27:8:30 | argv indirection | test.c:17:11:17:18 | fileName indirection | This argument to a file access function is derived from $@ and then passed to fopen(filename). | test.c:8:27:8:30 | argv indirection | user input (a command-line argument) |
|
||||||
| test.c:17:11:17:18 | fileName | test.c:8:27:8:30 | argv indirection | test.c:17:11:17:18 | fileName indirection | This argument to a file access function is derived from $@ and then passed to fopen(filename). | test.c:8:27:8:30 | argv indirection | user input (a command-line argument) |
|
|
||||||
| test.c:32:11:32:18 | fileName | test.c:8:27:8:30 | argv indirection | test.c:32:11:32:18 | fileName indirection | This argument to a file access function is derived from $@ and then passed to fopen(filename). | test.c:8:27:8:30 | argv indirection | user input (a command-line argument) |
|
|
||||||
| test.c:32:11:32:18 | fileName | test.c:8:27:8:30 | argv indirection | test.c:32:11:32:18 | fileName indirection | This argument to a file access function is derived from $@ and then passed to fopen(filename). | test.c:8:27:8:30 | argv indirection | user input (a command-line argument) |
|
| test.c:32:11:32:18 | fileName | test.c:8:27:8:30 | argv indirection | test.c:32:11:32:18 | fileName indirection | This argument to a file access function is derived from $@ and then passed to fopen(filename). | test.c:8:27:8:30 | argv indirection | user input (a command-line argument) |
|
||||||
| test.c:38:11:38:18 | fileName | test.c:37:17:37:24 | scanf output argument | test.c:38:11:38:18 | fileName indirection | This argument to a file access function is derived from $@ and then passed to fopen(filename). | test.c:37:17:37:24 | scanf output argument | user input (value read by scanf) |
|
| test.c:38:11:38:18 | fileName | test.c:37:17:37:24 | scanf output argument | test.c:38:11:38:18 | fileName indirection | This argument to a file access function is derived from $@ and then passed to fopen(filename). | test.c:37:17:37:24 | scanf output argument | user input (value read by scanf) |
|
||||||
| test.c:44:11:44:18 | fileName | test.c:43:17:43:24 | scanf output argument | test.c:44:11:44:18 | fileName indirection | This argument to a file access function is derived from $@ and then passed to fopen(filename). | test.c:43:17:43:24 | scanf output argument | user input (value read by scanf) |
|
| test.c:44:11:44:18 | fileName | test.c:43:17:43:24 | scanf output argument | test.c:44:11:44:18 | fileName indirection | This argument to a file access function is derived from $@ and then passed to fopen(filename). | test.c:43:17:43:24 | scanf output argument | user input (value read by scanf) |
|
||||||
| test.c:57:10:57:16 | access to array | test.c:8:27:8:30 | argv indirection | test.c:57:10:57:16 | access to array indirection | This argument to a file access function is derived from $@ and then passed to read(fileName), which calls fopen(filename). | test.c:8:27:8:30 | argv indirection | user input (a command-line argument) |
|
| test.c:57:10:57:16 | access to array | test.c:8:27:8:30 | argv indirection | test.c:57:10:57:16 | access to array indirection | This argument to a file access function is derived from $@ and then passed to read(fileName), which calls fopen(filename). | test.c:8:27:8:30 | argv indirection | user input (a command-line argument) |
|
||||||
| test.c:57:10:57:16 | access to array | test.c:8:27:8:30 | argv indirection | test.c:57:10:57:16 | access to array indirection | This argument to a file access function is derived from $@ and then passed to read(fileName), which calls fopen(filename). | test.c:8:27:8:30 | argv indirection | user input (a command-line argument) |
|
|
||||||
|
|||||||
@@ -1,6 +1,5 @@
|
|||||||
edges
|
edges
|
||||||
| test.cpp:15:27:15:30 | argv indirection | test.cpp:22:45:22:52 | userName indirection |
|
| test.cpp:15:27:15:30 | argv indirection | test.cpp:22:45:22:52 | userName indirection |
|
||||||
| test.cpp:15:27:15:30 | argv indirection | test.cpp:22:45:22:52 | userName indirection |
|
|
||||||
| test.cpp:22:13:22:20 | sprintf output argument | test.cpp:23:12:23:19 | command1 indirection |
|
| test.cpp:22:13:22:20 | sprintf output argument | test.cpp:23:12:23:19 | command1 indirection |
|
||||||
| test.cpp:22:45:22:52 | userName indirection | test.cpp:22:13:22:20 | sprintf output argument |
|
| test.cpp:22:45:22:52 | userName indirection | test.cpp:22:13:22:20 | sprintf output argument |
|
||||||
| test.cpp:47:21:47:26 | call to getenv indirection | test.cpp:50:35:50:43 | envCflags indirection |
|
| test.cpp:47:21:47:26 | call to getenv indirection | test.cpp:50:35:50:43 | envCflags indirection |
|
||||||
@@ -71,7 +70,6 @@ edges
|
|||||||
| test.cpp:220:19:220:26 | filename indirection | test.cpp:220:19:220:26 | filename indirection |
|
| test.cpp:220:19:220:26 | filename indirection | test.cpp:220:19:220:26 | filename indirection |
|
||||||
nodes
|
nodes
|
||||||
| test.cpp:15:27:15:30 | argv indirection | semmle.label | argv indirection |
|
| test.cpp:15:27:15:30 | argv indirection | semmle.label | argv indirection |
|
||||||
| test.cpp:15:27:15:30 | argv indirection | semmle.label | argv indirection |
|
|
||||||
| test.cpp:22:13:22:20 | sprintf output argument | semmle.label | sprintf output argument |
|
| test.cpp:22:13:22:20 | sprintf output argument | semmle.label | sprintf output argument |
|
||||||
| test.cpp:22:45:22:52 | userName indirection | semmle.label | userName indirection |
|
| test.cpp:22:45:22:52 | userName indirection | semmle.label | userName indirection |
|
||||||
| test.cpp:23:12:23:19 | command1 indirection | semmle.label | command1 indirection |
|
| test.cpp:23:12:23:19 | command1 indirection | semmle.label | command1 indirection |
|
||||||
@@ -154,7 +152,6 @@ subpaths
|
|||||||
| 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
|
#select
|
||||||
| test.cpp:23:12:23:19 | command1 | test.cpp:15:27:15:30 | argv indirection | test.cpp:23:12:23:19 | command1 indirection | This argument to an OS command is derived from $@, dangerously concatenated into $@, and then passed to system(string). | test.cpp:15:27:15:30 | argv indirection | user input (a command-line argument) | test.cpp:22:13:22:20 | sprintf output argument | sprintf output argument |
|
| test.cpp:23:12:23:19 | command1 | test.cpp:15:27:15:30 | argv indirection | test.cpp:23:12:23:19 | command1 indirection | This argument to an OS command is derived from $@, dangerously concatenated into $@, and then passed to system(string). | test.cpp:15:27:15:30 | argv indirection | user input (a command-line argument) | test.cpp:22:13:22:20 | sprintf output argument | sprintf output argument |
|
||||||
| test.cpp:23:12:23:19 | command1 | test.cpp:15:27:15:30 | argv indirection | test.cpp:23:12:23:19 | command1 indirection | This argument to an OS command is derived from $@, dangerously concatenated into $@, and then passed to system(string). | test.cpp:15:27:15:30 | argv indirection | user input (a command-line argument) | test.cpp:22:13:22:20 | sprintf output argument | sprintf output argument |
|
|
||||||
| test.cpp:51:10:51:16 | command | test.cpp:47:21:47:26 | call to getenv 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 to getenv indirection | user input (an environment variable) | test.cpp:50:11:50:17 | sprintf output argument | sprintf output argument |
|
| test.cpp:51:10:51:16 | command | test.cpp:47:21:47:26 | call to getenv 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 to getenv 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: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: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 |
|
||||||
|
|||||||
@@ -1,25 +1,12 @@
|
|||||||
edges
|
edges
|
||||||
| test.c:15:20:15:23 | argv | test.c:21:18:21:23 | query1 |
|
| test.c:14:27:14:30 | argv indirection | test.c:21:18:21:23 | query1 indirection |
|
||||||
| test.c:15:20:15:23 | argv | test.c:21:18:21:23 | query1 |
|
| test.cpp:39:27:39:30 | argv indirection | test.cpp:43:27:43:33 | access to array indirection |
|
||||||
| test.c:15:20:15:23 | argv | test.c:21:18:21:23 | query1 |
|
|
||||||
| test.c:15:20:15:23 | argv | test.c:21:18:21:23 | query1 |
|
|
||||||
| test.cpp:43:27:43:30 | argv | test.cpp:43:27:43:33 | access to array |
|
|
||||||
| test.cpp:43:27:43:30 | argv | test.cpp:43:27:43:33 | access to array |
|
|
||||||
| test.cpp:43:27:43:30 | argv | test.cpp:43:27:43:33 | access to array |
|
|
||||||
| test.cpp:43:27:43:30 | argv | test.cpp:43:27:43:33 | access to array |
|
|
||||||
| test.cpp:43:27:43:30 | argv | test.cpp:43:27:43:33 | access to array |
|
|
||||||
| test.cpp:43:27:43:30 | argv | test.cpp:43:27:43:33 | access to array |
|
|
||||||
subpaths
|
|
||||||
nodes
|
nodes
|
||||||
| test.c:15:20:15:23 | argv | semmle.label | argv |
|
| test.c:14:27:14:30 | argv indirection | semmle.label | argv indirection |
|
||||||
| test.c:15:20:15:23 | argv | semmle.label | argv |
|
| test.c:21:18:21:23 | query1 indirection | semmle.label | query1 indirection |
|
||||||
| test.c:21:18:21:23 | query1 | semmle.label | query1 |
|
| test.cpp:39:27:39:30 | argv indirection | semmle.label | argv indirection |
|
||||||
| test.c:21:18:21:23 | query1 | semmle.label | query1 |
|
| test.cpp:43:27:43:33 | access to array indirection | semmle.label | access to array indirection |
|
||||||
| test.cpp:43:27:43:30 | argv | semmle.label | argv |
|
subpaths
|
||||||
| test.cpp:43:27:43:30 | argv | semmle.label | argv |
|
|
||||||
| test.cpp:43:27:43:33 | access to array | semmle.label | access to array |
|
|
||||||
| test.cpp:43:27:43:33 | access to array | semmle.label | access to array |
|
|
||||||
| test.cpp:43:27:43:33 | access to array | semmle.label | access to array |
|
|
||||||
#select
|
#select
|
||||||
| test.c:21:18:21:23 | query1 | test.c:15:20:15:23 | argv | test.c:21:18:21:23 | query1 | This argument to a SQL query function is derived from $@ and then passed to mysql_query(sqlArg). | test.c:15:20:15:23 | argv | user input (argv) |
|
| test.c:21:18:21:23 | query1 | test.c:14:27:14:30 | argv indirection | test.c:21:18:21:23 | query1 indirection | This argument to a SQL query function is derived from $@ and then passed to mysql_query(sqlArg). | test.c:14:27:14:30 | argv indirection | user input (a command-line argument) |
|
||||||
| test.cpp:43:27:43:33 | access to array | test.cpp:43:27:43:30 | argv | test.cpp:43:27:43:33 | access to array | This argument to a SQL query function is derived from $@ and then passed to pqxx::work::exec1((unnamed parameter 0)). | test.cpp:43:27:43:30 | argv | user input (argv) |
|
| test.cpp:43:27:43:33 | access to array | test.cpp:39:27:39:30 | argv indirection | test.cpp:43:27:43:33 | access to array indirection | This argument to a SQL query function is derived from $@ and then passed to pqxx::work::exec1((unnamed parameter 0)). | test.cpp:39:27:39:30 | argv indirection | user input (a command-line argument) |
|
||||||
|
|||||||
@@ -1,10 +1,6 @@
|
|||||||
edges
|
edges
|
||||||
| main.cpp:6:27:6:30 | argv indirection | main.cpp:7:33:7:36 | argv indirection |
|
| main.cpp:6:27:6:30 | argv indirection | main.cpp:7:33:7:36 | argv indirection |
|
||||||
| main.cpp:6:27:6:30 | argv indirection | main.cpp:7:33:7:36 | argv indirection |
|
|
||||||
| main.cpp:7:33:7:36 | argv indirection | overflowdestination.cpp:23:45:23:48 | argv indirection |
|
| main.cpp:7:33:7:36 | argv indirection | overflowdestination.cpp:23:45:23:48 | argv indirection |
|
||||||
| main.cpp:7:33:7:36 | argv indirection | overflowdestination.cpp:23:45:23:48 | argv indirection |
|
|
||||||
| overflowdestination.cpp:23:45:23:48 | argv indirection | overflowdestination.cpp:30:17:30:20 | arg1 indirection |
|
|
||||||
| overflowdestination.cpp:23:45:23:48 | argv indirection | overflowdestination.cpp:30:17:30:20 | arg1 indirection |
|
|
||||||
| overflowdestination.cpp:23:45:23:48 | argv indirection | overflowdestination.cpp:30:17:30:20 | arg1 indirection |
|
| overflowdestination.cpp:23:45:23:48 | argv indirection | overflowdestination.cpp:30:17:30:20 | arg1 indirection |
|
||||||
| overflowdestination.cpp:23:45:23:48 | argv indirection | overflowdestination.cpp:30:17:30:20 | arg1 indirection |
|
| overflowdestination.cpp:23:45:23:48 | argv indirection | overflowdestination.cpp:30:17:30:20 | arg1 indirection |
|
||||||
| overflowdestination.cpp:43:8:43:10 | fgets output argument | overflowdestination.cpp:46:15:46:17 | src indirection |
|
| overflowdestination.cpp:43:8:43:10 | fgets output argument | overflowdestination.cpp:46:15:46:17 | src indirection |
|
||||||
@@ -24,10 +20,7 @@ edges
|
|||||||
| overflowdestination.cpp:76:30:76:32 | src indirection | overflowdestination.cpp:57:52:57:54 | src indirection |
|
| overflowdestination.cpp:76:30:76:32 | src indirection | overflowdestination.cpp:57:52:57:54 | src indirection |
|
||||||
nodes
|
nodes
|
||||||
| main.cpp:6:27:6:30 | argv indirection | semmle.label | argv indirection |
|
| main.cpp:6:27:6:30 | argv indirection | semmle.label | argv indirection |
|
||||||
| main.cpp:6:27:6:30 | argv indirection | semmle.label | argv indirection |
|
|
||||||
| main.cpp:7:33:7:36 | argv indirection | semmle.label | argv indirection |
|
| main.cpp:7:33:7:36 | argv indirection | semmle.label | argv indirection |
|
||||||
| main.cpp:7:33:7:36 | argv indirection | semmle.label | argv indirection |
|
|
||||||
| overflowdestination.cpp:23:45:23:48 | argv indirection | semmle.label | argv indirection |
|
|
||||||
| overflowdestination.cpp:23:45:23:48 | argv indirection | semmle.label | argv indirection |
|
| overflowdestination.cpp:23:45:23:48 | argv indirection | semmle.label | argv indirection |
|
||||||
| overflowdestination.cpp:30:17:30:20 | arg1 indirection | semmle.label | arg1 indirection |
|
| overflowdestination.cpp:30:17:30:20 | arg1 indirection | semmle.label | arg1 indirection |
|
||||||
| overflowdestination.cpp:30:17:30:20 | arg1 indirection | semmle.label | arg1 indirection |
|
| overflowdestination.cpp:30:17:30:20 | arg1 indirection | semmle.label | arg1 indirection |
|
||||||
@@ -51,8 +44,6 @@ subpaths
|
|||||||
#select
|
#select
|
||||||
| overflowdestination.cpp:30:2:30:8 | call to strncpy | main.cpp:6:27:6:30 | argv indirection | overflowdestination.cpp:30:17:30:20 | arg1 indirection | To avoid overflow, this operation should be bounded by destination-buffer size, not source-buffer size. |
|
| overflowdestination.cpp:30:2:30:8 | call to strncpy | main.cpp:6:27:6:30 | argv indirection | overflowdestination.cpp:30:17:30:20 | arg1 indirection | To avoid overflow, this operation should be bounded by destination-buffer size, not source-buffer size. |
|
||||||
| overflowdestination.cpp:30:2:30:8 | call to strncpy | main.cpp:6:27:6:30 | argv indirection | overflowdestination.cpp:30:17:30:20 | arg1 indirection | To avoid overflow, this operation should be bounded by destination-buffer size, not source-buffer size. |
|
| overflowdestination.cpp:30:2:30:8 | call to strncpy | main.cpp:6:27:6:30 | argv indirection | overflowdestination.cpp:30:17:30:20 | arg1 indirection | To avoid overflow, this operation should be bounded by destination-buffer size, not source-buffer size. |
|
||||||
| overflowdestination.cpp:30:2:30:8 | call to strncpy | main.cpp:6:27:6:30 | argv indirection | overflowdestination.cpp:30:17:30:20 | arg1 indirection | To avoid overflow, this operation should be bounded by destination-buffer size, not source-buffer size. |
|
|
||||||
| overflowdestination.cpp:30:2:30:8 | call to strncpy | main.cpp:6:27:6:30 | argv indirection | overflowdestination.cpp:30:17:30:20 | arg1 indirection | To avoid overflow, this operation should be bounded by destination-buffer size, not source-buffer size. |
|
|
||||||
| overflowdestination.cpp:46:2:46:7 | call to memcpy | overflowdestination.cpp:43:8:43:10 | fgets output argument | overflowdestination.cpp:46:15:46:17 | src indirection | To avoid overflow, this operation should be bounded by destination-buffer size, not source-buffer size. |
|
| overflowdestination.cpp:46:2:46:7 | call to memcpy | overflowdestination.cpp:43:8:43:10 | fgets output argument | overflowdestination.cpp:46:15:46:17 | src indirection | To avoid overflow, this operation should be bounded by destination-buffer size, not source-buffer size. |
|
||||||
| overflowdestination.cpp:53:2:53:7 | call to memcpy | overflowdestination.cpp:73:8:73:10 | fgets output argument | overflowdestination.cpp:53:15:53:17 | src indirection | To avoid overflow, this operation should be bounded by destination-buffer size, not source-buffer size. |
|
| overflowdestination.cpp:53:2:53:7 | call to memcpy | overflowdestination.cpp:73:8:73:10 | fgets output argument | overflowdestination.cpp:53:15:53:17 | src indirection | To avoid overflow, this operation should be bounded by destination-buffer size, not source-buffer size. |
|
||||||
| overflowdestination.cpp:53:2:53:7 | call to memcpy | overflowdestination.cpp:73:8:73:10 | fgets output argument | overflowdestination.cpp:53:15:53:17 | src indirection | To avoid overflow, this operation should be bounded by destination-buffer size, not source-buffer size. |
|
| overflowdestination.cpp:53:2:53:7 | call to memcpy | overflowdestination.cpp:73:8:73:10 | fgets output argument | overflowdestination.cpp:53:15:53:17 | src indirection | To avoid overflow, this operation should be bounded by destination-buffer size, not source-buffer size. |
|
||||||
|
|||||||
@@ -1,2 +1,6 @@
|
|||||||
|
| tests2.cpp:59:3:59:10 | call to snprintf | This 'call to snprintf' operation is limited to 13 bytes but the destination is only 0 bytes. |
|
||||||
|
| tests2.cpp:59:3:59:10 | call to snprintf | This 'call to snprintf' operation is limited to 13 bytes but the destination is only 2 bytes. |
|
||||||
|
| tests2.cpp:63:3:63:10 | call to snprintf | This 'call to snprintf' operation is limited to 13 bytes but the destination is only 0 bytes. |
|
||||||
|
| tests2.cpp:63:3:63:10 | call to snprintf | This 'call to snprintf' operation is limited to 13 bytes but the destination is only 3 bytes. |
|
||||||
| tests.c:43:3:43:10 | call to snprintf | This 'call to snprintf' operation is limited to 111 bytes but the destination is only 110 bytes. |
|
| tests.c:43:3:43:10 | call to snprintf | This 'call to snprintf' operation is limited to 111 bytes but the destination is only 110 bytes. |
|
||||||
| tests.c:46:3:46:10 | call to snprintf | This 'call to snprintf' operation is limited to 111 bytes but the destination is only 110 bytes. |
|
| tests.c:46:3:46:10 | call to snprintf | This 'call to snprintf' operation is limited to 111 bytes but the destination is only 110 bytes. |
|
||||||
|
|||||||
@@ -1,10 +1,10 @@
|
|||||||
| tests2.cpp:17:3:17:8 | call to wcscpy | This 'call to wcscpy' operation requires 12 bytes but the destination is only 8 bytes. |
|
| tests2.cpp:18:3:18:8 | call to wcscpy | This 'call to wcscpy' operation requires 12 bytes but the destination is only 8 bytes. |
|
||||||
| tests2.cpp:22:3:22:8 | call to wcscpy | This 'call to wcscpy' operation requires 16 bytes but the destination is only 12 bytes. |
|
| tests2.cpp:23:3:23:8 | call to wcscpy | This 'call to wcscpy' operation requires 16 bytes but the destination is only 12 bytes. |
|
||||||
| tests2.cpp:27:3:27:8 | call to wcscpy | This 'call to wcscpy' operation requires 20 bytes but the destination is only 16 bytes. |
|
| tests2.cpp:28:3:28:8 | call to wcscpy | This 'call to wcscpy' operation requires 20 bytes but the destination is only 16 bytes. |
|
||||||
| tests2.cpp:31:3:31:8 | call to wcscpy | This 'call to wcscpy' operation requires 24 bytes but the destination is only 20 bytes. |
|
| tests2.cpp:32:3:32:8 | call to wcscpy | This 'call to wcscpy' operation requires 24 bytes but the destination is only 20 bytes. |
|
||||||
| tests2.cpp:36:3:36:8 | call to wcscpy | This 'call to wcscpy' operation requires 28 bytes but the destination is only 24 bytes. |
|
| tests2.cpp:37:3:37:8 | call to wcscpy | This 'call to wcscpy' operation requires 28 bytes but the destination is only 24 bytes. |
|
||||||
| tests2.cpp:41:3:41:8 | call to wcscpy | This 'call to wcscpy' operation requires 32 bytes but the destination is only 28 bytes. |
|
| tests2.cpp:42:3:42:8 | call to wcscpy | This 'call to wcscpy' operation requires 32 bytes but the destination is only 28 bytes. |
|
||||||
| tests2.cpp:46:3:46:8 | call to wcscpy | This 'call to wcscpy' operation requires 36 bytes but the destination is only 32 bytes. |
|
| tests2.cpp:47:3:47:8 | call to wcscpy | This 'call to wcscpy' operation requires 36 bytes but the destination is only 32 bytes. |
|
||||||
| tests.c:54:3:54:9 | call to sprintf | This 'call to sprintf' operation requires 11 bytes but the destination is only 10 bytes. |
|
| tests.c:54:3:54:9 | call to sprintf | This 'call to sprintf' operation requires 11 bytes but the destination is only 10 bytes. |
|
||||||
| tests.c:58:3:58:9 | call to sprintf | This 'call to sprintf' operation requires 11 bytes but the destination is only 10 bytes. |
|
| tests.c:58:3:58:9 | call to sprintf | This 'call to sprintf' operation requires 11 bytes but the destination is only 10 bytes. |
|
||||||
| tests.c:62:17:62:24 | buffer10 | This 'scanf string argument' operation requires 11 bytes but the destination is only 10 bytes. |
|
| tests.c:62:17:62:24 | buffer10 | This 'scanf string argument' operation requires 11 bytes but the destination is only 10 bytes. |
|
||||||
|
|||||||
@@ -6,6 +6,7 @@ void *realloc(void *ptr, size_t size);
|
|||||||
void *calloc(size_t nmemb, size_t size);
|
void *calloc(size_t nmemb, size_t size);
|
||||||
void free(void *ptr);
|
void free(void *ptr);
|
||||||
wchar_t *wcscpy(wchar_t *s1, const wchar_t *s2);
|
wchar_t *wcscpy(wchar_t *s1, const wchar_t *s2);
|
||||||
|
int snprintf(char *s, size_t n, const char *format, ...);
|
||||||
|
|
||||||
// --- Semmle tests ---
|
// --- Semmle tests ---
|
||||||
|
|
||||||
@@ -46,3 +47,18 @@ void tests2() {
|
|||||||
wcscpy(buffer, L"12345678"); // BAD: buffer overflow
|
wcscpy(buffer, L"12345678"); // BAD: buffer overflow
|
||||||
delete [] buffer;
|
delete [] buffer;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
char* dest1 = "a";
|
||||||
|
char* dest2 = "abcdefghijklmnopqrstuvwxyz";
|
||||||
|
|
||||||
|
void test3() {
|
||||||
|
const char src[] = "abcdefghijkl";
|
||||||
|
dest1 = (char*)malloc(sizeof(src));
|
||||||
|
if (!dest1)
|
||||||
|
return;
|
||||||
|
snprintf(dest1, sizeof(src), "%s", src); // GOOD [FALSE POSITIVE]
|
||||||
|
dest2 = (char*)malloc(3);
|
||||||
|
if (!dest2)
|
||||||
|
return;
|
||||||
|
snprintf(dest2, sizeof(src), "%s", src); // BAD (but with duplicate alerts)
|
||||||
|
}
|
||||||
|
|||||||
@@ -1,12 +1,6 @@
|
|||||||
edges
|
edges
|
||||||
| test1.c:7:26:7:29 | argv | test1.c:9:9:9:9 | i |
|
|
||||||
| test1.c:7:26:7:29 | argv | test1.c:11:9:11:9 | i |
|
|
||||||
| test1.c:7:26:7:29 | argv | test1.c:13:9:13:9 | i |
|
|
||||||
| test1.c:7:26:7:29 | argv indirection | test1.c:9:9:9:9 | i |
|
|
||||||
| test1.c:7:26:7:29 | argv indirection | test1.c:9:9:9:9 | i |
|
| test1.c:7:26:7:29 | argv indirection | test1.c:9:9:9:9 | i |
|
||||||
| test1.c:7:26:7:29 | argv indirection | test1.c:11:9:11:9 | i |
|
| test1.c:7:26:7:29 | argv indirection | test1.c:11:9:11:9 | i |
|
||||||
| test1.c:7:26:7:29 | argv indirection | test1.c:11:9:11:9 | i |
|
|
||||||
| test1.c:7:26:7:29 | argv indirection | test1.c:13:9:13:9 | i |
|
|
||||||
| test1.c:7:26:7:29 | argv indirection | test1.c:13:9:13:9 | i |
|
| test1.c:7:26:7:29 | argv indirection | test1.c:13:9:13:9 | i |
|
||||||
| test1.c:9:9:9:9 | i | test1.c:16:16:16:16 | i |
|
| test1.c:9:9:9:9 | i | test1.c:16:16:16:16 | i |
|
||||||
| test1.c:11:9:11:9 | i | test1.c:32:16:32:16 | i |
|
| test1.c:11:9:11:9 | i | test1.c:32:16:32:16 | i |
|
||||||
@@ -15,8 +9,6 @@ edges
|
|||||||
| test1.c:32:16:32:16 | i | test1.c:33:11:33:11 | i |
|
| test1.c:32:16:32:16 | i | test1.c:33:11:33:11 | i |
|
||||||
| test1.c:48:16:48:16 | i | test1.c:53:15:53:15 | j |
|
| test1.c:48:16:48:16 | i | test1.c:53:15:53:15 | j |
|
||||||
nodes
|
nodes
|
||||||
| test1.c:7:26:7:29 | argv | semmle.label | argv |
|
|
||||||
| test1.c:7:26:7:29 | argv indirection | semmle.label | argv indirection |
|
|
||||||
| test1.c:7:26:7:29 | argv indirection | semmle.label | argv indirection |
|
| test1.c:7:26:7:29 | argv indirection | semmle.label | argv indirection |
|
||||||
| test1.c:9:9:9:9 | i | semmle.label | i |
|
| test1.c:9:9:9:9 | i | semmle.label | i |
|
||||||
| test1.c:11:9:11:9 | i | semmle.label | i |
|
| test1.c:11:9:11:9 | i | semmle.label | i |
|
||||||
@@ -29,12 +21,6 @@ nodes
|
|||||||
| test1.c:53:15:53:15 | j | semmle.label | j |
|
| test1.c:53:15:53:15 | j | semmle.label | j |
|
||||||
subpaths
|
subpaths
|
||||||
#select
|
#select
|
||||||
| test1.c:18:16:18:16 | i | test1.c:7:26:7:29 | argv | test1.c:18:16:18:16 | i | An array indexing expression depends on $@ that might be outside the bounds of the array. | test1.c:7:26:7:29 | argv | a command-line argument |
|
|
||||||
| test1.c:18:16:18:16 | i | test1.c:7:26:7:29 | argv indirection | test1.c:18:16:18:16 | i | An array indexing expression depends on $@ that might be outside the bounds of the array. | test1.c:7:26:7:29 | argv indirection | a command-line argument |
|
| test1.c:18:16:18:16 | i | test1.c:7:26:7:29 | argv indirection | test1.c:18:16:18:16 | i | An array indexing expression depends on $@ that might be outside the bounds of the array. | test1.c:7:26:7:29 | argv indirection | a command-line argument |
|
||||||
| test1.c:18:16:18:16 | i | test1.c:7:26:7:29 | argv indirection | test1.c:18:16:18:16 | i | An array indexing expression depends on $@ that might be outside the bounds of the array. | test1.c:7:26:7:29 | argv indirection | a command-line argument |
|
|
||||||
| test1.c:33:11:33:11 | i | test1.c:7:26:7:29 | argv | test1.c:33:11:33:11 | i | An array indexing expression depends on $@ that might be outside the bounds of the array. | test1.c:7:26:7:29 | argv | a command-line argument |
|
|
||||||
| test1.c:33:11:33:11 | i | test1.c:7:26:7:29 | argv indirection | test1.c:33:11:33:11 | i | An array indexing expression depends on $@ that might be outside the bounds of the array. | test1.c:7:26:7:29 | argv indirection | a command-line argument |
|
| test1.c:33:11:33:11 | i | test1.c:7:26:7:29 | argv indirection | test1.c:33:11:33:11 | i | An array indexing expression depends on $@ that might be outside the bounds of the array. | test1.c:7:26:7:29 | argv indirection | a command-line argument |
|
||||||
| test1.c:33:11:33:11 | i | test1.c:7:26:7:29 | argv indirection | test1.c:33:11:33:11 | i | An array indexing expression depends on $@ that might be outside the bounds of the array. | test1.c:7:26:7:29 | argv indirection | a command-line argument |
|
|
||||||
| test1.c:53:15:53:15 | j | test1.c:7:26:7:29 | argv | test1.c:53:15:53:15 | j | An array indexing expression depends on $@ that might be outside the bounds of the array. | test1.c:7:26:7:29 | argv | a command-line argument |
|
|
||||||
| test1.c:53:15:53:15 | j | test1.c:7:26:7:29 | argv indirection | test1.c:53:15:53:15 | j | An array indexing expression depends on $@ that might be outside the bounds of the array. | test1.c:7:26:7:29 | argv indirection | a command-line argument |
|
|
||||||
| test1.c:53:15:53:15 | j | test1.c:7:26:7:29 | argv indirection | test1.c:53:15:53:15 | j | An array indexing expression depends on $@ that might be outside the bounds of the array. | test1.c:7:26:7:29 | argv indirection | a command-line argument |
|
| test1.c:53:15:53:15 | j | test1.c:7:26:7:29 | argv indirection | test1.c:53:15:53:15 | j | An array indexing expression depends on $@ that might be outside the bounds of the array. | test1.c:7:26:7:29 | argv indirection | a command-line argument |
|
||||||
|
|||||||
@@ -1,21 +1,9 @@
|
|||||||
edges
|
edges
|
||||||
| test.cpp:39:27:39:30 | argv | test.cpp:43:38:43:44 | tainted |
|
|
||||||
| test.cpp:39:27:39:30 | argv | test.cpp:44:38:44:63 | ... * ... |
|
|
||||||
| test.cpp:39:27:39:30 | argv | test.cpp:46:38:46:63 | ... + ... |
|
|
||||||
| test.cpp:39:27:39:30 | argv | test.cpp:49:32:49:35 | size |
|
|
||||||
| test.cpp:39:27:39:30 | argv | test.cpp:50:26:50:29 | size |
|
|
||||||
| test.cpp:39:27:39:30 | argv | test.cpp:53:35:53:60 | ... * ... |
|
|
||||||
| test.cpp:39:27:39:30 | argv indirection | test.cpp:43:38:43:44 | tainted |
|
|
||||||
| test.cpp:39:27:39:30 | argv indirection | test.cpp:43:38:43:44 | tainted |
|
| test.cpp:39:27:39:30 | argv indirection | test.cpp:43:38:43:44 | tainted |
|
||||||
| test.cpp:39:27:39:30 | argv indirection | test.cpp:44:38:44:63 | ... * ... |
|
| test.cpp:39:27:39:30 | argv indirection | test.cpp:44:38:44:63 | ... * ... |
|
||||||
| test.cpp:39:27:39:30 | argv indirection | test.cpp:44:38:44:63 | ... * ... |
|
|
||||||
| test.cpp:39:27:39:30 | argv indirection | test.cpp:46:38:46:63 | ... + ... |
|
|
||||||
| test.cpp:39:27:39:30 | argv indirection | test.cpp:46:38:46:63 | ... + ... |
|
| test.cpp:39:27:39:30 | argv indirection | test.cpp:46:38:46:63 | ... + ... |
|
||||||
| test.cpp:39:27:39:30 | argv indirection | test.cpp:49:32:49:35 | size |
|
| test.cpp:39:27:39:30 | argv indirection | test.cpp:49:32:49:35 | size |
|
||||||
| test.cpp:39:27:39:30 | argv indirection | test.cpp:49:32:49:35 | size |
|
|
||||||
| test.cpp:39:27:39:30 | argv indirection | test.cpp:50:26:50:29 | size |
|
| test.cpp:39:27:39:30 | argv indirection | test.cpp:50:26:50:29 | size |
|
||||||
| test.cpp:39:27:39:30 | argv indirection | test.cpp:50:26:50:29 | size |
|
|
||||||
| test.cpp:39:27:39:30 | argv indirection | test.cpp:53:35:53:60 | ... * ... |
|
|
||||||
| test.cpp:39:27:39:30 | argv indirection | test.cpp:53:35:53:60 | ... * ... |
|
| test.cpp:39:27:39:30 | argv indirection | test.cpp:53:35:53:60 | ... * ... |
|
||||||
| test.cpp:124:18:124:23 | call to getenv | test.cpp:128:24:128:41 | ... * ... |
|
| 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:128:24:128:41 | ... * ... |
|
| test.cpp:124:18:124:31 | call to getenv indirection | test.cpp:128:24:128:41 | ... * ... |
|
||||||
@@ -47,8 +35,6 @@ edges
|
|||||||
| test.cpp:353:18:353:31 | call to getenv indirection | test.cpp:355:35:355:38 | size |
|
| test.cpp:353:18:353:31 | call to getenv indirection | test.cpp:355:35:355:38 | size |
|
||||||
| test.cpp:353:18:353:31 | call to getenv indirection | test.cpp:356:35:356:38 | size |
|
| test.cpp:353:18:353:31 | call to getenv indirection | test.cpp:356:35:356:38 | size |
|
||||||
nodes
|
nodes
|
||||||
| test.cpp:39:27:39:30 | argv | semmle.label | argv |
|
|
||||||
| test.cpp:39:27:39:30 | argv indirection | semmle.label | argv indirection |
|
|
||||||
| test.cpp:39:27:39:30 | argv indirection | semmle.label | argv indirection |
|
| test.cpp:39:27:39:30 | argv indirection | semmle.label | argv indirection |
|
||||||
| test.cpp:43:38:43:44 | tainted | semmle.label | tainted |
|
| test.cpp:43:38:43:44 | tainted | semmle.label | tainted |
|
||||||
| test.cpp:44:38:44:63 | ... * ... | semmle.label | ... * ... |
|
| test.cpp:44:38:44:63 | ... * ... | semmle.label | ... * ... |
|
||||||
@@ -92,23 +78,11 @@ nodes
|
|||||||
| test.cpp:356:35:356:38 | size | semmle.label | size |
|
| test.cpp:356:35:356:38 | size | semmle.label | size |
|
||||||
subpaths
|
subpaths
|
||||||
#select
|
#select
|
||||||
| test.cpp:43:31:43:36 | call to malloc | test.cpp:39:27:39:30 | argv | test.cpp:43:38:43:44 | tainted | This allocation size is derived from $@ and might overflow. | test.cpp:39:27:39:30 | argv | user input (a command-line argument) |
|
|
||||||
| test.cpp:43:31:43:36 | call to malloc | test.cpp:39:27:39:30 | argv indirection | test.cpp:43:38:43:44 | tainted | This allocation size is derived from $@ and might overflow. | test.cpp:39:27:39:30 | argv indirection | user input (a command-line argument) |
|
| test.cpp:43:31:43:36 | call to malloc | test.cpp:39:27:39:30 | argv indirection | test.cpp:43:38:43:44 | tainted | This allocation size is derived from $@ and might overflow. | test.cpp:39:27:39:30 | argv indirection | user input (a command-line argument) |
|
||||||
| test.cpp:43:31:43:36 | call to malloc | test.cpp:39:27:39:30 | argv indirection | test.cpp:43:38:43:44 | tainted | This allocation size is derived from $@ and might overflow. | test.cpp:39:27:39:30 | argv indirection | user input (a command-line argument) |
|
|
||||||
| test.cpp:44:31:44:36 | call to malloc | test.cpp:39:27:39:30 | argv | test.cpp:44:38:44:63 | ... * ... | This allocation size is derived from $@ and might overflow. | test.cpp:39:27:39:30 | argv | user input (a command-line argument) |
|
|
||||||
| test.cpp:44:31:44:36 | call to malloc | test.cpp:39:27:39:30 | argv indirection | test.cpp:44:38:44:63 | ... * ... | This allocation size is derived from $@ and might overflow. | test.cpp:39:27:39:30 | argv indirection | user input (a command-line argument) |
|
| test.cpp:44:31:44:36 | call to malloc | test.cpp:39:27:39:30 | argv indirection | test.cpp:44:38:44:63 | ... * ... | This allocation size is derived from $@ and might overflow. | test.cpp:39:27:39:30 | argv indirection | user input (a command-line argument) |
|
||||||
| test.cpp:44:31:44:36 | call to malloc | test.cpp:39:27:39:30 | argv indirection | test.cpp:44:38:44:63 | ... * ... | This allocation size is derived from $@ and might overflow. | test.cpp:39:27:39:30 | argv indirection | user input (a command-line argument) |
|
|
||||||
| test.cpp:46:31:46:36 | call to malloc | test.cpp:39:27:39:30 | argv | test.cpp:46:38:46:63 | ... + ... | This allocation size is derived from $@ and might overflow. | test.cpp:39:27:39:30 | argv | user input (a command-line argument) |
|
|
||||||
| test.cpp:46:31:46:36 | call to malloc | test.cpp:39:27:39:30 | argv indirection | test.cpp:46:38:46:63 | ... + ... | This allocation size is derived from $@ and might overflow. | test.cpp:39:27:39:30 | argv indirection | user input (a command-line argument) |
|
| test.cpp:46:31:46:36 | call to malloc | test.cpp:39:27:39:30 | argv indirection | test.cpp:46:38:46:63 | ... + ... | This allocation size is derived from $@ and might overflow. | test.cpp:39:27:39:30 | argv indirection | user input (a command-line argument) |
|
||||||
| test.cpp:46:31:46:36 | call to malloc | test.cpp:39:27:39:30 | argv indirection | test.cpp:46:38:46:63 | ... + ... | This allocation size is derived from $@ and might overflow. | test.cpp:39:27:39:30 | argv indirection | user input (a command-line argument) |
|
|
||||||
| test.cpp:49:25:49:30 | call to malloc | test.cpp:39:27:39:30 | argv | test.cpp:49:32:49:35 | size | This allocation size is derived from $@ and might overflow. | test.cpp:39:27:39:30 | argv | user input (a command-line argument) |
|
|
||||||
| test.cpp:49:25:49:30 | call to malloc | test.cpp:39:27:39:30 | argv indirection | test.cpp:49:32:49:35 | size | This allocation size is derived from $@ and might overflow. | test.cpp:39:27:39:30 | argv indirection | user input (a command-line argument) |
|
| test.cpp:49:25:49:30 | call to malloc | test.cpp:39:27:39:30 | argv indirection | test.cpp:49:32:49:35 | size | This allocation size is derived from $@ and might overflow. | test.cpp:39:27:39:30 | argv indirection | user input (a command-line argument) |
|
||||||
| test.cpp:49:25:49:30 | call to malloc | test.cpp:39:27:39:30 | argv indirection | test.cpp:49:32:49:35 | size | This allocation size is derived from $@ and might overflow. | test.cpp:39:27:39:30 | argv indirection | user input (a command-line argument) |
|
|
||||||
| test.cpp:50:17:50:30 | new[] | test.cpp:39:27:39:30 | argv | test.cpp:50:26:50:29 | size | This allocation size is derived from $@ and might overflow. | test.cpp:39:27:39:30 | argv | user input (a command-line argument) |
|
|
||||||
| test.cpp:50:17:50:30 | new[] | test.cpp:39:27:39:30 | argv indirection | test.cpp:50:26:50:29 | size | This allocation size is derived from $@ and might overflow. | test.cpp:39:27:39:30 | argv indirection | user input (a command-line argument) |
|
| test.cpp:50:17:50:30 | new[] | test.cpp:39:27:39:30 | argv indirection | test.cpp:50:26:50:29 | size | This allocation size is derived from $@ and might overflow. | test.cpp:39:27:39:30 | argv indirection | user input (a command-line argument) |
|
||||||
| test.cpp:50:17:50:30 | new[] | test.cpp:39:27:39:30 | argv indirection | test.cpp:50:26:50:29 | size | This allocation size is derived from $@ and might overflow. | test.cpp:39:27:39:30 | argv indirection | user input (a command-line argument) |
|
|
||||||
| test.cpp:53:21:53:27 | call to realloc | test.cpp:39:27:39:30 | argv | test.cpp:53:35:53:60 | ... * ... | This allocation size is derived from $@ and might overflow. | test.cpp:39:27:39:30 | argv | user input (a command-line argument) |
|
|
||||||
| test.cpp:53:21:53:27 | call to realloc | test.cpp:39:27:39:30 | argv indirection | test.cpp:53:35:53:60 | ... * ... | This allocation size is derived from $@ and might overflow. | test.cpp:39:27:39:30 | argv indirection | user input (a command-line argument) |
|
|
||||||
| test.cpp:53:21:53:27 | call to realloc | test.cpp:39:27:39:30 | argv indirection | test.cpp:53:35:53:60 | ... * ... | This allocation size is derived from $@ and might overflow. | test.cpp:39:27:39:30 | argv indirection | user input (a command-line argument) |
|
| test.cpp:53:21:53:27 | call to realloc | test.cpp:39:27:39:30 | argv indirection | test.cpp:53:35:53:60 | ... * ... | This allocation size is derived from $@ and might overflow. | test.cpp:39:27:39:30 | argv indirection | user input (a command-line argument) |
|
||||||
| 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: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: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) |
|
||||||
|
|||||||
@@ -1,12 +1,9 @@
|
|||||||
edges
|
edges
|
||||||
| test.cpp:53:27:53:30 | argv indirection | test.cpp:58:25:58:29 | input indirection |
|
| test.cpp:53:27:53:30 | argv indirection | test.cpp:58:25:58:29 | input indirection |
|
||||||
| test.cpp:53:27:53:30 | argv indirection | test.cpp:58:25:58:29 | input indirection |
|
| test.cpp:53:27:53:30 | argv indirection | test.cpp:58:25:58:29 | input indirection |
|
||||||
| test.cpp:53:27:53:30 | argv indirection | test.cpp:58:25:58:29 | input indirection |
|
|
||||||
| test.cpp:53:27:53:30 | argv indirection | test.cpp:58:25:58:29 | input indirection |
|
|
||||||
nodes
|
nodes
|
||||||
| test2.cpp:110:3:110:6 | call to gets indirection | semmle.label | call to gets indirection |
|
| test2.cpp:110:3:110:6 | call to gets indirection | semmle.label | call to gets indirection |
|
||||||
| test.cpp:53:27:53:30 | argv indirection | semmle.label | argv indirection |
|
| test.cpp:53:27:53:30 | argv indirection | semmle.label | argv indirection |
|
||||||
| test.cpp:53:27:53:30 | argv indirection | semmle.label | argv indirection |
|
|
||||||
| test.cpp:58:25:58:29 | input indirection | semmle.label | input indirection |
|
| test.cpp:58:25:58:29 | input indirection | semmle.label | input indirection |
|
||||||
| test.cpp:58:25:58:29 | input indirection | semmle.label | input indirection |
|
| test.cpp:58:25:58:29 | input indirection | semmle.label | input indirection |
|
||||||
subpaths
|
subpaths
|
||||||
@@ -14,5 +11,3 @@ subpaths
|
|||||||
| test2.cpp:110:3:110:6 | call to gets | test2.cpp:110:3:110:6 | call to gets indirection | test2.cpp:110:3:110:6 | call to gets indirection | This write into buffer 'password' may contain unencrypted data from $@. | test2.cpp:110:3:110:6 | call to gets indirection | user input (string read by gets) |
|
| test2.cpp:110:3:110:6 | call to gets | test2.cpp:110:3:110:6 | call to gets indirection | test2.cpp:110:3:110:6 | call to gets indirection | This write into buffer 'password' may contain unencrypted data from $@. | test2.cpp:110:3:110:6 | call to gets indirection | user input (string read by gets) |
|
||||||
| test.cpp:58:3:58:9 | call to sprintf | test.cpp:53:27:53:30 | argv indirection | test.cpp:58:25:58:29 | input indirection | This write into buffer 'passwd' may contain unencrypted data from $@. | test.cpp:53:27:53:30 | argv indirection | user input (a command-line argument) |
|
| test.cpp:58:3:58:9 | call to sprintf | test.cpp:53:27:53:30 | argv indirection | test.cpp:58:25:58:29 | input indirection | This write into buffer 'passwd' may contain unencrypted data from $@. | test.cpp:53:27:53:30 | argv indirection | user input (a command-line argument) |
|
||||||
| test.cpp:58:3:58:9 | call to sprintf | test.cpp:53:27:53:30 | argv indirection | test.cpp:58:25:58:29 | input indirection | This write into buffer 'passwd' may contain unencrypted data from $@. | test.cpp:53:27:53:30 | argv indirection | user input (a command-line argument) |
|
| test.cpp:58:3:58:9 | call to sprintf | test.cpp:53:27:53:30 | argv indirection | test.cpp:58:25:58:29 | input indirection | This write into buffer 'passwd' may contain unencrypted data from $@. | test.cpp:53:27:53:30 | argv indirection | user input (a command-line argument) |
|
||||||
| test.cpp:58:3:58:9 | call to sprintf | test.cpp:53:27:53:30 | argv indirection | test.cpp:58:25:58:29 | input indirection | This write into buffer 'passwd' may contain unencrypted data from $@. | test.cpp:53:27:53:30 | argv indirection | user input (a command-line argument) |
|
|
||||||
| test.cpp:58:3:58:9 | call to sprintf | test.cpp:53:27:53:30 | argv indirection | test.cpp:58:25:58:29 | input indirection | This write into buffer 'passwd' may contain unencrypted data from $@. | test.cpp:53:27:53:30 | argv indirection | user input (a command-line argument) |
|
|
||||||
|
|||||||
8
csharp/.vscode/extensions.json
vendored
8
csharp/.vscode/extensions.json
vendored
@@ -1,9 +1,11 @@
|
|||||||
{
|
{
|
||||||
"recommendations": [
|
"recommendations": [
|
||||||
"github.vscode-codeql",
|
|
||||||
"ms-dotnettools.csharp",
|
|
||||||
"formulahendry.dotnet-test-explorer",
|
"formulahendry.dotnet-test-explorer",
|
||||||
"hbenl.vscode-test-explorer"
|
"gaoshan0621.csharp-format-usings",
|
||||||
|
"github.vscode-codeql",
|
||||||
|
"hbenl.vscode-test-explorer",
|
||||||
|
"ms-dotnettools.csharp",
|
||||||
|
"ms-dotnettools.csdevkit"
|
||||||
],
|
],
|
||||||
"unwantedRecommendations": []
|
"unwantedRecommendations": []
|
||||||
}
|
}
|
||||||
5
csharp/.vscode/settings.json
vendored
5
csharp/.vscode/settings.json
vendored
@@ -7,5 +7,8 @@
|
|||||||
"editor.defaultFormatter": "ms-dotnettools.csharp"
|
"editor.defaultFormatter": "ms-dotnettools.csharp"
|
||||||
},
|
},
|
||||||
"omnisharp.enableEditorConfigSupport": true,
|
"omnisharp.enableEditorConfigSupport": true,
|
||||||
"omnisharp.enableRoslynAnalyzers": true
|
"omnisharp.enableRoslynAnalyzers": true,
|
||||||
|
"csharpFormatUsings.splitGroups": false,
|
||||||
|
"csharpFormatUsings.sortOrder": "Xunit System Microsoft Semmle.Util Semmle",
|
||||||
|
"dotnet.defaultSolution": "CSharp.sln"
|
||||||
}
|
}
|
||||||
53
csharp/.vscode/tasks.json
vendored
53
csharp/.vscode/tasks.json
vendored
@@ -1,53 +0,0 @@
|
|||||||
{
|
|
||||||
"version": "2.0.0",
|
|
||||||
"tasks": [
|
|
||||||
{
|
|
||||||
"label": "dotnet build",
|
|
||||||
"command": "dotnet",
|
|
||||||
"type": "shell",
|
|
||||||
"args": [
|
|
||||||
"build",
|
|
||||||
// Ask dotnet build to generate full paths for file names.
|
|
||||||
"/property:GenerateFullPaths=true",
|
|
||||||
// Do not generate summary otherwise it leads to duplicate errors in Problems panel
|
|
||||||
"/consoleloggerparameters:NoSummary"
|
|
||||||
],
|
|
||||||
"group": "build",
|
|
||||||
"presentation": {
|
|
||||||
"reveal": "always"
|
|
||||||
},
|
|
||||||
"problemMatcher": "$msCompile"
|
|
||||||
},
|
|
||||||
{
|
|
||||||
"label": "dotnet rebuild",
|
|
||||||
"command": "dotnet",
|
|
||||||
"type": "shell",
|
|
||||||
"args": [
|
|
||||||
"build",
|
|
||||||
"--no-incremental",
|
|
||||||
"/property:GenerateFullPaths=true",
|
|
||||||
"/consoleloggerparameters:NoSummary"
|
|
||||||
],
|
|
||||||
"group": "build",
|
|
||||||
"presentation": {
|
|
||||||
"reveal": "always"
|
|
||||||
},
|
|
||||||
"problemMatcher": "$msCompile"
|
|
||||||
},
|
|
||||||
{
|
|
||||||
"label": "dotnet test",
|
|
||||||
"command": "dotnet",
|
|
||||||
"type": "shell",
|
|
||||||
"args": [
|
|
||||||
"test",
|
|
||||||
"/property:GenerateFullPaths=true",
|
|
||||||
"/consoleloggerparameters:NoSummary"
|
|
||||||
],
|
|
||||||
"group": "test",
|
|
||||||
"presentation": {
|
|
||||||
"reveal": "always"
|
|
||||||
},
|
|
||||||
"problemMatcher": "$msCompile"
|
|
||||||
}
|
|
||||||
]
|
|
||||||
}
|
|
||||||
@@ -11,6 +11,8 @@ Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "Semmle.Extraction.CSharp",
|
|||||||
EndProject
|
EndProject
|
||||||
Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "Semmle.Extraction.CIL", "extractor\Semmle.Extraction.CIL\Semmle.Extraction.CIL.csproj", "{399A1579-68F0-40F4-9A23-F241BA697F9C}"
|
Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "Semmle.Extraction.CIL", "extractor\Semmle.Extraction.CIL\Semmle.Extraction.CIL.csproj", "{399A1579-68F0-40F4-9A23-F241BA697F9C}"
|
||||||
EndProject
|
EndProject
|
||||||
|
Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "Semmle.Extraction.CSharp.DependencyFetching", "extractor\Semmle.Extraction.CSharp.DependencyFetching\Semmle.Extraction.CSharp.DependencyFetching.csproj", "{541D1AC5-E42C-4AB2-A1A4-C2355CE2A2EF}"
|
||||||
|
EndProject
|
||||||
Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "Semmle.Extraction.CSharp.Standalone", "extractor\Semmle.Extraction.CSharp.Standalone\Semmle.Extraction.CSharp.Standalone.csproj", "{D00E7D25-0FA0-48EC-B048-CD60CE1B30D8}"
|
Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "Semmle.Extraction.CSharp.Standalone", "extractor\Semmle.Extraction.CSharp.Standalone\Semmle.Extraction.CSharp.Standalone.csproj", "{D00E7D25-0FA0-48EC-B048-CD60CE1B30D8}"
|
||||||
EndProject
|
EndProject
|
||||||
Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "Semmle.Extraction.CIL.Driver", "extractor\Semmle.Extraction.CIL.Driver\Semmle.Extraction.CIL.Driver.csproj", "{EFA400B3-C1CE-446F-A4E2-8B44E61EF47C}"
|
Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "Semmle.Extraction.CIL.Driver", "extractor\Semmle.Extraction.CIL.Driver\Semmle.Extraction.CIL.Driver.csproj", "{EFA400B3-C1CE-446F-A4E2-8B44E61EF47C}"
|
||||||
@@ -49,6 +51,10 @@ Global
|
|||||||
{399A1579-68F0-40F4-9A23-F241BA697F9C}.Debug|Any CPU.Build.0 = Debug|Any CPU
|
{399A1579-68F0-40F4-9A23-F241BA697F9C}.Debug|Any CPU.Build.0 = Debug|Any CPU
|
||||||
{399A1579-68F0-40F4-9A23-F241BA697F9C}.Release|Any CPU.ActiveCfg = Release|Any CPU
|
{399A1579-68F0-40F4-9A23-F241BA697F9C}.Release|Any CPU.ActiveCfg = Release|Any CPU
|
||||||
{399A1579-68F0-40F4-9A23-F241BA697F9C}.Release|Any CPU.Build.0 = Release|Any CPU
|
{399A1579-68F0-40F4-9A23-F241BA697F9C}.Release|Any CPU.Build.0 = Release|Any CPU
|
||||||
|
{541D1AC5-E42C-4AB2-A1A4-C2355CE2A2EF}.Debug|Any CPU.ActiveCfg = Debug|Any CPU
|
||||||
|
{541D1AC5-E42C-4AB2-A1A4-C2355CE2A2EF}.Debug|Any CPU.Build.0 = Debug|Any CPU
|
||||||
|
{541D1AC5-E42C-4AB2-A1A4-C2355CE2A2EF}.Release|Any CPU.ActiveCfg = Release|Any CPU
|
||||||
|
{541D1AC5-E42C-4AB2-A1A4-C2355CE2A2EF}.Release|Any CPU.Build.0 = Release|Any CPU
|
||||||
{D00E7D25-0FA0-48EC-B048-CD60CE1B30D8}.Debug|Any CPU.ActiveCfg = Debug|Any CPU
|
{D00E7D25-0FA0-48EC-B048-CD60CE1B30D8}.Debug|Any CPU.ActiveCfg = Debug|Any CPU
|
||||||
{D00E7D25-0FA0-48EC-B048-CD60CE1B30D8}.Debug|Any CPU.Build.0 = Debug|Any CPU
|
{D00E7D25-0FA0-48EC-B048-CD60CE1B30D8}.Debug|Any CPU.Build.0 = Debug|Any CPU
|
||||||
{D00E7D25-0FA0-48EC-B048-CD60CE1B30D8}.Release|Any CPU.ActiveCfg = Release|Any CPU
|
{D00E7D25-0FA0-48EC-B048-CD60CE1B30D8}.Release|Any CPU.ActiveCfg = Release|Any CPU
|
||||||
|
|||||||
@@ -725,7 +725,7 @@ namespace Semmle.Autobuild.CSharp.Tests
|
|||||||
[Fact]
|
[Fact]
|
||||||
public void TestWindowsCmdIgnoreErrors()
|
public void TestWindowsCmdIgnoreErrors()
|
||||||
{
|
{
|
||||||
actions.RunProcess["cmd.exe /C ^\"build.cmd --skip-tests^\""] = 3;
|
actions.RunProcess["cmd.exe /C ^\"build.cmd^ --skip-tests^\""] = 3;
|
||||||
actions.RunProcess[@"cmd.exe /C C:\codeql\tools\java\bin\java -jar C:\codeql\csharp\tools\extractor-asp.jar ."] = 0;
|
actions.RunProcess[@"cmd.exe /C C:\codeql\tools\java\bin\java -jar C:\codeql\csharp\tools\extractor-asp.jar ."] = 0;
|
||||||
actions.RunProcess[@"cmd.exe /C C:\codeql\tools\codeql index --xml --extensions config"] = 0;
|
actions.RunProcess[@"cmd.exe /C C:\codeql\tools\codeql index --xml --extensions config"] = 0;
|
||||||
actions.FileExists["csharp.log"] = true;
|
actions.FileExists["csharp.log"] = true;
|
||||||
@@ -744,9 +744,9 @@ namespace Semmle.Autobuild.CSharp.Tests
|
|||||||
public void TestWindowCSharpMsBuild()
|
public void TestWindowCSharpMsBuild()
|
||||||
{
|
{
|
||||||
actions.RunProcess[@"cmd.exe /C C:\Project\.nuget\nuget.exe restore C:\Project\test1.sln -DisableParallelProcessing"] = 0;
|
actions.RunProcess[@"cmd.exe /C C:\Project\.nuget\nuget.exe restore C:\Project\test1.sln -DisableParallelProcessing"] = 0;
|
||||||
actions.RunProcess["cmd.exe /C CALL ^\"C:\\Program Files ^(x86^)\\Microsoft Visual Studio 12.0\\VC\\vcvarsall.bat^\" && set Platform=&& type NUL && msbuild C:\\Project\\test1.sln /t:Windows /p:Platform=\"x86\" /p:Configuration=\"Debug\" /P:Fu=Bar"] = 0;
|
actions.RunProcess["cmd.exe /C CALL ^\"C:\\Program^ Files^ ^(x86^)\\Microsoft^ Visual^ Studio^ 12.0\\VC\\vcvarsall.bat^\" && set Platform=&& type NUL && msbuild C:\\Project\\test1.sln /t:Windows /p:Platform=\"x86\" /p:Configuration=\"Debug\" /P:Fu=Bar"] = 0;
|
||||||
actions.RunProcess[@"cmd.exe /C C:\Project\.nuget\nuget.exe restore C:\Project\test2.sln -DisableParallelProcessing"] = 0;
|
actions.RunProcess[@"cmd.exe /C C:\Project\.nuget\nuget.exe restore C:\Project\test2.sln -DisableParallelProcessing"] = 0;
|
||||||
actions.RunProcess["cmd.exe /C CALL ^\"C:\\Program Files ^(x86^)\\Microsoft Visual Studio 12.0\\VC\\vcvarsall.bat^\" && set Platform=&& type NUL && msbuild C:\\Project\\test2.sln /t:Windows /p:Platform=\"x86\" /p:Configuration=\"Debug\" /P:Fu=Bar"] = 0;
|
actions.RunProcess["cmd.exe /C CALL ^\"C:\\Program^ Files^ ^(x86^)\\Microsoft^ Visual^ Studio^ 12.0\\VC\\vcvarsall.bat^\" && set Platform=&& type NUL && msbuild C:\\Project\\test2.sln /t:Windows /p:Platform=\"x86\" /p:Configuration=\"Debug\" /P:Fu=Bar"] = 0;
|
||||||
actions.FileExists["csharp.log"] = true;
|
actions.FileExists["csharp.log"] = true;
|
||||||
actions.FileExists[@"C:\Program Files (x86)\Microsoft Visual Studio\Installer\vswhere.exe"] = false;
|
actions.FileExists[@"C:\Program Files (x86)\Microsoft Visual Studio\Installer\vswhere.exe"] = false;
|
||||||
actions.FileExists[@"C:\Program Files (x86)\Microsoft Visual Studio 14.0\VC\vcvarsall.bat"] = false;
|
actions.FileExists[@"C:\Program Files (x86)\Microsoft Visual Studio 14.0\VC\vcvarsall.bat"] = false;
|
||||||
@@ -775,9 +775,9 @@ namespace Semmle.Autobuild.CSharp.Tests
|
|||||||
public void TestWindowCSharpMsBuildMultipleSolutions()
|
public void TestWindowCSharpMsBuildMultipleSolutions()
|
||||||
{
|
{
|
||||||
actions.RunProcess[@"cmd.exe /C nuget restore C:\Project\test1.csproj -DisableParallelProcessing"] = 0;
|
actions.RunProcess[@"cmd.exe /C nuget restore C:\Project\test1.csproj -DisableParallelProcessing"] = 0;
|
||||||
actions.RunProcess["cmd.exe /C CALL ^\"C:\\Program Files ^(x86^)\\Microsoft Visual Studio 12.0\\VC\\vcvarsall.bat^\" && set Platform=&& type NUL && msbuild C:\\Project\\test1.csproj /t:Windows /p:Platform=\"x86\" /p:Configuration=\"Debug\" /P:Fu=Bar"] = 0;
|
actions.RunProcess["cmd.exe /C CALL ^\"C:\\Program^ Files^ ^(x86^)\\Microsoft^ Visual^ Studio^ 12.0\\VC\\vcvarsall.bat^\" && set Platform=&& type NUL && msbuild C:\\Project\\test1.csproj /t:Windows /p:Platform=\"x86\" /p:Configuration=\"Debug\" /P:Fu=Bar"] = 0;
|
||||||
actions.RunProcess[@"cmd.exe /C nuget restore C:\Project\test2.csproj -DisableParallelProcessing"] = 0;
|
actions.RunProcess[@"cmd.exe /C nuget restore C:\Project\test2.csproj -DisableParallelProcessing"] = 0;
|
||||||
actions.RunProcess["cmd.exe /C CALL ^\"C:\\Program Files ^(x86^)\\Microsoft Visual Studio 12.0\\VC\\vcvarsall.bat^\" && set Platform=&& type NUL && msbuild C:\\Project\\test2.csproj /t:Windows /p:Platform=\"x86\" /p:Configuration=\"Debug\" /P:Fu=Bar"] = 0;
|
actions.RunProcess["cmd.exe /C CALL ^\"C:\\Program^ Files^ ^(x86^)\\Microsoft^ Visual^ Studio^ 12.0\\VC\\vcvarsall.bat^\" && set Platform=&& type NUL && msbuild C:\\Project\\test2.csproj /t:Windows /p:Platform=\"x86\" /p:Configuration=\"Debug\" /P:Fu=Bar"] = 0;
|
||||||
actions.FileExists["csharp.log"] = true;
|
actions.FileExists["csharp.log"] = true;
|
||||||
actions.FileExists[@"C:\Project\test1.csproj"] = true;
|
actions.FileExists[@"C:\Project\test1.csproj"] = true;
|
||||||
actions.FileExists[@"C:\Project\test2.csproj"] = true;
|
actions.FileExists[@"C:\Project\test2.csproj"] = true;
|
||||||
@@ -820,7 +820,7 @@ namespace Semmle.Autobuild.CSharp.Tests
|
|||||||
public void TestWindowCSharpMsBuildFailed()
|
public void TestWindowCSharpMsBuildFailed()
|
||||||
{
|
{
|
||||||
actions.RunProcess[@"cmd.exe /C nuget restore C:\Project\test1.sln -DisableParallelProcessing"] = 0;
|
actions.RunProcess[@"cmd.exe /C nuget restore C:\Project\test1.sln -DisableParallelProcessing"] = 0;
|
||||||
actions.RunProcess["cmd.exe /C CALL ^\"C:\\Program Files ^(x86^)\\Microsoft Visual Studio 12.0\\VC\\vcvarsall.bat^\" && set Platform=&& type NUL && msbuild C:\\Project\\test1.sln /t:Windows /p:Platform=\"x86\" /p:Configuration=\"Debug\" /P:Fu=Bar"] = 1;
|
actions.RunProcess["cmd.exe /C CALL ^\"C:\\Program^ Files^ ^(x86^)\\Microsoft^ Visual^ Studio^ 12.0\\VC\\vcvarsall.bat^\" && set Platform=&& type NUL && msbuild C:\\Project\\test1.sln /t:Windows /p:Platform=\"x86\" /p:Configuration=\"Debug\" /P:Fu=Bar"] = 1;
|
||||||
actions.FileExists["csharp.log"] = true;
|
actions.FileExists["csharp.log"] = true;
|
||||||
actions.FileExists[@"C:\Program Files (x86)\Microsoft Visual Studio\Installer\vswhere.exe"] = false;
|
actions.FileExists[@"C:\Program Files (x86)\Microsoft Visual Studio\Installer\vswhere.exe"] = false;
|
||||||
actions.FileExists[@"C:\Program Files (x86)\Microsoft Visual Studio 14.0\VC\vcvarsall.bat"] = false;
|
actions.FileExists[@"C:\Program Files (x86)\Microsoft Visual Studio 14.0\VC\vcvarsall.bat"] = false;
|
||||||
@@ -846,8 +846,8 @@ namespace Semmle.Autobuild.CSharp.Tests
|
|||||||
[Fact]
|
[Fact]
|
||||||
public void TestSkipNugetMsBuild()
|
public void TestSkipNugetMsBuild()
|
||||||
{
|
{
|
||||||
actions.RunProcess["cmd.exe /C CALL ^\"C:\\Program Files ^(x86^)\\Microsoft Visual Studio 12.0\\VC\\vcvarsall.bat^\" && set Platform=&& type NUL && msbuild C:\\Project\\test1.sln /t:Windows /p:Platform=\"x86\" /p:Configuration=\"Debug\" /P:Fu=Bar"] = 0;
|
actions.RunProcess["cmd.exe /C CALL ^\"C:\\Program^ Files^ ^(x86^)\\Microsoft^ Visual^ Studio^ 12.0\\VC\\vcvarsall.bat^\" && set Platform=&& type NUL && msbuild C:\\Project\\test1.sln /t:Windows /p:Platform=\"x86\" /p:Configuration=\"Debug\" /P:Fu=Bar"] = 0;
|
||||||
actions.RunProcess["cmd.exe /C CALL ^\"C:\\Program Files ^(x86^)\\Microsoft Visual Studio 12.0\\VC\\vcvarsall.bat^\" && set Platform=&& type NUL && msbuild C:\\Project\\test2.sln /t:Windows /p:Platform=\"x86\" /p:Configuration=\"Debug\" /P:Fu=Bar"] = 0;
|
actions.RunProcess["cmd.exe /C CALL ^\"C:\\Program^ Files^ ^(x86^)\\Microsoft^ Visual^ Studio^ 12.0\\VC\\vcvarsall.bat^\" && set Platform=&& type NUL && msbuild C:\\Project\\test2.sln /t:Windows /p:Platform=\"x86\" /p:Configuration=\"Debug\" /P:Fu=Bar"] = 0;
|
||||||
actions.FileExists["csharp.log"] = true;
|
actions.FileExists["csharp.log"] = true;
|
||||||
actions.FileExists[@"C:\Program Files (x86)\Microsoft Visual Studio\Installer\vswhere.exe"] = false;
|
actions.FileExists[@"C:\Program Files (x86)\Microsoft Visual Studio\Installer\vswhere.exe"] = false;
|
||||||
actions.FileExists[@"C:\Program Files (x86)\Microsoft Visual Studio 14.0\VC\vcvarsall.bat"] = false;
|
actions.FileExists[@"C:\Program Files (x86)\Microsoft Visual Studio 14.0\VC\vcvarsall.bat"] = false;
|
||||||
@@ -1037,7 +1037,7 @@ namespace Semmle.Autobuild.CSharp.Tests
|
|||||||
{
|
{
|
||||||
actions.RunProcess[@"cmd.exe /C nuget restore C:\Project\dirs.proj -DisableParallelProcessing"] = 1;
|
actions.RunProcess[@"cmd.exe /C nuget restore C:\Project\dirs.proj -DisableParallelProcessing"] = 1;
|
||||||
actions.RunProcess[@"cmd.exe /C C:\Project\.nuget\nuget.exe restore C:\Project\dirs.proj -DisableParallelProcessing"] = 0;
|
actions.RunProcess[@"cmd.exe /C C:\Project\.nuget\nuget.exe restore C:\Project\dirs.proj -DisableParallelProcessing"] = 0;
|
||||||
actions.RunProcess["cmd.exe /C CALL ^\"C:\\Program Files ^(x86^)\\Microsoft Visual Studio 12.0\\VC\\vcvarsall.bat^\" && set Platform=&& type NUL && msbuild C:\\Project\\dirs.proj /t:Windows /p:Platform=\"x86\" /p:Configuration=\"Debug\" /P:Fu=Bar"] = 0;
|
actions.RunProcess["cmd.exe /C CALL ^\"C:\\Program^ Files^ ^(x86^)\\Microsoft^ Visual^ Studio^ 12.0\\VC\\vcvarsall.bat^\" && set Platform=&& type NUL && msbuild C:\\Project\\dirs.proj /t:Windows /p:Platform=\"x86\" /p:Configuration=\"Debug\" /P:Fu=Bar"] = 0;
|
||||||
actions.FileExists["csharp.log"] = true;
|
actions.FileExists["csharp.log"] = true;
|
||||||
actions.FileExists[@"C:\Project\a\test.csproj"] = true;
|
actions.FileExists[@"C:\Project\a\test.csproj"] = true;
|
||||||
actions.FileExists[@"C:\Project\dirs.proj"] = true;
|
actions.FileExists[@"C:\Project\dirs.proj"] = true;
|
||||||
|
|||||||
@@ -55,7 +55,7 @@ namespace Semmle.Autobuild.Shared
|
|||||||
}
|
}
|
||||||
|
|
||||||
private static readonly char[] specialChars = { ' ', '\t', '\n', '\v', '\"' };
|
private static readonly char[] specialChars = { ' ', '\t', '\n', '\v', '\"' };
|
||||||
private static readonly char[] cmdMetacharacter = { '(', ')', '%', '!', '^', '\"', '<', '>', '&', '|' };
|
private static readonly char[] cmdMetacharacter = { '(', ')', '%', '!', '^', '\"', '<', '>', '&', '|', ' ' };
|
||||||
|
|
||||||
/// <summary>
|
/// <summary>
|
||||||
/// Appends the given argument to the command line.
|
/// Appends the given argument to the command line.
|
||||||
|
|||||||
@@ -1,4 +1,6 @@
|
|||||||
name: "csharp"
|
name: "csharp"
|
||||||
|
aliases:
|
||||||
|
- "c#"
|
||||||
display_name: "C#"
|
display_name: "C#"
|
||||||
version: 1.22.1
|
version: 1.22.1
|
||||||
column_kind: "utf16"
|
column_kind: "utf16"
|
||||||
|
|||||||
@@ -1,13 +1,12 @@
|
|||||||
using System.Collections.Generic;
|
using System.Collections.Generic;
|
||||||
using System.Linq;
|
|
||||||
using System.IO;
|
|
||||||
using System.Reflection.PortableExecutable;
|
|
||||||
using System.Reflection.Metadata;
|
|
||||||
using System.Reflection;
|
|
||||||
using System.Runtime.InteropServices;
|
|
||||||
using System.Globalization;
|
using System.Globalization;
|
||||||
|
using System.IO;
|
||||||
|
using System.Linq;
|
||||||
|
using System.Reflection;
|
||||||
|
using System.Reflection.Metadata;
|
||||||
|
using System.Reflection.PortableExecutable;
|
||||||
|
using System.Runtime.InteropServices;
|
||||||
using Semmle.Util;
|
using Semmle.Util;
|
||||||
using Semmle.Util.Logging;
|
|
||||||
|
|
||||||
namespace Semmle.Extraction.CIL.Driver
|
namespace Semmle.Extraction.CIL.Driver
|
||||||
{
|
{
|
||||||
|
|||||||
@@ -1,8 +1,8 @@
|
|||||||
using System;
|
using System;
|
||||||
|
using System.Diagnostics;
|
||||||
using System.Linq;
|
using System.Linq;
|
||||||
using System.Threading.Tasks;
|
using System.Threading.Tasks;
|
||||||
using Semmle.Util.Logging;
|
using Semmle.Util.Logging;
|
||||||
using System.Diagnostics;
|
|
||||||
|
|
||||||
namespace Semmle.Extraction.CIL.Driver
|
namespace Semmle.Extraction.CIL.Driver
|
||||||
{
|
{
|
||||||
|
|||||||
@@ -1,6 +1,6 @@
|
|||||||
using Semmle.Util.Logging;
|
|
||||||
using System;
|
using System;
|
||||||
using Semmle.Util;
|
using Semmle.Util;
|
||||||
|
using Semmle.Util.Logging;
|
||||||
using Semmle.Extraction.CIL.Entities;
|
using Semmle.Extraction.CIL.Entities;
|
||||||
|
|
||||||
namespace Semmle.Extraction.CIL
|
namespace Semmle.Extraction.CIL
|
||||||
|
|||||||
@@ -1,8 +1,7 @@
|
|||||||
using Semmle.Extraction.CIL.Entities;
|
using System;
|
||||||
using System;
|
|
||||||
using System.Collections.Generic;
|
using System.Collections.Generic;
|
||||||
using System.IO;
|
|
||||||
using System.Reflection.Metadata;
|
using System.Reflection.Metadata;
|
||||||
|
using Semmle.Extraction.CIL.Entities;
|
||||||
|
|
||||||
namespace Semmle.Extraction.CIL
|
namespace Semmle.Extraction.CIL
|
||||||
{
|
{
|
||||||
|
|||||||
@@ -1,8 +1,7 @@
|
|||||||
using System.Reflection;
|
using System.Collections.Generic;
|
||||||
using System.Globalization;
|
using System.Globalization;
|
||||||
using System.Collections.Generic;
|
using System.Reflection;
|
||||||
using Semmle.Extraction.Entities;
|
using Semmle.Extraction.Entities;
|
||||||
using System.IO;
|
|
||||||
|
|
||||||
namespace Semmle.Extraction.CIL.Entities
|
namespace Semmle.Extraction.CIL.Entities
|
||||||
{
|
{
|
||||||
|
|||||||
@@ -1,5 +1,4 @@
|
|||||||
using System;
|
using System.Collections.Generic;
|
||||||
using System.Collections.Generic;
|
|
||||||
using System.Linq;
|
using System.Linq;
|
||||||
using System.Reflection.Metadata;
|
using System.Reflection.Metadata;
|
||||||
|
|
||||||
|
|||||||
@@ -1,6 +1,5 @@
|
|||||||
using System;
|
using System;
|
||||||
using System.Collections.Generic;
|
using System.Collections.Generic;
|
||||||
using System.IO;
|
|
||||||
|
|
||||||
namespace Semmle.Extraction.CIL
|
namespace Semmle.Extraction.CIL
|
||||||
{
|
{
|
||||||
|
|||||||
@@ -1,7 +1,7 @@
|
|||||||
using System;
|
using System;
|
||||||
using System.Linq;
|
|
||||||
using System.Collections.Generic;
|
using System.Collections.Generic;
|
||||||
using System.IO;
|
using System.IO;
|
||||||
|
using System.Linq;
|
||||||
using Semmle.Util;
|
using Semmle.Util;
|
||||||
|
|
||||||
namespace Semmle.Extraction.CIL.Entities
|
namespace Semmle.Extraction.CIL.Entities
|
||||||
|
|||||||
@@ -1,7 +1,7 @@
|
|||||||
using System;
|
using System;
|
||||||
using System.Collections.Generic;
|
using System.Collections.Generic;
|
||||||
using System.Reflection.Metadata;
|
|
||||||
using System.Reflection;
|
using System.Reflection;
|
||||||
|
using System.Reflection.Metadata;
|
||||||
using System.Reflection.Metadata.Ecma335;
|
using System.Reflection.Metadata.Ecma335;
|
||||||
|
|
||||||
namespace Semmle.Extraction.CIL.Entities
|
namespace Semmle.Extraction.CIL.Entities
|
||||||
|
|||||||
@@ -1,7 +1,7 @@
|
|||||||
using System.Reflection.Metadata;
|
|
||||||
using System.Collections.Generic;
|
using System.Collections.Generic;
|
||||||
using System.Reflection;
|
|
||||||
using System.Linq;
|
using System.Linq;
|
||||||
|
using System.Reflection;
|
||||||
|
using System.Reflection.Metadata;
|
||||||
using System.Reflection.Metadata.Ecma335;
|
using System.Reflection.Metadata.Ecma335;
|
||||||
|
|
||||||
namespace Semmle.Extraction.CIL.Entities
|
namespace Semmle.Extraction.CIL.Entities
|
||||||
|
|||||||
@@ -1,5 +1,4 @@
|
|||||||
using System.Collections.Generic;
|
using System.Collections.Generic;
|
||||||
using System.IO;
|
|
||||||
using System.Reflection.Metadata;
|
using System.Reflection.Metadata;
|
||||||
|
|
||||||
namespace Semmle.Extraction.CIL.Entities
|
namespace Semmle.Extraction.CIL.Entities
|
||||||
|
|||||||
@@ -1,5 +1,4 @@
|
|||||||
using System.Collections.Generic;
|
using System.Collections.Generic;
|
||||||
using System.IO;
|
|
||||||
|
|
||||||
namespace Semmle.Extraction.CIL.Entities
|
namespace Semmle.Extraction.CIL.Entities
|
||||||
{
|
{
|
||||||
|
|||||||
@@ -1,5 +1,4 @@
|
|||||||
using System.Collections.Generic;
|
using System.Collections.Generic;
|
||||||
using System.IO;
|
|
||||||
|
|
||||||
namespace Semmle.Extraction.CIL.Entities
|
namespace Semmle.Extraction.CIL.Entities
|
||||||
{
|
{
|
||||||
|
|||||||
@@ -1,5 +1,3 @@
|
|||||||
using System.IO;
|
|
||||||
|
|
||||||
namespace Semmle.Extraction.CIL.Entities
|
namespace Semmle.Extraction.CIL.Entities
|
||||||
{
|
{
|
||||||
internal interface ITypeSignature
|
internal interface ITypeSignature
|
||||||
|
|||||||
@@ -1,5 +1,4 @@
|
|||||||
using System.Collections.Generic;
|
using System.Collections.Generic;
|
||||||
using System.IO;
|
|
||||||
|
|
||||||
namespace Semmle.Extraction.CIL.Entities
|
namespace Semmle.Extraction.CIL.Entities
|
||||||
{
|
{
|
||||||
|
|||||||
@@ -1,6 +1,6 @@
|
|||||||
using System.Reflection.Metadata;
|
|
||||||
using System.Collections.Generic;
|
using System.Collections.Generic;
|
||||||
using System.Linq;
|
using System.Linq;
|
||||||
|
using System.Reflection.Metadata;
|
||||||
|
|
||||||
namespace Semmle.Extraction.CIL.Entities
|
namespace Semmle.Extraction.CIL.Entities
|
||||||
{
|
{
|
||||||
|
|||||||
@@ -1,8 +1,7 @@
|
|||||||
using System;
|
using System;
|
||||||
using System.Reflection.Metadata;
|
|
||||||
using System.Collections.Generic;
|
using System.Collections.Generic;
|
||||||
using System.Linq;
|
using System.Linq;
|
||||||
using System.IO;
|
using System.Reflection.Metadata;
|
||||||
|
|
||||||
namespace Semmle.Extraction.CIL.Entities
|
namespace Semmle.Extraction.CIL.Entities
|
||||||
{
|
{
|
||||||
|
|||||||
@@ -1,9 +1,8 @@
|
|||||||
using System;
|
using System;
|
||||||
using System.Collections.Immutable;
|
|
||||||
using System.Reflection.Metadata;
|
|
||||||
using System.Collections.Generic;
|
using System.Collections.Generic;
|
||||||
|
using System.Collections.Immutable;
|
||||||
using System.Linq;
|
using System.Linq;
|
||||||
using System.IO;
|
using System.Reflection.Metadata;
|
||||||
using Semmle.Util;
|
using Semmle.Util;
|
||||||
|
|
||||||
namespace Semmle.Extraction.CIL.Entities
|
namespace Semmle.Extraction.CIL.Entities
|
||||||
|
|||||||
@@ -1,6 +1,5 @@
|
|||||||
using System;
|
using System;
|
||||||
using System.Collections.Generic;
|
using System.Collections.Generic;
|
||||||
using System.IO;
|
|
||||||
|
|
||||||
namespace Semmle.Extraction.CIL.Entities
|
namespace Semmle.Extraction.CIL.Entities
|
||||||
{
|
{
|
||||||
|
|||||||
@@ -1,5 +1,4 @@
|
|||||||
using System.Linq;
|
using System.Linq;
|
||||||
using System.IO;
|
|
||||||
|
|
||||||
namespace Semmle.Extraction.CIL.Entities
|
namespace Semmle.Extraction.CIL.Entities
|
||||||
{
|
{
|
||||||
|
|||||||
@@ -1,6 +1,5 @@
|
|||||||
using System;
|
using System;
|
||||||
using System.Collections.Generic;
|
using System.Collections.Generic;
|
||||||
using System.IO;
|
|
||||||
|
|
||||||
namespace Semmle.Extraction.CIL.Entities
|
namespace Semmle.Extraction.CIL.Entities
|
||||||
{
|
{
|
||||||
|
|||||||
@@ -1,4 +1,3 @@
|
|||||||
using System;
|
|
||||||
using System.Collections.Generic;
|
using System.Collections.Generic;
|
||||||
using System.Linq;
|
using System.Linq;
|
||||||
using Semmle.Util;
|
using Semmle.Util;
|
||||||
|
|||||||
@@ -1,5 +1,4 @@
|
|||||||
using System.Collections.Generic;
|
using System.Collections.Generic;
|
||||||
using System.IO;
|
|
||||||
|
|
||||||
namespace Semmle.Extraction.CIL.Entities
|
namespace Semmle.Extraction.CIL.Entities
|
||||||
{
|
{
|
||||||
|
|||||||
@@ -1,7 +1,7 @@
|
|||||||
using System;
|
using System;
|
||||||
using System.Reflection.Metadata;
|
|
||||||
using System.Collections.Generic;
|
using System.Collections.Generic;
|
||||||
using System.IO;
|
using System.IO;
|
||||||
|
using System.Reflection.Metadata;
|
||||||
|
|
||||||
namespace Semmle.Extraction.CIL.Entities
|
namespace Semmle.Extraction.CIL.Entities
|
||||||
{
|
{
|
||||||
|
|||||||
@@ -1,7 +1,6 @@
|
|||||||
using System.Collections.Generic;
|
using System.Collections.Generic;
|
||||||
using System.Reflection.Metadata;
|
using System.Reflection.Metadata;
|
||||||
using System.Reflection.Metadata.Ecma335;
|
using System.Reflection.Metadata.Ecma335;
|
||||||
using System.IO;
|
|
||||||
|
|
||||||
namespace Semmle.Extraction.CIL.Entities
|
namespace Semmle.Extraction.CIL.Entities
|
||||||
{
|
{
|
||||||
|
|||||||
@@ -1,6 +1,5 @@
|
|||||||
using System.Reflection.Metadata;
|
|
||||||
using System.Collections.Immutable;
|
using System.Collections.Immutable;
|
||||||
using System.IO;
|
using System.Reflection.Metadata;
|
||||||
|
|
||||||
namespace Semmle.Extraction.CIL.Entities
|
namespace Semmle.Extraction.CIL.Entities
|
||||||
{
|
{
|
||||||
|
|||||||
@@ -1,5 +1,4 @@
|
|||||||
using System.Collections.Generic;
|
using System.Collections.Generic;
|
||||||
using System.IO;
|
|
||||||
using Semmle.Extraction.PDB;
|
using Semmle.Extraction.PDB;
|
||||||
|
|
||||||
namespace Semmle.Extraction.CIL.Entities
|
namespace Semmle.Extraction.CIL.Entities
|
||||||
|
|||||||
@@ -1,8 +1,8 @@
|
|||||||
using System.Reflection.Metadata;
|
using System.Collections.Generic;
|
||||||
using System.Collections.Generic;
|
|
||||||
using System.IO;
|
|
||||||
using System.Diagnostics.CodeAnalysis;
|
using System.Diagnostics.CodeAnalysis;
|
||||||
|
using System.IO;
|
||||||
using System.Linq;
|
using System.Linq;
|
||||||
|
using System.Reflection.Metadata;
|
||||||
|
|
||||||
namespace Semmle.Extraction.CIL.Entities
|
namespace Semmle.Extraction.CIL.Entities
|
||||||
{
|
{
|
||||||
|
|||||||
@@ -1,5 +1,4 @@
|
|||||||
using System.Collections.Generic;
|
using System.Collections.Generic;
|
||||||
using System.IO;
|
|
||||||
|
|
||||||
namespace Semmle.Extraction.CIL.Entities
|
namespace Semmle.Extraction.CIL.Entities
|
||||||
{
|
{
|
||||||
|
|||||||
@@ -1,10 +1,10 @@
|
|||||||
using System;
|
using System;
|
||||||
using System.Linq;
|
|
||||||
using System.Collections.Generic;
|
using System.Collections.Generic;
|
||||||
using System.Reflection;
|
|
||||||
using System.IO;
|
using System.IO;
|
||||||
using System.Reflection.Metadata.Ecma335;
|
using System.Linq;
|
||||||
|
using System.Reflection;
|
||||||
using System.Reflection.Metadata;
|
using System.Reflection.Metadata;
|
||||||
|
using System.Reflection.Metadata.Ecma335;
|
||||||
|
|
||||||
namespace Semmle.Extraction.CIL.Entities
|
namespace Semmle.Extraction.CIL.Entities
|
||||||
{
|
{
|
||||||
|
|||||||
@@ -1,9 +1,9 @@
|
|||||||
using System;
|
using System;
|
||||||
using System.Reflection.Metadata;
|
|
||||||
using System.Linq;
|
|
||||||
using System.Collections.Generic;
|
using System.Collections.Generic;
|
||||||
using System.Reflection;
|
|
||||||
using System.IO;
|
using System.IO;
|
||||||
|
using System.Linq;
|
||||||
|
using System.Reflection;
|
||||||
|
using System.Reflection.Metadata;
|
||||||
|
|
||||||
namespace Semmle.Extraction.CIL.Entities
|
namespace Semmle.Extraction.CIL.Entities
|
||||||
{
|
{
|
||||||
|
|||||||
@@ -1,8 +1,8 @@
|
|||||||
using System;
|
using System;
|
||||||
using System.Reflection.Metadata;
|
|
||||||
using System.Linq;
|
|
||||||
using System.Collections.Generic;
|
using System.Collections.Generic;
|
||||||
using System.IO;
|
using System.IO;
|
||||||
|
using System.Linq;
|
||||||
|
using System.Reflection.Metadata;
|
||||||
|
|
||||||
namespace Semmle.Extraction.CIL.Entities
|
namespace Semmle.Extraction.CIL.Entities
|
||||||
{
|
{
|
||||||
|
|||||||
@@ -1,7 +1,7 @@
|
|||||||
using System;
|
using System;
|
||||||
using System.Reflection.Metadata;
|
|
||||||
using System.Collections.Immutable;
|
using System.Collections.Immutable;
|
||||||
using System.Linq;
|
using System.Linq;
|
||||||
|
using System.Reflection.Metadata;
|
||||||
|
|
||||||
namespace Semmle.Extraction.CIL.Entities
|
namespace Semmle.Extraction.CIL.Entities
|
||||||
{
|
{
|
||||||
|
|||||||
@@ -1,6 +1,5 @@
|
|||||||
using System.Linq;
|
|
||||||
using System.Collections.Generic;
|
using System.Collections.Generic;
|
||||||
using System.IO;
|
using System.Linq;
|
||||||
|
|
||||||
namespace Semmle.Extraction.CIL.Entities
|
namespace Semmle.Extraction.CIL.Entities
|
||||||
{
|
{
|
||||||
|
|||||||
@@ -1,6 +1,6 @@
|
|||||||
using System;
|
using System;
|
||||||
using Microsoft.DiaSymReader;
|
|
||||||
using System.Reflection;
|
using System.Reflection;
|
||||||
|
using Microsoft.DiaSymReader;
|
||||||
|
|
||||||
#pragma warning disable IDE0060, CA1822
|
#pragma warning disable IDE0060, CA1822
|
||||||
|
|
||||||
|
|||||||
Some files were not shown because too many files have changed in this diff Show More
Reference in New Issue
Block a user