зеркало из https://github.com/github/codeql.git
Merge branch 'main' into main
This commit is contained in:
Коммит
a130c0f6b3
|
@ -8,6 +8,8 @@
|
|||
/swift/ @github/codeql-swift
|
||||
/misc/codegen/ @github/codeql-swift
|
||||
/java/kotlin-extractor/ @github/codeql-kotlin
|
||||
/java/ql/test-kotlin1/ @github/codeql-kotlin
|
||||
/java/ql/test-kotlin2/ @github/codeql-kotlin
|
||||
|
||||
# ML-powered queries
|
||||
/javascript/ql/experimental/adaptivethreatmodeling/ @github/codeql-ml-powered-queries-reviewers
|
||||
|
|
|
@ -1,7 +1,7 @@
|
|||
provide:
|
||||
- "*/ql/src/qlpack.yml"
|
||||
- "*/ql/lib/qlpack.yml"
|
||||
- "*/ql/test/qlpack.yml"
|
||||
- "*/ql/test*/qlpack.yml"
|
||||
- "*/ql/examples/qlpack.yml"
|
||||
- "*/ql/consistency-queries/qlpack.yml"
|
||||
- "*/ql/automodel/src/qlpack.yml"
|
||||
|
|
|
@ -1,3 +1,17 @@
|
|||
## 0.12.0
|
||||
|
||||
### Breaking Changes
|
||||
|
||||
* The expressions `AssignPointerAddExpr` and `AssignPointerSubExpr` are no longer subtypes of `AssignBitwiseOperation`.
|
||||
|
||||
### Minor Analysis Improvements
|
||||
|
||||
* The "Returning stack-allocated memory" (`cpp/return-stack-allocated-memory`) query now also detects returning stack-allocated memory allocated by calls to `alloca`, `strdupa`, and `strndupa`.
|
||||
* Added models for `strlcpy` and `strlcat`.
|
||||
* Added models for the `sprintf` variants from the `StrSafe.h` header.
|
||||
* Added SQL API models for `ODBC`.
|
||||
* Added taint models for `realloc` and related functions.
|
||||
|
||||
## 0.11.0
|
||||
|
||||
### Breaking Changes
|
||||
|
|
|
@ -1,4 +0,0 @@
|
|||
---
|
||||
category: minorAnalysis
|
||||
---
|
||||
* Added taint models for `realloc` and related functions.
|
|
@ -1,4 +0,0 @@
|
|||
---
|
||||
category: breaking
|
||||
---
|
||||
* The expressions `AssignPointerAddExpr` and `AssignPointerSubExpr` are no longer subtypes of `AssignBitwiseOperation`.
|
|
@ -1,4 +0,0 @@
|
|||
---
|
||||
category: minorAnalysis
|
||||
---
|
||||
* Added models for the `sprintf` variants from the `StrSafe.h` header.
|
|
@ -1,4 +0,0 @@
|
|||
---
|
||||
category: minorAnalysis
|
||||
---
|
||||
* Added models for `strlcpy` and `strlcat`.
|
|
@ -0,0 +1,13 @@
|
|||
## 0.12.0
|
||||
|
||||
### Breaking Changes
|
||||
|
||||
* The expressions `AssignPointerAddExpr` and `AssignPointerSubExpr` are no longer subtypes of `AssignBitwiseOperation`.
|
||||
|
||||
### Minor Analysis Improvements
|
||||
|
||||
* The "Returning stack-allocated memory" (`cpp/return-stack-allocated-memory`) query now also detects returning stack-allocated memory allocated by calls to `alloca`, `strdupa`, and `strndupa`.
|
||||
* Added models for `strlcpy` and `strlcat`.
|
||||
* Added models for the `sprintf` variants from the `StrSafe.h` header.
|
||||
* Added SQL API models for `ODBC`.
|
||||
* Added taint models for `realloc` and related functions.
|
|
@ -1,2 +1,2 @@
|
|||
---
|
||||
lastReleaseVersion: 0.11.0
|
||||
lastReleaseVersion: 0.12.0
|
||||
|
|
|
@ -1,5 +1,5 @@
|
|||
name: codeql/cpp-all
|
||||
version: 0.11.1-dev
|
||||
version: 0.12.1-dev
|
||||
groups: cpp
|
||||
dbscheme: semmlecode.cpp.dbscheme
|
||||
extractor: cpp
|
||||
|
|
|
@ -645,6 +645,24 @@ class GlobalLikeVariable extends Variable {
|
|||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns the smallest indirection for the type `t`.
|
||||
*
|
||||
* For most types this is `1`, but for `ArrayType`s (which are allocated on
|
||||
* the stack) this is `0`
|
||||
*/
|
||||
int getMinIndirectionsForType(Type t) {
|
||||
if t.getUnspecifiedType() instanceof Cpp::ArrayType then result = 0 else result = 1
|
||||
}
|
||||
|
||||
private int getMinIndirectionForGlobalUse(Ssa::GlobalUse use) {
|
||||
result = getMinIndirectionsForType(use.getUnspecifiedType())
|
||||
}
|
||||
|
||||
private int getMinIndirectionForGlobalDef(Ssa::GlobalDef def) {
|
||||
result = getMinIndirectionsForType(def.getUnspecifiedType())
|
||||
}
|
||||
|
||||
/**
|
||||
* Holds if data can flow from `node1` to `node2` in a way that loses the
|
||||
* calling context. For example, this would happen with flow through a
|
||||
|
@ -656,7 +674,7 @@ predicate jumpStep(Node n1, Node n2) {
|
|||
v = globalUse.getVariable() and
|
||||
n1.(FinalGlobalValue).getGlobalUse() = globalUse
|
||||
|
|
||||
globalUse.getIndirection() = 1 and
|
||||
globalUse.getIndirection() = getMinIndirectionForGlobalUse(globalUse) and
|
||||
v = n2.asVariable()
|
||||
or
|
||||
v = n2.asIndirectVariable(globalUse.getIndirection())
|
||||
|
@ -666,7 +684,7 @@ predicate jumpStep(Node n1, Node n2) {
|
|||
v = globalDef.getVariable() and
|
||||
n2.(InitialGlobalValue).getGlobalDef() = globalDef
|
||||
|
|
||||
globalDef.getIndirection() = 1 and
|
||||
globalDef.getIndirection() = getMinIndirectionForGlobalDef(globalDef) and
|
||||
v = n1.asVariable()
|
||||
or
|
||||
v = n1.asIndirectVariable(globalDef.getIndirection())
|
||||
|
|
|
@ -34,7 +34,8 @@ cached
|
|||
private newtype TIRDataFlowNode =
|
||||
TNode0(Node0Impl node) { DataFlowImplCommon::forceCachingInSameStage() } or
|
||||
TVariableNode(Variable var, int indirectionIndex) {
|
||||
indirectionIndex = [1 .. Ssa::getMaxIndirectionsForType(var.getUnspecifiedType())]
|
||||
indirectionIndex =
|
||||
[getMinIndirectionsForType(var.getUnspecifiedType()) .. Ssa::getMaxIndirectionsForType(var.getUnspecifiedType())]
|
||||
} or
|
||||
TPostFieldUpdateNode(FieldAddress operand, int indirectionIndex) {
|
||||
indirectionIndex =
|
||||
|
@ -346,7 +347,9 @@ class Node extends TIRDataFlowNode {
|
|||
* Gets the variable corresponding to this node, if any. This can be used for
|
||||
* modeling flow in and out of global variables.
|
||||
*/
|
||||
Variable asVariable() { this = TVariableNode(result, 1) }
|
||||
Variable asVariable() {
|
||||
this = TVariableNode(result, getMinIndirectionsForType(result.getUnspecifiedType()))
|
||||
}
|
||||
|
||||
/**
|
||||
* Gets the `indirectionIndex`'th indirection of this node's underlying variable, if any.
|
||||
|
@ -354,7 +357,7 @@ class Node extends TIRDataFlowNode {
|
|||
* This can be used for modeling flow in and out of global variables.
|
||||
*/
|
||||
Variable asIndirectVariable(int indirectionIndex) {
|
||||
indirectionIndex > 1 and
|
||||
indirectionIndex > getMinIndirectionsForType(result.getUnspecifiedType()) and
|
||||
this = TVariableNode(result, indirectionIndex)
|
||||
}
|
||||
|
||||
|
@ -1273,31 +1276,90 @@ abstract private class IndirectExprNodeBase extends Node {
|
|||
}
|
||||
}
|
||||
|
||||
private class IndirectOperandIndirectExprNode extends IndirectExprNodeBase instanceof IndirectOperand
|
||||
{
|
||||
IndirectOperandIndirectExprNode() {
|
||||
exists(Expr e, int n, int indirectionIndex |
|
||||
indirectExprNodeShouldBeIndirectOperand(this, e, n, indirectionIndex) and
|
||||
not indirectExprNodeShouldBeIndirectOperand(_, e, n + 1, indirectionIndex)
|
||||
)
|
||||
/** A signature for converting an indirect node to an expression. */
|
||||
private signature module IndirectNodeToIndirectExprSig {
|
||||
/** The indirect node class to be converted to an expression */
|
||||
class IndirectNode;
|
||||
|
||||
/**
|
||||
* Holds if the indirect expression at indirection index `indirectionIndex`
|
||||
* of `node` is `e`. The integer `n` specifies how many conversions has been
|
||||
* applied to `node`.
|
||||
*/
|
||||
predicate indirectNodeHasIndirectExpr(IndirectNode node, Expr e, int n, int indirectionIndex);
|
||||
}
|
||||
|
||||
/**
|
||||
* A module that implements the logic for deciding whether an indirect node
|
||||
* should be an `IndirectExprNode`.
|
||||
*/
|
||||
private module IndirectNodeToIndirectExpr<IndirectNodeToIndirectExprSig Sig> {
|
||||
import Sig
|
||||
|
||||
/**
|
||||
* This predicate shifts the indirection index by one when `conv` is a
|
||||
* `ReferenceDereferenceExpr`.
|
||||
*
|
||||
* This is necessary because `ReferenceDereferenceExpr` is a conversion
|
||||
* in the AST, but appears as a `LoadInstruction` in the IR.
|
||||
*/
|
||||
bindingset[e, indirectionIndex]
|
||||
private predicate adjustForReference(
|
||||
Expr e, int indirectionIndex, Expr conv, int adjustedIndirectionIndex
|
||||
) {
|
||||
conv.(ReferenceDereferenceExpr).getExpr() = e and
|
||||
adjustedIndirectionIndex = indirectionIndex - 1
|
||||
or
|
||||
not conv instanceof ReferenceDereferenceExpr and
|
||||
conv = e and
|
||||
adjustedIndirectionIndex = indirectionIndex
|
||||
}
|
||||
|
||||
final override Expr getConvertedExpr(int n, int index) {
|
||||
indirectExprNodeShouldBeIndirectOperand(this, result, n, index)
|
||||
/** Holds if `node` should be an `IndirectExprNode`. */
|
||||
predicate charpred(IndirectNode node) {
|
||||
exists(Expr e, int n, int indirectionIndex |
|
||||
indirectNodeHasIndirectExpr(node, e, n, indirectionIndex) and
|
||||
not exists(Expr conv, int adjustedIndirectionIndex |
|
||||
adjustForReference(e, indirectionIndex, conv, adjustedIndirectionIndex) and
|
||||
indirectNodeHasIndirectExpr(_, conv, n + 1, adjustedIndirectionIndex)
|
||||
)
|
||||
)
|
||||
}
|
||||
}
|
||||
|
||||
private class IndirectInstructionIndirectExprNode extends IndirectExprNodeBase instanceof IndirectInstruction
|
||||
private module IndirectOperandIndirectExprNodeImpl implements IndirectNodeToIndirectExprSig {
|
||||
class IndirectNode = IndirectOperand;
|
||||
|
||||
predicate indirectNodeHasIndirectExpr = indirectExprNodeShouldBeIndirectOperand/4;
|
||||
}
|
||||
|
||||
module IndirectOperandToIndirectExpr =
|
||||
IndirectNodeToIndirectExpr<IndirectOperandIndirectExprNodeImpl>;
|
||||
|
||||
private class IndirectOperandIndirectExprNode extends IndirectExprNodeBase instanceof IndirectOperand
|
||||
{
|
||||
IndirectInstructionIndirectExprNode() {
|
||||
exists(Expr e, int n, int indirectionIndex |
|
||||
indirectExprNodeShouldBeIndirectInstruction(this, e, n, indirectionIndex) and
|
||||
not indirectExprNodeShouldBeIndirectInstruction(_, e, n + 1, indirectionIndex)
|
||||
)
|
||||
}
|
||||
IndirectOperandIndirectExprNode() { IndirectOperandToIndirectExpr::charpred(this) }
|
||||
|
||||
final override Expr getConvertedExpr(int n, int index) {
|
||||
indirectExprNodeShouldBeIndirectInstruction(this, result, n, index)
|
||||
IndirectOperandToIndirectExpr::indirectNodeHasIndirectExpr(this, result, n, index)
|
||||
}
|
||||
}
|
||||
|
||||
private module IndirectInstructionIndirectExprNodeImpl implements IndirectNodeToIndirectExprSig {
|
||||
class IndirectNode = IndirectInstruction;
|
||||
|
||||
predicate indirectNodeHasIndirectExpr = indirectExprNodeShouldBeIndirectInstruction/4;
|
||||
}
|
||||
|
||||
module IndirectInstructionToIndirectExpr =
|
||||
IndirectNodeToIndirectExpr<IndirectInstructionIndirectExprNodeImpl>;
|
||||
|
||||
private class IndirectInstructionIndirectExprNode extends IndirectExprNodeBase instanceof IndirectInstruction
|
||||
{
|
||||
IndirectInstructionIndirectExprNode() { IndirectInstructionToIndirectExpr::charpred(this) }
|
||||
|
||||
final override Expr getConvertedExpr(int n, int index) {
|
||||
IndirectInstructionToIndirectExpr::indirectNodeHasIndirectExpr(this, result, n, index)
|
||||
}
|
||||
}
|
||||
|
||||
|
|
|
@ -59,6 +59,9 @@ private module SourceVariables {
|
|||
then result = base.getType()
|
||||
else result = getTypeImpl(base.getType(), ind - 1)
|
||||
}
|
||||
|
||||
/** Gets the location of this variable. */
|
||||
Location getLocation() { result = this.getBaseVariable().getLocation() }
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -869,7 +872,7 @@ private predicate sourceVariableIsGlobal(
|
|||
)
|
||||
}
|
||||
|
||||
private module SsaInput implements SsaImplCommon::InputSig {
|
||||
private module SsaInput implements SsaImplCommon::InputSig<Location> {
|
||||
import InputSigCommon
|
||||
import SourceVariables
|
||||
|
||||
|
@ -1092,7 +1095,7 @@ class Def extends DefOrUse {
|
|||
predicate isCertain() { defOrUse.isCertain() }
|
||||
}
|
||||
|
||||
private module SsaImpl = SsaImplCommon::Make<SsaInput>;
|
||||
private module SsaImpl = SsaImplCommon::Make<Location, SsaInput>;
|
||||
|
||||
class PhiNode extends SsaImpl::DefinitionExt {
|
||||
PhiNode() {
|
||||
|
|
|
@ -377,6 +377,9 @@ abstract private class AbstractBaseSourceVariable extends TBaseSourceVariable {
|
|||
/** Gets a textual representation of this element. */
|
||||
abstract string toString();
|
||||
|
||||
/** Gets the location of this variable. */
|
||||
abstract Location getLocation();
|
||||
|
||||
/** Gets the type of this base source variable. */
|
||||
final DataFlowType getType() { this.getLanguageType().hasUnspecifiedType(result, _) }
|
||||
|
||||
|
@ -395,6 +398,8 @@ class BaseIRVariable extends AbstractBaseSourceVariable, TBaseIRVariable {
|
|||
|
||||
override string toString() { result = var.toString() }
|
||||
|
||||
override Location getLocation() { result = var.getLocation() }
|
||||
|
||||
override CppType getLanguageType() { result = var.getLanguageType() }
|
||||
}
|
||||
|
||||
|
@ -407,6 +412,8 @@ class BaseCallVariable extends AbstractBaseSourceVariable, TBaseCallVariable {
|
|||
|
||||
override string toString() { result = call.toString() }
|
||||
|
||||
override Location getLocation() { result = call.getLocation() }
|
||||
|
||||
override CppType getLanguageType() { result = getResultLanguageType(call) }
|
||||
}
|
||||
|
||||
|
@ -872,7 +879,7 @@ private module Cached {
|
|||
upper = countIndirectionsForCppType(type) and
|
||||
ind = ind0 + [lower .. upper] and
|
||||
indirectionIndex = ind - (ind0 + lower) and
|
||||
(if type.hasType(any(Cpp::ArrayType arrayType), true) then lower = 0 else lower = 1)
|
||||
lower = getMinIndirectionsForType(any(Type t | type.hasUnspecifiedType(t, _)))
|
||||
)
|
||||
}
|
||||
|
||||
|
|
|
@ -229,7 +229,7 @@ private class FinalParameterUse extends UseImpl, TFinalParameterUse {
|
|||
override predicate isCertain() { any() }
|
||||
}
|
||||
|
||||
private module SsaInput implements SsaImplCommon::InputSig {
|
||||
private module SsaInput implements SsaImplCommon::InputSig<Location> {
|
||||
import InputSigCommon
|
||||
import SourceVariables
|
||||
|
||||
|
@ -335,7 +335,7 @@ class Def extends DefOrUse {
|
|||
predicate isIteratorDef() { defOrUse instanceof IteratorDef }
|
||||
}
|
||||
|
||||
private module SsaImpl = SsaImplCommon::Make<SsaInput>;
|
||||
private module SsaImpl = SsaImplCommon::Make<Location, SsaInput>;
|
||||
|
||||
class PhiNode extends SsaImpl::DefinitionExt {
|
||||
PhiNode() {
|
||||
|
|
|
@ -1,3 +1,9 @@
|
|||
## 0.8.3
|
||||
|
||||
### Minor Analysis Improvements
|
||||
|
||||
* The `cpp/uninitialized-local` query has been improved to produce fewer false positives.
|
||||
|
||||
## 0.8.2
|
||||
|
||||
No user-facing changes.
|
||||
|
|
|
@ -27,16 +27,26 @@ class ReturnStackAllocatedMemoryConfig extends MustFlowConfiguration {
|
|||
ReturnStackAllocatedMemoryConfig() { this = "ReturnStackAllocatedMemoryConfig" }
|
||||
|
||||
override predicate isSource(Instruction source) {
|
||||
// Holds if `source` is a node that represents the use of a stack variable
|
||||
exists(VariableAddressInstruction var, Function func |
|
||||
var = source and
|
||||
func = source.getEnclosingFunction() and
|
||||
var.getAstVariable() instanceof StackVariable and
|
||||
// Pointer-to-member types aren't properly handled in the dbscheme.
|
||||
not var.getResultType() instanceof PointerToMemberType and
|
||||
exists(Function func |
|
||||
// Rule out FPs caused by extraction errors.
|
||||
not any(ErrorExpr e).getEnclosingFunction() = func and
|
||||
not intentionallyReturnsStackPointer(func)
|
||||
not intentionallyReturnsStackPointer(func) and
|
||||
func = source.getEnclosingFunction()
|
||||
|
|
||||
// `source` is an instruction that represents the use of a stack variable
|
||||
exists(VariableAddressInstruction var |
|
||||
var = source and
|
||||
var.getAstVariable() instanceof StackVariable and
|
||||
// Pointer-to-member types aren't properly handled in the dbscheme.
|
||||
not var.getResultType() instanceof PointerToMemberType
|
||||
)
|
||||
or
|
||||
// `source` is an instruction that represents the return value of a
|
||||
// function that is known to return stack-allocated memory.
|
||||
exists(Call call |
|
||||
call.getTarget().hasGlobalName(["alloca", "strdupa", "strndupa", "_alloca", "_malloca"]) and
|
||||
source.getUnconvertedResultExpression() = call
|
||||
)
|
||||
)
|
||||
}
|
||||
|
||||
|
@ -85,10 +95,10 @@ class ReturnStackAllocatedMemoryConfig extends MustFlowConfiguration {
|
|||
}
|
||||
|
||||
from
|
||||
MustFlowPathNode source, MustFlowPathNode sink, VariableAddressInstruction var,
|
||||
MustFlowPathNode source, MustFlowPathNode sink, Instruction instr,
|
||||
ReturnStackAllocatedMemoryConfig conf
|
||||
where
|
||||
conf.hasFlowPath(pragma[only_bind_into](source), pragma[only_bind_into](sink)) and
|
||||
source.getInstruction() = var
|
||||
source.getInstruction() = instr
|
||||
select sink.getInstruction(), source, sink, "May return stack-allocated memory from $@.",
|
||||
var.getAst(), var.getAst().toString()
|
||||
instr.getAst(), instr.getAst().toString()
|
||||
|
|
|
@ -14,25 +14,47 @@
|
|||
|
||||
import cpp
|
||||
import semmle.code.cpp.security.Security
|
||||
import semmle.code.cpp.ir.dataflow.internal.DefaultTaintTrackingImpl
|
||||
import TaintedWithPath
|
||||
import semmle.code.cpp.security.FlowSources
|
||||
import semmle.code.cpp.ir.dataflow.TaintTracking
|
||||
import semmle.code.cpp.ir.IR
|
||||
import Flow::PathGraph
|
||||
|
||||
predicate isProcessOperationExplanation(Expr arg, string processOperation) {
|
||||
predicate isProcessOperationExplanation(DataFlow::Node arg, string processOperation) {
|
||||
exists(int processOperationArg, FunctionCall call |
|
||||
isProcessOperationArgument(processOperation, processOperationArg) and
|
||||
call.getTarget().getName() = processOperation and
|
||||
call.getArgument(processOperationArg) = arg
|
||||
call.getArgument(processOperationArg) = [arg.asExpr(), arg.asIndirectExpr()]
|
||||
)
|
||||
}
|
||||
|
||||
class Configuration extends TaintTrackingConfiguration {
|
||||
override predicate isSink(Element arg) { isProcessOperationExplanation(arg, _) }
|
||||
predicate isSource(FlowSource source, string sourceType) {
|
||||
not source instanceof DataFlow::ExprNode and
|
||||
sourceType = source.getSourceType()
|
||||
}
|
||||
|
||||
from string processOperation, Expr arg, Expr source, PathNode sourceNode, PathNode sinkNode
|
||||
module Config implements DataFlow::ConfigSig {
|
||||
predicate isSource(DataFlow::Node node) { isSource(node, _) }
|
||||
|
||||
predicate isSink(DataFlow::Node node) { isProcessOperationExplanation(node, _) }
|
||||
|
||||
predicate isBarrier(DataFlow::Node node) {
|
||||
isSink(node) and node.asExpr().getUnspecifiedType() instanceof ArithmeticType
|
||||
or
|
||||
node.asInstruction().(StoreInstruction).getResultType() instanceof ArithmeticType
|
||||
}
|
||||
}
|
||||
|
||||
module Flow = TaintTracking::Global<Config>;
|
||||
|
||||
from
|
||||
string processOperation, string sourceType, DataFlow::Node source, DataFlow::Node sink,
|
||||
Flow::PathNode sourceNode, Flow::PathNode sinkNode
|
||||
where
|
||||
isProcessOperationExplanation(arg, processOperation) and
|
||||
taintedWithPath(source, arg, sourceNode, sinkNode)
|
||||
select arg, sourceNode, sinkNode,
|
||||
source = sourceNode.getNode() and
|
||||
sink = sinkNode.getNode() and
|
||||
isSource(source, sourceType) and
|
||||
isProcessOperationExplanation(sink, processOperation) and
|
||||
Flow::flowPath(sourceNode, sinkNode)
|
||||
select sink, sourceNode, sinkNode,
|
||||
"The value of this argument may come from $@ and is being passed to " + processOperation + ".",
|
||||
source, source.toString()
|
||||
source, sourceType
|
||||
|
|
|
@ -1,24 +0,0 @@
|
|||
#include <stdio.h>
|
||||
|
||||
char *copy;
|
||||
|
||||
void copyArgv(char **argv) {
|
||||
copy = argv[1];
|
||||
}
|
||||
|
||||
void printWrapper(char *str) {
|
||||
printf(str);
|
||||
}
|
||||
|
||||
int main(int argc, char **argv) {
|
||||
copyArgv(argv);
|
||||
|
||||
// This should be avoided
|
||||
printf(copy);
|
||||
|
||||
// This should be avoided too, because it has the same effect
|
||||
printWrapper(copy);
|
||||
|
||||
// This is fine
|
||||
printf("%s", copy);
|
||||
}
|
|
@ -1,36 +0,0 @@
|
|||
<!DOCTYPE qhelp PUBLIC
|
||||
"-//Semmle//qhelp//EN"
|
||||
"qhelp.dtd">
|
||||
<qhelp>
|
||||
<overview>
|
||||
<p>The program uses input from the user, propagated via a global variable, as a format string for <code>printf</code> style functions.
|
||||
This can lead to buffer overflows or data representation problems. An attacker can exploit this weakness to crash the program,
|
||||
disclose information or even execute arbitrary code.</p>
|
||||
|
||||
<p>This rule only identifies inputs from the user that are transferred through global variables before being used in <code>printf</code> style functions.
|
||||
Analyzing the flow of data through global variables is more prone to errors and so this rule may identify some examples of code where
|
||||
the input is not really from the user. For example, when a global variable is set in two places, one that comes from the user and one that does not.
|
||||
In this case we would mark all usages of the global variable as input from the user, but the input from the user may always came after the call to the
|
||||
<code>printf</code> style functions.</p>
|
||||
|
||||
<p>The results of this rule should be considered alongside the related rule "Uncontrolled format string" which tracks the flow of the
|
||||
values input by a user, excluding global variables, until the values are used as the format argument for a <code>printf</code> like function call.</p>
|
||||
|
||||
</overview>
|
||||
<recommendation>
|
||||
<p>Use constant expressions as the format strings. If you need to print a value from the user, use <code>printf("%s", value_from_user)</code>.</p>
|
||||
|
||||
</recommendation>
|
||||
<example>
|
||||
<sample src="UncontrolledFormatStringThroughGlobalVar.c" />
|
||||
|
||||
</example>
|
||||
<references>
|
||||
|
||||
<li>CERT C Coding
|
||||
Standard: <a href="https://www.securecoding.cert.org/confluence/display/c/FIO30-C.+Exclude+user+input+from+format+strings">FIO30-C. Exclude
|
||||
user input from format strings</a>.</li>
|
||||
|
||||
|
||||
</references>
|
||||
</qhelp>
|
|
@ -1,40 +0,0 @@
|
|||
/**
|
||||
* @name Uncontrolled format string (through global variable)
|
||||
* @description Using externally-controlled format strings in
|
||||
* printf-style functions can lead to buffer overflows
|
||||
* or data representation problems.
|
||||
* @kind path-problem
|
||||
* @problem.severity warning
|
||||
* @security-severity 9.3
|
||||
* @precision high
|
||||
* @id cpp/tainted-format-string-through-global
|
||||
* @tags reliability
|
||||
* security
|
||||
* external/cwe/cwe-134
|
||||
*/
|
||||
|
||||
import cpp
|
||||
import semmle.code.cpp.security.FunctionWithWrappers
|
||||
import semmle.code.cpp.security.Security
|
||||
import semmle.code.cpp.ir.dataflow.internal.DefaultTaintTrackingImpl
|
||||
import TaintedWithPath
|
||||
|
||||
class Configuration extends TaintTrackingConfiguration {
|
||||
override predicate isSink(Element tainted) {
|
||||
exists(PrintfLikeFunction printf | printf.outermostWrapperFunctionCall(tainted, _))
|
||||
}
|
||||
|
||||
override predicate taintThroughGlobals() { any() }
|
||||
}
|
||||
|
||||
from
|
||||
PrintfLikeFunction printf, Expr arg, PathNode sourceNode, PathNode sinkNode,
|
||||
string printfFunction, Expr userValue, string cause
|
||||
where
|
||||
printf.outermostWrapperFunctionCall(arg, printfFunction) and
|
||||
not taintedWithoutGlobals(arg) and
|
||||
taintedWithPath(userValue, arg, sourceNode, sinkNode) and
|
||||
isUserInput(userValue, cause)
|
||||
select arg, sourceNode, sinkNode,
|
||||
"The value of this argument may come from $@ and is being used as a formatting argument to " +
|
||||
printfFunction + ".", userValue, cause
|
|
@ -14,10 +14,13 @@
|
|||
|
||||
import cpp
|
||||
import semmle.code.cpp.security.Overflow
|
||||
import semmle.code.cpp.security.Security
|
||||
import semmle.code.cpp.ir.dataflow.internal.DefaultTaintTrackingImpl
|
||||
import TaintedWithPath
|
||||
import semmle.code.cpp.dataflow.new.TaintTracking
|
||||
import semmle.code.cpp.dataflow.new.DataFlow
|
||||
import semmle.code.cpp.ir.IR
|
||||
import semmle.code.cpp.controlflow.IRGuards as IRGuards
|
||||
import semmle.code.cpp.security.FlowSources as FS
|
||||
import Bounded
|
||||
import Flow::PathGraph
|
||||
|
||||
bindingset[op]
|
||||
predicate missingGuard(Operation op, Expr e, string effect) {
|
||||
|
@ -28,28 +31,90 @@ predicate missingGuard(Operation op, Expr e, string effect) {
|
|||
not e instanceof VariableAccess and effect = "overflow"
|
||||
}
|
||||
|
||||
class Configuration extends TaintTrackingConfiguration {
|
||||
override predicate isSink(Element e) {
|
||||
exists(Operation op |
|
||||
missingGuard(op, e, _) and
|
||||
op.getAnOperand() = e
|
||||
|
|
||||
op instanceof UnaryArithmeticOperation or
|
||||
op instanceof BinaryArithmeticOperation or
|
||||
op instanceof AssignArithmeticOperation
|
||||
)
|
||||
}
|
||||
predicate isSource(FS::FlowSource source, string sourceType) { sourceType = source.getSourceType() }
|
||||
|
||||
override predicate isBarrier(Expr e) {
|
||||
super.isBarrier(e) or bounded(e) or e.getUnspecifiedType().(IntegralType).getSize() <= 1
|
||||
predicate isSink(DataFlow::Node sink, Operation op, Expr e) {
|
||||
e = sink.asExpr() and
|
||||
missingGuard(op, e, _) and
|
||||
op.getAnOperand() = e and
|
||||
(
|
||||
op instanceof UnaryArithmeticOperation or
|
||||
op instanceof BinaryArithmeticOperation or
|
||||
op instanceof AssignArithmeticOperation
|
||||
)
|
||||
}
|
||||
|
||||
predicate hasUpperBoundsCheck(Variable var) {
|
||||
exists(RelationalOperation oper, VariableAccess access |
|
||||
oper.getAnOperand() = access and
|
||||
access.getTarget() = var and
|
||||
// Comparing to 0 is not an upper bound check
|
||||
not oper.getAnOperand().getValue() = "0"
|
||||
)
|
||||
}
|
||||
|
||||
predicate constantInstruction(Instruction instr) {
|
||||
instr instanceof ConstantInstruction or
|
||||
constantInstruction(instr.(UnaryInstruction).getUnary())
|
||||
}
|
||||
|
||||
predicate readsVariable(LoadInstruction load, Variable var) {
|
||||
load.getSourceAddress().(VariableAddressInstruction).getAstVariable() = var
|
||||
}
|
||||
|
||||
predicate nodeIsBarrierEqualityCandidate(DataFlow::Node node, Operand access, Variable checkedVar) {
|
||||
exists(Instruction instr | instr = node.asInstruction() |
|
||||
readsVariable(instr, checkedVar) and
|
||||
any(IRGuards::IRGuardCondition guard).ensuresEq(access, _, _, instr.getBlock(), true)
|
||||
)
|
||||
}
|
||||
|
||||
module Config implements DataFlow::ConfigSig {
|
||||
predicate isSource(DataFlow::Node source) { isSource(source, _) }
|
||||
|
||||
predicate isSink(DataFlow::Node sink) { isSink(sink, _, _) }
|
||||
|
||||
predicate isBarrier(DataFlow::Node node) {
|
||||
exists(StoreInstruction store | store = node.asInstruction() |
|
||||
// Block flow to "likely small expressions"
|
||||
bounded(store.getSourceValue().getUnconvertedResultExpression())
|
||||
or
|
||||
// Block flow to "small types"
|
||||
store.getResultType().getUnspecifiedType().(IntegralType).getSize() <= 1
|
||||
)
|
||||
or
|
||||
// Block flow if there's an upper bound check of the variable anywhere in the program
|
||||
exists(Variable checkedVar, Instruction instr | instr = node.asInstruction() |
|
||||
readsVariable(instr, checkedVar) and
|
||||
hasUpperBoundsCheck(checkedVar)
|
||||
)
|
||||
or
|
||||
// Block flow if the node is guarded by an equality check
|
||||
exists(Variable checkedVar, Operand access |
|
||||
nodeIsBarrierEqualityCandidate(node, access, checkedVar) and
|
||||
readsVariable(access.getDef(), checkedVar)
|
||||
)
|
||||
or
|
||||
// Block flow to any binary instruction whose operands are both non-constants.
|
||||
exists(BinaryInstruction iTo |
|
||||
iTo = node.asInstruction() and
|
||||
not constantInstruction(iTo.getLeft()) and
|
||||
not constantInstruction(iTo.getRight()) and
|
||||
// propagate taint from either the pointer or the offset, regardless of constantness
|
||||
not iTo instanceof PointerArithmeticInstruction
|
||||
)
|
||||
}
|
||||
}
|
||||
|
||||
from Expr origin, Expr e, string effect, PathNode sourceNode, PathNode sinkNode, Operation op
|
||||
module Flow = TaintTracking::Global<Config>;
|
||||
|
||||
from
|
||||
Expr e, string effect, Flow::PathNode source, Flow::PathNode sink, Operation op, string sourceType
|
||||
where
|
||||
taintedWithPath(origin, e, sourceNode, sinkNode) and
|
||||
op.getAnOperand() = e and
|
||||
Flow::flowPath(source, sink) and
|
||||
isSource(source.getNode(), sourceType) and
|
||||
isSink(sink.getNode(), op, e) and
|
||||
missingGuard(op, e, effect)
|
||||
select e, sourceNode, sinkNode,
|
||||
select e, source, sink,
|
||||
"$@ flows to an operand of an arithmetic expression, potentially causing an " + effect + ".",
|
||||
origin, "User-provided value"
|
||||
source, sourceType
|
||||
|
|
|
@ -16,45 +16,30 @@
|
|||
|
||||
import cpp
|
||||
import semmle.code.cpp.security.Overflow
|
||||
import semmle.code.cpp.security.Security
|
||||
import semmle.code.cpp.ir.dataflow.internal.DefaultTaintTrackingImpl
|
||||
import semmle.code.cpp.dataflow.new.TaintTracking
|
||||
import semmle.code.cpp.ir.IR
|
||||
import semmle.code.cpp.controlflow.IRGuards as IRGuards
|
||||
|
||||
predicate isMaxValue(Expr mie) {
|
||||
exists(MacroInvocation mi |
|
||||
mi.getExpr() = mie and
|
||||
(
|
||||
mi.getMacroName() = "CHAR_MAX" or
|
||||
mi.getMacroName() = "LLONG_MAX" or
|
||||
mi.getMacroName() = "INT_MAX" or
|
||||
mi.getMacroName() = "SHRT_MAX" or
|
||||
mi.getMacroName() = "UINT_MAX"
|
||||
)
|
||||
mi.getMacroName() = ["CHAR_MAX", "LLONG_MAX", "INT_MAX", "SHRT_MAX", "UINT_MAX"]
|
||||
)
|
||||
}
|
||||
|
||||
predicate isMinValue(Expr mie) {
|
||||
exists(MacroInvocation mi |
|
||||
mi.getExpr() = mie and
|
||||
(
|
||||
mi.getMacroName() = "CHAR_MIN" or
|
||||
mi.getMacroName() = "LLONG_MIN" or
|
||||
mi.getMacroName() = "INT_MIN" or
|
||||
mi.getMacroName() = "SHRT_MIN"
|
||||
)
|
||||
mi.getMacroName() = ["CHAR_MIN", "LLONG_MIN", "INT_MIN", "SHRT_MIN"]
|
||||
)
|
||||
}
|
||||
|
||||
class SecurityOptionsArith extends SecurityOptions {
|
||||
override predicate isUserInput(Expr expr, string cause) {
|
||||
predicate isSource(DataFlow::Node source, string cause) {
|
||||
exists(Expr expr | expr = source.asExpr() |
|
||||
isMaxValue(expr) and cause = "max value"
|
||||
or
|
||||
isMinValue(expr) and cause = "min value"
|
||||
}
|
||||
}
|
||||
|
||||
predicate taintedVarAccess(Expr origin, VariableAccess va, string cause) {
|
||||
isUserInput(origin, cause) and
|
||||
tainted(origin, va)
|
||||
)
|
||||
}
|
||||
|
||||
predicate causeEffectCorrespond(string cause, string effect) {
|
||||
|
@ -65,16 +50,79 @@ predicate causeEffectCorrespond(string cause, string effect) {
|
|||
effect = "underflow"
|
||||
}
|
||||
|
||||
from Expr origin, Operation op, VariableAccess va, string cause, string effect
|
||||
where
|
||||
taintedVarAccess(origin, va, cause) and
|
||||
op.getAnOperand() = va and
|
||||
(
|
||||
predicate isSink(DataFlow::Node sink, VariableAccess va, string effect) {
|
||||
exists(Operation op |
|
||||
sink.asExpr() = va and
|
||||
op.getAnOperand() = va
|
||||
|
|
||||
missingGuardAgainstUnderflow(op, va) and effect = "underflow"
|
||||
or
|
||||
missingGuardAgainstOverflow(op, va) and effect = "overflow"
|
||||
) and
|
||||
causeEffectCorrespond(cause, effect)
|
||||
)
|
||||
}
|
||||
|
||||
predicate hasUpperBoundsCheck(Variable var) {
|
||||
exists(RelationalOperation oper, VariableAccess access |
|
||||
oper.getAnOperand() = access and
|
||||
access.getTarget() = var and
|
||||
// Comparing to 0 is not an upper bound check
|
||||
not oper.getAnOperand().getValue() = "0"
|
||||
)
|
||||
}
|
||||
|
||||
predicate constantInstruction(Instruction instr) {
|
||||
instr instanceof ConstantInstruction or
|
||||
constantInstruction(instr.(UnaryInstruction).getUnary())
|
||||
}
|
||||
|
||||
predicate readsVariable(LoadInstruction load, Variable var) {
|
||||
load.getSourceAddress().(VariableAddressInstruction).getAstVariable() = var
|
||||
}
|
||||
|
||||
predicate nodeIsBarrierEqualityCandidate(DataFlow::Node node, Operand access, Variable checkedVar) {
|
||||
exists(Instruction instr | instr = node.asInstruction() |
|
||||
readsVariable(instr, checkedVar) and
|
||||
any(IRGuards::IRGuardCondition guard).ensuresEq(access, _, _, instr.getBlock(), true)
|
||||
)
|
||||
}
|
||||
|
||||
module Config implements DataFlow::ConfigSig {
|
||||
predicate isSource(DataFlow::Node source) { isSource(source, _) }
|
||||
|
||||
predicate isSink(DataFlow::Node sink) { isSink(sink, _, _) }
|
||||
|
||||
predicate isBarrier(DataFlow::Node node) {
|
||||
// Block flow if there's an upper bound check of the variable anywhere in the program
|
||||
exists(Variable checkedVar, Instruction instr | instr = node.asInstruction() |
|
||||
readsVariable(instr, checkedVar) and
|
||||
hasUpperBoundsCheck(checkedVar)
|
||||
)
|
||||
or
|
||||
// Block flow if the node is guarded by an equality check
|
||||
exists(Variable checkedVar, Operand access |
|
||||
nodeIsBarrierEqualityCandidate(node, access, checkedVar) and
|
||||
readsVariable(access.getDef(), checkedVar)
|
||||
)
|
||||
or
|
||||
// Block flow to any binary instruction whose operands are both non-constants.
|
||||
exists(BinaryInstruction iTo |
|
||||
iTo = node.asInstruction() and
|
||||
not constantInstruction(iTo.getLeft()) and
|
||||
not constantInstruction(iTo.getRight()) and
|
||||
// propagate taint from either the pointer or the offset, regardless of constantness
|
||||
not iTo instanceof PointerArithmeticInstruction
|
||||
)
|
||||
}
|
||||
}
|
||||
|
||||
module Flow = TaintTracking::Global<Config>;
|
||||
|
||||
from DataFlow::Node source, DataFlow::Node sink, VariableAccess va, string cause, string effect
|
||||
where
|
||||
Flow::flow(source, sink) and
|
||||
isSource(source, cause) and
|
||||
causeEffectCorrespond(cause, effect) and
|
||||
isSink(sink, va, effect)
|
||||
select va,
|
||||
"$@ flows to an operand of an arithmetic expression, potentially causing an " + effect + ".",
|
||||
origin, "Extreme value"
|
||||
source, "Extreme value"
|
||||
|
|
|
@ -15,7 +15,11 @@
|
|||
|
||||
import cpp
|
||||
import semmle.code.cpp.rangeanalysis.SimpleRangeAnalysis
|
||||
import semmle.code.cpp.ir.dataflow.internal.DefaultTaintTrackingImpl
|
||||
import semmle.code.cpp.dataflow.new.DataFlow
|
||||
import semmle.code.cpp.security.FlowSources as FS
|
||||
import semmle.code.cpp.dataflow.new.TaintTracking
|
||||
import semmle.code.cpp.ir.IR
|
||||
import semmle.code.cpp.controlflow.IRGuards as IRGuards
|
||||
|
||||
/** Holds if `expr` might overflow. */
|
||||
predicate outOfBoundsExpr(Expr expr, string kind) {
|
||||
|
@ -27,13 +31,76 @@ predicate outOfBoundsExpr(Expr expr, string kind) {
|
|||
else none()
|
||||
}
|
||||
|
||||
from Expr use, Expr origin, string kind
|
||||
predicate isSource(FS::FlowSource source, string sourceType) { sourceType = source.getSourceType() }
|
||||
|
||||
predicate isSink(DataFlow::Node sink, string kind) {
|
||||
exists(Expr use |
|
||||
use = sink.asExpr() and
|
||||
not use.getUnspecifiedType() instanceof PointerType and
|
||||
outOfBoundsExpr(use, kind) and
|
||||
not inSystemMacroExpansion(use)
|
||||
)
|
||||
}
|
||||
|
||||
predicate hasUpperBoundsCheck(Variable var) {
|
||||
exists(RelationalOperation oper, VariableAccess access |
|
||||
oper.getAnOperand() = access and
|
||||
access.getTarget() = var and
|
||||
// Comparing to 0 is not an upper bound check
|
||||
not oper.getAnOperand().getValue() = "0"
|
||||
)
|
||||
}
|
||||
|
||||
predicate constantInstruction(Instruction instr) {
|
||||
instr instanceof ConstantInstruction or
|
||||
constantInstruction(instr.(UnaryInstruction).getUnary())
|
||||
}
|
||||
|
||||
predicate readsVariable(LoadInstruction load, Variable var) {
|
||||
load.getSourceAddress().(VariableAddressInstruction).getAstVariable() = var
|
||||
}
|
||||
|
||||
predicate nodeIsBarrierEqualityCandidate(DataFlow::Node node, Operand access, Variable checkedVar) {
|
||||
exists(Instruction instr | instr = node.asInstruction() |
|
||||
readsVariable(instr, checkedVar) and
|
||||
any(IRGuards::IRGuardCondition guard).ensuresEq(access, _, _, instr.getBlock(), true)
|
||||
)
|
||||
}
|
||||
|
||||
module Config implements DataFlow::ConfigSig {
|
||||
predicate isSource(DataFlow::Node source) { isSource(source, _) }
|
||||
|
||||
predicate isSink(DataFlow::Node sink) { isSink(sink, _) }
|
||||
|
||||
predicate isBarrier(DataFlow::Node node) {
|
||||
// Block flow if there's an upper bound check of the variable anywhere in the program
|
||||
exists(Variable checkedVar, Instruction instr | instr = node.asInstruction() |
|
||||
readsVariable(instr, checkedVar) and
|
||||
hasUpperBoundsCheck(checkedVar)
|
||||
)
|
||||
or
|
||||
// Block flow if the node is guarded by an equality check
|
||||
exists(Variable checkedVar, Operand access |
|
||||
nodeIsBarrierEqualityCandidate(node, access, checkedVar) and
|
||||
readsVariable(access.getDef(), checkedVar)
|
||||
)
|
||||
or
|
||||
// Block flow to any binary instruction whose operands are both non-constants.
|
||||
exists(BinaryInstruction iTo |
|
||||
iTo = node.asInstruction() and
|
||||
not constantInstruction(iTo.getLeft()) and
|
||||
not constantInstruction(iTo.getRight()) and
|
||||
// propagate taint from either the pointer or the offset, regardless of constantness
|
||||
not iTo instanceof PointerArithmeticInstruction
|
||||
)
|
||||
}
|
||||
}
|
||||
|
||||
module Flow = TaintTracking::Global<Config>;
|
||||
|
||||
from DataFlow::Node source, DataFlow::Node sink, string kind, string sourceType
|
||||
where
|
||||
not use.getUnspecifiedType() instanceof PointerType and
|
||||
outOfBoundsExpr(use, kind) and
|
||||
tainted(origin, use) and
|
||||
origin != use and
|
||||
not inSystemMacroExpansion(use) and
|
||||
// Avoid double-counting: don't include all the conversions of `use`.
|
||||
not use instanceof Conversion
|
||||
select use, "$@ flows an expression which might " + kind + ".", origin, "User-provided value"
|
||||
Flow::flow(source, sink) and
|
||||
isSource(source, sourceType) and
|
||||
isSink(sink, kind)
|
||||
select sink, "$@ flows an expression which might " + kind + ".", source, sourceType
|
||||
|
|
|
@ -4,6 +4,7 @@
|
|||
* @description The total number of lines of C/C++ code across all files, including system headers, libraries, and auto-generated files. This is a useful metric of the size of a database. For all files that were seen during the build, this query counts the lines of code, excluding whitespace or comments.
|
||||
* @kind metric
|
||||
* @tags summary
|
||||
* telemetry
|
||||
*/
|
||||
|
||||
import cpp
|
||||
|
|
|
@ -1,4 +0,0 @@
|
|||
---
|
||||
category: minorAnalysis
|
||||
---
|
||||
* Added SQL API models for `ODBC`.
|
|
@ -0,0 +1,4 @@
|
|||
---
|
||||
category: breaking
|
||||
---
|
||||
* The `cpp/tainted-format-string-through-global` query has been deleted. This does not lead to a loss of relevant alerts, as the query duplicated a subset of the alerts from `cpp/tainted-format-string`.
|
|
@ -1,4 +1,5 @@
|
|||
---
|
||||
category: minorAnalysis
|
||||
---
|
||||
## 0.8.3
|
||||
|
||||
### Minor Analysis Improvements
|
||||
|
||||
* The `cpp/uninitialized-local` query has been improved to produce fewer false positives.
|
|
@ -1,2 +1,2 @@
|
|||
---
|
||||
lastReleaseVersion: 0.8.2
|
||||
lastReleaseVersion: 0.8.3
|
||||
|
|
|
@ -4,7 +4,6 @@
|
|||
* @kind problem
|
||||
* @id cpp/quantum-readiness/cbom/all-asymmetric-algorithms
|
||||
* @problem.severity error
|
||||
* @precision high
|
||||
* @tags cbom
|
||||
* cryptography
|
||||
*/
|
||||
|
|
|
@ -4,7 +4,6 @@
|
|||
* @kind problem
|
||||
* @id cpp/quantum-readiness/cbom/all-cryptographic-algorithms
|
||||
* @problem.severity error
|
||||
* @precision high
|
||||
* @tags cbom
|
||||
* cryptography
|
||||
*/
|
||||
|
|
|
@ -4,7 +4,6 @@
|
|||
* @kind problem
|
||||
* @id cpp/quantum-readiness/cbom/all-asymmetric-encryption-algorithms
|
||||
* @problem.severity error
|
||||
* @precision high
|
||||
* @tags cbom
|
||||
* cryptography
|
||||
*/
|
||||
|
|
|
@ -4,7 +4,6 @@
|
|||
* @kind problem
|
||||
* @id cpp/quantum-readiness/cbom/authenticated-encryption-algorithms
|
||||
* @problem.severity error
|
||||
* @precision high
|
||||
* @tags cbom
|
||||
* cryptography
|
||||
*/
|
||||
|
|
|
@ -4,7 +4,6 @@
|
|||
* @kind problem
|
||||
* @id cpp/quantum-readiness/cbom/block-cipher-mode
|
||||
* @problem.severity error
|
||||
* @precision high
|
||||
* @tags cbom
|
||||
* cryptography
|
||||
*/
|
||||
|
|
|
@ -4,7 +4,6 @@
|
|||
* @kind problem
|
||||
* @id cpp/quantum-readiness/cbom/iv-sources
|
||||
* @problem.severity error
|
||||
* @precision high
|
||||
* @tags cbom
|
||||
* cryptography
|
||||
*/
|
||||
|
|
|
@ -4,7 +4,6 @@
|
|||
* @kind problem
|
||||
* @id cpp/quantum-readiness/cbom/unkown-iv-sources
|
||||
* @problem.severity error
|
||||
* @precision high
|
||||
* @tags cbom
|
||||
* cryptography
|
||||
*/
|
||||
|
|
|
@ -4,7 +4,6 @@
|
|||
* @kind problem
|
||||
* @id cpp/quantum-readiness/cbom/elliptic-curve-key-length
|
||||
* @problem.severity error
|
||||
* @precision high
|
||||
* @tags cbom
|
||||
* cryptography
|
||||
*/
|
||||
|
|
|
@ -4,7 +4,6 @@
|
|||
* @kind problem
|
||||
* @id cpp/quantum-readiness/cbom/elliptic-curve-algorithms
|
||||
* @problem.severity error
|
||||
* @precision high
|
||||
* @tags cbom
|
||||
* cryptography
|
||||
*/
|
||||
|
|
|
@ -4,7 +4,6 @@
|
|||
* @kind problem
|
||||
* @id cpp/quantum-readiness/cbom/hash-algorithms
|
||||
* @problem.severity error
|
||||
* @precision high
|
||||
* @tags cbom
|
||||
* cryptography
|
||||
*/
|
||||
|
|
|
@ -4,7 +4,6 @@
|
|||
* @kind problem
|
||||
* @id cpp/quantum-readiness/cbom/key-exchange
|
||||
* @problem.severity error
|
||||
* @precision high
|
||||
* @tags cbom
|
||||
* cryptography
|
||||
*/
|
||||
|
|
|
@ -4,7 +4,6 @@
|
|||
* @kind problem
|
||||
* @id cpp/quantum-readiness/cbom/asymmetric-key-generation
|
||||
* @problem.severity error
|
||||
* @precision high
|
||||
* @tags cbom
|
||||
* cryptography
|
||||
*/
|
||||
|
|
|
@ -4,7 +4,6 @@
|
|||
* @kind problem
|
||||
* @id cpp/quantum-readiness/cbom/signing-algorithms
|
||||
* @problem.severity error
|
||||
* @precision high
|
||||
* @tags cbom
|
||||
* cryptography
|
||||
*/
|
||||
|
|
|
@ -4,7 +4,6 @@
|
|||
* @kind problem
|
||||
* @id cpp/quantum-readiness/cbom/symmetric-encryption-algorithms
|
||||
* @problem.severity error
|
||||
* @precision high
|
||||
* @tags cbom
|
||||
* cryptography
|
||||
*/
|
||||
|
|
|
@ -4,7 +4,6 @@
|
|||
* @kind problem
|
||||
* @id cpp/quantum-readiness/cbom/unkwon-asymmetric-key-generation
|
||||
* @problem.severity error
|
||||
* @precision high
|
||||
* @tags cbom
|
||||
* cryptography
|
||||
*/
|
||||
|
|
|
@ -1,5 +1,5 @@
|
|||
name: codeql/cpp-queries
|
||||
version: 0.8.3-dev
|
||||
version: 0.8.4-dev
|
||||
groups:
|
||||
- cpp
|
||||
- queries
|
||||
|
|
|
@ -0,0 +1,111 @@
|
|||
module AstTest {
|
||||
import semmle.code.cpp.dataflow.DataFlow
|
||||
private import semmle.code.cpp.controlflow.Guards
|
||||
|
||||
/**
|
||||
* A `BarrierGuard` that stops flow to all occurrences of `x` within statement
|
||||
* S in `if (guarded(x)) S`.
|
||||
*/
|
||||
// This is tested in `BarrierGuard.cpp`.
|
||||
predicate testBarrierGuard(GuardCondition g, Expr checked, boolean isTrue) {
|
||||
g.(FunctionCall).getTarget().getName() = "guarded" and
|
||||
checked = g.(FunctionCall).getArgument(0) and
|
||||
isTrue = true
|
||||
}
|
||||
|
||||
/** Common data flow configuration to be used by tests. */
|
||||
module AstTestAllocationConfig implements DataFlow::ConfigSig {
|
||||
predicate isSource(DataFlow::Node source) {
|
||||
source.asExpr().(FunctionCall).getTarget().getName() = "source"
|
||||
or
|
||||
source.asParameter().getName().matches("source%")
|
||||
or
|
||||
source.asExpr().(FunctionCall).getTarget().getName() = "indirect_source"
|
||||
or
|
||||
source.(DataFlow::DefinitionByReferenceNode).getParameter().getName().matches("ref_source%")
|
||||
or
|
||||
// Track uninitialized variables
|
||||
exists(source.asUninitialized())
|
||||
}
|
||||
|
||||
predicate isSink(DataFlow::Node sink) {
|
||||
exists(FunctionCall call |
|
||||
call.getTarget().getName() = ["sink", "indirect_sink"] and
|
||||
sink.asExpr() = call.getAnArgument()
|
||||
)
|
||||
}
|
||||
|
||||
predicate isBarrier(DataFlow::Node barrier) {
|
||||
barrier.asExpr().(VariableAccess).getTarget().hasName("barrier") or
|
||||
barrier = DataFlow::BarrierGuard<testBarrierGuard/3>::getABarrierNode()
|
||||
}
|
||||
}
|
||||
|
||||
module AstFlow = DataFlow::Global<AstTestAllocationConfig>;
|
||||
}
|
||||
|
||||
module IRTest {
|
||||
private import cpp
|
||||
import semmle.code.cpp.ir.dataflow.DataFlow
|
||||
private import semmle.code.cpp.ir.IR
|
||||
private import semmle.code.cpp.controlflow.IRGuards
|
||||
|
||||
/**
|
||||
* A `BarrierGuard` that stops flow to all occurrences of `x` within statement
|
||||
* S in `if (guarded(x)) S`.
|
||||
*/
|
||||
// This is tested in `BarrierGuard.cpp`.
|
||||
predicate testBarrierGuard(IRGuardCondition g, Expr checked, boolean isTrue) {
|
||||
exists(Call call |
|
||||
call = g.getUnconvertedResultExpression() and
|
||||
call.getTarget().hasName("guarded") and
|
||||
checked = call.getArgument(0) and
|
||||
isTrue = true
|
||||
)
|
||||
}
|
||||
|
||||
/** Common data flow configuration to be used by tests. */
|
||||
module IRTestAllocationConfig implements DataFlow::ConfigSig {
|
||||
predicate isSource(DataFlow::Node source) {
|
||||
source.asExpr().(FunctionCall).getTarget().getName() = "source"
|
||||
or
|
||||
source.asIndirectExpr(1).(FunctionCall).getTarget().getName() = "indirect_source"
|
||||
or
|
||||
source.asExpr().(StringLiteral).getValue() = "source"
|
||||
or
|
||||
// indirect_source(n) gives the dataflow node representing the indirect node after n dereferences.
|
||||
exists(int n, string s |
|
||||
n = s.regexpCapture("indirect_source\\((\\d)\\)", 1).toInt() and
|
||||
source.asIndirectExpr(n).(StringLiteral).getValue() = s
|
||||
)
|
||||
or
|
||||
source.asParameter().getName().matches("source%")
|
||||
or
|
||||
source.(DataFlow::DefinitionByReferenceNode).getParameter().getName().matches("ref_source%")
|
||||
or
|
||||
exists(source.asUninitialized())
|
||||
}
|
||||
|
||||
predicate isSink(DataFlow::Node sink) {
|
||||
exists(FunctionCall call, Expr e | e = call.getAnArgument() |
|
||||
call.getTarget().getName() = "sink" and
|
||||
sink.asExpr() = e
|
||||
or
|
||||
call.getTarget().getName() = "indirect_sink" and
|
||||
sink.asIndirectExpr() = e
|
||||
)
|
||||
}
|
||||
|
||||
predicate isBarrier(DataFlow::Node barrier) {
|
||||
exists(Expr barrierExpr | barrierExpr in [barrier.asExpr(), barrier.asIndirectExpr()] |
|
||||
barrierExpr.(VariableAccess).getTarget().hasName("barrier")
|
||||
)
|
||||
or
|
||||
barrier = DataFlow::BarrierGuard<testBarrierGuard/3>::getABarrierNode()
|
||||
or
|
||||
barrier = DataFlow::BarrierGuard<testBarrierGuard/3>::getAnIndirectBarrierNode()
|
||||
}
|
||||
}
|
||||
|
||||
module IRFlow = DataFlow::Global<IRTestAllocationConfig>;
|
||||
}
|
|
@ -1,5 +1,11 @@
|
|||
uniqueEnclosingCallable
|
||||
| test.cpp:864:44:864:58 | {...} | Node should have one enclosing callable but has 0. |
|
||||
| test.cpp:864:47:864:54 | call to source | Node should have one enclosing callable but has 0. |
|
||||
| test.cpp:872:46:872:51 | call to source | Node should have one enclosing callable but has 0. |
|
||||
| test.cpp:872:53:872:56 | 1 | Node should have one enclosing callable but has 0. |
|
||||
uniqueCallEnclosingCallable
|
||||
| test.cpp:864:47:864:54 | call to source | Call should have one enclosing callable but has 0. |
|
||||
| test.cpp:872:46:872:51 | call to source | Call should have one enclosing callable but has 0. |
|
||||
uniqueType
|
||||
uniqueNodeLocation
|
||||
missingLocation
|
||||
|
@ -24,6 +30,7 @@ argHasPostUpdate
|
|||
| lambdas.cpp:45:2:45:2 | e | ArgumentNode is missing PostUpdateNode. |
|
||||
| test.cpp:67:29:67:35 | source1 | ArgumentNode is missing PostUpdateNode. |
|
||||
| test.cpp:813:19:813:35 | * ... | ArgumentNode is missing PostUpdateNode. |
|
||||
| test.cpp:848:23:848:25 | rpx | ArgumentNode is missing PostUpdateNode. |
|
||||
postWithInFlow
|
||||
| BarrierGuard.cpp:49:6:49:6 | x [post update] | PostUpdateNode should not be the target of local flow. |
|
||||
| BarrierGuard.cpp:60:7:60:7 | x [post update] | PostUpdateNode should not be the target of local flow. |
|
||||
|
|
|
@ -0,0 +1,306 @@
|
|||
WARNING: Module DataFlow has been deprecated and may be removed in future (test-source-sink.ql:3,25-42)
|
||||
WARNING: Module DataFlow has been deprecated and may be removed in future (test-source-sink.ql:3,57-74)
|
||||
astFlow
|
||||
| BarrierGuard.cpp:5:19:5:24 | source | BarrierGuard.cpp:9:10:9:15 | source |
|
||||
| BarrierGuard.cpp:13:17:13:22 | source | BarrierGuard.cpp:15:10:15:15 | source |
|
||||
| BarrierGuard.cpp:21:17:21:22 | source | BarrierGuard.cpp:25:10:25:15 | source |
|
||||
| BarrierGuard.cpp:29:16:29:21 | source | BarrierGuard.cpp:31:10:31:15 | source |
|
||||
| BarrierGuard.cpp:29:16:29:21 | source | BarrierGuard.cpp:33:10:33:15 | source |
|
||||
| BarrierGuard.cpp:49:10:49:15 | call to source | BarrierGuard.cpp:51:13:51:13 | x |
|
||||
| BarrierGuard.cpp:49:10:49:15 | call to source | BarrierGuard.cpp:53:13:53:13 | x |
|
||||
| BarrierGuard.cpp:49:10:49:15 | call to source | BarrierGuard.cpp:55:13:55:13 | x |
|
||||
| BarrierGuard.cpp:60:11:60:16 | call to source | BarrierGuard.cpp:62:14:62:14 | x |
|
||||
| BarrierGuard.cpp:60:11:60:16 | call to source | BarrierGuard.cpp:64:14:64:14 | x |
|
||||
| BarrierGuard.cpp:60:11:60:16 | call to source | BarrierGuard.cpp:66:14:66:14 | x |
|
||||
| acrossLinkTargets.cpp:19:27:19:32 | call to source | acrossLinkTargets.cpp:12:8:12:8 | x |
|
||||
| clang.cpp:12:9:12:20 | sourceArray1 | clang.cpp:18:8:18:19 | sourceArray1 |
|
||||
| clang.cpp:12:9:12:20 | sourceArray1 | clang.cpp:22:8:22:20 | & ... |
|
||||
| clang.cpp:12:9:12:20 | sourceArray1 | clang.cpp:23:17:23:29 | & ... |
|
||||
| clang.cpp:29:27:29:32 | call to source | clang.cpp:30:27:30:28 | m1 |
|
||||
| clang.cpp:29:27:29:32 | call to source | clang.cpp:31:27:31:34 | call to getFirst |
|
||||
| clang.cpp:35:32:35:37 | call to source | clang.cpp:38:10:38:11 | m2 |
|
||||
| clang.cpp:44:35:44:40 | call to source | clang.cpp:46:17:46:18 | m2 |
|
||||
| clang.cpp:51:19:51:24 | call to source | clang.cpp:52:8:52:17 | stackArray |
|
||||
| clang.cpp:51:19:51:24 | call to source | clang.cpp:53:17:53:26 | stackArray |
|
||||
| dispatch.cpp:9:37:9:42 | call to source | dispatch.cpp:35:16:35:25 | call to notSource1 |
|
||||
| dispatch.cpp:9:37:9:42 | call to source | dispatch.cpp:43:15:43:24 | call to notSource1 |
|
||||
| dispatch.cpp:10:37:10:42 | call to source | dispatch.cpp:36:16:36:25 | call to notSource2 |
|
||||
| dispatch.cpp:10:37:10:42 | call to source | dispatch.cpp:44:15:44:24 | call to notSource2 |
|
||||
| dispatch.cpp:37:19:37:24 | call to source | dispatch.cpp:11:38:11:38 | x |
|
||||
| dispatch.cpp:45:18:45:23 | call to source | dispatch.cpp:11:38:11:38 | x |
|
||||
| globals.cpp:5:17:5:22 | call to source | globals.cpp:6:10:6:14 | local |
|
||||
| lambdas.cpp:8:10:8:15 | call to source | lambdas.cpp:14:3:14:6 | t |
|
||||
| lambdas.cpp:8:10:8:15 | call to source | lambdas.cpp:18:8:18:8 | call to operator() |
|
||||
| lambdas.cpp:8:10:8:15 | call to source | lambdas.cpp:21:3:21:6 | t |
|
||||
| lambdas.cpp:8:10:8:15 | call to source | lambdas.cpp:29:3:29:6 | t |
|
||||
| lambdas.cpp:8:10:8:15 | call to source | lambdas.cpp:35:8:35:8 | a |
|
||||
| lambdas.cpp:8:10:8:15 | call to source | lambdas.cpp:41:8:41:8 | a |
|
||||
| lambdas.cpp:43:7:43:12 | call to source | lambdas.cpp:46:7:46:7 | w |
|
||||
| ref.cpp:29:11:29:16 | call to source | ref.cpp:62:10:62:11 | x3 |
|
||||
| ref.cpp:53:9:53:10 | x1 | ref.cpp:56:10:56:11 | x1 |
|
||||
| ref.cpp:53:13:53:14 | x2 | ref.cpp:59:10:59:11 | x2 |
|
||||
| ref.cpp:53:17:53:18 | x3 | ref.cpp:62:10:62:11 | x3 |
|
||||
| ref.cpp:53:21:53:22 | x4 | ref.cpp:65:10:65:11 | x4 |
|
||||
| ref.cpp:55:23:55:28 | call to source | ref.cpp:56:10:56:11 | x1 |
|
||||
| ref.cpp:94:15:94:20 | call to source | ref.cpp:129:13:129:15 | val |
|
||||
| ref.cpp:109:15:109:20 | call to source | ref.cpp:132:13:132:15 | val |
|
||||
| ref.cpp:122:23:122:28 | call to source | ref.cpp:123:13:123:15 | val |
|
||||
| ref.cpp:125:19:125:24 | call to source | ref.cpp:126:13:126:15 | val |
|
||||
| self-Iterator.cpp:19:23:19:28 | call to source | self-Iterator.cpp:20:10:20:10 | x |
|
||||
| test.cpp:6:12:6:17 | call to source | test.cpp:7:8:7:9 | t1 |
|
||||
| test.cpp:6:12:6:17 | call to source | test.cpp:9:8:9:9 | t1 |
|
||||
| test.cpp:6:12:6:17 | call to source | test.cpp:10:8:10:9 | t2 |
|
||||
| test.cpp:6:12:6:17 | call to source | test.cpp:15:8:15:9 | t2 |
|
||||
| test.cpp:6:12:6:17 | call to source | test.cpp:26:8:26:9 | t1 |
|
||||
| test.cpp:35:10:35:15 | call to source | test.cpp:30:8:30:8 | t |
|
||||
| test.cpp:36:13:36:18 | call to source | test.cpp:31:8:31:8 | c |
|
||||
| test.cpp:50:14:50:19 | call to source | test.cpp:58:10:58:10 | t |
|
||||
| test.cpp:66:30:66:36 | source1 | test.cpp:71:8:71:9 | x4 |
|
||||
| test.cpp:75:7:75:8 | u1 | test.cpp:76:8:76:9 | u1 |
|
||||
| test.cpp:83:7:83:8 | u2 | test.cpp:84:8:84:18 | ... ? ... : ... |
|
||||
| test.cpp:83:7:83:8 | u2 | test.cpp:86:8:86:9 | i1 |
|
||||
| test.cpp:89:28:89:34 | source1 | test.cpp:90:8:90:14 | source1 |
|
||||
| test.cpp:100:13:100:18 | call to source | test.cpp:103:10:103:12 | ref |
|
||||
| test.cpp:138:27:138:32 | call to source | test.cpp:140:8:140:8 | y |
|
||||
| test.cpp:151:33:151:38 | call to source | test.cpp:144:8:144:8 | s |
|
||||
| test.cpp:151:33:151:38 | call to source | test.cpp:152:8:152:8 | y |
|
||||
| test.cpp:164:34:164:39 | call to source | test.cpp:157:8:157:8 | x |
|
||||
| test.cpp:164:34:164:39 | call to source | test.cpp:165:8:165:8 | y |
|
||||
| test.cpp:171:11:171:16 | call to source | test.cpp:178:8:178:8 | y |
|
||||
| test.cpp:245:14:245:19 | call to source | test.cpp:260:12:260:12 | x |
|
||||
| test.cpp:265:22:265:27 | call to source | test.cpp:266:12:266:12 | x |
|
||||
| test.cpp:305:17:305:22 | call to source | test.cpp:289:14:289:14 | x |
|
||||
| test.cpp:314:4:314:9 | call to source | test.cpp:318:7:318:7 | x |
|
||||
| test.cpp:347:17:347:22 | call to source | test.cpp:349:10:349:18 | globalVar |
|
||||
| test.cpp:359:13:359:18 | call to source | test.cpp:365:10:365:14 | field |
|
||||
| test.cpp:373:13:373:18 | call to source | test.cpp:369:10:369:14 | field |
|
||||
| test.cpp:373:13:373:18 | call to source | test.cpp:375:10:375:14 | field |
|
||||
| test.cpp:382:48:382:54 | source1 | test.cpp:385:8:385:10 | tmp |
|
||||
| test.cpp:388:53:388:59 | source1 | test.cpp:392:8:392:10 | tmp |
|
||||
| test.cpp:388:53:388:59 | source1 | test.cpp:394:10:394:12 | tmp |
|
||||
| test.cpp:399:7:399:9 | tmp | test.cpp:401:8:401:10 | tmp |
|
||||
| test.cpp:405:7:405:9 | tmp | test.cpp:408:8:408:10 | tmp |
|
||||
| test.cpp:416:7:416:11 | local | test.cpp:418:8:418:12 | local |
|
||||
| test.cpp:417:16:417:20 | ref arg local | test.cpp:418:8:418:12 | local |
|
||||
| test.cpp:422:7:422:11 | local | test.cpp:424:8:424:12 | local |
|
||||
| test.cpp:423:20:423:25 | ref arg & ... | test.cpp:424:8:424:12 | local |
|
||||
| test.cpp:433:7:433:11 | local | test.cpp:435:8:435:12 | local |
|
||||
| test.cpp:433:7:433:11 | local | test.cpp:436:8:436:13 | * ... |
|
||||
| test.cpp:434:20:434:24 | ref arg local | test.cpp:435:8:435:12 | local |
|
||||
| test.cpp:434:20:434:24 | ref arg local | test.cpp:436:8:436:13 | * ... |
|
||||
| test.cpp:440:7:440:11 | local | test.cpp:442:8:442:12 | local |
|
||||
| test.cpp:441:18:441:23 | ref arg & ... | test.cpp:442:8:442:12 | local |
|
||||
| test.cpp:448:7:448:11 | local | test.cpp:450:8:450:12 | local |
|
||||
| test.cpp:448:7:448:11 | local | test.cpp:451:8:451:13 | * ... |
|
||||
| test.cpp:449:18:449:22 | ref arg local | test.cpp:450:8:450:12 | local |
|
||||
| test.cpp:449:18:449:22 | ref arg local | test.cpp:451:8:451:13 | * ... |
|
||||
| test.cpp:456:26:456:32 | source1 | test.cpp:457:9:457:22 | (statement expression) |
|
||||
| test.cpp:456:26:456:32 | source1 | test.cpp:468:8:468:12 | local |
|
||||
| test.cpp:472:8:472:13 | call to source | test.cpp:478:8:478:8 | x |
|
||||
| test.cpp:506:8:506:13 | call to source | test.cpp:513:8:513:8 | x |
|
||||
| test.cpp:517:7:517:16 | stackArray | test.cpp:521:8:521:20 | access to array |
|
||||
| test.cpp:519:19:519:24 | call to source | test.cpp:521:8:521:20 | access to array |
|
||||
| test.cpp:551:9:551:9 | y | test.cpp:541:10:541:10 | y |
|
||||
| test.cpp:583:11:583:16 | call to source | test.cpp:590:8:590:8 | x |
|
||||
| test.cpp:628:20:628:25 | ref arg buffer | test.cpp:629:17:629:22 | buffer |
|
||||
| test.cpp:633:18:633:23 | call to source | test.cpp:634:8:634:8 | x |
|
||||
| test.cpp:702:38:702:43 | source | test.cpp:695:8:695:10 | buf |
|
||||
| test.cpp:726:11:726:16 | call to source | test.cpp:735:8:735:8 | x |
|
||||
| test.cpp:733:7:733:7 | x | test.cpp:735:8:735:8 | x |
|
||||
| test.cpp:749:27:749:32 | call to source | test.cpp:740:10:740:10 | x |
|
||||
| test.cpp:751:27:751:32 | call to source | test.cpp:740:10:740:10 | x |
|
||||
| test.cpp:753:32:753:37 | call to source | test.cpp:740:10:740:10 | x |
|
||||
| test.cpp:755:32:755:37 | call to source | test.cpp:740:10:740:10 | x |
|
||||
| test.cpp:769:27:769:32 | call to source | test.cpp:760:10:760:10 | x |
|
||||
| test.cpp:771:27:771:32 | call to source | test.cpp:760:10:760:10 | x |
|
||||
| test.cpp:773:32:773:37 | call to source | test.cpp:760:10:760:10 | x |
|
||||
| test.cpp:775:32:775:37 | call to source | test.cpp:760:10:760:10 | x |
|
||||
| test.cpp:788:31:788:36 | call to source | test.cpp:782:12:782:12 | x |
|
||||
| test.cpp:790:31:790:36 | call to source | test.cpp:782:12:782:12 | x |
|
||||
| test.cpp:797:22:797:28 | ref arg content | test.cpp:798:19:798:25 | content |
|
||||
| test.cpp:842:11:842:16 | call to source | test.cpp:844:8:844:8 | y |
|
||||
| test.cpp:846:13:846:27 | call to indirect_source | test.cpp:848:23:848:25 | rpx |
|
||||
| test.cpp:860:54:860:59 | call to source | test.cpp:861:10:861:37 | static_local_pointer_dynamic |
|
||||
| true_upon_entry.cpp:17:11:17:16 | call to source | true_upon_entry.cpp:21:8:21:8 | x |
|
||||
| true_upon_entry.cpp:27:9:27:14 | call to source | true_upon_entry.cpp:29:8:29:8 | x |
|
||||
| true_upon_entry.cpp:33:11:33:16 | call to source | true_upon_entry.cpp:39:8:39:8 | x |
|
||||
| true_upon_entry.cpp:43:11:43:16 | call to source | true_upon_entry.cpp:49:8:49:8 | x |
|
||||
| true_upon_entry.cpp:54:11:54:16 | call to source | true_upon_entry.cpp:57:8:57:8 | x |
|
||||
| true_upon_entry.cpp:70:11:70:16 | call to source | true_upon_entry.cpp:78:8:78:8 | x |
|
||||
| true_upon_entry.cpp:83:11:83:16 | call to source | true_upon_entry.cpp:86:8:86:8 | x |
|
||||
irFlow
|
||||
| BarrierGuard.cpp:5:19:5:24 | source | BarrierGuard.cpp:9:10:9:15 | source |
|
||||
| BarrierGuard.cpp:13:17:13:22 | source | BarrierGuard.cpp:15:10:15:15 | source |
|
||||
| BarrierGuard.cpp:21:17:21:22 | source | BarrierGuard.cpp:25:10:25:15 | source |
|
||||
| BarrierGuard.cpp:29:16:29:21 | source | BarrierGuard.cpp:31:10:31:15 | source |
|
||||
| BarrierGuard.cpp:29:16:29:21 | source | BarrierGuard.cpp:33:10:33:15 | source |
|
||||
| BarrierGuard.cpp:49:10:49:15 | call to source | BarrierGuard.cpp:53:13:53:13 | x |
|
||||
| BarrierGuard.cpp:49:10:49:15 | call to source | BarrierGuard.cpp:55:13:55:13 | x |
|
||||
| BarrierGuard.cpp:60:11:60:16 | call to source | BarrierGuard.cpp:64:14:64:14 | x |
|
||||
| BarrierGuard.cpp:60:11:60:16 | call to source | BarrierGuard.cpp:66:14:66:14 | x |
|
||||
| acrossLinkTargets.cpp:19:27:19:32 | call to source | acrossLinkTargets.cpp:12:8:12:8 | x |
|
||||
| clang.cpp:12:9:12:20 | sourceArray1 | clang.cpp:18:8:18:19 | sourceArray1 |
|
||||
| clang.cpp:12:9:12:20 | sourceArray1 | clang.cpp:23:17:23:29 | & ... indirection |
|
||||
| clang.cpp:29:27:29:32 | call to source | clang.cpp:30:27:30:28 | m1 |
|
||||
| clang.cpp:29:27:29:32 | call to source | clang.cpp:31:27:31:34 | call to getFirst |
|
||||
| clang.cpp:35:32:35:37 | call to source | clang.cpp:38:10:38:11 | m2 |
|
||||
| clang.cpp:40:42:40:47 | call to source | clang.cpp:42:18:42:19 | m2 |
|
||||
| clang.cpp:44:35:44:40 | call to source | clang.cpp:46:17:46:18 | m2 |
|
||||
| clang.cpp:50:7:50:16 | definition of stackArray | clang.cpp:52:8:52:17 | stackArray |
|
||||
| clang.cpp:50:25:50:30 | call to source | clang.cpp:53:17:53:26 | stackArray indirection |
|
||||
| clang.cpp:50:35:50:40 | call to source | clang.cpp:53:17:53:26 | stackArray indirection |
|
||||
| clang.cpp:51:19:51:24 | call to source | clang.cpp:53:17:53:26 | stackArray indirection |
|
||||
| dispatch.cpp:9:37:9:42 | call to source | dispatch.cpp:35:16:35:25 | call to notSource1 |
|
||||
| dispatch.cpp:9:37:9:42 | call to source | dispatch.cpp:43:15:43:24 | call to notSource1 |
|
||||
| dispatch.cpp:10:37:10:42 | call to source | dispatch.cpp:36:16:36:25 | call to notSource2 |
|
||||
| dispatch.cpp:10:37:10:42 | call to source | dispatch.cpp:44:15:44:24 | call to notSource2 |
|
||||
| dispatch.cpp:16:37:16:42 | call to source | dispatch.cpp:32:16:32:24 | call to isSource2 |
|
||||
| dispatch.cpp:16:37:16:42 | call to source | dispatch.cpp:40:15:40:23 | call to isSource2 |
|
||||
| dispatch.cpp:22:37:22:42 | call to source | dispatch.cpp:31:16:31:24 | call to isSource1 |
|
||||
| dispatch.cpp:22:37:22:42 | call to source | dispatch.cpp:39:15:39:23 | call to isSource1 |
|
||||
| dispatch.cpp:22:37:22:42 | call to source | dispatch.cpp:55:22:55:30 | call to isSource1 |
|
||||
| dispatch.cpp:22:37:22:42 | call to source | dispatch.cpp:58:28:58:36 | call to isSource1 |
|
||||
| dispatch.cpp:33:18:33:23 | call to source | dispatch.cpp:23:38:23:38 | x |
|
||||
| dispatch.cpp:37:19:37:24 | call to source | dispatch.cpp:11:38:11:38 | x |
|
||||
| dispatch.cpp:41:17:41:22 | call to source | dispatch.cpp:23:38:23:38 | x |
|
||||
| dispatch.cpp:45:18:45:23 | call to source | dispatch.cpp:11:38:11:38 | x |
|
||||
| dispatch.cpp:69:15:69:20 | call to source | dispatch.cpp:23:38:23:38 | x |
|
||||
| dispatch.cpp:73:14:73:19 | call to source | dispatch.cpp:23:38:23:38 | x |
|
||||
| dispatch.cpp:81:13:81:18 | call to source | dispatch.cpp:23:38:23:38 | x |
|
||||
| dispatch.cpp:107:17:107:22 | call to source | dispatch.cpp:96:8:96:8 | x |
|
||||
| dispatch.cpp:140:8:140:13 | call to source | dispatch.cpp:96:8:96:8 | x |
|
||||
| dispatch.cpp:144:8:144:13 | call to source | dispatch.cpp:96:8:96:8 | x |
|
||||
| flowOut.cpp:5:16:5:21 | call to source | flowOut.cpp:19:9:19:9 | x |
|
||||
| globals.cpp:5:17:5:22 | call to source | globals.cpp:6:10:6:14 | local |
|
||||
| globals.cpp:13:23:13:28 | call to source | globals.cpp:12:10:12:24 | flowTestGlobal1 |
|
||||
| globals.cpp:23:23:23:28 | call to source | globals.cpp:19:10:19:24 | flowTestGlobal2 |
|
||||
| lambdas.cpp:8:10:8:15 | call to source | lambdas.cpp:14:8:14:8 | t |
|
||||
| lambdas.cpp:8:10:8:15 | call to source | lambdas.cpp:18:8:18:8 | call to operator() |
|
||||
| lambdas.cpp:8:10:8:15 | call to source | lambdas.cpp:21:8:21:8 | t |
|
||||
| lambdas.cpp:8:10:8:15 | call to source | lambdas.cpp:29:8:29:8 | t |
|
||||
| lambdas.cpp:8:10:8:15 | call to source | lambdas.cpp:35:8:35:8 | a |
|
||||
| lambdas.cpp:8:10:8:15 | call to source | lambdas.cpp:41:8:41:8 | a |
|
||||
| lambdas.cpp:43:7:43:12 | call to source | lambdas.cpp:46:7:46:7 | w |
|
||||
| ref.cpp:29:11:29:16 | call to source | ref.cpp:62:10:62:11 | x3 |
|
||||
| ref.cpp:53:9:53:10 | definition of x1 | ref.cpp:56:10:56:11 | x1 |
|
||||
| ref.cpp:53:13:53:14 | definition of x2 | ref.cpp:59:10:59:11 | x2 |
|
||||
| ref.cpp:53:17:53:18 | definition of x3 | ref.cpp:62:10:62:11 | x3 |
|
||||
| ref.cpp:53:21:53:22 | definition of x4 | ref.cpp:65:10:65:11 | x4 |
|
||||
| ref.cpp:55:23:55:28 | call to source | ref.cpp:56:10:56:11 | x1 |
|
||||
| ref.cpp:94:15:94:20 | call to source | ref.cpp:129:13:129:15 | val |
|
||||
| ref.cpp:109:15:109:20 | call to source | ref.cpp:132:13:132:15 | val |
|
||||
| ref.cpp:122:23:122:28 | call to source | ref.cpp:123:13:123:15 | val |
|
||||
| ref.cpp:125:19:125:24 | call to source | ref.cpp:126:13:126:15 | val |
|
||||
| self-Iterator.cpp:19:23:19:30 | call to source | self-Iterator.cpp:20:10:20:10 | x |
|
||||
| test.cpp:6:12:6:17 | call to source | test.cpp:7:8:7:9 | t1 |
|
||||
| test.cpp:6:12:6:17 | call to source | test.cpp:9:8:9:9 | t1 |
|
||||
| test.cpp:6:12:6:17 | call to source | test.cpp:10:8:10:9 | t2 |
|
||||
| test.cpp:6:12:6:17 | call to source | test.cpp:15:8:15:9 | t2 |
|
||||
| test.cpp:6:12:6:17 | call to source | test.cpp:26:8:26:9 | t1 |
|
||||
| test.cpp:35:10:35:15 | call to source | test.cpp:30:8:30:8 | t |
|
||||
| test.cpp:36:13:36:18 | call to source | test.cpp:31:8:31:8 | c |
|
||||
| test.cpp:50:14:50:19 | call to source | test.cpp:58:10:58:10 | t |
|
||||
| test.cpp:66:30:66:36 | source1 | test.cpp:71:8:71:9 | x4 |
|
||||
| test.cpp:75:7:75:8 | definition of u1 | test.cpp:76:8:76:9 | u1 |
|
||||
| test.cpp:83:7:83:8 | definition of u2 | test.cpp:84:8:84:18 | ... ? ... : ... |
|
||||
| test.cpp:83:7:83:8 | definition of u2 | test.cpp:86:8:86:9 | i1 |
|
||||
| test.cpp:89:28:89:34 | source1 indirection | test.cpp:90:8:90:14 | source1 |
|
||||
| test.cpp:100:13:100:18 | call to source | test.cpp:103:10:103:12 | ref |
|
||||
| test.cpp:138:27:138:32 | call to source | test.cpp:140:8:140:8 | y |
|
||||
| test.cpp:151:33:151:38 | call to source | test.cpp:144:8:144:8 | s |
|
||||
| test.cpp:151:33:151:38 | call to source | test.cpp:152:8:152:8 | y |
|
||||
| test.cpp:164:34:164:39 | call to source | test.cpp:157:8:157:8 | x |
|
||||
| test.cpp:164:34:164:39 | call to source | test.cpp:165:8:165:8 | y |
|
||||
| test.cpp:171:11:171:16 | call to source | test.cpp:178:8:178:8 | y |
|
||||
| test.cpp:245:14:245:19 | call to source | test.cpp:260:12:260:12 | x |
|
||||
| test.cpp:265:22:265:27 | call to source | test.cpp:266:12:266:12 | x |
|
||||
| test.cpp:305:17:305:22 | call to source | test.cpp:289:14:289:14 | x |
|
||||
| test.cpp:314:4:314:9 | call to source | test.cpp:318:7:318:7 | x |
|
||||
| test.cpp:333:17:333:22 | call to source | test.cpp:337:10:337:18 | globalVar |
|
||||
| test.cpp:333:17:333:22 | call to source | test.cpp:339:10:339:18 | globalVar |
|
||||
| test.cpp:333:17:333:22 | call to source | test.cpp:343:10:343:18 | globalVar |
|
||||
| test.cpp:333:17:333:22 | call to source | test.cpp:349:10:349:18 | globalVar |
|
||||
| test.cpp:347:17:347:22 | call to source | test.cpp:337:10:337:18 | globalVar |
|
||||
| test.cpp:347:17:347:22 | call to source | test.cpp:339:10:339:18 | globalVar |
|
||||
| test.cpp:347:17:347:22 | call to source | test.cpp:343:10:343:18 | globalVar |
|
||||
| test.cpp:347:17:347:22 | call to source | test.cpp:349:10:349:18 | globalVar |
|
||||
| test.cpp:359:13:359:18 | call to source | test.cpp:365:10:365:14 | field |
|
||||
| test.cpp:373:13:373:18 | call to source | test.cpp:369:10:369:14 | field |
|
||||
| test.cpp:373:13:373:18 | call to source | test.cpp:375:10:375:14 | field |
|
||||
| test.cpp:382:48:382:54 | source1 | test.cpp:385:8:385:10 | tmp |
|
||||
| test.cpp:388:53:388:59 | source1 | test.cpp:392:8:392:10 | tmp |
|
||||
| test.cpp:388:53:388:59 | source1 | test.cpp:394:10:394:12 | tmp |
|
||||
| test.cpp:399:7:399:9 | definition of tmp | test.cpp:401:8:401:10 | tmp |
|
||||
| test.cpp:405:7:405:9 | definition of tmp | test.cpp:408:8:408:10 | tmp |
|
||||
| test.cpp:416:7:416:11 | definition of local | test.cpp:418:8:418:12 | local |
|
||||
| test.cpp:417:16:417:20 | intRefSource output argument | test.cpp:418:8:418:12 | local |
|
||||
| test.cpp:422:7:422:11 | definition of local | test.cpp:424:8:424:12 | local |
|
||||
| test.cpp:423:20:423:25 | intPointerSource output argument | test.cpp:424:8:424:12 | local |
|
||||
| test.cpp:433:7:433:11 | definition of local | test.cpp:435:8:435:12 | local |
|
||||
| test.cpp:434:20:434:24 | intPointerSource output argument | test.cpp:436:8:436:13 | * ... |
|
||||
| test.cpp:440:7:440:11 | definition of local | test.cpp:442:8:442:12 | local |
|
||||
| test.cpp:441:18:441:23 | intArraySource output argument | test.cpp:442:8:442:12 | local |
|
||||
| test.cpp:448:7:448:11 | definition of local | test.cpp:450:8:450:12 | local |
|
||||
| test.cpp:449:18:449:22 | intArraySource output argument | test.cpp:451:8:451:13 | * ... |
|
||||
| test.cpp:456:26:456:32 | source1 | test.cpp:457:9:457:22 | (statement expression) |
|
||||
| test.cpp:456:26:456:32 | source1 | test.cpp:468:8:468:12 | local |
|
||||
| test.cpp:472:8:472:13 | call to source | test.cpp:478:8:478:8 | x |
|
||||
| test.cpp:506:8:506:13 | call to source | test.cpp:513:8:513:8 | x |
|
||||
| test.cpp:519:19:519:24 | call to source | test.cpp:521:8:521:20 | access to array |
|
||||
| test.cpp:531:29:531:34 | call to source | test.cpp:532:8:532:9 | * ... |
|
||||
| test.cpp:547:9:547:9 | definition of x | test.cpp:536:10:536:11 | * ... |
|
||||
| test.cpp:551:9:551:9 | definition of y | test.cpp:541:10:541:10 | y |
|
||||
| test.cpp:562:17:562:31 | call to indirect_source indirection | test.cpp:566:10:566:19 | * ... |
|
||||
| test.cpp:562:17:562:31 | call to indirect_source indirection | test.cpp:568:10:568:19 | * ... |
|
||||
| test.cpp:562:17:562:31 | call to indirect_source indirection | test.cpp:572:10:572:19 | * ... |
|
||||
| test.cpp:562:17:562:31 | call to indirect_source indirection | test.cpp:578:10:578:19 | * ... |
|
||||
| test.cpp:576:17:576:31 | call to indirect_source indirection | test.cpp:566:10:566:19 | * ... |
|
||||
| test.cpp:576:17:576:31 | call to indirect_source indirection | test.cpp:568:10:568:19 | * ... |
|
||||
| test.cpp:576:17:576:31 | call to indirect_source indirection | test.cpp:572:10:572:19 | * ... |
|
||||
| test.cpp:576:17:576:31 | call to indirect_source indirection | test.cpp:578:10:578:19 | * ... |
|
||||
| test.cpp:594:12:594:26 | call to indirect_source indirection | test.cpp:597:8:597:13 | * ... |
|
||||
| test.cpp:601:20:601:20 | intPointerSource output argument | test.cpp:603:8:603:9 | * ... |
|
||||
| test.cpp:607:20:607:20 | intPointerSource output argument | test.cpp:609:8:609:9 | * ... |
|
||||
| test.cpp:614:20:614:20 | intPointerSource output argument | test.cpp:616:8:616:17 | * ... |
|
||||
| test.cpp:628:20:628:25 | intPointerSource output argument | test.cpp:629:17:629:22 | buffer indirection |
|
||||
| test.cpp:633:18:633:23 | call to source | test.cpp:634:8:634:8 | x |
|
||||
| test.cpp:646:7:646:12 | call to source | test.cpp:645:8:645:8 | x |
|
||||
| test.cpp:660:7:660:12 | call to source | test.cpp:658:8:658:8 | x |
|
||||
| test.cpp:664:18:664:23 | call to source | test.cpp:666:8:666:16 | * ... |
|
||||
| test.cpp:681:7:681:12 | call to source | test.cpp:679:8:679:16 | * ... |
|
||||
| test.cpp:733:7:733:7 | definition of x | test.cpp:735:8:735:8 | x |
|
||||
| test.cpp:751:27:751:32 | call to source | test.cpp:740:10:740:10 | x |
|
||||
| test.cpp:753:32:753:37 | call to source | test.cpp:740:10:740:10 | x |
|
||||
| test.cpp:755:32:755:37 | call to source | test.cpp:740:10:740:10 | x |
|
||||
| test.cpp:771:27:771:32 | call to source | test.cpp:760:10:760:10 | x |
|
||||
| test.cpp:773:32:773:37 | call to source | test.cpp:760:10:760:10 | x |
|
||||
| test.cpp:775:32:775:37 | call to source | test.cpp:760:10:760:10 | x |
|
||||
| test.cpp:788:31:788:36 | call to source | test.cpp:782:12:782:12 | x |
|
||||
| test.cpp:790:31:790:36 | call to source | test.cpp:782:12:782:12 | x |
|
||||
| test.cpp:797:22:797:28 | intPointerSource output argument | test.cpp:798:19:798:25 | content indirection |
|
||||
| test.cpp:808:25:808:39 | call to indirect_source indirection | test.cpp:813:19:813:35 | * ... indirection |
|
||||
| test.cpp:818:26:818:31 | call to source | test.cpp:823:10:823:27 | * ... |
|
||||
| test.cpp:832:21:832:26 | call to source | test.cpp:836:10:836:22 | global_direct |
|
||||
| test.cpp:842:11:842:16 | call to source | test.cpp:844:8:844:8 | y |
|
||||
| test.cpp:846:13:846:27 | call to indirect_source indirection | test.cpp:848:17:848:25 | rpx indirection |
|
||||
| test.cpp:853:55:853:62 | call to source | test.cpp:854:10:854:36 | * ... |
|
||||
| test.cpp:860:54:860:59 | call to source | test.cpp:861:10:861:37 | static_local_pointer_dynamic |
|
||||
| test.cpp:872:46:872:51 | call to source | test.cpp:875:10:875:31 | global_pointer_dynamic |
|
||||
| test.cpp:880:64:880:83 | indirect_source(1) indirection | test.cpp:883:10:883:45 | static_local_array_static_indirect_1 |
|
||||
| test.cpp:881:64:881:83 | indirect_source(2) indirection | test.cpp:886:19:886:54 | static_local_array_static_indirect_2 indirection |
|
||||
| test.cpp:890:54:890:61 | source | test.cpp:893:10:893:36 | static_local_pointer_static |
|
||||
| test.cpp:891:65:891:84 | indirect_source(1) indirection | test.cpp:895:19:895:56 | static_local_pointer_static_indirect_1 indirection |
|
||||
| test.cpp:901:56:901:75 | indirect_source(1) indirection | test.cpp:907:10:907:39 | global_array_static_indirect_1 |
|
||||
| test.cpp:902:56:902:75 | indirect_source(2) indirection | test.cpp:911:19:911:48 | global_array_static_indirect_2 indirection |
|
||||
| test.cpp:914:46:914:53 | source | test.cpp:919:10:919:30 | global_pointer_static |
|
||||
| test.cpp:915:57:915:76 | indirect_source(1) indirection | test.cpp:921:19:921:50 | global_pointer_static_indirect_1 indirection |
|
||||
| true_upon_entry.cpp:9:11:9:16 | call to source | true_upon_entry.cpp:13:8:13:8 | x |
|
||||
| true_upon_entry.cpp:17:11:17:16 | call to source | true_upon_entry.cpp:21:8:21:8 | x |
|
||||
| true_upon_entry.cpp:27:9:27:14 | call to source | true_upon_entry.cpp:29:8:29:8 | x |
|
||||
| true_upon_entry.cpp:33:11:33:16 | call to source | true_upon_entry.cpp:39:8:39:8 | x |
|
||||
| true_upon_entry.cpp:43:11:43:16 | call to source | true_upon_entry.cpp:49:8:49:8 | x |
|
||||
| true_upon_entry.cpp:54:11:54:16 | call to source | true_upon_entry.cpp:57:8:57:8 | x |
|
||||
| true_upon_entry.cpp:62:11:62:16 | call to source | true_upon_entry.cpp:66:8:66:8 | x |
|
||||
| true_upon_entry.cpp:70:11:70:16 | call to source | true_upon_entry.cpp:78:8:78:8 | x |
|
||||
| true_upon_entry.cpp:83:11:83:16 | call to source | true_upon_entry.cpp:86:8:86:8 | x |
|
||||
| true_upon_entry.cpp:98:11:98:16 | call to source | true_upon_entry.cpp:105:8:105:8 | x |
|
|
@ -0,0 +1,9 @@
|
|||
import TestBase
|
||||
|
||||
query predicate astFlow(AstTest::DataFlow::Node source, AstTest::DataFlow::Node sink) {
|
||||
AstTest::AstFlow::flow(source, sink)
|
||||
}
|
||||
|
||||
query predicate irFlow(IRTest::DataFlow::Node source, IRTest::DataFlow::Node sink) {
|
||||
IRTest::IRFlow::flow(source, sink)
|
||||
}
|
|
@ -1,5 +1,5 @@
|
|||
int source();
|
||||
void sink(int); void sink(const int *); void sink(int **); void indirect_sink(...);
|
||||
void sink(...); void indirect_sink(...);
|
||||
|
||||
void intraprocedural_with_local_flow() {
|
||||
int t2;
|
||||
|
@ -836,4 +836,90 @@ namespace MoreGlobalTests {
|
|||
sink(global_direct); // $ ir MISSING: ast
|
||||
indirect_sink(global_direct); // clean
|
||||
}
|
||||
}
|
||||
|
||||
void test_references() {
|
||||
int x = source();
|
||||
int &y = x;
|
||||
sink(y); // $ ast,ir
|
||||
|
||||
int* px = indirect_source();
|
||||
int*& rpx = px;
|
||||
indirect_sink((int*)rpx); // $ ast,ir
|
||||
}
|
||||
|
||||
namespace GlobalArrays {
|
||||
void test1() {
|
||||
static const int static_local_array_dynamic[] = { ::source() };
|
||||
sink(*static_local_array_dynamic); // $ ir MISSING: ast
|
||||
}
|
||||
|
||||
const int* source(bool);
|
||||
|
||||
void test2() {
|
||||
static const int* static_local_pointer_dynamic = source(true);
|
||||
sink(static_local_pointer_dynamic); // $ ast,ir
|
||||
}
|
||||
|
||||
static const int global_array_dynamic[] = { ::source() };
|
||||
|
||||
void test3() {
|
||||
sink(*global_array_dynamic); // $ MISSING: ir,ast // Missing in IR because no 'IRFunction' for global_array is generated because the type of global_array_dynamic is "deeply const".
|
||||
}
|
||||
|
||||
const int* source(bool);
|
||||
|
||||
static const int* global_pointer_dynamic = source(true);
|
||||
|
||||
void test4() {
|
||||
sink(global_pointer_dynamic); // $ ir MISSING: ast
|
||||
}
|
||||
|
||||
void test5() {
|
||||
static const char static_local_array_static[] = "source";
|
||||
static const char static_local_array_static_indirect_1[] = "indirect_source(1)";
|
||||
static const char static_local_array_static_indirect_2[] = "indirect_source(2)";
|
||||
sink(static_local_array_static); // clean
|
||||
sink(static_local_array_static_indirect_1); // $ ir MISSING: ast
|
||||
indirect_sink(static_local_array_static_indirect_1); // clean
|
||||
sink(static_local_array_static_indirect_2); // clean
|
||||
indirect_sink(static_local_array_static_indirect_2); // $ ir MISSING: ast
|
||||
}
|
||||
|
||||
void test6() {
|
||||
static const char* static_local_pointer_static = "source";
|
||||
static const char* static_local_pointer_static_indirect_1 = "indirect_source(1)";
|
||||
static const char* static_local_pointer_static_indirect_2 = "indirect_source(2)";
|
||||
sink(static_local_pointer_static); // $ ir MISSING: ast
|
||||
sink(static_local_pointer_static_indirect_1); // clean
|
||||
indirect_sink(static_local_pointer_static_indirect_1); // $ ir MISSING: ast
|
||||
sink(static_local_pointer_static_indirect_2); // clean: static_local_pointer_static_indirect_2 does not have 2 indirections
|
||||
indirect_sink(static_local_pointer_static_indirect_2); // clean: static_local_pointer_static_indirect_2 does not have 2 indirections
|
||||
}
|
||||
|
||||
static const char global_array_static[] = "source";
|
||||
static const char global_array_static_indirect_1[] = "indirect_source(1)";
|
||||
static const char global_array_static_indirect_2[] = "indirect_source(2)";
|
||||
|
||||
void test7() {
|
||||
sink(global_array_static); // clean
|
||||
sink(*global_array_static); // clean
|
||||
sink(global_array_static_indirect_1); // $ ir MISSING: ast
|
||||
sink(*global_array_static_indirect_1); // clean
|
||||
indirect_sink(global_array_static); // clean
|
||||
indirect_sink(global_array_static_indirect_1); // clean
|
||||
indirect_sink(global_array_static_indirect_2); // $ ir MISSING: ast
|
||||
}
|
||||
|
||||
static const char* global_pointer_static = "source";
|
||||
static const char* global_pointer_static_indirect_1 = "indirect_source(1)";
|
||||
static const char* global_pointer_static_indirect_2 = "indirect_source(2)";
|
||||
|
||||
void test8() {
|
||||
sink(global_pointer_static); // $ ir MISSING: ast
|
||||
sink(global_pointer_static_indirect_1); // clean
|
||||
indirect_sink(global_pointer_static_indirect_1); // $ ir MISSING: ast
|
||||
sink(global_pointer_static_indirect_2); // clean: global_pointer_static_indirect_2 does not have 2 indirections
|
||||
indirect_sink(global_pointer_static_indirect_2); // clean: global_pointer_static_indirect_2 does not have 2 indirections
|
||||
}
|
||||
}
|
|
@ -1,9 +1,2 @@
|
|||
WARNING: Module DataFlow has been deprecated and may be removed in future (test.ql:19,45-53)
|
||||
WARNING: Module DataFlow has been deprecated and may be removed in future (test.ql:20,24-32)
|
||||
WARNING: Module DataFlow has been deprecated and may be removed in future (test.ql:27,15-23)
|
||||
WARNING: Module DataFlow has been deprecated and may be removed in future (test.ql:33,22-30)
|
||||
WARNING: Module DataFlow has been deprecated and may be removed in future (test.ql:40,25-33)
|
||||
WARNING: Module DataFlow has been deprecated and may be removed in future (test.ql:42,17-25)
|
||||
WARNING: Module DataFlow has been deprecated and may be removed in future (test.ql:46,20-28)
|
||||
testFailures
|
||||
failures
|
||||
|
|
|
@ -1,107 +1,3 @@
|
|||
import TestBase
|
||||
import TestUtilities.dataflow.FlowTestCommon
|
||||
|
||||
module AstTest {
|
||||
private import semmle.code.cpp.dataflow.DataFlow
|
||||
private import semmle.code.cpp.controlflow.Guards
|
||||
|
||||
/**
|
||||
* A `BarrierGuard` that stops flow to all occurrences of `x` within statement
|
||||
* S in `if (guarded(x)) S`.
|
||||
*/
|
||||
// This is tested in `BarrierGuard.cpp`.
|
||||
predicate testBarrierGuard(GuardCondition g, Expr checked, boolean isTrue) {
|
||||
g.(FunctionCall).getTarget().getName() = "guarded" and
|
||||
checked = g.(FunctionCall).getArgument(0) and
|
||||
isTrue = true
|
||||
}
|
||||
|
||||
/** Common data flow configuration to be used by tests. */
|
||||
module AstTestAllocationConfig implements DataFlow::ConfigSig {
|
||||
predicate isSource(DataFlow::Node source) {
|
||||
source.asExpr().(FunctionCall).getTarget().getName() = "source"
|
||||
or
|
||||
source.asParameter().getName().matches("source%")
|
||||
or
|
||||
source.asExpr().(FunctionCall).getTarget().getName() = "indirect_source"
|
||||
or
|
||||
source.(DataFlow::DefinitionByReferenceNode).getParameter().getName().matches("ref_source%")
|
||||
or
|
||||
// Track uninitialized variables
|
||||
exists(source.asUninitialized())
|
||||
}
|
||||
|
||||
predicate isSink(DataFlow::Node sink) {
|
||||
exists(FunctionCall call |
|
||||
call.getTarget().getName() = ["sink", "indirect_sink"] and
|
||||
sink.asExpr() = call.getAnArgument()
|
||||
)
|
||||
}
|
||||
|
||||
predicate isBarrier(DataFlow::Node barrier) {
|
||||
barrier.asExpr().(VariableAccess).getTarget().hasName("barrier") or
|
||||
barrier = DataFlow::BarrierGuard<testBarrierGuard/3>::getABarrierNode()
|
||||
}
|
||||
}
|
||||
|
||||
module AstFlow = DataFlow::Global<AstTestAllocationConfig>;
|
||||
}
|
||||
|
||||
module IRTest {
|
||||
private import cpp
|
||||
private import semmle.code.cpp.ir.dataflow.DataFlow
|
||||
private import semmle.code.cpp.ir.IR
|
||||
private import semmle.code.cpp.controlflow.IRGuards
|
||||
|
||||
/**
|
||||
* A `BarrierGuard` that stops flow to all occurrences of `x` within statement
|
||||
* S in `if (guarded(x)) S`.
|
||||
*/
|
||||
// This is tested in `BarrierGuard.cpp`.
|
||||
predicate testBarrierGuard(IRGuardCondition g, Expr checked, boolean isTrue) {
|
||||
exists(Call call |
|
||||
call = g.getUnconvertedResultExpression() and
|
||||
call.getTarget().hasName("guarded") and
|
||||
checked = call.getArgument(0) and
|
||||
isTrue = true
|
||||
)
|
||||
}
|
||||
|
||||
/** Common data flow configuration to be used by tests. */
|
||||
module IRTestAllocationConfig implements DataFlow::ConfigSig {
|
||||
predicate isSource(DataFlow::Node source) {
|
||||
source.asExpr().(FunctionCall).getTarget().getName() = "source"
|
||||
or
|
||||
source.asIndirectExpr(1).(FunctionCall).getTarget().getName() = "indirect_source"
|
||||
or
|
||||
source.asParameter().getName().matches("source%")
|
||||
or
|
||||
source.(DataFlow::DefinitionByReferenceNode).getParameter().getName().matches("ref_source%")
|
||||
or
|
||||
exists(source.asUninitialized())
|
||||
}
|
||||
|
||||
predicate isSink(DataFlow::Node sink) {
|
||||
exists(FunctionCall call, Expr e | e = call.getAnArgument() |
|
||||
call.getTarget().getName() = "sink" and
|
||||
sink.asExpr() = e
|
||||
or
|
||||
call.getTarget().getName() = "indirect_sink" and
|
||||
sink.asIndirectExpr() = e
|
||||
)
|
||||
}
|
||||
|
||||
predicate isBarrier(DataFlow::Node barrier) {
|
||||
exists(Expr barrierExpr | barrierExpr in [barrier.asExpr(), barrier.asIndirectExpr()] |
|
||||
barrierExpr.(VariableAccess).getTarget().hasName("barrier")
|
||||
)
|
||||
or
|
||||
barrier = DataFlow::BarrierGuard<testBarrierGuard/3>::getABarrierNode()
|
||||
or
|
||||
barrier = DataFlow::BarrierGuard<testBarrierGuard/3>::getAnIndirectBarrierNode()
|
||||
}
|
||||
}
|
||||
|
||||
module IRFlow = DataFlow::Global<IRTestAllocationConfig>;
|
||||
}
|
||||
|
||||
import MakeTest<MergeTests<AstFlowTest<AstTest::AstFlow>, IRFlowTest<IRTest::IRFlow>>>
|
||||
|
|
|
@ -43,6 +43,11 @@ edges
|
|||
| test.cpp:189:16:189:16 | p | test.cpp:189:16:189:16 | (reference to) |
|
||||
| test.cpp:190:10:190:13 | (reference dereference) | test.cpp:190:10:190:13 | (reference to) |
|
||||
| test.cpp:190:10:190:13 | pRef | test.cpp:190:10:190:13 | (reference dereference) |
|
||||
| test.cpp:237:12:237:17 | call to alloca | test.cpp:237:12:237:17 | call to alloca |
|
||||
| test.cpp:237:12:237:17 | call to alloca | test.cpp:238:9:238:9 | p |
|
||||
| test.cpp:249:13:249:20 | call to strndupa | test.cpp:249:13:249:20 | call to strndupa |
|
||||
| test.cpp:249:13:249:20 | call to strndupa | test.cpp:250:9:250:10 | s2 |
|
||||
| test.cpp:250:9:250:10 | s2 | test.cpp:250:9:250:10 | (void *)... |
|
||||
nodes
|
||||
| test.cpp:17:9:17:11 | & ... | semmle.label | & ... |
|
||||
| test.cpp:17:10:17:11 | mc | semmle.label | mc |
|
||||
|
@ -101,6 +106,14 @@ nodes
|
|||
| test.cpp:190:10:190:13 | (reference dereference) | semmle.label | (reference dereference) |
|
||||
| test.cpp:190:10:190:13 | (reference to) | semmle.label | (reference to) |
|
||||
| test.cpp:190:10:190:13 | pRef | semmle.label | pRef |
|
||||
| test.cpp:237:12:237:17 | call to alloca | semmle.label | call to alloca |
|
||||
| test.cpp:237:12:237:17 | call to alloca | semmle.label | call to alloca |
|
||||
| test.cpp:238:9:238:9 | p | semmle.label | p |
|
||||
| test.cpp:245:9:245:15 | call to strdupa | semmle.label | call to strdupa |
|
||||
| test.cpp:249:13:249:20 | call to strndupa | semmle.label | call to strndupa |
|
||||
| test.cpp:249:13:249:20 | call to strndupa | semmle.label | call to strndupa |
|
||||
| test.cpp:250:9:250:10 | (void *)... | semmle.label | (void *)... |
|
||||
| test.cpp:250:9:250:10 | s2 | semmle.label | s2 |
|
||||
#select
|
||||
| test.cpp:17:9:17:11 | CopyValue: & ... | test.cpp:17:10:17:11 | mc | test.cpp:17:9:17:11 | & ... | May return stack-allocated memory from $@. | test.cpp:17:10:17:11 | mc | mc |
|
||||
| test.cpp:25:9:25:11 | Load: ptr | test.cpp:23:18:23:19 | mc | test.cpp:25:9:25:11 | ptr | May return stack-allocated memory from $@. | test.cpp:23:18:23:19 | mc | mc |
|
||||
|
@ -115,3 +128,6 @@ nodes
|
|||
| test.cpp:177:10:177:23 | Convert: (void *)... | test.cpp:176:25:176:34 | localArray | test.cpp:177:10:177:23 | (void *)... | May return stack-allocated memory from $@. | test.cpp:176:25:176:34 | localArray | localArray |
|
||||
| test.cpp:183:10:183:19 | CopyValue: (reference to) | test.cpp:182:21:182:27 | myLocal | test.cpp:183:10:183:19 | (reference to) | May return stack-allocated memory from $@. | test.cpp:182:21:182:27 | myLocal | myLocal |
|
||||
| test.cpp:190:10:190:13 | CopyValue: (reference to) | test.cpp:189:16:189:16 | p | test.cpp:190:10:190:13 | (reference to) | May return stack-allocated memory from $@. | test.cpp:189:16:189:16 | p | p |
|
||||
| test.cpp:238:9:238:9 | Load: p | test.cpp:237:12:237:17 | call to alloca | test.cpp:238:9:238:9 | p | May return stack-allocated memory from $@. | test.cpp:237:12:237:17 | call to alloca | call to alloca |
|
||||
| test.cpp:245:9:245:15 | Call: call to strdupa | test.cpp:245:9:245:15 | call to strdupa | test.cpp:245:9:245:15 | call to strdupa | May return stack-allocated memory from $@. | test.cpp:245:9:245:15 | call to strdupa | call to strdupa |
|
||||
| test.cpp:250:9:250:10 | Convert: (void *)... | test.cpp:249:13:249:20 | call to strndupa | test.cpp:250:9:250:10 | (void *)... | May return stack-allocated memory from $@. | test.cpp:249:13:249:20 | call to strndupa | call to strndupa |
|
||||
|
|
|
@ -229,4 +229,23 @@ int* id(int* px) {
|
|||
void f() {
|
||||
int x;
|
||||
int* px = id(&x); // GOOD
|
||||
}
|
||||
|
||||
void *alloca(size_t);
|
||||
|
||||
void* test_alloca() {
|
||||
void* p = alloca(10);
|
||||
return p; // BAD
|
||||
}
|
||||
|
||||
char *strdupa(const char *);
|
||||
char *strndupa(const char *, size_t);
|
||||
|
||||
char* test_strdupa(const char* s) {
|
||||
return strdupa(s); // BAD
|
||||
}
|
||||
|
||||
void* test_strndupa(const char* s, size_t size) {
|
||||
char* s2 = strndupa(s, size);
|
||||
return s2; // BAD
|
||||
}
|
|
@ -1,23 +1,12 @@
|
|||
edges
|
||||
| test.cpp:37:73:37:76 | data | test.cpp:43:32:43:35 | data |
|
||||
| test.cpp:37:73:37:76 | data | test.cpp:43:32:43:35 | data |
|
||||
| test.cpp:37:73:37:76 | data indirection | test.cpp:43:32:43:35 | data |
|
||||
| test.cpp:37:73:37:76 | data indirection | test.cpp:43:32:43:35 | data |
|
||||
| test.cpp:64:30:64:35 | call to getenv | test.cpp:73:24:73:27 | data |
|
||||
| test.cpp:64:30:64:35 | call to getenv | test.cpp:73:24:73:27 | data |
|
||||
| test.cpp:64:30:64:35 | call to getenv | test.cpp:73:24:73:27 | data indirection |
|
||||
| test.cpp:64:30:64:35 | call to getenv | test.cpp:73:24:73:27 | data indirection |
|
||||
| test.cpp:73:24:73:27 | data | test.cpp:37:73:37:76 | data |
|
||||
| test.cpp:37:73:37:76 | data indirection | test.cpp:43:32:43:35 | data indirection |
|
||||
| test.cpp:64:30:64:35 | call to getenv indirection | test.cpp:73:24:73:27 | data indirection |
|
||||
| test.cpp:73:24:73:27 | data indirection | test.cpp:37:73:37:76 | data indirection |
|
||||
subpaths
|
||||
nodes
|
||||
| test.cpp:37:73:37:76 | data | semmle.label | data |
|
||||
| test.cpp:37:73:37:76 | data indirection | semmle.label | data indirection |
|
||||
| test.cpp:43:32:43:35 | data | semmle.label | data |
|
||||
| test.cpp:43:32:43:35 | data | semmle.label | data |
|
||||
| test.cpp:64:30:64:35 | call to getenv | semmle.label | call to getenv |
|
||||
| test.cpp:64:30:64:35 | call to getenv | semmle.label | call to getenv |
|
||||
| test.cpp:73:24:73:27 | data | semmle.label | data |
|
||||
| test.cpp:43:32:43:35 | data indirection | semmle.label | data indirection |
|
||||
| test.cpp:64:30:64:35 | call to getenv indirection | semmle.label | call to getenv indirection |
|
||||
| test.cpp:73:24:73:27 | data indirection | semmle.label | data indirection |
|
||||
subpaths
|
||||
#select
|
||||
| test.cpp:43:32:43:35 | data | test.cpp:64:30:64:35 | call to getenv | test.cpp:43:32:43:35 | data | The value of this argument may come from $@ and is being passed to LoadLibraryA. | test.cpp:64:30:64:35 | call to getenv | call to getenv |
|
||||
| test.cpp:43:32:43:35 | data indirection | test.cpp:64:30:64:35 | call to getenv indirection | test.cpp:43:32:43:35 | data indirection | The value of this argument may come from $@ and is being passed to LoadLibraryA. | test.cpp:64:30:64:35 | call to getenv indirection | an environment variable |
|
||||
|
|
|
@ -1,112 +1,45 @@
|
|||
edges
|
||||
| test.cpp:24:30:24:36 | command | test.cpp:26:10:26:16 | command |
|
||||
| test.cpp:24:30:24:36 | command | test.cpp:26:10:26:16 | command |
|
||||
| test.cpp:29:30:29:36 | command | test.cpp:31:10:31:16 | command |
|
||||
| test.cpp:29:30:29:36 | command | test.cpp:31:10:31:16 | command |
|
||||
| test.cpp:42:18:42:23 | call to getenv | test.cpp:24:30:24:36 | command |
|
||||
| test.cpp:42:18:42:34 | call to getenv | test.cpp:24:30:24:36 | command |
|
||||
| test.cpp:43:18:43:23 | call to getenv | test.cpp:29:30:29:36 | command |
|
||||
| test.cpp:43:18:43:34 | call to getenv | test.cpp:29:30:29:36 | command |
|
||||
| test.cpp:56:12:56:17 | buffer | test.cpp:62:10:62:15 | buffer |
|
||||
| test.cpp:56:12:56:17 | buffer | test.cpp:62:10:62:15 | buffer |
|
||||
| test.cpp:56:12:56:17 | buffer | test.cpp:62:10:62:15 | buffer |
|
||||
| test.cpp:56:12:56:17 | buffer | test.cpp:62:10:62:15 | buffer |
|
||||
| test.cpp:56:12:56:17 | buffer | test.cpp:63:10:63:13 | data |
|
||||
| test.cpp:56:12:56:17 | buffer | test.cpp:63:10:63:13 | data |
|
||||
| test.cpp:56:12:56:17 | buffer | test.cpp:63:10:63:13 | data |
|
||||
| test.cpp:56:12:56:17 | buffer | test.cpp:63:10:63:13 | data |
|
||||
| test.cpp:56:12:56:17 | buffer | test.cpp:64:10:64:16 | dataref |
|
||||
| test.cpp:56:12:56:17 | buffer | test.cpp:64:10:64:16 | dataref |
|
||||
| test.cpp:56:12:56:17 | buffer | test.cpp:64:10:64:16 | dataref |
|
||||
| test.cpp:56:12:56:17 | buffer | test.cpp:64:10:64:16 | dataref |
|
||||
| test.cpp:56:12:56:17 | buffer | test.cpp:64:10:64:16 | dataref |
|
||||
| test.cpp:56:12:56:17 | buffer | test.cpp:64:10:64:16 | dataref |
|
||||
| test.cpp:56:12:56:17 | buffer | test.cpp:65:10:65:14 | data2 |
|
||||
| test.cpp:56:12:56:17 | buffer | test.cpp:65:10:65:14 | data2 |
|
||||
| test.cpp:56:12:56:17 | buffer | test.cpp:65:10:65:14 | data2 |
|
||||
| test.cpp:56:12:56:17 | buffer | test.cpp:65:10:65:14 | data2 |
|
||||
| test.cpp:56:12:56:17 | fgets output argument | test.cpp:62:10:62:15 | buffer |
|
||||
| test.cpp:56:12:56:17 | fgets output argument | test.cpp:62:10:62:15 | buffer |
|
||||
| test.cpp:56:12:56:17 | fgets output argument | test.cpp:63:10:63:13 | data |
|
||||
| test.cpp:56:12:56:17 | fgets output argument | test.cpp:63:10:63:13 | data |
|
||||
| test.cpp:56:12:56:17 | fgets output argument | test.cpp:64:10:64:16 | dataref |
|
||||
| test.cpp:56:12:56:17 | fgets output argument | test.cpp:64:10:64:16 | dataref |
|
||||
| test.cpp:56:12:56:17 | fgets output argument | test.cpp:64:10:64:16 | dataref |
|
||||
| test.cpp:56:12:56:17 | fgets output argument | test.cpp:65:10:65:14 | data2 |
|
||||
| test.cpp:56:12:56:17 | fgets output argument | test.cpp:65:10:65:14 | data2 |
|
||||
| test.cpp:76:12:76:17 | buffer | test.cpp:78:10:78:15 | buffer |
|
||||
| test.cpp:76:12:76:17 | buffer | test.cpp:78:10:78:15 | buffer |
|
||||
| test.cpp:76:12:76:17 | buffer | test.cpp:78:10:78:15 | buffer |
|
||||
| test.cpp:76:12:76:17 | buffer | test.cpp:78:10:78:15 | buffer |
|
||||
| test.cpp:76:12:76:17 | fgets output argument | test.cpp:78:10:78:15 | buffer |
|
||||
| test.cpp:76:12:76:17 | fgets output argument | test.cpp:78:10:78:15 | buffer |
|
||||
| test.cpp:98:17:98:22 | buffer | test.cpp:99:15:99:20 | buffer |
|
||||
| test.cpp:98:17:98:22 | buffer | test.cpp:99:15:99:20 | buffer |
|
||||
| test.cpp:98:17:98:22 | buffer | test.cpp:99:15:99:20 | buffer |
|
||||
| test.cpp:98:17:98:22 | buffer | test.cpp:99:15:99:20 | buffer |
|
||||
| test.cpp:98:17:98:22 | recv output argument | test.cpp:99:15:99:20 | buffer |
|
||||
| test.cpp:98:17:98:22 | recv output argument | test.cpp:99:15:99:20 | buffer |
|
||||
| test.cpp:106:17:106:22 | buffer | test.cpp:107:15:107:20 | buffer |
|
||||
| test.cpp:106:17:106:22 | buffer | test.cpp:107:15:107:20 | buffer |
|
||||
| test.cpp:106:17:106:22 | buffer | test.cpp:107:15:107:20 | buffer |
|
||||
| test.cpp:106:17:106:22 | buffer | test.cpp:107:15:107:20 | buffer |
|
||||
| test.cpp:106:17:106:22 | recv output argument | test.cpp:107:15:107:20 | buffer |
|
||||
| test.cpp:106:17:106:22 | recv output argument | test.cpp:107:15:107:20 | buffer |
|
||||
| test.cpp:113:8:113:12 | call to fgets | test.cpp:114:9:114:11 | ptr |
|
||||
| test.cpp:113:8:113:12 | call to fgets | test.cpp:114:9:114:11 | ptr |
|
||||
| test.cpp:113:8:113:12 | call to fgets | test.cpp:114:9:114:11 | ptr |
|
||||
| test.cpp:113:8:113:12 | call to fgets | test.cpp:114:9:114:11 | ptr |
|
||||
subpaths
|
||||
| test.cpp:24:30:24:36 | command indirection | test.cpp:26:10:26:16 | command indirection |
|
||||
| test.cpp:29:30:29:36 | command indirection | test.cpp:31:10:31:16 | command indirection |
|
||||
| test.cpp:42:18:42:34 | call to getenv indirection | test.cpp:24:30:24:36 | command indirection |
|
||||
| test.cpp:43:18:43:34 | call to getenv indirection | test.cpp:29:30:29:36 | command indirection |
|
||||
| test.cpp:56:12:56:17 | fgets output argument | test.cpp:62:10:62:15 | buffer indirection |
|
||||
| test.cpp:56:12:56:17 | fgets output argument | test.cpp:63:10:63:13 | data indirection |
|
||||
| test.cpp:56:12:56:17 | fgets output argument | test.cpp:64:10:64:16 | dataref indirection |
|
||||
| test.cpp:56:12:56:17 | fgets output argument | test.cpp:65:10:65:14 | data2 indirection |
|
||||
| test.cpp:76:12:76:17 | fgets output argument | test.cpp:78:10:78:15 | buffer indirection |
|
||||
| test.cpp:98:17:98:22 | recv output argument | test.cpp:99:15:99:20 | buffer indirection |
|
||||
| test.cpp:106:17:106:22 | recv output argument | test.cpp:107:15:107:20 | buffer indirection |
|
||||
| test.cpp:113:8:113:12 | call to fgets indirection | test.cpp:114:9:114:11 | ptr indirection |
|
||||
nodes
|
||||
| test.cpp:24:30:24:36 | command | semmle.label | command |
|
||||
| test.cpp:26:10:26:16 | command | semmle.label | command |
|
||||
| test.cpp:26:10:26:16 | command | semmle.label | command |
|
||||
| test.cpp:29:30:29:36 | command | semmle.label | command |
|
||||
| test.cpp:31:10:31:16 | command | semmle.label | command |
|
||||
| test.cpp:31:10:31:16 | command | semmle.label | command |
|
||||
| test.cpp:42:18:42:23 | call to getenv | semmle.label | call to getenv |
|
||||
| test.cpp:42:18:42:34 | call to getenv | semmle.label | call to getenv |
|
||||
| test.cpp:43:18:43:23 | call to getenv | semmle.label | call to getenv |
|
||||
| test.cpp:43:18:43:34 | call to getenv | semmle.label | call to getenv |
|
||||
| test.cpp:56:12:56:17 | buffer | semmle.label | buffer |
|
||||
| test.cpp:56:12:56:17 | buffer | semmle.label | buffer |
|
||||
| test.cpp:24:30:24:36 | command indirection | semmle.label | command indirection |
|
||||
| test.cpp:26:10:26:16 | command indirection | semmle.label | command indirection |
|
||||
| test.cpp:29:30:29:36 | command indirection | semmle.label | command indirection |
|
||||
| test.cpp:31:10:31:16 | command indirection | semmle.label | command indirection |
|
||||
| test.cpp:42:18:42:34 | call to getenv indirection | semmle.label | call to getenv indirection |
|
||||
| test.cpp:43:18:43:34 | call to getenv indirection | semmle.label | call to getenv indirection |
|
||||
| test.cpp:56:12:56:17 | fgets output argument | semmle.label | fgets output argument |
|
||||
| test.cpp:62:10:62:15 | buffer | semmle.label | buffer |
|
||||
| test.cpp:62:10:62:15 | buffer | semmle.label | buffer |
|
||||
| test.cpp:63:10:63:13 | data | semmle.label | data |
|
||||
| test.cpp:63:10:63:13 | data | semmle.label | data |
|
||||
| test.cpp:64:10:64:16 | dataref | semmle.label | dataref |
|
||||
| test.cpp:64:10:64:16 | dataref | semmle.label | dataref |
|
||||
| test.cpp:64:10:64:16 | dataref | semmle.label | dataref |
|
||||
| test.cpp:65:10:65:14 | data2 | semmle.label | data2 |
|
||||
| test.cpp:65:10:65:14 | data2 | semmle.label | data2 |
|
||||
| test.cpp:76:12:76:17 | buffer | semmle.label | buffer |
|
||||
| test.cpp:76:12:76:17 | buffer | semmle.label | buffer |
|
||||
| test.cpp:62:10:62:15 | buffer indirection | semmle.label | buffer indirection |
|
||||
| test.cpp:63:10:63:13 | data indirection | semmle.label | data indirection |
|
||||
| test.cpp:64:10:64:16 | dataref indirection | semmle.label | dataref indirection |
|
||||
| test.cpp:65:10:65:14 | data2 indirection | semmle.label | data2 indirection |
|
||||
| test.cpp:76:12:76:17 | fgets output argument | semmle.label | fgets output argument |
|
||||
| test.cpp:78:10:78:15 | buffer | semmle.label | buffer |
|
||||
| test.cpp:78:10:78:15 | buffer | semmle.label | buffer |
|
||||
| test.cpp:98:17:98:22 | buffer | semmle.label | buffer |
|
||||
| test.cpp:98:17:98:22 | buffer | semmle.label | buffer |
|
||||
| test.cpp:78:10:78:15 | buffer indirection | semmle.label | buffer indirection |
|
||||
| test.cpp:98:17:98:22 | recv output argument | semmle.label | recv output argument |
|
||||
| test.cpp:99:15:99:20 | buffer | semmle.label | buffer |
|
||||
| test.cpp:99:15:99:20 | buffer | semmle.label | buffer |
|
||||
| test.cpp:106:17:106:22 | buffer | semmle.label | buffer |
|
||||
| test.cpp:106:17:106:22 | buffer | semmle.label | buffer |
|
||||
| test.cpp:99:15:99:20 | buffer indirection | semmle.label | buffer indirection |
|
||||
| test.cpp:106:17:106:22 | recv output argument | semmle.label | recv output argument |
|
||||
| test.cpp:107:15:107:20 | buffer | semmle.label | buffer |
|
||||
| test.cpp:107:15:107:20 | buffer | semmle.label | buffer |
|
||||
| test.cpp:113:8:113:12 | call to fgets | semmle.label | call to fgets |
|
||||
| test.cpp:113:8:113:12 | call to fgets | semmle.label | call to fgets |
|
||||
| test.cpp:114:9:114:11 | ptr | semmle.label | ptr |
|
||||
| test.cpp:114:9:114:11 | ptr | semmle.label | ptr |
|
||||
| test.cpp:107:15:107:20 | buffer indirection | semmle.label | buffer indirection |
|
||||
| test.cpp:113:8:113:12 | call to fgets indirection | semmle.label | call to fgets indirection |
|
||||
| test.cpp:114:9:114:11 | ptr indirection | semmle.label | ptr indirection |
|
||||
subpaths
|
||||
#select
|
||||
| test.cpp:26:10:26:16 | command | test.cpp:42:18:42:23 | call to getenv | test.cpp:26:10:26:16 | command | The value of this argument may come from $@ and is being passed to system. | test.cpp:42:18:42:23 | call to getenv | call to getenv |
|
||||
| test.cpp:31:10:31:16 | command | test.cpp:43:18:43:23 | call to getenv | test.cpp:31:10:31:16 | command | The value of this argument may come from $@ and is being passed to system. | test.cpp:43:18:43:23 | call to getenv | call to getenv |
|
||||
| test.cpp:62:10:62:15 | buffer | test.cpp:56:12:56:17 | buffer | test.cpp:62:10:62:15 | buffer | The value of this argument may come from $@ and is being passed to system. | test.cpp:56:12:56:17 | buffer | buffer |
|
||||
| test.cpp:63:10:63:13 | data | test.cpp:56:12:56:17 | buffer | test.cpp:63:10:63:13 | data | The value of this argument may come from $@ and is being passed to system. | test.cpp:56:12:56:17 | buffer | buffer |
|
||||
| test.cpp:64:10:64:16 | dataref | test.cpp:56:12:56:17 | buffer | test.cpp:64:10:64:16 | dataref | The value of this argument may come from $@ and is being passed to system. | test.cpp:56:12:56:17 | buffer | buffer |
|
||||
| test.cpp:65:10:65:14 | data2 | test.cpp:56:12:56:17 | buffer | test.cpp:65:10:65:14 | data2 | The value of this argument may come from $@ and is being passed to system. | test.cpp:56:12:56:17 | buffer | buffer |
|
||||
| test.cpp:78:10:78:15 | buffer | test.cpp:76:12:76:17 | buffer | test.cpp:78:10:78:15 | buffer | The value of this argument may come from $@ and is being passed to system. | test.cpp:76:12:76:17 | buffer | buffer |
|
||||
| test.cpp:99:15:99:20 | buffer | test.cpp:98:17:98:22 | buffer | test.cpp:99:15:99:20 | buffer | The value of this argument may come from $@ and is being passed to LoadLibrary. | test.cpp:98:17:98:22 | buffer | buffer |
|
||||
| test.cpp:107:15:107:20 | buffer | test.cpp:106:17:106:22 | buffer | test.cpp:107:15:107:20 | buffer | The value of this argument may come from $@ and is being passed to LoadLibrary. | test.cpp:106:17:106:22 | buffer | buffer |
|
||||
| test.cpp:114:9:114:11 | ptr | test.cpp:113:8:113:12 | call to fgets | test.cpp:114:9:114:11 | ptr | The value of this argument may come from $@ and is being passed to system. | test.cpp:113:8:113:12 | call to fgets | call to fgets |
|
||||
| test.cpp:26:10:26:16 | command indirection | test.cpp:42:18:42:34 | call to getenv indirection | test.cpp:26:10:26:16 | command indirection | The value of this argument may come from $@ and is being passed to system. | test.cpp:42:18:42:34 | call to getenv indirection | an environment variable |
|
||||
| test.cpp:31:10:31:16 | command indirection | test.cpp:43:18:43:34 | call to getenv indirection | test.cpp:31:10:31:16 | command indirection | The value of this argument may come from $@ and is being passed to system. | test.cpp:43:18:43:34 | call to getenv indirection | an environment variable |
|
||||
| test.cpp:62:10:62:15 | buffer indirection | test.cpp:56:12:56:17 | fgets output argument | test.cpp:62:10:62:15 | buffer indirection | The value of this argument may come from $@ and is being passed to system. | test.cpp:56:12:56:17 | fgets output argument | string read by fgets |
|
||||
| test.cpp:63:10:63:13 | data indirection | test.cpp:56:12:56:17 | fgets output argument | test.cpp:63:10:63:13 | data indirection | The value of this argument may come from $@ and is being passed to system. | test.cpp:56:12:56:17 | fgets output argument | string read by fgets |
|
||||
| test.cpp:64:10:64:16 | dataref indirection | test.cpp:56:12:56:17 | fgets output argument | test.cpp:64:10:64:16 | dataref indirection | The value of this argument may come from $@ and is being passed to system. | test.cpp:56:12:56:17 | fgets output argument | string read by fgets |
|
||||
| test.cpp:65:10:65:14 | data2 indirection | test.cpp:56:12:56:17 | fgets output argument | test.cpp:65:10:65:14 | data2 indirection | The value of this argument may come from $@ and is being passed to system. | test.cpp:56:12:56:17 | fgets output argument | string read by fgets |
|
||||
| test.cpp:78:10:78:15 | buffer indirection | test.cpp:76:12:76:17 | fgets output argument | test.cpp:78:10:78:15 | buffer indirection | The value of this argument may come from $@ and is being passed to system. | test.cpp:76:12:76:17 | fgets output argument | string read by fgets |
|
||||
| test.cpp:99:15:99:20 | buffer indirection | test.cpp:98:17:98:22 | recv output argument | test.cpp:99:15:99:20 | buffer indirection | The value of this argument may come from $@ and is being passed to LoadLibrary. | test.cpp:98:17:98:22 | recv output argument | buffer read by recv |
|
||||
| test.cpp:107:15:107:20 | buffer indirection | test.cpp:106:17:106:22 | recv output argument | test.cpp:107:15:107:20 | buffer indirection | The value of this argument may come from $@ and is being passed to LoadLibrary. | test.cpp:106:17:106:22 | recv output argument | buffer read by recv |
|
||||
| test.cpp:114:9:114:11 | ptr indirection | test.cpp:113:8:113:12 | call to fgets indirection | test.cpp:114:9:114:11 | ptr indirection | The value of this argument may come from $@ and is being passed to system. | test.cpp:113:8:113:12 | call to fgets indirection | string read by fgets |
|
||||
|
|
|
@ -1,69 +0,0 @@
|
|||
edges
|
||||
| globalVars.c:8:7:8:10 | copy | globalVars.c:27:9:27:12 | copy |
|
||||
| globalVars.c:8:7:8:10 | copy | globalVars.c:27:9:27:12 | copy |
|
||||
| globalVars.c:8:7:8:10 | copy | globalVars.c:30:15:30:18 | copy |
|
||||
| globalVars.c:8:7:8:10 | copy | globalVars.c:30:15:30:18 | copy |
|
||||
| globalVars.c:8:7:8:10 | copy | globalVars.c:30:15:30:18 | copy |
|
||||
| globalVars.c:8:7:8:10 | copy | globalVars.c:33:15:33:18 | copy |
|
||||
| globalVars.c:8:7:8:10 | copy | globalVars.c:35:11:35:14 | copy |
|
||||
| globalVars.c:9:7:9:11 | copy2 | globalVars.c:38:9:38:13 | copy2 |
|
||||
| globalVars.c:9:7:9:11 | copy2 | globalVars.c:38:9:38:13 | copy2 |
|
||||
| globalVars.c:9:7:9:11 | copy2 | globalVars.c:41:15:41:19 | copy2 |
|
||||
| globalVars.c:9:7:9:11 | copy2 | globalVars.c:41:15:41:19 | copy2 |
|
||||
| globalVars.c:9:7:9:11 | copy2 | globalVars.c:41:15:41:19 | copy2 |
|
||||
| globalVars.c:9:7:9:11 | copy2 | globalVars.c:44:15:44:19 | copy2 |
|
||||
| globalVars.c:9:7:9:11 | copy2 | globalVars.c:50:9:50:13 | copy2 |
|
||||
| globalVars.c:9:7:9:11 | copy2 | globalVars.c:50:9:50:13 | copy2 |
|
||||
| globalVars.c:11:22:11:25 | argv | globalVars.c:8:7:8:10 | copy |
|
||||
| globalVars.c:11:22:11:25 | argv | globalVars.c:12:2:12:15 | ... = ... |
|
||||
| globalVars.c:12:2:12:15 | ... = ... | globalVars.c:8:7:8:10 | copy |
|
||||
| globalVars.c:15:21:15:23 | val | globalVars.c:9:7:9:11 | copy2 |
|
||||
| globalVars.c:15:21:15:23 | val | globalVars.c:16:2:16:12 | ... = ... |
|
||||
| globalVars.c:16:2:16:12 | ... = ... | globalVars.c:9:7:9:11 | copy2 |
|
||||
| globalVars.c:24:11:24:14 | argv | globalVars.c:11:22:11:25 | argv |
|
||||
| globalVars.c:24:11:24:14 | argv | globalVars.c:11:22:11:25 | argv |
|
||||
| globalVars.c:30:15:30:18 | copy | globalVars.c:30:15:30:18 | copy |
|
||||
| globalVars.c:30:15:30:18 | copy | globalVars.c:30:15:30:18 | copy |
|
||||
| globalVars.c:30:15:30:18 | copy | globalVars.c:30:15:30:18 | copy |
|
||||
| globalVars.c:30:15:30:18 | copy | globalVars.c:35:11:35:14 | copy |
|
||||
| globalVars.c:33:15:33:18 | copy | globalVars.c:35:11:35:14 | copy |
|
||||
| globalVars.c:35:11:35:14 | copy | globalVars.c:15:21:15:23 | val |
|
||||
| globalVars.c:35:11:35:14 | copy | globalVars.c:35:11:35:14 | copy |
|
||||
| globalVars.c:41:15:41:19 | copy2 | globalVars.c:41:15:41:19 | copy2 |
|
||||
| globalVars.c:41:15:41:19 | copy2 | globalVars.c:41:15:41:19 | copy2 |
|
||||
| globalVars.c:41:15:41:19 | copy2 | globalVars.c:41:15:41:19 | copy2 |
|
||||
| globalVars.c:41:15:41:19 | copy2 | globalVars.c:50:9:50:13 | copy2 |
|
||||
| globalVars.c:41:15:41:19 | copy2 | globalVars.c:50:9:50:13 | copy2 |
|
||||
| globalVars.c:44:15:44:19 | copy2 | globalVars.c:50:9:50:13 | copy2 |
|
||||
| globalVars.c:44:15:44:19 | copy2 | globalVars.c:50:9:50:13 | copy2 |
|
||||
subpaths
|
||||
nodes
|
||||
| globalVars.c:8:7:8:10 | copy | semmle.label | copy |
|
||||
| globalVars.c:9:7:9:11 | copy2 | semmle.label | copy2 |
|
||||
| globalVars.c:11:22:11:25 | argv | semmle.label | argv |
|
||||
| globalVars.c:12:2:12:15 | ... = ... | semmle.label | ... = ... |
|
||||
| globalVars.c:15:21:15:23 | val | semmle.label | val |
|
||||
| globalVars.c:16:2:16:12 | ... = ... | semmle.label | ... = ... |
|
||||
| globalVars.c:24:11:24:14 | argv | semmle.label | argv |
|
||||
| globalVars.c:24:11:24:14 | argv | semmle.label | argv |
|
||||
| globalVars.c:27:9:27:12 | copy | semmle.label | copy |
|
||||
| globalVars.c:27:9:27:12 | copy | semmle.label | copy |
|
||||
| globalVars.c:30:15:30:18 | copy | semmle.label | copy |
|
||||
| globalVars.c:30:15:30:18 | copy | semmle.label | copy |
|
||||
| globalVars.c:30:15:30:18 | copy | semmle.label | copy |
|
||||
| globalVars.c:33:15:33:18 | copy | semmle.label | copy |
|
||||
| globalVars.c:35:11:35:14 | copy | semmle.label | copy |
|
||||
| globalVars.c:38:9:38:13 | copy2 | semmle.label | copy2 |
|
||||
| globalVars.c:38:9:38:13 | copy2 | semmle.label | copy2 |
|
||||
| globalVars.c:41:15:41:19 | copy2 | semmle.label | copy2 |
|
||||
| globalVars.c:41:15:41:19 | copy2 | semmle.label | copy2 |
|
||||
| globalVars.c:41:15:41:19 | copy2 | semmle.label | copy2 |
|
||||
| globalVars.c:44:15:44:19 | copy2 | semmle.label | copy2 |
|
||||
| globalVars.c:50:9:50:13 | copy2 | semmle.label | copy2 |
|
||||
| globalVars.c:50:9:50:13 | copy2 | semmle.label | copy2 |
|
||||
#select
|
||||
| globalVars.c:27:9:27:12 | copy | globalVars.c:24:11:24:14 | argv | globalVars.c:27:9:27:12 | copy | The value of this argument may come from $@ and is being used as a formatting argument to printf(format). | globalVars.c:24:11:24:14 | argv | argv |
|
||||
| globalVars.c:30:15:30:18 | copy | globalVars.c:24:11:24:14 | argv | globalVars.c:30:15:30:18 | copy | The value of this argument may come from $@ and is being used as a formatting argument to printWrapper(str), which calls printf(format). | globalVars.c:24:11:24:14 | argv | argv |
|
||||
| globalVars.c:38:9:38:13 | copy2 | globalVars.c:24:11:24:14 | argv | globalVars.c:38:9:38:13 | copy2 | The value of this argument may come from $@ and is being used as a formatting argument to printf(format). | globalVars.c:24:11:24:14 | argv | argv |
|
||||
| globalVars.c:41:15:41:19 | copy2 | globalVars.c:24:11:24:14 | argv | globalVars.c:41:15:41:19 | copy2 | The value of this argument may come from $@ and is being used as a formatting argument to printWrapper(str), which calls printf(format). | globalVars.c:24:11:24:14 | argv | argv |
|
||||
| globalVars.c:50:9:50:13 | copy2 | globalVars.c:24:11:24:14 | argv | globalVars.c:50:9:50:13 | copy2 | The value of this argument may come from $@ and is being used as a formatting argument to printf(format). | globalVars.c:24:11:24:14 | argv | argv |
|
|
@ -1 +0,0 @@
|
|||
Security/CWE/CWE-134/UncontrolledFormatStringThroughGlobalVar.ql
|
|
@ -1,13 +1,8 @@
|
|||
edges
|
||||
| examples.cpp:63:26:63:30 | & ... | examples.cpp:66:11:66:14 | data |
|
||||
| examples.cpp:63:26:63:30 | & ... | examples.cpp:66:11:66:14 | data |
|
||||
| examples.cpp:63:26:63:30 | fscanf output argument | examples.cpp:66:11:66:14 | data |
|
||||
| examples.cpp:63:26:63:30 | fscanf output argument | examples.cpp:66:11:66:14 | data |
|
||||
subpaths
|
||||
nodes
|
||||
| examples.cpp:63:26:63:30 | & ... | semmle.label | & ... |
|
||||
| examples.cpp:63:26:63:30 | fscanf output argument | semmle.label | fscanf output argument |
|
||||
| examples.cpp:66:11:66:14 | data | semmle.label | data |
|
||||
| examples.cpp:66:11:66:14 | data | semmle.label | data |
|
||||
subpaths
|
||||
#select
|
||||
| examples.cpp:66:11:66:14 | data | examples.cpp:63:26:63:30 | & ... | examples.cpp:66:11:66:14 | data | $@ flows to an operand of an arithmetic expression, potentially causing an underflow. | examples.cpp:63:26:63:30 | & ... | User-provided value |
|
||||
| examples.cpp:66:11:66:14 | data | examples.cpp:63:26:63:30 | fscanf output argument | examples.cpp:66:11:66:14 | data | $@ flows to an operand of an arithmetic expression, potentially causing an underflow. | examples.cpp:63:26:63:30 | fscanf output argument | value read by fscanf |
|
||||
|
|
|
@ -1 +1 @@
|
|||
| examples.cpp:66:9:66:14 | -- ... | $@ flows an expression which might overflow negatively. | examples.cpp:63:26:63:30 | & ... | User-provided value |
|
||||
| examples.cpp:66:9:66:14 | -- ... | $@ flows an expression which might overflow negatively. | examples.cpp:63:26:63:30 | fscanf output argument | value read by fscanf |
|
||||
|
|
|
@ -1,86 +1,59 @@
|
|||
edges
|
||||
| test2.cpp:12:21:12:21 | v | test2.cpp:14:11:14:11 | v |
|
||||
| test2.cpp:12:21:12:21 | v | test2.cpp:14:11:14:11 | v |
|
||||
| test2.cpp:25:22:25:23 | & ... | test2.cpp:27:13:27:13 | v |
|
||||
| test2.cpp:25:22:25:23 | fscanf output argument | test2.cpp:27:13:27:13 | v |
|
||||
| test2.cpp:27:13:27:13 | v | test2.cpp:12:21:12:21 | v |
|
||||
| test2.cpp:36:9:36:14 | buffer | test2.cpp:39:9:39:11 | num |
|
||||
| test2.cpp:36:9:36:14 | buffer | test2.cpp:39:9:39:11 | num |
|
||||
| test2.cpp:36:9:36:14 | buffer | test2.cpp:39:9:39:11 | num |
|
||||
| test2.cpp:36:9:36:14 | buffer | test2.cpp:39:9:39:11 | num |
|
||||
| test2.cpp:36:9:36:14 | buffer | test2.cpp:40:3:40:5 | num |
|
||||
| test2.cpp:36:9:36:14 | buffer | test2.cpp:40:3:40:5 | num |
|
||||
| test2.cpp:36:9:36:14 | buffer | test2.cpp:40:3:40:5 | num |
|
||||
| test2.cpp:36:9:36:14 | buffer | test2.cpp:40:3:40:5 | num |
|
||||
| test2.cpp:36:9:36:14 | fgets output argument | test2.cpp:39:9:39:11 | num |
|
||||
| test2.cpp:36:9:36:14 | fgets output argument | test2.cpp:39:9:39:11 | num |
|
||||
| test2.cpp:36:9:36:14 | fgets output argument | test2.cpp:40:3:40:5 | num |
|
||||
| test2.cpp:36:9:36:14 | fgets output argument | test2.cpp:40:3:40:5 | num |
|
||||
| test5.cpp:5:5:5:17 | getTaintedInt indirection | test5.cpp:17:6:17:18 | call to getTaintedInt |
|
||||
| test3.c:10:27:10:30 | argv indirection | test.c:14:15:14:28 | maxConnections |
|
||||
| test3.c:10:27:10:30 | argv indirection | test.c:44:7:44:10 | len2 |
|
||||
| test3.c:10:27:10:30 | argv indirection | test.c:54:7:54:10 | len3 |
|
||||
| test5.cpp:5:5:5:17 | getTaintedInt indirection | test5.cpp:17:6:17:18 | call to getTaintedInt |
|
||||
| test5.cpp:5:5:5:17 | getTaintedInt indirection | test5.cpp:18:6:18:18 | call to getTaintedInt |
|
||||
| test5.cpp:9:7:9:9 | buf | test5.cpp:5:5:5:17 | getTaintedInt indirection |
|
||||
| test5.cpp:9:7:9:9 | buf | test5.cpp:5:5:5:17 | getTaintedInt indirection |
|
||||
| test5.cpp:9:7:9:9 | gets output argument | test5.cpp:5:5:5:17 | getTaintedInt indirection |
|
||||
| test5.cpp:18:6:18:18 | call to getTaintedInt | test5.cpp:19:6:19:6 | y |
|
||||
| test5.cpp:18:6:18:18 | call to getTaintedInt | test5.cpp:19:6:19:6 | y |
|
||||
| test.c:11:29:11:32 | argv | test.c:14:15:14:28 | maxConnections |
|
||||
| test.c:11:29:11:32 | argv | test.c:14:15:14:28 | maxConnections |
|
||||
| test.c:11:29:11:32 | argv | test.c:14:15:14:28 | maxConnections |
|
||||
| test.c:11:29:11:32 | argv | test.c:14:15:14:28 | maxConnections |
|
||||
| test.c:41:17:41:20 | argv | test.c:44:7:44:10 | len2 |
|
||||
| test.c:41:17:41:20 | argv | test.c:44:7:44:10 | len2 |
|
||||
| test.c:41:17:41:20 | argv | test.c:44:7:44:10 | len2 |
|
||||
| test.c:41:17:41:20 | argv | test.c:44:7:44:10 | len2 |
|
||||
| test.c:51:17:51:20 | argv | test.c:54:7:54:10 | len3 |
|
||||
| test.c:51:17:51:20 | argv | test.c:54:7:54:10 | len3 |
|
||||
| test.c:51:17:51:20 | argv | test.c:54:7:54:10 | len3 |
|
||||
| test.c:51:17:51:20 | argv | test.c:54:7:54:10 | len3 |
|
||||
subpaths
|
||||
| test.c:10:27:10:30 | argv indirection | test.c:14:15:14:28 | maxConnections |
|
||||
| test.c:10:27:10:30 | argv indirection | test.c:44:7:44:10 | len2 |
|
||||
| test.c:10:27:10:30 | argv indirection | test.c:54:7:54:10 | len3 |
|
||||
nodes
|
||||
| test2.cpp:12:21:12:21 | v | semmle.label | v |
|
||||
| test2.cpp:14:11:14:11 | v | semmle.label | v |
|
||||
| test2.cpp:14:11:14:11 | v | semmle.label | v |
|
||||
| test2.cpp:25:22:25:23 | & ... | semmle.label | & ... |
|
||||
| test2.cpp:25:22:25:23 | fscanf output argument | semmle.label | fscanf output argument |
|
||||
| test2.cpp:27:13:27:13 | v | semmle.label | v |
|
||||
| test2.cpp:36:9:36:14 | buffer | semmle.label | buffer |
|
||||
| test2.cpp:36:9:36:14 | buffer | semmle.label | buffer |
|
||||
| test2.cpp:36:9:36:14 | fgets output argument | semmle.label | fgets output argument |
|
||||
| test2.cpp:39:9:39:11 | num | semmle.label | num |
|
||||
| test2.cpp:39:9:39:11 | num | semmle.label | num |
|
||||
| test2.cpp:40:3:40:5 | num | semmle.label | num |
|
||||
| test2.cpp:40:3:40:5 | num | semmle.label | num |
|
||||
| test3.c:10:27:10:30 | argv indirection | semmle.label | argv indirection |
|
||||
| test5.cpp:5:5:5:17 | getTaintedInt indirection | semmle.label | getTaintedInt indirection |
|
||||
| test5.cpp:9:7:9:9 | buf | semmle.label | buf |
|
||||
| test5.cpp:9:7:9:9 | buf | semmle.label | buf |
|
||||
| test5.cpp:9:7:9:9 | gets output argument | semmle.label | gets output argument |
|
||||
| test5.cpp:17:6:17:18 | call to getTaintedInt | semmle.label | call to getTaintedInt |
|
||||
| test5.cpp:17:6:17:18 | call to getTaintedInt | semmle.label | call to getTaintedInt |
|
||||
| test5.cpp:18:6:18:18 | call to getTaintedInt | semmle.label | call to getTaintedInt |
|
||||
| test5.cpp:19:6:19:6 | y | semmle.label | y |
|
||||
| test5.cpp:19:6:19:6 | y | semmle.label | y |
|
||||
| test.c:11:29:11:32 | argv | semmle.label | argv |
|
||||
| test.c:11:29:11:32 | argv | semmle.label | argv |
|
||||
| test.c:10:27:10:30 | argv indirection | semmle.label | argv indirection |
|
||||
| test.c:14:15:14:28 | maxConnections | semmle.label | maxConnections |
|
||||
| test.c:14:15:14:28 | maxConnections | semmle.label | maxConnections |
|
||||
| test.c:41:17:41:20 | argv | semmle.label | argv |
|
||||
| test.c:41:17:41:20 | argv | semmle.label | argv |
|
||||
| test.c:44:7:44:10 | len2 | semmle.label | len2 |
|
||||
| test.c:44:7:44:10 | len2 | semmle.label | len2 |
|
||||
| test.c:51:17:51:20 | argv | semmle.label | argv |
|
||||
| test.c:51:17:51:20 | argv | semmle.label | argv |
|
||||
| test.c:54:7:54:10 | len3 | semmle.label | len3 |
|
||||
| test.c:54:7:54:10 | len3 | semmle.label | len3 |
|
||||
subpaths
|
||||
#select
|
||||
| test2.cpp:14:11:14:11 | v | test2.cpp:25:22:25:23 | & ... | test2.cpp:14:11:14:11 | v | $@ flows to an operand of an arithmetic expression, potentially causing an overflow. | test2.cpp:25:22:25:23 | & ... | User-provided value |
|
||||
| test2.cpp:14:11:14:11 | v | test2.cpp:25:22:25:23 | & ... | test2.cpp:14:11:14:11 | v | $@ flows to an operand of an arithmetic expression, potentially causing an underflow. | test2.cpp:25:22:25:23 | & ... | User-provided value |
|
||||
| test2.cpp:39:9:39:11 | num | test2.cpp:36:9:36:14 | buffer | test2.cpp:39:9:39:11 | num | $@ flows to an operand of an arithmetic expression, potentially causing an overflow. | test2.cpp:36:9:36:14 | buffer | User-provided value |
|
||||
| test2.cpp:40:3:40:5 | num | test2.cpp:36:9:36:14 | buffer | test2.cpp:40:3:40:5 | num | $@ flows to an operand of an arithmetic expression, potentially causing an overflow. | test2.cpp:36:9:36:14 | buffer | User-provided value |
|
||||
| test5.cpp:17:6:17:18 | call to getTaintedInt | test5.cpp:9:7:9:9 | buf | test5.cpp:17:6:17:18 | call to getTaintedInt | $@ flows to an operand of an arithmetic expression, potentially causing an overflow. | test5.cpp:9:7:9:9 | buf | User-provided value |
|
||||
| test5.cpp:19:6:19:6 | y | test5.cpp:9:7:9:9 | buf | test5.cpp:19:6:19:6 | y | $@ flows to an operand of an arithmetic expression, potentially causing an overflow. | test5.cpp:9:7:9:9 | buf | User-provided value |
|
||||
| test5.cpp:19:6:19:6 | y | test5.cpp:9:7:9:9 | buf | test5.cpp:19:6:19:6 | y | $@ flows to an operand of an arithmetic expression, potentially causing an underflow. | test5.cpp:9:7:9:9 | buf | User-provided value |
|
||||
| test.c:14:15:14:28 | maxConnections | test.c:11:29:11:32 | argv | test.c:14:15:14:28 | maxConnections | $@ flows to an operand of an arithmetic expression, potentially causing an overflow. | test.c:11:29:11:32 | argv | User-provided value |
|
||||
| test.c:14:15:14:28 | maxConnections | test.c:11:29:11:32 | argv | test.c:14:15:14:28 | maxConnections | $@ flows to an operand of an arithmetic expression, potentially causing an underflow. | test.c:11:29:11:32 | argv | User-provided value |
|
||||
| test.c:44:7:44:10 | len2 | test.c:41:17:41:20 | argv | test.c:44:7:44:10 | len2 | $@ flows to an operand of an arithmetic expression, potentially causing an underflow. | test.c:41:17:41:20 | argv | User-provided value |
|
||||
| test.c:54:7:54:10 | len3 | test.c:51:17:51:20 | argv | test.c:54:7:54:10 | len3 | $@ flows to an operand of an arithmetic expression, potentially causing an underflow. | test.c:51:17:51:20 | argv | User-provided value |
|
||||
| test2.cpp:14:11:14:11 | v | test2.cpp:25:22:25:23 | fscanf output argument | test2.cpp:14:11:14:11 | v | $@ flows to an operand of an arithmetic expression, potentially causing an overflow. | test2.cpp:25:22:25:23 | fscanf output argument | value read by fscanf |
|
||||
| test2.cpp:14:11:14:11 | v | test2.cpp:25:22:25:23 | fscanf output argument | test2.cpp:14:11:14:11 | v | $@ flows to an operand of an arithmetic expression, potentially causing an underflow. | test2.cpp:25:22:25:23 | fscanf output argument | value read by fscanf |
|
||||
| test2.cpp:39:9:39:11 | num | test2.cpp:36:9:36:14 | fgets output argument | test2.cpp:39:9:39:11 | num | $@ flows to an operand of an arithmetic expression, potentially causing an overflow. | test2.cpp:36:9:36:14 | fgets output argument | string read by fgets |
|
||||
| test2.cpp:40:3:40:5 | num | test2.cpp:36:9:36:14 | fgets output argument | test2.cpp:40:3:40:5 | num | $@ flows to an operand of an arithmetic expression, potentially causing an overflow. | test2.cpp:36:9:36:14 | fgets output argument | string read by fgets |
|
||||
| test5.cpp:17:6:17:18 | call to getTaintedInt | test5.cpp:9:7:9:9 | gets output argument | test5.cpp:17:6:17:18 | call to getTaintedInt | $@ flows to an operand of an arithmetic expression, potentially causing an overflow. | test5.cpp:9:7:9:9 | gets output argument | string read by gets |
|
||||
| test5.cpp:19:6:19:6 | y | test5.cpp:9:7:9:9 | gets output argument | test5.cpp:19:6:19:6 | y | $@ flows to an operand of an arithmetic expression, potentially causing an overflow. | test5.cpp:9:7:9:9 | gets output argument | string read by gets |
|
||||
| test5.cpp:19:6:19:6 | y | test5.cpp:9:7:9:9 | gets output argument | test5.cpp:19:6:19:6 | y | $@ flows to an operand of an arithmetic expression, potentially causing an underflow. | test5.cpp:9:7:9:9 | gets output argument | string read by gets |
|
||||
| test.c:14:15:14:28 | maxConnections | test3.c:10:27:10:30 | argv indirection | test.c:14:15:14:28 | maxConnections | $@ flows to an operand of an arithmetic expression, potentially causing an overflow. | test3.c:10:27:10:30 | argv indirection | a command-line argument |
|
||||
| test.c:14:15:14:28 | maxConnections | test3.c:10:27:10:30 | argv indirection | test.c:14:15:14:28 | maxConnections | $@ flows to an operand of an arithmetic expression, potentially causing an overflow. | test.c:10:27:10:30 | argv indirection | a command-line argument |
|
||||
| test.c:14:15:14:28 | maxConnections | test3.c:10:27:10:30 | argv indirection | test.c:14:15:14:28 | maxConnections | $@ flows to an operand of an arithmetic expression, potentially causing an underflow. | test3.c:10:27:10:30 | argv indirection | a command-line argument |
|
||||
| test.c:14:15:14:28 | maxConnections | test3.c:10:27:10:30 | argv indirection | test.c:14:15:14:28 | maxConnections | $@ flows to an operand of an arithmetic expression, potentially causing an underflow. | test.c:10:27:10:30 | argv indirection | a command-line argument |
|
||||
| test.c:14:15:14:28 | maxConnections | test.c:10:27:10:30 | argv indirection | test.c:14:15:14:28 | maxConnections | $@ flows to an operand of an arithmetic expression, potentially causing an overflow. | test3.c:10:27:10:30 | argv indirection | a command-line argument |
|
||||
| test.c:14:15:14:28 | maxConnections | test.c:10:27:10:30 | argv indirection | test.c:14:15:14:28 | maxConnections | $@ flows to an operand of an arithmetic expression, potentially causing an overflow. | test.c:10:27:10:30 | argv indirection | a command-line argument |
|
||||
| test.c:14:15:14:28 | maxConnections | test.c:10:27:10:30 | argv indirection | test.c:14:15:14:28 | maxConnections | $@ flows to an operand of an arithmetic expression, potentially causing an underflow. | test3.c:10:27:10:30 | argv indirection | a command-line argument |
|
||||
| test.c:14:15:14:28 | maxConnections | test.c:10:27:10:30 | argv indirection | test.c:14:15:14:28 | maxConnections | $@ flows to an operand of an arithmetic expression, potentially causing an underflow. | test.c:10:27:10:30 | argv indirection | a command-line argument |
|
||||
| test.c:44:7:44:10 | len2 | test3.c:10:27:10:30 | argv indirection | test.c:44:7:44:10 | len2 | $@ flows to an operand of an arithmetic expression, potentially causing an underflow. | test3.c:10:27:10:30 | argv indirection | a command-line argument |
|
||||
| test.c:44:7:44:10 | len2 | test3.c:10:27:10:30 | argv indirection | test.c:44:7:44:10 | len2 | $@ flows to an operand of an arithmetic expression, potentially causing an underflow. | test.c:10:27:10:30 | argv indirection | a command-line argument |
|
||||
| test.c:44:7:44:10 | len2 | test.c:10:27:10:30 | argv indirection | test.c:44:7:44:10 | len2 | $@ flows to an operand of an arithmetic expression, potentially causing an underflow. | test3.c:10:27:10:30 | argv indirection | a command-line argument |
|
||||
| test.c:44:7:44:10 | len2 | test.c:10:27:10:30 | argv indirection | test.c:44:7:44:10 | len2 | $@ flows to an operand of an arithmetic expression, potentially causing an underflow. | test.c:10:27:10:30 | argv indirection | a command-line argument |
|
||||
| test.c:54:7:54:10 | len3 | test3.c:10:27:10:30 | argv indirection | test.c:54:7:54:10 | len3 | $@ flows to an operand of an arithmetic expression, potentially causing an underflow. | test3.c:10:27:10:30 | argv indirection | a command-line argument |
|
||||
| test.c:54:7:54:10 | len3 | test3.c:10:27:10:30 | argv indirection | test.c:54:7:54:10 | len3 | $@ flows to an operand of an arithmetic expression, potentially causing an underflow. | test.c:10:27:10:30 | argv indirection | a command-line argument |
|
||||
| test.c:54:7:54:10 | len3 | test.c:10:27:10:30 | argv indirection | test.c:54:7:54:10 | len3 | $@ flows to an operand of an arithmetic expression, potentially causing an underflow. | test3.c:10:27:10:30 | argv indirection | a command-line argument |
|
||||
| test.c:54:7:54:10 | len3 | test.c:10:27:10:30 | argv indirection | test.c:54:7:54:10 | len3 | $@ flows to an operand of an arithmetic expression, potentially causing an underflow. | test.c:10:27:10:30 | argv indirection | a command-line argument |
|
||||
|
|
|
@ -1,18 +1,23 @@
|
|||
| test2.cpp:14:11:14:15 | ... * ... | $@ flows an expression which might overflow. | test2.cpp:25:22:25:23 | & ... | User-provided value |
|
||||
| test2.cpp:15:11:15:19 | ... * ... | $@ flows an expression which might overflow. | test2.cpp:25:22:25:23 | & ... | User-provided value |
|
||||
| test2.cpp:16:11:16:21 | ... * ... | $@ flows an expression which might overflow. | test2.cpp:25:22:25:23 | & ... | User-provided value |
|
||||
| test2.cpp:17:11:17:22 | ... * ... | $@ flows an expression which might overflow. | test2.cpp:25:22:25:23 | & ... | User-provided value |
|
||||
| test2.cpp:39:9:39:18 | ... + ... | $@ flows an expression which might overflow. | test2.cpp:36:9:36:14 | buffer | User-provided value |
|
||||
| test2.cpp:40:3:40:13 | ... += ... | $@ flows an expression which might overflow. | test2.cpp:36:9:36:14 | buffer | User-provided value |
|
||||
| test3.c:12:31:12:34 | * ... | $@ flows an expression which might overflow negatively. | test3.c:11:15:11:18 | argv | User-provided value |
|
||||
| test3.c:13:16:13:19 | * ... | $@ flows an expression which might overflow negatively. | test3.c:11:15:11:18 | argv | User-provided value |
|
||||
| test4.cpp:13:17:13:20 | access to array | $@ flows an expression which might overflow negatively. | test4.cpp:9:13:9:16 | argv | User-provided value |
|
||||
| test5.cpp:10:9:10:15 | call to strtoul | $@ flows an expression which might overflow. | test5.cpp:9:7:9:9 | buf | User-provided value |
|
||||
| test5.cpp:17:6:17:27 | ... * ... | $@ flows an expression which might overflow. | test5.cpp:9:7:9:9 | buf | User-provided value |
|
||||
| test5.cpp:19:6:19:13 | ... * ... | $@ flows an expression which might overflow. | test5.cpp:9:7:9:9 | buf | User-provided value |
|
||||
| test6.cpp:11:15:11:15 | s | $@ flows an expression which might overflow. | test6.cpp:39:23:39:24 | & ... | User-provided value |
|
||||
| test6.cpp:16:15:16:15 | s | $@ flows an expression which might overflow. | test6.cpp:39:23:39:24 | & ... | User-provided value |
|
||||
| test6.cpp:30:16:30:16 | s | $@ flows an expression which might overflow. | test6.cpp:39:23:39:24 | & ... | User-provided value |
|
||||
| test.c:14:15:14:35 | ... * ... | $@ flows an expression which might overflow. | test.c:11:29:11:32 | argv | User-provided value |
|
||||
| test.c:44:7:44:12 | ... -- | $@ flows an expression which might overflow negatively. | test.c:41:17:41:20 | argv | User-provided value |
|
||||
| test.c:54:7:54:12 | ... -- | $@ flows an expression which might overflow negatively. | test.c:51:17:51:20 | argv | User-provided value |
|
||||
| test2.cpp:14:11:14:15 | ... * ... | $@ flows an expression which might overflow. | test2.cpp:25:22:25:23 | fscanf output argument | value read by fscanf |
|
||||
| test2.cpp:15:11:15:19 | ... * ... | $@ flows an expression which might overflow. | test2.cpp:25:22:25:23 | fscanf output argument | value read by fscanf |
|
||||
| test2.cpp:16:11:16:21 | ... * ... | $@ flows an expression which might overflow. | test2.cpp:25:22:25:23 | fscanf output argument | value read by fscanf |
|
||||
| test2.cpp:17:11:17:22 | ... * ... | $@ flows an expression which might overflow. | test2.cpp:25:22:25:23 | fscanf output argument | value read by fscanf |
|
||||
| test2.cpp:39:9:39:18 | ... + ... | $@ flows an expression which might overflow. | test2.cpp:36:9:36:14 | fgets output argument | string read by fgets |
|
||||
| test2.cpp:40:3:40:13 | ... += ... | $@ flows an expression which might overflow. | test2.cpp:36:9:36:14 | fgets output argument | string read by fgets |
|
||||
| test3.c:12:11:12:34 | * ... | $@ flows an expression which might overflow negatively. | test3.c:10:27:10:30 | argv indirection | a command-line argument |
|
||||
| test3.c:12:11:12:34 | * ... | $@ flows an expression which might overflow negatively. | test.c:10:27:10:30 | argv indirection | a command-line argument |
|
||||
| test3.c:13:11:13:20 | * ... | $@ flows an expression which might overflow negatively. | test3.c:10:27:10:30 | argv indirection | a command-line argument |
|
||||
| test3.c:13:11:13:20 | * ... | $@ flows an expression which might overflow negatively. | test.c:10:27:10:30 | argv indirection | a command-line argument |
|
||||
| test4.cpp:13:7:13:20 | access to array | $@ flows an expression which might overflow negatively. | test4.cpp:8:27:8:30 | argv indirection | a command-line argument |
|
||||
| test5.cpp:10:9:10:27 | call to strtoul | $@ flows an expression which might overflow. | test5.cpp:9:7:9:9 | gets output argument | string read by gets |
|
||||
| test5.cpp:17:6:17:27 | ... * ... | $@ flows an expression which might overflow. | test5.cpp:9:7:9:9 | gets output argument | string read by gets |
|
||||
| test5.cpp:19:6:19:13 | ... * ... | $@ flows an expression which might overflow. | test5.cpp:9:7:9:9 | gets output argument | string read by gets |
|
||||
| test6.cpp:11:10:11:15 | s | $@ flows an expression which might overflow. | test6.cpp:39:23:39:24 | fscanf output argument | value read by fscanf |
|
||||
| test6.cpp:16:10:16:15 | s | $@ flows an expression which might overflow. | test6.cpp:39:23:39:24 | fscanf output argument | value read by fscanf |
|
||||
| test6.cpp:30:11:30:16 | s | $@ flows an expression which might overflow. | test6.cpp:39:23:39:24 | fscanf output argument | value read by fscanf |
|
||||
| test.c:14:15:14:35 | ... * ... | $@ flows an expression which might overflow. | test3.c:10:27:10:30 | argv indirection | a command-line argument |
|
||||
| test.c:14:15:14:35 | ... * ... | $@ flows an expression which might overflow. | test.c:10:27:10:30 | argv indirection | a command-line argument |
|
||||
| test.c:44:7:44:12 | ... -- | $@ flows an expression which might overflow negatively. | test3.c:10:27:10:30 | argv indirection | a command-line argument |
|
||||
| test.c:44:7:44:12 | ... -- | $@ flows an expression which might overflow negatively. | test.c:10:27:10:30 | argv indirection | a command-line argument |
|
||||
| test.c:54:7:54:12 | ... -- | $@ flows an expression which might overflow negatively. | test3.c:10:27:10:30 | argv indirection | a command-line argument |
|
||||
| test.c:54:7:54:12 | ... -- | $@ flows an expression which might overflow negatively. | test.c:10:27:10:30 | argv indirection | a command-line argument |
|
||||
|
|
|
@ -1 +1 @@
|
|||
| tests.cpp:38:31:38:34 | data | $@ flows an expression which might overflow. | tests.cpp:57:27:57:31 | & ... | User-provided value |
|
||||
| tests.cpp:38:25:38:34 | data | $@ flows an expression which might overflow. | tests.cpp:57:27:57:31 | fscanf output argument | value read by fscanf |
|
||||
|
|
|
@ -1,5 +1,6 @@
|
|||
using System;
|
||||
using System.Collections.Generic;
|
||||
using System.Diagnostics.CodeAnalysis;
|
||||
using System.IO;
|
||||
using System.Linq;
|
||||
using Newtonsoft.Json.Linq;
|
||||
|
@ -14,14 +15,6 @@ namespace Semmle.Extraction.CSharp.DependencyFetching
|
|||
{
|
||||
private readonly ProgressMonitor progressMonitor;
|
||||
|
||||
private static readonly string[] netFrameworks = new[] {
|
||||
"microsoft.aspnetcore.app.ref",
|
||||
"microsoft.netcore.app.ref",
|
||||
"microsoft.netframework.referenceassemblies",
|
||||
"microsoft.windowsdesktop.app.ref",
|
||||
"netstandard.library.ref"
|
||||
};
|
||||
|
||||
internal Assets(ProgressMonitor progressMonitor)
|
||||
{
|
||||
this.progressMonitor = progressMonitor;
|
||||
|
@ -68,19 +61,19 @@ namespace Semmle.Extraction.CSharp.DependencyFetching
|
|||
/// }
|
||||
/// }
|
||||
///
|
||||
/// Returns dependencies
|
||||
/// RequiredPaths = {
|
||||
/// Adds the following dependencies
|
||||
/// Paths: {
|
||||
/// "castle.core/4.4.1/lib/netstandard1.5/Castle.Core.dll",
|
||||
/// "json.net/1.0.33/lib/netstandard2.0/Json.Net.dll"
|
||||
/// }
|
||||
/// UsedPackages = {
|
||||
/// Packages: {
|
||||
/// "castle.core",
|
||||
/// "json.net"
|
||||
/// }
|
||||
/// </summary>
|
||||
private DependencyContainer AddPackageDependencies(JObject json, DependencyContainer dependencies)
|
||||
private void AddPackageDependencies(JObject json, DependencyContainer dependencies)
|
||||
{
|
||||
// If there are more than one framework we need to pick just one.
|
||||
// If there is more than one framework we need to pick just one.
|
||||
// To ensure stability we pick one based on the lexicographic order of
|
||||
// the framework names.
|
||||
var references = json
|
||||
|
@ -93,7 +86,7 @@ namespace Semmle.Extraction.CSharp.DependencyFetching
|
|||
if (references is null)
|
||||
{
|
||||
progressMonitor.LogDebug("No references found in the targets section in the assets file.");
|
||||
return dependencies;
|
||||
return;
|
||||
}
|
||||
|
||||
// Find all the compile dependencies for each reference and
|
||||
|
@ -108,19 +101,83 @@ namespace Semmle.Extraction.CSharp.DependencyFetching
|
|||
return;
|
||||
}
|
||||
|
||||
// If this is a .NET framework reference then include everything.
|
||||
if (netFrameworks.Any(framework => name.StartsWith(framework)))
|
||||
if (info.Compile is null || !info.Compile.Any())
|
||||
{
|
||||
dependencies.Add(name);
|
||||
}
|
||||
else
|
||||
{
|
||||
info.Compile?
|
||||
.ForEach(r => dependencies.Add(name, r.Key));
|
||||
// If this is a framework reference then include everything.
|
||||
if (FrameworkPackageNames.AllFrameworks.Any(framework => name.StartsWith(framework)))
|
||||
{
|
||||
dependencies.AddFramework(name);
|
||||
}
|
||||
return;
|
||||
}
|
||||
|
||||
info.Compile
|
||||
.ForEach(r => dependencies.Add(name, r.Key));
|
||||
});
|
||||
|
||||
return dependencies;
|
||||
return;
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Add the framework dependencies from the assets file to dependencies.
|
||||
///
|
||||
/// Example:
|
||||
/// "project": {
|
||||
// "version": "1.0.0",
|
||||
// "frameworks": {
|
||||
// "net7.0": {
|
||||
// "frameworkReferences": {
|
||||
// "Microsoft.AspNetCore.App": {
|
||||
// "privateAssets": "none"
|
||||
// },
|
||||
// "Microsoft.NETCore.App": {
|
||||
// "privateAssets": "all"
|
||||
// }
|
||||
// }
|
||||
// }
|
||||
// }
|
||||
// }
|
||||
//
|
||||
/// Adds the following dependencies
|
||||
/// Paths: {
|
||||
/// "microsoft.aspnetcore.app.ref",
|
||||
/// "microsoft.netcore.app.ref"
|
||||
/// }
|
||||
/// Packages: {
|
||||
/// "microsoft.aspnetcore.app.ref",
|
||||
/// "microsoft.netcore.app.ref"
|
||||
/// }
|
||||
/// </summary>
|
||||
private void AddFrameworkDependencies(JObject json, DependencyContainer dependencies)
|
||||
{
|
||||
|
||||
var frameworks = json
|
||||
.GetProperty("project")?
|
||||
.GetProperty("frameworks");
|
||||
|
||||
if (frameworks is null)
|
||||
{
|
||||
progressMonitor.LogDebug("No framework section in assets.json.");
|
||||
return;
|
||||
}
|
||||
|
||||
// If there is more than one framework we need to pick just one.
|
||||
// To ensure stability we pick one based on the lexicographic order of
|
||||
// the framework names.
|
||||
var references = frameworks
|
||||
.Properties()?
|
||||
.MaxBy(p => p.Name)?
|
||||
.Value["frameworkReferences"] as JObject;
|
||||
|
||||
if (references is null)
|
||||
{
|
||||
progressMonitor.LogDebug("No framework references in assets.json.");
|
||||
return;
|
||||
}
|
||||
|
||||
references
|
||||
.Properties()
|
||||
.ForEach(f => dependencies.AddFramework($"{f.Name}.Ref".ToLowerInvariant()));
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
|
@ -134,6 +191,7 @@ namespace Semmle.Extraction.CSharp.DependencyFetching
|
|||
{
|
||||
var obj = JObject.Parse(json);
|
||||
AddPackageDependencies(obj, dependencies);
|
||||
AddFrameworkDependencies(obj, dependencies);
|
||||
return true;
|
||||
}
|
||||
catch (Exception e)
|
||||
|
@ -143,14 +201,31 @@ namespace Semmle.Extraction.CSharp.DependencyFetching
|
|||
}
|
||||
}
|
||||
|
||||
private static bool TryReadAllText(string path, ProgressMonitor progressMonitor, [NotNullWhen(returnValue: true)] out string? content)
|
||||
{
|
||||
try
|
||||
{
|
||||
content = File.ReadAllText(path);
|
||||
return true;
|
||||
}
|
||||
catch (Exception e)
|
||||
{
|
||||
progressMonitor.LogInfo($"Failed to read assets file '{path}': {e.Message}");
|
||||
content = null;
|
||||
return false;
|
||||
}
|
||||
}
|
||||
|
||||
public static DependencyContainer GetCompilationDependencies(ProgressMonitor progressMonitor, IEnumerable<string> assets)
|
||||
{
|
||||
var parser = new Assets(progressMonitor);
|
||||
var dependencies = new DependencyContainer();
|
||||
assets.ForEach(asset =>
|
||||
{
|
||||
var json = File.ReadAllText(asset);
|
||||
parser.TryParse(json, dependencies);
|
||||
if (TryReadAllText(asset, progressMonitor, out var json))
|
||||
{
|
||||
parser.TryParse(json, dependencies);
|
||||
}
|
||||
});
|
||||
return dependencies;
|
||||
}
|
||||
|
|
|
@ -9,14 +9,19 @@ namespace Semmle.Extraction.CSharp.DependencyFetching
|
|||
/// </summary>
|
||||
internal class DependencyContainer
|
||||
{
|
||||
private readonly List<string> requiredPaths = new();
|
||||
private readonly HashSet<string> usedPackages = new();
|
||||
/// <summary>
|
||||
/// Paths to dependencies required for compilation.
|
||||
/// </summary>
|
||||
public List<string> Paths { get; } = new();
|
||||
|
||||
/// <summary>
|
||||
/// In most cases paths in asset files point to dll's or the empty _._ file, which
|
||||
/// is sometimes there to avoid the directory being empty.
|
||||
/// That is, if the path specifically adds a .dll we use that, otherwise we as a fallback
|
||||
/// add the entire directory (which should be fine in case of _._ as well).
|
||||
/// Packages that are used as a part of the required dependencies.
|
||||
/// </summary>
|
||||
public HashSet<string> Packages { get; } = new();
|
||||
|
||||
/// <summary>
|
||||
/// If the path specifically adds a .dll we use that, otherwise we as a fallback
|
||||
/// add the entire directory.
|
||||
/// </summary>
|
||||
private static string ParseFilePath(string path)
|
||||
{
|
||||
|
@ -32,16 +37,6 @@ namespace Semmle.Extraction.CSharp.DependencyFetching
|
|||
.Split(Path.DirectorySeparatorChar)
|
||||
.First();
|
||||
|
||||
/// <summary>
|
||||
/// Paths to dependencies required for compilation.
|
||||
/// </summary>
|
||||
public IEnumerable<string> RequiredPaths => requiredPaths;
|
||||
|
||||
/// <summary>
|
||||
/// Packages that are used as a part of the required dependencies.
|
||||
/// </summary>
|
||||
public HashSet<string> UsedPackages => usedPackages;
|
||||
|
||||
/// <summary>
|
||||
/// Add a dependency inside a package.
|
||||
/// </summary>
|
||||
|
@ -50,20 +45,27 @@ namespace Semmle.Extraction.CSharp.DependencyFetching
|
|||
var p = package.Replace('/', Path.DirectorySeparatorChar);
|
||||
var d = dependency.Replace('/', Path.DirectorySeparatorChar);
|
||||
|
||||
// In most cases paths in asset files point to dll's or the empty _._ file.
|
||||
// That is, for _._ we don't need to add anything.
|
||||
if (Path.GetFileName(d) == "_._")
|
||||
{
|
||||
return;
|
||||
}
|
||||
|
||||
var path = Path.Combine(p, ParseFilePath(d));
|
||||
requiredPaths.Add(path);
|
||||
usedPackages.Add(GetPackageName(p));
|
||||
Paths.Add(path);
|
||||
Packages.Add(GetPackageName(p));
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Add a dependency to an entire package
|
||||
/// Add a dependency to an entire framework package.
|
||||
/// </summary>
|
||||
public void Add(string package)
|
||||
public void AddFramework(string framework)
|
||||
{
|
||||
var p = package.Replace('/', Path.DirectorySeparatorChar);
|
||||
var p = framework.Replace('/', Path.DirectorySeparatorChar);
|
||||
|
||||
requiredPaths.Add(p);
|
||||
usedPackages.Add(GetPackageName(p));
|
||||
Paths.Add(p);
|
||||
Packages.Add(GetPackageName(p));
|
||||
}
|
||||
}
|
||||
}
|
|
@ -119,7 +119,7 @@ namespace Semmle.Extraction.CSharp.DependencyFetching
|
|||
var dependencies = Assets.GetCompilationDependencies(progressMonitor, assets1.Union(assets2));
|
||||
|
||||
var paths = dependencies
|
||||
.RequiredPaths
|
||||
.Paths
|
||||
.Select(d => Path.Combine(packageDirectory.DirInfo.FullName, d))
|
||||
.ToList();
|
||||
dllPaths.UnionWith(paths);
|
||||
|
@ -232,13 +232,7 @@ namespace Semmle.Extraction.CSharp.DependencyFetching
|
|||
{
|
||||
// Multiple dotnet framework packages could be present.
|
||||
// The order of the packages is important, we're adding the first one that is present in the nuget cache.
|
||||
var packagesInPrioOrder = new string[]
|
||||
{
|
||||
"microsoft.netcore.app.ref", // net7.0, ... net5.0, netcoreapp3.1, netcoreapp3.0
|
||||
"microsoft.netframework.referenceassemblies.", // net48, ..., net20
|
||||
"netstandard.library.ref", // netstandard2.1
|
||||
"netstandard.library" // netstandard2.0
|
||||
};
|
||||
var packagesInPrioOrder = FrameworkPackageNames.NetFrameworks;
|
||||
|
||||
var frameworkPath = packagesInPrioOrder
|
||||
.Select((s, index) => (Index: index, Path: GetPackageDirectory(s)))
|
||||
|
@ -308,7 +302,7 @@ namespace Semmle.Extraction.CSharp.DependencyFetching
|
|||
}
|
||||
|
||||
// First try to find ASP.NET Core assemblies in the NuGet packages
|
||||
if (GetPackageDirectory("microsoft.aspnetcore.app.ref") is string aspNetCorePackage)
|
||||
if (GetPackageDirectory(FrameworkPackageNames.AspNetCoreFramework) is string aspNetCorePackage)
|
||||
{
|
||||
progressMonitor.LogInfo($"Found ASP.NET Core in NuGet packages. Not adding installation directory.");
|
||||
dllPaths.Add(aspNetCorePackage);
|
||||
|
@ -322,7 +316,7 @@ namespace Semmle.Extraction.CSharp.DependencyFetching
|
|||
|
||||
private void AddMicrosoftWindowsDesktopDlls(ISet<string> dllPaths)
|
||||
{
|
||||
if (GetPackageDirectory("microsoft.windowsdesktop.app.ref") is string windowsDesktopApp)
|
||||
if (GetPackageDirectory(FrameworkPackageNames.WindowsDesktopFramework) is string windowsDesktopApp)
|
||||
{
|
||||
progressMonitor.LogInfo($"Found Windows Desktop App in NuGet packages.");
|
||||
dllPaths.Add(windowsDesktopApp);
|
||||
|
@ -356,7 +350,7 @@ namespace Semmle.Extraction.CSharp.DependencyFetching
|
|||
|
||||
private void LogAllUnusedPackages(DependencyContainer dependencies) =>
|
||||
GetAllPackageDirectories()
|
||||
.Where(package => !dependencies.UsedPackages.Contains(package))
|
||||
.Where(package => !dependencies.Packages.Contains(package))
|
||||
.ForEach(package => progressMonitor.LogInfo($"Unused package: {package}"));
|
||||
|
||||
private void GenerateSourceFileFromImplicitUsings()
|
||||
|
|
|
@ -128,7 +128,7 @@ namespace Semmle.Extraction.CSharp.DependencyFetching
|
|||
[GeneratedRegex("Restored\\s+(.+\\.csproj)", RegexOptions.Compiled)]
|
||||
private static partial Regex RestoredProjectRegex();
|
||||
|
||||
[GeneratedRegex("[Assets\\sfile\\shas\\snot\\schanged.\\sSkipping\\sassets\\sfile\\swriting.|Writing\\sassets\\sfile\\sto\\sdisk.]\\sPath:\\s(.*)", RegexOptions.Compiled)]
|
||||
[GeneratedRegex("[Assets\\sfile\\shas\\snot\\schanged.\\sSkipping\\sassets\\sfile\\swriting.|Writing\\sassets\\sfile\\sto\\sdisk.]\\sPath:\\s(.+)", RegexOptions.Compiled)]
|
||||
private static partial Regex AssetsFileRegex();
|
||||
}
|
||||
}
|
||||
|
|
|
@ -0,0 +1,25 @@
|
|||
using System.Collections.Generic;
|
||||
using System.Linq;
|
||||
|
||||
namespace Semmle.Extraction.CSharp.DependencyFetching
|
||||
{
|
||||
internal static class FrameworkPackageNames
|
||||
{
|
||||
public static string AspNetCoreFramework { get; } = "microsoft.aspnetcore.app.ref";
|
||||
|
||||
public static string WindowsDesktopFramework { get; } = "microsoft.windowsdesktop.app.ref";
|
||||
|
||||
// The order of the packages is important.
|
||||
public static string[] NetFrameworks { get; } = new string[]
|
||||
{
|
||||
"microsoft.netcore.app.ref", // net7.0, ... net5.0, netcoreapp3.1, netcoreapp3.0
|
||||
"microsoft.netframework.referenceassemblies.", // net48, ..., net20
|
||||
"netstandard.library.ref", // netstandard2.1
|
||||
"netstandard.library" // netstandard2.0
|
||||
};
|
||||
|
||||
public static IEnumerable<string> AllFrameworks { get; } =
|
||||
NetFrameworks
|
||||
.Union(new string[] { AspNetCoreFramework, WindowsDesktopFramework });
|
||||
}
|
||||
}
|
|
@ -89,8 +89,10 @@ namespace Semmle.Extraction.CSharp.Populators
|
|||
SyntaxKind.ModuleKeyword => Entities.AttributeKind.Module,
|
||||
_ => throw new InternalError(node, "Unhandled global target")
|
||||
};
|
||||
foreach (var attribute in node.Attributes)
|
||||
var attributes = node.Attributes;
|
||||
for (var i = 0; i < attributes.Count; i++)
|
||||
{
|
||||
var attribute = attributes[i];
|
||||
if (attributeLookup.Value(attribute) is AttributeData attributeData)
|
||||
{
|
||||
var ae = Entities.Attribute.Create(Cx, attributeData, outputAssembly, kind);
|
||||
|
|
Разница между файлами не показана из-за своего большого размера
Загрузить разницу
|
@ -1,3 +1,7 @@
|
|||
## 1.7.3
|
||||
|
||||
No user-facing changes.
|
||||
|
||||
## 1.7.2
|
||||
|
||||
No user-facing changes.
|
||||
|
|
|
@ -0,0 +1,3 @@
|
|||
## 1.7.3
|
||||
|
||||
No user-facing changes.
|
|
@ -1,2 +1,2 @@
|
|||
---
|
||||
lastReleaseVersion: 1.7.2
|
||||
lastReleaseVersion: 1.7.3
|
||||
|
|
|
@ -1,5 +1,5 @@
|
|||
name: codeql/csharp-solorigate-all
|
||||
version: 1.7.3-dev
|
||||
version: 1.7.4-dev
|
||||
groups:
|
||||
- csharp
|
||||
- solorigate
|
||||
|
|
|
@ -1,3 +1,7 @@
|
|||
## 1.7.3
|
||||
|
||||
No user-facing changes.
|
||||
|
||||
## 1.7.2
|
||||
|
||||
No user-facing changes.
|
||||
|
|
|
@ -0,0 +1,3 @@
|
|||
## 1.7.3
|
||||
|
||||
No user-facing changes.
|
|
@ -1,2 +1,2 @@
|
|||
---
|
||||
lastReleaseVersion: 1.7.2
|
||||
lastReleaseVersion: 1.7.3
|
||||
|
|
|
@ -1,5 +1,5 @@
|
|||
name: codeql/csharp-solorigate-queries
|
||||
version: 1.7.3-dev
|
||||
version: 1.7.4-dev
|
||||
groups:
|
||||
- csharp
|
||||
- solorigate
|
||||
|
|
|
@ -2,10 +2,10 @@ import os
|
|||
from create_database_utils import *
|
||||
from diagnostics_test_utils import *
|
||||
|
||||
run_codeql_database_create(['dotnet pack'], db=None, lang="csharp")
|
||||
run_codeql_database_create(['dotnet pack -o nugetpackage'], db=None, lang="csharp")
|
||||
|
||||
## Check that the NuGet package is created.
|
||||
if not os.path.isfile("bin/Debug/dotnet_pack.1.0.0.nupkg"):
|
||||
if not os.path.isfile("nugetpackage/dotnet_pack.1.0.0.nupkg"):
|
||||
raise Exception("The NuGet package was not created.")
|
||||
|
||||
check_diagnostics()
|
||||
|
|
|
@ -7,6 +7,7 @@
|
|||
|
||||
<IsPackable>false</IsPackable>
|
||||
<OutputType>Exe</OutputType>
|
||||
<SelfContained>false</SelfContained>
|
||||
</PropertyGroup>
|
||||
|
||||
<ItemGroup>
|
||||
|
|
|
@ -1,3 +1,49 @@
|
|||
## 0.8.3
|
||||
|
||||
### Minor Analysis Improvements
|
||||
|
||||
* The predicate `UnboundGeneric::getName` now prints the number of type parameters as a `` `N`` suffix, instead of a `<,...,>` suffix. For example, the unbound generic type
|
||||
`System.Collections.Generic.IList<T>` is printed as ``IList`1`` instead of `IList<>`.
|
||||
* The predicates `hasQualifiedName`, `getQualifiedName`, and `getQualifiedNameWithTypes` have been deprecated, and are instead replaced by `hasFullyQualifiedName`, `getFullyQualifiedName`, and `getFullyQualifiedNameWithTypes`, respectively. The new predicates use the same format for unbound generic types as mentioned above.
|
||||
* These changes also affect models-as-data rows that refer to a field or a property belonging to a generic type. For example, instead of writing
|
||||
```yml
|
||||
extensions:
|
||||
- addsTo:
|
||||
pack: codeql/csharp-all
|
||||
extensible: summaryModel
|
||||
data:
|
||||
- ["System.Collections.Generic", "Dictionary<TKey,TValue>", False, "Add", "(System.Collections.Generic.KeyValuePair<TKey,TValue>)", "", "Argument[0].Property[System.Collections.Generic.KeyValuePair<,>.Key]", "Argument[this].Element.Property[System.Collections.Generic.KeyValuePair<,>.Key]", "value", "manual"]
|
||||
```
|
||||
one now writes
|
||||
```yml
|
||||
extensions:
|
||||
- addsTo:
|
||||
pack: codeql/csharp-all
|
||||
extensible: summaryModel
|
||||
data:
|
||||
- ["System.Collections.Generic", "Dictionary<TKey,TValue>", False, "Add", "(System.Collections.Generic.KeyValuePair<TKey,TValue>)", "", "Argument[0].Property[System.Collections.Generic.KeyValuePair`2.Key]", "Argument[this].Element.Property[System.Collections.Generic.KeyValuePair`2.Key]", "value", "manual"]
|
||||
```
|
||||
* The models-as-data format for types and methods with type parameters has been changed to include the names of the type parameters. For example, instead of writing
|
||||
```yml
|
||||
extensions:
|
||||
- addsTo:
|
||||
pack: codeql/csharp-all
|
||||
extensible: summaryModel
|
||||
data:
|
||||
- ["System.Collections.Generic", "IList<>", True, "Insert", "(System.Int32,T)", "", "Argument[1]", "Argument[this].Element", "value", "manual"]
|
||||
- ["System.Linq", "Enumerable", False, "Select<,>", "(System.Collections.Generic.IEnumerable<TSource>,System.Func<TSource,System.Int32,TResult>)", "", "Argument[0].Element", "Argument[1].Parameter[0]", "value", "manual"]
|
||||
```
|
||||
one now writes
|
||||
```yml
|
||||
extensions:
|
||||
- addsTo:
|
||||
pack: codeql/csharp-all
|
||||
extensible: summaryModel
|
||||
data:
|
||||
- ["System.Collections.Generic", "IList<T>", True, "Insert", "(System.Int32,T)", "", "Argument[1]", "Argument[this].Element", "value", "manual"]
|
||||
- ["System.Linq", "Enumerable", False, "Select<TSource,TResult>", "(System.Collections.Generic.IEnumerable<TSource>,System.Func<TSource,System.Int32,TResult>)", "", "Argument[0].Element", "Argument[1].Parameter[0]", "value", "manual"]
|
||||
```
|
||||
|
||||
## 0.8.2
|
||||
|
||||
No user-facing changes.
|
||||
|
|
|
@ -1,24 +0,0 @@
|
|||
---
|
||||
category: minorAnalysis
|
||||
---
|
||||
|
||||
* The models-as-data format for types and methods with type parameters has been changed to include the names of the type parameters. For example, instead of writing
|
||||
```yml
|
||||
extensions:
|
||||
- addsTo:
|
||||
pack: codeql/csharp-all
|
||||
extensible: summaryModel
|
||||
data:
|
||||
- ["System.Collections.Generic", "IList<>", True, "Insert", "(System.Int32,T)", "", "Argument[1]", "Argument[this].Element", "value", "manual"]
|
||||
- ["System.Linq", "Enumerable", False, "Select<,>", "(System.Collections.Generic.IEnumerable<TSource>,System.Func<TSource,System.Int32,TResult>)", "", "Argument[0].Element", "Argument[1].Parameter[0]", "value", "manual"]
|
||||
```
|
||||
one now writes
|
||||
```yml
|
||||
extensions:
|
||||
- addsTo:
|
||||
pack: codeql/csharp-all
|
||||
extensible: summaryModel
|
||||
data:
|
||||
- ["System.Collections.Generic", "IList<T>", True, "Insert", "(System.Int32,T)", "", "Argument[1]", "Argument[this].Element", "value", "manual"]
|
||||
- ["System.Linq", "Enumerable", False, "Select<TSource,TResult>", "(System.Collections.Generic.IEnumerable<TSource>,System.Func<TSource,System.Int32,TResult>)", "", "Argument[0].Element", "Argument[1].Parameter[0]", "value", "manual"]
|
||||
```
|
|
@ -1,6 +1,6 @@
|
|||
---
|
||||
category: minorAnalysis
|
||||
---
|
||||
## 0.8.3
|
||||
|
||||
### Minor Analysis Improvements
|
||||
|
||||
* The predicate `UnboundGeneric::getName` now prints the number of type parameters as a `` `N`` suffix, instead of a `<,...,>` suffix. For example, the unbound generic type
|
||||
`System.Collections.Generic.IList<T>` is printed as ``IList`1`` instead of `IList<>`.
|
||||
|
@ -23,3 +23,23 @@ extensions:
|
|||
data:
|
||||
- ["System.Collections.Generic", "Dictionary<TKey,TValue>", False, "Add", "(System.Collections.Generic.KeyValuePair<TKey,TValue>)", "", "Argument[0].Property[System.Collections.Generic.KeyValuePair`2.Key]", "Argument[this].Element.Property[System.Collections.Generic.KeyValuePair`2.Key]", "value", "manual"]
|
||||
```
|
||||
* The models-as-data format for types and methods with type parameters has been changed to include the names of the type parameters. For example, instead of writing
|
||||
```yml
|
||||
extensions:
|
||||
- addsTo:
|
||||
pack: codeql/csharp-all
|
||||
extensible: summaryModel
|
||||
data:
|
||||
- ["System.Collections.Generic", "IList<>", True, "Insert", "(System.Int32,T)", "", "Argument[1]", "Argument[this].Element", "value", "manual"]
|
||||
- ["System.Linq", "Enumerable", False, "Select<,>", "(System.Collections.Generic.IEnumerable<TSource>,System.Func<TSource,System.Int32,TResult>)", "", "Argument[0].Element", "Argument[1].Parameter[0]", "value", "manual"]
|
||||
```
|
||||
one now writes
|
||||
```yml
|
||||
extensions:
|
||||
- addsTo:
|
||||
pack: codeql/csharp-all
|
||||
extensible: summaryModel
|
||||
data:
|
||||
- ["System.Collections.Generic", "IList<T>", True, "Insert", "(System.Int32,T)", "", "Argument[1]", "Argument[this].Element", "value", "manual"]
|
||||
- ["System.Linq", "Enumerable", False, "Select<TSource,TResult>", "(System.Collections.Generic.IEnumerable<TSource>,System.Func<TSource,System.Int32,TResult>)", "", "Argument[0].Element", "Argument[1].Parameter[0]", "value", "manual"]
|
||||
```
|
|
@ -1,2 +1,2 @@
|
|||
---
|
||||
lastReleaseVersion: 0.8.2
|
||||
lastReleaseVersion: 0.8.3
|
||||
|
|
|
@ -1,5 +1,5 @@
|
|||
name: codeql/csharp-all
|
||||
version: 0.8.3-dev
|
||||
version: 0.8.4-dev
|
||||
groups: csharp
|
||||
dbscheme: semmlecode.csharp.dbscheme
|
||||
extractor: csharp
|
||||
|
|
|
@ -1,7 +1,7 @@
|
|||
private import cil
|
||||
private import codeql.ssa.Ssa as SsaImplCommon
|
||||
|
||||
private module SsaInput implements SsaImplCommon::InputSig {
|
||||
private module SsaInput implements SsaImplCommon::InputSig<CIL::Location> {
|
||||
class BasicBlock = CIL::BasicBlock;
|
||||
|
||||
BasicBlock getImmediateBasicBlockDominator(BasicBlock bb) { result = bb.getImmediateDominator() }
|
||||
|
@ -29,7 +29,7 @@ private module SsaInput implements SsaImplCommon::InputSig {
|
|||
}
|
||||
}
|
||||
|
||||
import SsaImplCommon::Make<SsaInput>
|
||||
import SsaImplCommon::Make<CIL::Location, SsaInput>
|
||||
|
||||
cached
|
||||
private module Cached {
|
||||
|
|
|
@ -36,7 +36,7 @@ module PreSsa {
|
|||
scopeFirst(c, bb)
|
||||
}
|
||||
|
||||
module SsaInput implements SsaImplCommon::InputSig {
|
||||
module SsaInput implements SsaImplCommon::InputSig<Location> {
|
||||
class BasicBlock = PreBasicBlocks::PreBasicBlock;
|
||||
|
||||
BasicBlock getImmediateBasicBlockDominator(BasicBlock bb) { result.immediatelyDominates(bb) }
|
||||
|
@ -137,7 +137,7 @@ module PreSsa {
|
|||
}
|
||||
}
|
||||
|
||||
private module SsaImpl = SsaImplCommon::Make<SsaInput>;
|
||||
private module SsaImpl = SsaImplCommon::Make<Location, SsaInput>;
|
||||
|
||||
class Definition extends SsaImpl::Definition {
|
||||
final AssignableRead getARead() {
|
||||
|
|
|
@ -24,7 +24,7 @@ module BaseSsa {
|
|||
)
|
||||
}
|
||||
|
||||
private module SsaInput implements SsaImplCommon::InputSig {
|
||||
private module SsaInput implements SsaImplCommon::InputSig<Location> {
|
||||
class BasicBlock = ControlFlow::BasicBlock;
|
||||
|
||||
BasicBlock getImmediateBasicBlockDominator(BasicBlock bb) {
|
||||
|
@ -60,7 +60,7 @@ module BaseSsa {
|
|||
}
|
||||
}
|
||||
|
||||
private module SsaImpl = SsaImplCommon::Make<SsaInput>;
|
||||
private module SsaImpl = SsaImplCommon::Make<Location, SsaInput>;
|
||||
|
||||
class Definition extends SsaImpl::Definition {
|
||||
final AssignableRead getARead() {
|
||||
|
|
|
@ -6,7 +6,7 @@ import csharp
|
|||
private import codeql.ssa.Ssa as SsaImplCommon
|
||||
private import AssignableDefinitions
|
||||
|
||||
private module SsaInput implements SsaImplCommon::InputSig {
|
||||
private module SsaInput implements SsaImplCommon::InputSig<Location> {
|
||||
class BasicBlock = ControlFlow::BasicBlock;
|
||||
|
||||
BasicBlock getImmediateBasicBlockDominator(BasicBlock bb) { result = bb.getImmediateDominator() }
|
||||
|
@ -49,7 +49,7 @@ private module SsaInput implements SsaImplCommon::InputSig {
|
|||
}
|
||||
}
|
||||
|
||||
private import SsaImplCommon::Make<SsaInput> as Impl
|
||||
private import SsaImplCommon::Make<Location, SsaInput> as Impl
|
||||
|
||||
class Definition = Impl::Definition;
|
||||
|
||||
|
|
|
@ -27,8 +27,9 @@ private class ExternalModelSink extends ExternalLocationSink {
|
|||
*/
|
||||
class LogMessageSink extends ExternalLocationSink {
|
||||
LogMessageSink() {
|
||||
this.getExpr() = any(LoggerType i).getAMethod().getACall().getAnArgument()
|
||||
or
|
||||
this.getExpr() = any(LoggerType i).getAMethod().getACall().getAnArgument() or
|
||||
this.getExpr() =
|
||||
any(MethodCall call | call.getQualifier().getType() instanceof LoggerType).getAnArgument() or
|
||||
this.getExpr() =
|
||||
any(ExtensionMethodCall call |
|
||||
call.getTarget().(ExtensionMethod).getExtendedType() instanceof LoggerType
|
||||
|
|
|
@ -1,3 +1,9 @@
|
|||
## 0.8.3
|
||||
|
||||
### Minor Analysis Improvements
|
||||
|
||||
* CIL extraction is now disabled by default. It is still possible to turn on CIL extraction by setting the `cil` extractor option to `true` or by setting the environment variable `$CODEQL_EXTRACTOR_CSHARP_OPTION_CIL` to `true`. This is the first step towards sun-setting the CIL extractor entirely.
|
||||
|
||||
## 0.8.2
|
||||
|
||||
No user-facing changes.
|
||||
|
|
|
@ -29,11 +29,6 @@ number generator. <code>Random</code> is not cryptographically secure, and shoul
|
|||
security contexts. For contexts which are not security sensitive, <code>Random</code> may be
|
||||
preferable as it has a more convenient interface, and is likely to be faster.
|
||||
</p>
|
||||
<p>
|
||||
For the specific use-case of generating passwords, consider
|
||||
<code>System.Web.Security.Membership.GeneratePassword</code>, which provides a cryptographically
|
||||
secure method of generating random passwords.
|
||||
</p>
|
||||
|
||||
</recommendation>
|
||||
|
||||
|
@ -54,10 +49,7 @@ purpose. In this case, it is much harder to predict the generated integers.
|
|||
</p>
|
||||
<p>
|
||||
In the final example, the password is generated using the <code>Membership.GeneratePassword</code>
|
||||
library method, which uses a cryptographically secure random number generator to generate a random
|
||||
series of characters. This method should be preferred when generating passwords, if possible, as it
|
||||
avoids potential pitfalls when converting the output of a random number generator (usually an int or
|
||||
a byte) to a series of permitted characters.
|
||||
library method, which generates a password with a bias, therefore should be avoided.
|
||||
</p>
|
||||
<sample src="InsecureRandomness.cs" />
|
||||
|
||||
|
|
|
@ -1,4 +1,5 @@
|
|||
---
|
||||
category: minorAnalysis
|
||||
---
|
||||
* CIL extraction is now disabled by default. It is still possible to turn on CIL extraction by setting the `cil` extractor option to `true` or by setting the environment variable `$CODEQL_EXTRACTOR_CSHARP_OPTION_CIL` to `true`. This is the first step towards sun-setting the CIL extractor entirely.
|
||||
## 0.8.3
|
||||
|
||||
### Minor Analysis Improvements
|
||||
|
||||
* CIL extraction is now disabled by default. It is still possible to turn on CIL extraction by setting the `cil` extractor option to `true` or by setting the environment variable `$CODEQL_EXTRACTOR_CSHARP_OPTION_CIL` to `true`. This is the first step towards sun-setting the CIL extractor entirely.
|
|
@ -1,2 +1,2 @@
|
|||
---
|
||||
lastReleaseVersion: 0.8.2
|
||||
lastReleaseVersion: 0.8.3
|
||||
|
|
|
@ -1,5 +1,5 @@
|
|||
name: codeql/csharp-queries
|
||||
version: 0.8.3-dev
|
||||
version: 0.8.4-dev
|
||||
groups:
|
||||
- csharp
|
||||
- queries
|
||||
|
|
|
@ -0,0 +1,2 @@
|
|||
| standalone.cs:3:12:3:29 | [assembly: Attribute1(...)] |
|
||||
| standalone.cs:9:2:9:11 | [Attribute1(...)] |
|
|
@ -0,0 +1,5 @@
|
|||
import csharp
|
||||
|
||||
from Attribute a
|
||||
where a.getType().getName() = "Attribute1Attribute"
|
||||
select a
|
|
@ -0,0 +1 @@
|
|||
semmle-extractor-options: --standalone
|
|
@ -0,0 +1,12 @@
|
|||
using System;
|
||||
|
||||
[assembly: global::Attribute1]
|
||||
|
||||
class Attribute1Attribute : Attribute
|
||||
{
|
||||
}
|
||||
|
||||
[Attribute1]
|
||||
class A
|
||||
{
|
||||
}
|
|
@ -0,0 +1,8 @@
|
|||
#select
|
||||
| standalone.cs:20:20:20:20 | access to parameter s | standalone.cs:20:20:20:20 | access to parameter s |
|
||||
| standalone.cs:25:28:25:32 | "abc" | standalone.cs:25:28:25:32 | "abc" |
|
||||
compilationErrors
|
||||
| standalone.cs:16:12:16:18 | CS0104: 'ILogger' is an ambiguous reference between 'A.ILogger' and 'B.ILogger' |
|
||||
methodCalls
|
||||
| standalone.cs:20:9:20:21 | call to method |
|
||||
| standalone.cs:25:9:25:33 | call to method |
|
Некоторые файлы не были показаны из-за слишком большого количества измененных файлов Показать больше
Загрузка…
Ссылка в новой задаче