mirror of
https://github.com/github/codeql.git
synced 2026-04-25 16:55:19 +02:00
Merge branch 'main' into reduce-duplication-from-operators
This commit is contained in:
@@ -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"
|
||||
|
||||
2233
cpp/downgrades/0a9eb01d3650642e013eb86be45d952289537f91/old.dbscheme
Normal file
2233
cpp/downgrades/0a9eb01d3650642e013eb86be45d952289537f91/old.dbscheme
Normal file
File diff suppressed because it is too large
Load Diff
File diff suppressed because it is too large
Load Diff
@@ -0,0 +1,3 @@
|
||||
description: Expose whether a function was prototyped or not
|
||||
compatibility: backwards
|
||||
function_prototyped.rel: delete
|
||||
4
cpp/ql/lib/change-notes/2023-11-28-prototyped.md
Normal file
4
cpp/ql/lib/change-notes/2023-11-28-prototyped.md
Normal file
@@ -0,0 +1,4 @@
|
||||
---
|
||||
category: feature
|
||||
---
|
||||
* Added an `isPrototyped` predicate to `Function` that holds when the function has a prototype.
|
||||
@@ -112,6 +112,16 @@ class Function extends Declaration, ControlFlowNode, AccessHolder, @function {
|
||||
*/
|
||||
predicate isDeleted() { function_deleted(underlyingElement(this)) }
|
||||
|
||||
/**
|
||||
* Holds if this function has a prototyped interface.
|
||||
*
|
||||
* Functions generally have a prototyped interface, unless they are
|
||||
* K&R-style functions either without any forward function declaration,
|
||||
* or with all the forward declarations omitting the parameters of the
|
||||
* function.
|
||||
*/
|
||||
predicate isPrototyped() { function_prototyped(underlyingElement(this)) }
|
||||
|
||||
/**
|
||||
* Holds if this function is explicitly defaulted with the `= default`
|
||||
* specifier.
|
||||
|
||||
@@ -30,11 +30,6 @@ class GuardCondition extends Expr {
|
||||
or
|
||||
// no binary operators in the IR
|
||||
this.(BinaryLogicalOperation).getAnOperand() instanceof GuardCondition
|
||||
or
|
||||
// the IR short-circuits if(!x)
|
||||
// don't produce a guard condition for `y = !x` and other non-short-circuited cases
|
||||
not exists(Instruction inst | this.getFullyConverted() = inst.getAst()) and
|
||||
exists(IRGuardCondition ir | this.(NotExpr).getOperand() = ir.getAst())
|
||||
}
|
||||
|
||||
/**
|
||||
@@ -140,39 +135,6 @@ private class GuardConditionFromBinaryLogicalOperator extends GuardCondition {
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* A `!` operator in the AST that guards one or more basic blocks, and does not have a corresponding
|
||||
* IR instruction.
|
||||
*/
|
||||
private class GuardConditionFromShortCircuitNot extends GuardCondition, NotExpr {
|
||||
GuardConditionFromShortCircuitNot() {
|
||||
not exists(Instruction inst | this.getFullyConverted() = inst.getAst()) and
|
||||
exists(IRGuardCondition ir | this.getOperand() = ir.getAst())
|
||||
}
|
||||
|
||||
override predicate controls(BasicBlock controlled, boolean testIsTrue) {
|
||||
this.getOperand().(GuardCondition).controls(controlled, testIsTrue.booleanNot())
|
||||
}
|
||||
|
||||
override predicate comparesLt(Expr left, Expr right, int k, boolean isLessThan, boolean testIsTrue) {
|
||||
this.getOperand()
|
||||
.(GuardCondition)
|
||||
.comparesLt(left, right, k, isLessThan, testIsTrue.booleanNot())
|
||||
}
|
||||
|
||||
override predicate ensuresLt(Expr left, Expr right, int k, BasicBlock block, boolean isLessThan) {
|
||||
this.getOperand().(GuardCondition).ensuresLt(left, right, k, block, isLessThan.booleanNot())
|
||||
}
|
||||
|
||||
override predicate comparesEq(Expr left, Expr right, int k, boolean areEqual, boolean testIsTrue) {
|
||||
this.getOperand().(GuardCondition).comparesEq(left, right, k, areEqual, testIsTrue.booleanNot())
|
||||
}
|
||||
|
||||
override predicate ensuresEq(Expr left, Expr right, int k, BasicBlock block, boolean areEqual) {
|
||||
this.getOperand().(GuardCondition).ensuresEq(left, right, k, block, areEqual.booleanNot())
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* A Boolean condition in the AST that guards one or more basic blocks and has a corresponding IR
|
||||
* instruction.
|
||||
|
||||
@@ -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) }
|
||||
}
|
||||
|
||||
|
||||
@@ -72,6 +72,16 @@ private predicate operandToInstructionTaintStep(Operand opFrom, Instruction inst
|
||||
or
|
||||
instrTo.(FieldAddressInstruction).getField().getDeclaringType() instanceof Union
|
||||
)
|
||||
or
|
||||
// Taint from int to boolean casts. This ensures that we have flow to `!x` in:
|
||||
// ```cpp
|
||||
// x = integer_source();
|
||||
// if(!x) { ... }
|
||||
// ```
|
||||
exists(Operand zero |
|
||||
zero.getDef().(ConstantValueInstruction).getValue() = "0" and
|
||||
instrTo.(CompareNEInstruction).hasOperands(opFrom, zero)
|
||||
)
|
||||
}
|
||||
|
||||
/**
|
||||
|
||||
@@ -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() {
|
||||
|
||||
@@ -12,6 +12,9 @@ int getConstantValue(Instruction instr) {
|
||||
or
|
||||
result = getConstantValue(instr.(CopyInstruction).getSourceValue())
|
||||
or
|
||||
getConstantValue(instr.(LogicalNotInstruction).getUnary()) != 0 and
|
||||
result = 0
|
||||
or
|
||||
exists(PhiInstruction phi |
|
||||
phi = instr and
|
||||
result = unique(Operand op | op = phi.getAnInputOperand() | getConstantValue(op.getDef()))
|
||||
@@ -26,28 +29,25 @@ private predicate binaryInstructionOperands(BinaryInstruction instr, int left, i
|
||||
|
||||
pragma[noinline]
|
||||
private int getBinaryInstructionValue(BinaryInstruction instr) {
|
||||
exists(int left, int right |
|
||||
binaryInstructionOperands(instr, left, right) and
|
||||
(
|
||||
instr instanceof AddInstruction and result = add(left, right)
|
||||
or
|
||||
instr instanceof SubInstruction and result = sub(left, right)
|
||||
or
|
||||
instr instanceof MulInstruction and result = mul(left, right)
|
||||
or
|
||||
instr instanceof DivInstruction and result = div(left, right)
|
||||
or
|
||||
instr instanceof CompareEQInstruction and result = compareEQ(left, right)
|
||||
or
|
||||
instr instanceof CompareNEInstruction and result = compareNE(left, right)
|
||||
or
|
||||
instr instanceof CompareLTInstruction and result = compareLT(left, right)
|
||||
or
|
||||
instr instanceof CompareGTInstruction and result = compareGT(left, right)
|
||||
or
|
||||
instr instanceof CompareLEInstruction and result = compareLE(left, right)
|
||||
or
|
||||
instr instanceof CompareGEInstruction and result = compareGE(left, right)
|
||||
)
|
||||
exists(int left, int right | binaryInstructionOperands(instr, left, right) |
|
||||
instr instanceof AddInstruction and result = add(left, right)
|
||||
or
|
||||
instr instanceof SubInstruction and result = sub(left, right)
|
||||
or
|
||||
instr instanceof MulInstruction and result = mul(left, right)
|
||||
or
|
||||
instr instanceof DivInstruction and result = div(left, right)
|
||||
or
|
||||
instr instanceof CompareEQInstruction and result = compareEQ(left, right)
|
||||
or
|
||||
instr instanceof CompareNEInstruction and result = compareNE(left, right)
|
||||
or
|
||||
instr instanceof CompareLTInstruction and result = compareLT(left, right)
|
||||
or
|
||||
instr instanceof CompareGTInstruction and result = compareGT(left, right)
|
||||
or
|
||||
instr instanceof CompareLEInstruction and result = compareLE(left, right)
|
||||
or
|
||||
instr instanceof CompareGEInstruction and result = compareGE(left, right)
|
||||
)
|
||||
}
|
||||
|
||||
@@ -12,6 +12,9 @@ int getConstantValue(Instruction instr) {
|
||||
or
|
||||
result = getConstantValue(instr.(CopyInstruction).getSourceValue())
|
||||
or
|
||||
getConstantValue(instr.(LogicalNotInstruction).getUnary()) != 0 and
|
||||
result = 0
|
||||
or
|
||||
exists(PhiInstruction phi |
|
||||
phi = instr and
|
||||
result = unique(Operand op | op = phi.getAnInputOperand() | getConstantValue(op.getDef()))
|
||||
@@ -26,28 +29,25 @@ private predicate binaryInstructionOperands(BinaryInstruction instr, int left, i
|
||||
|
||||
pragma[noinline]
|
||||
private int getBinaryInstructionValue(BinaryInstruction instr) {
|
||||
exists(int left, int right |
|
||||
binaryInstructionOperands(instr, left, right) and
|
||||
(
|
||||
instr instanceof AddInstruction and result = add(left, right)
|
||||
or
|
||||
instr instanceof SubInstruction and result = sub(left, right)
|
||||
or
|
||||
instr instanceof MulInstruction and result = mul(left, right)
|
||||
or
|
||||
instr instanceof DivInstruction and result = div(left, right)
|
||||
or
|
||||
instr instanceof CompareEQInstruction and result = compareEQ(left, right)
|
||||
or
|
||||
instr instanceof CompareNEInstruction and result = compareNE(left, right)
|
||||
or
|
||||
instr instanceof CompareLTInstruction and result = compareLT(left, right)
|
||||
or
|
||||
instr instanceof CompareGTInstruction and result = compareGT(left, right)
|
||||
or
|
||||
instr instanceof CompareLEInstruction and result = compareLE(left, right)
|
||||
or
|
||||
instr instanceof CompareGEInstruction and result = compareGE(left, right)
|
||||
)
|
||||
exists(int left, int right | binaryInstructionOperands(instr, left, right) |
|
||||
instr instanceof AddInstruction and result = add(left, right)
|
||||
or
|
||||
instr instanceof SubInstruction and result = sub(left, right)
|
||||
or
|
||||
instr instanceof MulInstruction and result = mul(left, right)
|
||||
or
|
||||
instr instanceof DivInstruction and result = div(left, right)
|
||||
or
|
||||
instr instanceof CompareEQInstruction and result = compareEQ(left, right)
|
||||
or
|
||||
instr instanceof CompareNEInstruction and result = compareNE(left, right)
|
||||
or
|
||||
instr instanceof CompareLTInstruction and result = compareLT(left, right)
|
||||
or
|
||||
instr instanceof CompareGTInstruction and result = compareGT(left, right)
|
||||
or
|
||||
instr instanceof CompareLEInstruction and result = compareLE(left, right)
|
||||
or
|
||||
instr instanceof CompareGEInstruction and result = compareGE(left, right)
|
||||
)
|
||||
}
|
||||
|
||||
@@ -77,24 +77,6 @@ class TranslatedParenthesisCondition extends TranslatedFlexibleCondition {
|
||||
}
|
||||
}
|
||||
|
||||
class TranslatedNotCondition extends TranslatedFlexibleCondition {
|
||||
override NotExpr expr;
|
||||
|
||||
override Instruction getChildTrueSuccessor(TranslatedCondition child) {
|
||||
child = this.getOperand() and
|
||||
result = this.getConditionContext().getChildFalseSuccessor(this)
|
||||
}
|
||||
|
||||
override Instruction getChildFalseSuccessor(TranslatedCondition child) {
|
||||
child = this.getOperand() and
|
||||
result = this.getConditionContext().getChildTrueSuccessor(this)
|
||||
}
|
||||
|
||||
override TranslatedCondition getOperand() {
|
||||
result = getTranslatedCondition(expr.getOperand().getFullyConverted())
|
||||
}
|
||||
}
|
||||
|
||||
abstract class TranslatedNativeCondition extends TranslatedCondition, TTranslatedNativeCondition {
|
||||
TranslatedNativeCondition() { this = TTranslatedNativeCondition(expr) }
|
||||
|
||||
|
||||
@@ -190,10 +190,7 @@ private predicate isNativeCondition(Expr expr) {
|
||||
* depending on context.
|
||||
*/
|
||||
private predicate isFlexibleCondition(Expr expr) {
|
||||
(
|
||||
expr instanceof ParenthesisExpr or
|
||||
expr instanceof NotExpr
|
||||
) and
|
||||
expr instanceof ParenthesisExpr and
|
||||
usedAsCondition(expr) and
|
||||
not isIRConstant(expr)
|
||||
}
|
||||
@@ -218,11 +215,6 @@ private predicate usedAsCondition(Expr expr) {
|
||||
condExpr.getCondition().getFullyConverted() = expr and not condExpr.isTwoOperand()
|
||||
)
|
||||
or
|
||||
exists(NotExpr notExpr |
|
||||
notExpr.getOperand().getFullyConverted() = expr and
|
||||
usedAsCondition(notExpr)
|
||||
)
|
||||
or
|
||||
exists(ParenthesisExpr paren |
|
||||
paren.getExpr() = expr and
|
||||
usedAsCondition(paren)
|
||||
|
||||
@@ -12,6 +12,9 @@ int getConstantValue(Instruction instr) {
|
||||
or
|
||||
result = getConstantValue(instr.(CopyInstruction).getSourceValue())
|
||||
or
|
||||
getConstantValue(instr.(LogicalNotInstruction).getUnary()) != 0 and
|
||||
result = 0
|
||||
or
|
||||
exists(PhiInstruction phi |
|
||||
phi = instr and
|
||||
result = unique(Operand op | op = phi.getAnInputOperand() | getConstantValue(op.getDef()))
|
||||
@@ -26,28 +29,25 @@ private predicate binaryInstructionOperands(BinaryInstruction instr, int left, i
|
||||
|
||||
pragma[noinline]
|
||||
private int getBinaryInstructionValue(BinaryInstruction instr) {
|
||||
exists(int left, int right |
|
||||
binaryInstructionOperands(instr, left, right) and
|
||||
(
|
||||
instr instanceof AddInstruction and result = add(left, right)
|
||||
or
|
||||
instr instanceof SubInstruction and result = sub(left, right)
|
||||
or
|
||||
instr instanceof MulInstruction and result = mul(left, right)
|
||||
or
|
||||
instr instanceof DivInstruction and result = div(left, right)
|
||||
or
|
||||
instr instanceof CompareEQInstruction and result = compareEQ(left, right)
|
||||
or
|
||||
instr instanceof CompareNEInstruction and result = compareNE(left, right)
|
||||
or
|
||||
instr instanceof CompareLTInstruction and result = compareLT(left, right)
|
||||
or
|
||||
instr instanceof CompareGTInstruction and result = compareGT(left, right)
|
||||
or
|
||||
instr instanceof CompareLEInstruction and result = compareLE(left, right)
|
||||
or
|
||||
instr instanceof CompareGEInstruction and result = compareGE(left, right)
|
||||
)
|
||||
exists(int left, int right | binaryInstructionOperands(instr, left, right) |
|
||||
instr instanceof AddInstruction and result = add(left, right)
|
||||
or
|
||||
instr instanceof SubInstruction and result = sub(left, right)
|
||||
or
|
||||
instr instanceof MulInstruction and result = mul(left, right)
|
||||
or
|
||||
instr instanceof DivInstruction and result = div(left, right)
|
||||
or
|
||||
instr instanceof CompareEQInstruction and result = compareEQ(left, right)
|
||||
or
|
||||
instr instanceof CompareNEInstruction and result = compareNE(left, right)
|
||||
or
|
||||
instr instanceof CompareLTInstruction and result = compareLT(left, right)
|
||||
or
|
||||
instr instanceof CompareGTInstruction and result = compareGT(left, right)
|
||||
or
|
||||
instr instanceof CompareLEInstruction and result = compareLE(left, right)
|
||||
or
|
||||
instr instanceof CompareGEInstruction and result = compareGE(left, right)
|
||||
)
|
||||
}
|
||||
|
||||
@@ -16,10 +16,7 @@ class Getenv extends LocalFlowSourceFunction {
|
||||
}
|
||||
|
||||
override predicate hasLocalFlowSource(FunctionOutput output, string description) {
|
||||
(
|
||||
output.isReturnValueDeref() or
|
||||
output.isReturnValue()
|
||||
) and
|
||||
output.isReturnValueDeref() and
|
||||
description = "an environment variable"
|
||||
}
|
||||
}
|
||||
|
||||
@@ -51,7 +51,6 @@ private class FgetsFunction extends DataFlowFunction, TaintFunction, ArrayFuncti
|
||||
override predicate hasRemoteFlowSource(FunctionOutput output, string description) {
|
||||
(
|
||||
output.isParameterDeref(0) or
|
||||
output.isReturnValue() or
|
||||
output.isReturnValueDeref()
|
||||
) and
|
||||
description = "string read by " + this.getName()
|
||||
@@ -102,7 +101,6 @@ private class GetsFunction extends DataFlowFunction, ArrayFunction, AliasFunctio
|
||||
override predicate hasLocalFlowSource(FunctionOutput output, string description) {
|
||||
(
|
||||
output.isParameterDeref(0) or
|
||||
output.isReturnValue() or
|
||||
output.isReturnValueDeref()
|
||||
) and
|
||||
description = "string read by " + this.getName()
|
||||
|
||||
@@ -123,7 +123,7 @@ private class StdSequenceContainerData extends TaintFunction {
|
||||
/**
|
||||
* The standard container functions `push_back` and `push_front`.
|
||||
*/
|
||||
private class StdSequenceContainerPush extends TaintFunction {
|
||||
class StdSequenceContainerPush extends MemberFunction {
|
||||
StdSequenceContainerPush() {
|
||||
this.getClassAndName("push_back") instanceof Vector or
|
||||
this.getClassAndName(["push_back", "push_front"]) instanceof Deque or
|
||||
@@ -131,6 +131,17 @@ private class StdSequenceContainerPush extends TaintFunction {
|
||||
this.getClassAndName(["push_back", "push_front"]) instanceof List
|
||||
}
|
||||
|
||||
/**
|
||||
* Gets the index of a parameter to this function that is a reference to the
|
||||
* value type of the container.
|
||||
*/
|
||||
int getAValueTypeParameterIndex() {
|
||||
this.getParameter(result).getUnspecifiedType().(ReferenceType).getBaseType() =
|
||||
this.getDeclaringType().getTemplateArgument(0).(Type).getUnspecifiedType() // i.e. the `T` of this `std::vector<T>`
|
||||
}
|
||||
}
|
||||
|
||||
private class StdSequenceContainerPushModel extends StdSequenceContainerPush, TaintFunction {
|
||||
override predicate hasTaintFlow(FunctionInput input, FunctionOutput output) {
|
||||
// flow from parameter to qualifier
|
||||
input.isParameterDeref(0) and
|
||||
@@ -160,7 +171,7 @@ private class StdSequenceContainerFrontBack extends TaintFunction {
|
||||
/**
|
||||
* The standard container functions `insert` and `insert_after`.
|
||||
*/
|
||||
private class StdSequenceContainerInsert extends TaintFunction {
|
||||
class StdSequenceContainerInsert extends MemberFunction {
|
||||
StdSequenceContainerInsert() {
|
||||
this.getClassAndName("insert") instanceof Deque or
|
||||
this.getClassAndName("insert") instanceof List or
|
||||
@@ -181,7 +192,9 @@ private class StdSequenceContainerInsert extends TaintFunction {
|
||||
* Gets the index of a parameter to this function that is an iterator.
|
||||
*/
|
||||
int getAnIteratorParameterIndex() { this.getParameter(result).getType() instanceof Iterator }
|
||||
}
|
||||
|
||||
private class StdSequenceContainerInsertModel extends StdSequenceContainerInsert, TaintFunction {
|
||||
override predicate hasTaintFlow(FunctionInput input, FunctionOutput output) {
|
||||
// flow from parameter to container itself (qualifier) and return value
|
||||
(
|
||||
@@ -253,11 +266,28 @@ private class StdSequenceContainerAt extends TaintFunction {
|
||||
}
|
||||
|
||||
/**
|
||||
* The standard vector `emplace` function.
|
||||
* The standard `emplace` function.
|
||||
*/
|
||||
class StdVectorEmplace extends TaintFunction {
|
||||
StdVectorEmplace() { this.getClassAndName("emplace") instanceof Vector }
|
||||
class StdSequenceEmplace extends MemberFunction {
|
||||
StdSequenceEmplace() {
|
||||
this.getClassAndName("emplace") instanceof Vector
|
||||
or
|
||||
this.getClassAndName("emplace") instanceof List
|
||||
or
|
||||
this.getClassAndName("emplace") instanceof Deque
|
||||
}
|
||||
|
||||
/**
|
||||
* Gets the index of a parameter to this function that is a reference to the
|
||||
* value type of the container.
|
||||
*/
|
||||
int getAValueTypeParameterIndex() {
|
||||
this.getParameter(result).getUnspecifiedType().(ReferenceType).getBaseType() =
|
||||
this.getDeclaringType().getTemplateArgument(0).(Type).getUnspecifiedType() // i.e. the `T` of this `std::vector<T>`
|
||||
}
|
||||
}
|
||||
|
||||
private class StdSequenceEmplaceModel extends StdSequenceEmplace, TaintFunction {
|
||||
override predicate hasTaintFlow(FunctionInput input, FunctionOutput output) {
|
||||
// flow from any parameter except the position iterator to qualifier and return value
|
||||
// (here we assume taint flow from any constructor parameter to the constructed object)
|
||||
@@ -269,12 +299,36 @@ class StdVectorEmplace extends TaintFunction {
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* The standard vector `emplace` function.
|
||||
*/
|
||||
class StdVectorEmplace extends StdSequenceEmplace {
|
||||
StdVectorEmplace() { this.getDeclaringType() instanceof Vector }
|
||||
}
|
||||
|
||||
/**
|
||||
* The standard vector `emplace_back` function.
|
||||
*/
|
||||
class StdVectorEmplaceBack extends TaintFunction {
|
||||
StdVectorEmplaceBack() { this.getClassAndName("emplace_back") instanceof Vector }
|
||||
class StdSequenceEmplaceBack extends MemberFunction {
|
||||
StdSequenceEmplaceBack() {
|
||||
this.getClassAndName("emplace_back") instanceof Vector
|
||||
or
|
||||
this.getClassAndName("emplace_back") instanceof List
|
||||
or
|
||||
this.getClassAndName("emplace_back") instanceof Deque
|
||||
}
|
||||
|
||||
/**
|
||||
* Gets the index of a parameter to this function that is a reference to the
|
||||
* value type of the container.
|
||||
*/
|
||||
int getAValueTypeParameterIndex() {
|
||||
this.getParameter(result).getUnspecifiedType().(ReferenceType).getBaseType() =
|
||||
this.getDeclaringType().getTemplateArgument(0).(Type).getUnspecifiedType() // i.e. the `T` of this `std::vector<T>`
|
||||
}
|
||||
}
|
||||
|
||||
private class StdSequenceEmplaceBackModel extends StdSequenceEmplaceBack, TaintFunction {
|
||||
override predicate hasTaintFlow(FunctionInput input, FunctionOutput output) {
|
||||
// flow from any parameter to qualifier
|
||||
// (here we assume taint flow from any constructor parameter to the constructed object)
|
||||
@@ -282,3 +336,10 @@ class StdVectorEmplaceBack extends TaintFunction {
|
||||
output.isQualifierObject()
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* The standard vector `emplace_back` function.
|
||||
*/
|
||||
class StdVectorEmplaceBack extends StdSequenceEmplaceBack {
|
||||
StdVectorEmplaceBack() { this.getDeclaringType() instanceof Vector }
|
||||
}
|
||||
|
||||
@@ -99,9 +99,11 @@ private class StdStringConstructor extends Constructor, StdStringTaintFunction {
|
||||
/**
|
||||
* The `std::string` function `c_str`.
|
||||
*/
|
||||
private class StdStringCStr extends StdStringTaintFunction {
|
||||
class StdStringCStr extends MemberFunction {
|
||||
StdStringCStr() { this.getClassAndName("c_str") instanceof StdBasicString }
|
||||
}
|
||||
|
||||
private class StdStringCStrModel extends StdStringCStr, StdStringTaintFunction {
|
||||
override predicate hasTaintFlow(FunctionInput input, FunctionOutput output) {
|
||||
// flow from string itself (qualifier) to return value
|
||||
input.isQualifierObject() and
|
||||
@@ -112,9 +114,11 @@ private class StdStringCStr extends StdStringTaintFunction {
|
||||
/**
|
||||
* The `std::string` function `data`.
|
||||
*/
|
||||
private class StdStringData extends StdStringTaintFunction {
|
||||
class StdStringData extends MemberFunction {
|
||||
StdStringData() { this.getClassAndName("data") instanceof StdBasicString }
|
||||
}
|
||||
|
||||
private class StdStringDataModel extends StdStringData, StdStringTaintFunction {
|
||||
override predicate hasTaintFlow(FunctionInput input, FunctionOutput output) {
|
||||
// flow from string itself (qualifier) to return value
|
||||
input.isQualifierObject() and
|
||||
|
||||
@@ -405,6 +405,8 @@ function_deleted(unique int id: @function ref);
|
||||
|
||||
function_defaulted(unique int id: @function ref);
|
||||
|
||||
function_prototyped(unique int id: @function ref)
|
||||
|
||||
member_function_this_type(
|
||||
unique int id: @function ref,
|
||||
int this_type: @type ref
|
||||
|
||||
File diff suppressed because it is too large
Load Diff
File diff suppressed because it is too large
Load Diff
File diff suppressed because it is too large
Load Diff
@@ -0,0 +1,2 @@
|
||||
description: Expose whether a function was prototyped or not
|
||||
compatibility: partial
|
||||
@@ -27,10 +27,7 @@ predicate isProcessOperationExplanation(DataFlow::Node arg, string processOperat
|
||||
)
|
||||
}
|
||||
|
||||
predicate isSource(FlowSource source, string sourceType) {
|
||||
not source instanceof DataFlow::ExprNode and
|
||||
sourceType = source.getSourceType()
|
||||
}
|
||||
predicate isSource(FlowSource source, string sourceType) { sourceType = source.getSourceType() }
|
||||
|
||||
module Config implements DataFlow::ConfigSig {
|
||||
predicate isSource(DataFlow::Node node) { isSource(node, _) }
|
||||
|
||||
@@ -16,22 +16,47 @@
|
||||
import cpp
|
||||
import semmle.code.cpp.security.Security
|
||||
import semmle.code.cpp.security.FunctionWithWrappers
|
||||
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
|
||||
|
||||
class Configuration extends TaintTrackingConfiguration {
|
||||
override predicate isSink(Element tainted) {
|
||||
exists(PrintfLikeFunction printf | printf.outermostWrapperFunctionCall(tainted, _))
|
||||
predicate isSource(FlowSource source, string sourceType) { sourceType = source.getSourceType() }
|
||||
|
||||
module Config implements DataFlow::ConfigSig {
|
||||
predicate isSource(DataFlow::Node node) { isSource(node, _) }
|
||||
|
||||
predicate isSink(DataFlow::Node node) {
|
||||
exists(PrintfLikeFunction printf |
|
||||
printf.outermostWrapperFunctionCall([node.asExpr(), node.asIndirectExpr()], _)
|
||||
)
|
||||
}
|
||||
|
||||
private predicate isArithmeticNonCharType(ArithmeticType type) {
|
||||
not type instanceof CharType and
|
||||
not type instanceof Char8Type and
|
||||
not type instanceof Char16Type and
|
||||
not type instanceof Char32Type
|
||||
}
|
||||
|
||||
predicate isBarrier(DataFlow::Node node) {
|
||||
isSink(node) and isArithmeticNonCharType(node.asExpr().getUnspecifiedType())
|
||||
or
|
||||
isArithmeticNonCharType(node.asInstruction().(StoreInstruction).getResultType())
|
||||
}
|
||||
}
|
||||
|
||||
module Flow = TaintTracking::Global<Config>;
|
||||
|
||||
from
|
||||
PrintfLikeFunction printf, Expr arg, PathNode sourceNode, PathNode sinkNode,
|
||||
string printfFunction, Expr userValue, string cause
|
||||
PrintfLikeFunction printf, string printfFunction, string sourceType, DataFlow::Node source,
|
||||
DataFlow::Node sink, Flow::PathNode sourceNode, Flow::PathNode sinkNode
|
||||
where
|
||||
printf.outermostWrapperFunctionCall(arg, printfFunction) and
|
||||
taintedWithPath(userValue, arg, sourceNode, sinkNode) and
|
||||
isUserInput(userValue, cause)
|
||||
select arg, sourceNode, sinkNode,
|
||||
source = sourceNode.getNode() and
|
||||
sink = sinkNode.getNode() and
|
||||
isSource(source, sourceType) and
|
||||
printf.outermostWrapperFunctionCall([sink.asExpr(), sink.asIndirectExpr()], printfFunction) and
|
||||
Flow::flowPath(sourceNode, sinkNode)
|
||||
select sink, sourceNode, sinkNode,
|
||||
"The value of this argument may come from $@ and is being used as a formatting argument to " +
|
||||
printfFunction + ".", userValue, cause
|
||||
printfFunction + ".", source, sourceType
|
||||
|
||||
@@ -12,79 +12,44 @@
|
||||
|
||||
import cpp
|
||||
import semmle.code.cpp.commons.NullTermination
|
||||
import semmle.code.cpp.ir.dataflow.internal.DefaultTaintTrackingImpl
|
||||
import semmle.code.cpp.security.FlowSources as FS
|
||||
import semmle.code.cpp.dataflow.new.TaintTracking
|
||||
import semmle.code.cpp.ir.IR
|
||||
|
||||
/** A user-controlled expression that may not be null terminated. */
|
||||
class TaintSource extends VariableAccess {
|
||||
TaintSource() {
|
||||
exists(SecurityOptions x, string cause |
|
||||
this.getTarget() instanceof SemanticStackVariable and
|
||||
x.isUserInput(this, cause)
|
||||
|
|
||||
cause = ["read", "fread", "recv", "recvfrom", "recvmsg"]
|
||||
)
|
||||
}
|
||||
|
||||
/**
|
||||
* Holds if `sink` is a tainted variable access that must be null
|
||||
* terminated.
|
||||
*/
|
||||
private predicate isSink(VariableAccess sink) {
|
||||
tainted(this, sink) and
|
||||
variableMustBeNullTerminated(sink)
|
||||
}
|
||||
|
||||
/**
|
||||
* Holds if this source can reach `va`, possibly using intermediate
|
||||
* reassignments.
|
||||
*/
|
||||
private predicate sourceReaches(VariableAccess va) {
|
||||
definitionUsePair(_, this, va)
|
||||
or
|
||||
exists(VariableAccess mid, Expr def |
|
||||
this.sourceReaches(mid) and
|
||||
exprDefinition(_, def, mid) and
|
||||
definitionUsePair(_, def, va)
|
||||
)
|
||||
}
|
||||
|
||||
/**
|
||||
* Holds if the sink `sink` is reachable both from this source and
|
||||
* from `va`, possibly using intermediate reassignments.
|
||||
*/
|
||||
private predicate reachesSink(VariableAccess va, VariableAccess sink) {
|
||||
this.isSink(sink) and
|
||||
va = sink
|
||||
or
|
||||
exists(VariableAccess mid, Expr def |
|
||||
this.reachesSink(mid, sink) and
|
||||
exprDefinition(_, def, va) and
|
||||
definitionUsePair(_, def, mid)
|
||||
)
|
||||
}
|
||||
|
||||
/**
|
||||
* Holds if `sink` is a tainted variable access that must be null
|
||||
* terminated, and no access which null terminates its contents can
|
||||
* either reach the sink or be reached from the source. (Ideally,
|
||||
* we should instead look for such accesses only on the path from
|
||||
* this source to `sink` found via `tainted(source, sink)`.)
|
||||
*/
|
||||
predicate reaches(VariableAccess sink) {
|
||||
this.isSink(sink) and
|
||||
not exists(VariableAccess va |
|
||||
va != this and
|
||||
va != sink and
|
||||
mayAddNullTerminator(_, va)
|
||||
|
|
||||
this.sourceReaches(va)
|
||||
or
|
||||
this.reachesSink(va, sink)
|
||||
)
|
||||
}
|
||||
predicate isSource(FS::FlowSource source, string sourceType) {
|
||||
sourceType = source.getSourceType() and
|
||||
exists(VariableAccess va, Call call |
|
||||
va = source.asDefiningArgument() and
|
||||
call.getAnArgument() = va and
|
||||
va.getTarget() instanceof SemanticStackVariable and
|
||||
call.getTarget().hasGlobalName(["read", "fread", "recv", "recvfrom", "recvmsg"])
|
||||
)
|
||||
}
|
||||
|
||||
from TaintSource source, VariableAccess sink
|
||||
where source.reaches(sink)
|
||||
select sink, "String operation depends on a $@ that may not be null terminated.", source,
|
||||
"user-provided value"
|
||||
predicate isSink(DataFlow::Node sink, VariableAccess va) {
|
||||
va = [sink.asExpr(), sink.asIndirectExpr()] and
|
||||
variableMustBeNullTerminated(va)
|
||||
}
|
||||
|
||||
private module Config implements DataFlow::ConfigSig {
|
||||
predicate isSource(DataFlow::Node source) { isSource(source, _) }
|
||||
|
||||
predicate isBarrier(DataFlow::Node node) {
|
||||
isSink(node) and node.asExpr().getUnspecifiedType() instanceof ArithmeticType
|
||||
or
|
||||
node.asInstruction().(StoreInstruction).getResultType() instanceof ArithmeticType
|
||||
or
|
||||
mayAddNullTerminator(_, node.asIndirectExpr())
|
||||
}
|
||||
|
||||
predicate isSink(DataFlow::Node sink) { isSink(sink, _) }
|
||||
}
|
||||
|
||||
module Flow = TaintTracking::Global<Config>;
|
||||
|
||||
from DataFlow::Node source, DataFlow::Node sink, VariableAccess va, string sourceType
|
||||
where
|
||||
Flow::flow(source, sink) and
|
||||
isSource(source, sourceType) and
|
||||
isSink(sink, va)
|
||||
select va, "String operation depends on $@ that may not be null terminated.", 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"
|
||||
|
||||
@@ -12,8 +12,10 @@
|
||||
* external/cwe/cwe-290
|
||||
*/
|
||||
|
||||
import semmle.code.cpp.ir.dataflow.internal.DefaultTaintTrackingImpl
|
||||
import TaintedWithPath
|
||||
import cpp
|
||||
import semmle.code.cpp.dataflow.new.TaintTracking
|
||||
import semmle.code.cpp.security.FlowSources as FS
|
||||
import Flow::PathGraph
|
||||
|
||||
string getATopLevelDomain() {
|
||||
result =
|
||||
@@ -60,13 +62,26 @@ predicate hardCodedAddressInCondition(Expr subexpression, Expr condition) {
|
||||
condition = any(IfStmt ifStmt).getCondition()
|
||||
}
|
||||
|
||||
class Configuration extends TaintTrackingConfiguration {
|
||||
override predicate isSink(Element sink) { hardCodedAddressInCondition(sink, _) }
|
||||
predicate isSource(FS::FlowSource source, string sourceType) { source.getSourceType() = sourceType }
|
||||
|
||||
predicate isSink(DataFlow::Node sink, Expr condition) {
|
||||
hardCodedAddressInCondition([sink.asExpr(), sink.asIndirectExpr()], condition)
|
||||
}
|
||||
|
||||
from Expr subexpression, Expr source, Expr condition, PathNode sourceNode, PathNode sinkNode
|
||||
module Config implements DataFlow::ConfigSig {
|
||||
predicate isSource(DataFlow::Node source) { isSource(source, _) }
|
||||
|
||||
predicate isSink(DataFlow::Node sink) { isSink(sink, _) }
|
||||
}
|
||||
|
||||
module Flow = TaintTracking::Global<Config>;
|
||||
|
||||
from
|
||||
Expr subexpression, Expr condition, Flow::PathNode source, Flow::PathNode sink, string sourceType
|
||||
where
|
||||
hardCodedAddressInCondition(subexpression, condition) and
|
||||
taintedWithPath(source, subexpression, sourceNode, sinkNode)
|
||||
select condition, sourceNode, sinkNode,
|
||||
"Untrusted input $@ might be vulnerable to a spoofing attack.", source, source.toString()
|
||||
isSource(source.getNode(), sourceType) and
|
||||
Flow::flowPath(source, sink) and
|
||||
isSink(sink.getNode(), condition)
|
||||
select condition, source, sink, "Untrusted input $@ might be vulnerable to a spoofing attack.",
|
||||
source, sourceType
|
||||
|
||||
@@ -0,0 +1,44 @@
|
||||
<!DOCTYPE qhelp PUBLIC
|
||||
"-//Semmle//qhelp//EN"
|
||||
"qhelp.dtd">
|
||||
<qhelp>
|
||||
|
||||
<overview>
|
||||
<p>Calling <code>c_str</code> on a <code>std::string</code> object returns a pointer to the underlying character array.
|
||||
When the <code>std::string</code> object is destroyed, the pointer returned by <code>c_str</code> is no
|
||||
longer valid. If the pointer is used after the <code>std::string</code> object is destroyed, then the behavior is undefined.
|
||||
</p>
|
||||
</overview>
|
||||
|
||||
<recommendation>
|
||||
<p>
|
||||
Ensure that the pointer returned by <code>c_str</code> does not outlive the underlying <code>std::string</code> object.
|
||||
</p>
|
||||
</recommendation>
|
||||
|
||||
<example>
|
||||
<p>
|
||||
The following example concatenates two <code>std::string</code> objects, and then converts the resulting string to a
|
||||
C string using <code>c_str</code> so that it can be passed to the <code>work</code> function.
|
||||
|
||||
However, the underlying <code>std::string</code> object that represents the concatenated string is destroyed as soon as the call
|
||||
to <code>c_str</code> returns. This means that <code>work</code> is given a pointer to invalid memory.
|
||||
</p>
|
||||
|
||||
<sample src="UseOfStringAfterLifetimeEndsBad.cpp" />
|
||||
|
||||
<p>
|
||||
The following example fixes the above code by ensuring that the pointer returned by the call to <code>c_str</code> does
|
||||
not outlive the underlying <code>std::string</code> objects. This ensures that the pointer passed to <code>work</code>
|
||||
points to valid memory.
|
||||
</p>
|
||||
|
||||
<sample src="UseOfStringAfterLifetimeEndsGood.cpp" />
|
||||
|
||||
</example>
|
||||
<references>
|
||||
|
||||
<li><a href="https://wiki.sei.cmu.edu/confluence/display/cplusplus/MEM50-CPP.+Do+not+access+freed+memory">MEM50-CPP. Do not access freed memory</a>.</li>
|
||||
|
||||
</references>
|
||||
</qhelp>
|
||||
100
cpp/ql/src/Security/CWE/CWE-416/UseOfStringAfterLifetimeEnds.ql
Normal file
100
cpp/ql/src/Security/CWE/CWE-416/UseOfStringAfterLifetimeEnds.ql
Normal file
@@ -0,0 +1,100 @@
|
||||
/**
|
||||
* @name Use of string after lifetime ends
|
||||
* @description If the value of a call to 'c_str' outlives the underlying object it may lead to unexpected behavior.
|
||||
* @kind problem
|
||||
* @precision high
|
||||
* @id cpp/use-of-string-after-lifetime-ends
|
||||
* @problem.severity warning
|
||||
* @security-severity 8.8
|
||||
* @tags reliability
|
||||
* security
|
||||
* external/cwe/cwe-416
|
||||
* external/cwe/cwe-664
|
||||
*/
|
||||
|
||||
import cpp
|
||||
import semmle.code.cpp.models.implementations.StdString
|
||||
import semmle.code.cpp.models.implementations.StdContainer
|
||||
|
||||
/**
|
||||
* Holds if `e` will be consumed by its parent as a glvalue and does not have
|
||||
* an lvalue-to-rvalue conversion. This means that it will be materialized into
|
||||
* a temporary object.
|
||||
*/
|
||||
predicate isTemporary(Expr e) {
|
||||
e instanceof TemporaryObjectExpr
|
||||
or
|
||||
e.isPRValueCategory() and
|
||||
e.getUnspecifiedType() instanceof Class and
|
||||
not e.hasLValueToRValueConversion()
|
||||
}
|
||||
|
||||
/** Holds if `e` is written to a container. */
|
||||
predicate isStoredInContainer(Expr e) {
|
||||
exists(StdSequenceContainerInsert insert, Call call, int index |
|
||||
call = insert.getACallToThisFunction() and
|
||||
index = insert.getAValueTypeParameterIndex() and
|
||||
call.getArgument(index) = e
|
||||
)
|
||||
or
|
||||
exists(StdSequenceContainerPush push, Call call, int index |
|
||||
call = push.getACallToThisFunction() and
|
||||
index = push.getAValueTypeParameterIndex() and
|
||||
call.getArgument(index) = e
|
||||
)
|
||||
or
|
||||
exists(StdSequenceEmplace emplace, Call call, int index |
|
||||
call = emplace.getACallToThisFunction() and
|
||||
index = emplace.getAValueTypeParameterIndex() and
|
||||
call.getArgument(index) = e
|
||||
)
|
||||
or
|
||||
exists(StdSequenceEmplaceBack emplaceBack, Call call, int index |
|
||||
call = emplaceBack.getACallToThisFunction() and
|
||||
index = emplaceBack.getAValueTypeParameterIndex() and
|
||||
call.getArgument(index) = e
|
||||
)
|
||||
}
|
||||
|
||||
/**
|
||||
* Holds if the value of `e` outlives the enclosing full expression. For
|
||||
* example, because the value is stored in a local variable.
|
||||
*/
|
||||
predicate outlivesFullExpr(Expr e) {
|
||||
any(Assignment assign).getRValue() = e
|
||||
or
|
||||
any(Variable v).getInitializer().getExpr() = e
|
||||
or
|
||||
any(ReturnStmt ret).getExpr() = e
|
||||
or
|
||||
exists(ConditionalExpr cond |
|
||||
outlivesFullExpr(cond) and
|
||||
[cond.getThen(), cond.getElse()] = e
|
||||
)
|
||||
or
|
||||
exists(BinaryOperation bin |
|
||||
outlivesFullExpr(bin) and
|
||||
bin.getAnOperand() = e
|
||||
)
|
||||
or
|
||||
exists(ClassAggregateLiteral aggr |
|
||||
outlivesFullExpr(aggr) and
|
||||
aggr.getAFieldExpr(_) = e
|
||||
)
|
||||
or
|
||||
exists(ArrayAggregateLiteral aggr |
|
||||
outlivesFullExpr(aggr) and
|
||||
aggr.getAnElementExpr(_) = e
|
||||
)
|
||||
or
|
||||
isStoredInContainer(e)
|
||||
}
|
||||
|
||||
from Call c
|
||||
where
|
||||
outlivesFullExpr(c) and
|
||||
not c.isFromUninstantiatedTemplate(_) and
|
||||
(c.getTarget() instanceof StdStringCStr or c.getTarget() instanceof StdStringData) and
|
||||
isTemporary(c.getQualifier().getFullyConverted())
|
||||
select c,
|
||||
"The underlying string object is destroyed after the call to '" + c.getTarget() + "' returns."
|
||||
@@ -0,0 +1,9 @@
|
||||
#include <string>
|
||||
void work(const char*);
|
||||
|
||||
// BAD: the concatenated string is deallocated when `c_str` returns. So `work`
|
||||
// is given a pointer to invalid memory.
|
||||
void work_with_combined_string_bad(std::string s1, std::string s2) {
|
||||
const char* combined_string = (s1 + s2).c_str();
|
||||
work(combined_string);
|
||||
}
|
||||
@@ -0,0 +1,9 @@
|
||||
#include <string>
|
||||
void work(const char*);
|
||||
|
||||
// GOOD: the concatenated string outlives the call to `work`. So the pointer
|
||||
// obtainted from `c_str` is valid.
|
||||
void work_with_combined_string_good(std::string s1, std::string s2) {
|
||||
auto combined_string = s1 + s2;
|
||||
work(combined_string.c_str());
|
||||
}
|
||||
@@ -12,8 +12,12 @@
|
||||
* external/cwe/cwe-807
|
||||
*/
|
||||
|
||||
import semmle.code.cpp.ir.dataflow.internal.DefaultTaintTrackingImpl
|
||||
import TaintedWithPath
|
||||
import cpp
|
||||
import semmle.code.cpp.security.Security
|
||||
import semmle.code.cpp.security.FlowSources
|
||||
import semmle.code.cpp.ir.dataflow.TaintTracking
|
||||
import semmle.code.cpp.ir.IR
|
||||
import Flow::PathGraph
|
||||
|
||||
predicate sensitiveCondition(Expr condition, Expr raise) {
|
||||
raisesPrivilege(raise) and
|
||||
@@ -23,19 +27,62 @@ predicate sensitiveCondition(Expr condition, Expr raise) {
|
||||
)
|
||||
}
|
||||
|
||||
class Configuration extends TaintTrackingConfiguration {
|
||||
override predicate isSink(Element tainted) { sensitiveCondition(tainted, _) }
|
||||
private predicate constantInstruction(Instruction instr) {
|
||||
instr instanceof ConstantInstruction
|
||||
or
|
||||
instr instanceof StringConstantInstruction
|
||||
or
|
||||
constantInstruction(instr.(UnaryInstruction).getUnary())
|
||||
}
|
||||
|
||||
predicate isSource(FlowSource source, string sourceType) { sourceType = source.getSourceType() }
|
||||
|
||||
module Config implements DataFlow::ConfigSig {
|
||||
predicate isSource(DataFlow::Node node) { isSource(node, _) }
|
||||
|
||||
predicate isSink(DataFlow::Node node) {
|
||||
sensitiveCondition([node.asExpr(), node.asIndirectExpr()], _)
|
||||
}
|
||||
|
||||
predicate isBarrier(DataFlow::Node node) {
|
||||
// Block flow into binary instructions if both operands are non-constant
|
||||
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 constant-ness
|
||||
not iTo instanceof PointerArithmeticInstruction
|
||||
)
|
||||
or
|
||||
// Block flow through calls to pure functions if two or more operands are non-constant
|
||||
exists(Instruction iFrom1, Instruction iFrom2, CallInstruction iTo |
|
||||
iTo = node.asInstruction() and
|
||||
isPureFunction(iTo.getStaticCallTarget().getName()) and
|
||||
iFrom1 = iTo.getAnArgument() and
|
||||
iFrom2 = iTo.getAnArgument() and
|
||||
not constantInstruction(iFrom1) and
|
||||
not constantInstruction(iFrom2) and
|
||||
iFrom1 != iFrom2
|
||||
)
|
||||
}
|
||||
}
|
||||
|
||||
module Flow = TaintTracking::Global<Config>;
|
||||
|
||||
/*
|
||||
* Produce an alert if there is an 'if' statement whose condition `condition`
|
||||
* is influenced by tainted data `source`, and the body contains
|
||||
* `raise` which escalates privilege.
|
||||
*/
|
||||
|
||||
from Expr source, Expr condition, Expr raise, PathNode sourceNode, PathNode sinkNode
|
||||
from
|
||||
Expr raise, string sourceType, DataFlow::Node source, DataFlow::Node sink,
|
||||
Flow::PathNode sourceNode, Flow::PathNode sinkNode
|
||||
where
|
||||
taintedWithPath(source, condition, sourceNode, sinkNode) and
|
||||
sensitiveCondition(condition, raise)
|
||||
select condition, sourceNode, sinkNode, "Reliance on untrusted input $@ to raise privilege at $@.",
|
||||
source, source.toString(), raise, raise.toString()
|
||||
source = sourceNode.getNode() and
|
||||
sink = sinkNode.getNode() and
|
||||
isSource(source, sourceType) and
|
||||
sensitiveCondition([sink.asExpr(), sink.asIndirectExpr()], raise) and
|
||||
Flow::flowPath(sourceNode, sinkNode)
|
||||
select sink, sourceNode, sinkNode, "Reliance on $@ to raise privilege at $@.", source, sourceType,
|
||||
raise, raise.toString()
|
||||
|
||||
@@ -0,0 +1,4 @@
|
||||
---
|
||||
category: newQuery
|
||||
---
|
||||
* Added a new query, `cpp/use-of-string-after-lifetime-ends`, to detect calls to `c_str` on strings that will be destroyed immediately.
|
||||
@@ -450,6 +450,7 @@ irGuards
|
||||
| test.c:126:12:126:26 | Call: call to test3_condition |
|
||||
| test.c:131:7:131:7 | Load: b |
|
||||
| test.c:137:7:137:7 | Constant: 0 |
|
||||
| test.c:146:7:146:8 | LogicalNot: ! ... |
|
||||
| test.c:146:8:146:8 | Load: x |
|
||||
| test.c:152:10:152:10 | Load: x |
|
||||
| test.c:152:15:152:15 | Load: y |
|
||||
@@ -640,6 +641,7 @@ irGuardsControl
|
||||
| test.c:126:12:126:26 | Call: call to test3_condition | true | 127 | 127 |
|
||||
| test.c:131:7:131:7 | Load: b | true | 132 | 132 |
|
||||
| test.c:137:7:137:7 | Constant: 0 | false | 142 | 142 |
|
||||
| test.c:146:7:146:8 | LogicalNot: ! ... | true | 147 | 147 |
|
||||
| test.c:146:8:146:8 | Load: x | false | 147 | 147 |
|
||||
| test.c:152:10:152:10 | Load: x | true | 152 | 152 |
|
||||
| test.c:152:15:152:15 | Load: y | true | 152 | 152 |
|
||||
|
||||
@@ -2770,43 +2770,65 @@ ir.cpp:
|
||||
# 462| m462_2(int) = Uninitialized[x] : &:r462_1
|
||||
# 463| r463_1(glval<bool>) = VariableAddress[a] :
|
||||
# 463| r463_2(bool) = Load[a] : &:r463_1, m461_6
|
||||
# 463| v463_3(void) = ConditionalBranch : r463_2
|
||||
#-----| False -> Block 1
|
||||
#-----| True -> Block 2
|
||||
# 463| r463_3(bool) = LogicalNot : r463_2
|
||||
# 463| v463_4(void) = ConditionalBranch : r463_3
|
||||
#-----| False -> Block 5
|
||||
#-----| True -> Block 1
|
||||
|
||||
# 464| Block 1
|
||||
# 464| r464_1(int) = Constant[1] :
|
||||
# 464| r464_2(glval<int>) = VariableAddress[x] :
|
||||
# 464| m464_3(int) = Store[x] : &:r464_2, r464_1
|
||||
#-----| Goto -> Block 2
|
||||
#-----| Goto -> Block 5
|
||||
|
||||
# 467| Block 2
|
||||
# 467| r467_1(glval<bool>) = VariableAddress[a] :
|
||||
# 467| r467_2(bool) = Load[a] : &:r467_1, m461_6
|
||||
# 467| v467_3(void) = ConditionalBranch : r467_2
|
||||
#-----| False -> Block 4
|
||||
#-----| True -> Block 3
|
||||
# 467| r467_1(glval<bool>) = VariableAddress[#temp467:11] :
|
||||
# 467| r467_2(bool) = Constant[0] :
|
||||
# 467| m467_3(bool) = Store[#temp467:11] : &:r467_1, r467_2
|
||||
#-----| Goto -> Block 3
|
||||
|
||||
# 467| Block 3
|
||||
# 467| r467_4(glval<bool>) = VariableAddress[b] :
|
||||
# 467| r467_5(bool) = Load[b] : &:r467_4, m461_8
|
||||
# 467| v467_6(void) = ConditionalBranch : r467_5
|
||||
#-----| False -> Block 4
|
||||
#-----| True -> Block 5
|
||||
# 467| m467_4(bool) = Phi : from 2:m467_3, from 4:m467_11
|
||||
# 467| r467_5(glval<bool>) = VariableAddress[#temp467:11] :
|
||||
# 467| r467_6(bool) = Load[#temp467:11] : &:r467_5, m467_4
|
||||
# 467| r467_7(bool) = LogicalNot : r467_6
|
||||
# 467| v467_8(void) = ConditionalBranch : r467_7
|
||||
#-----| False -> Block 8
|
||||
#-----| True -> Block 7
|
||||
|
||||
# 468| Block 4
|
||||
# 467| Block 4
|
||||
# 467| r467_9(glval<bool>) = VariableAddress[#temp467:11] :
|
||||
# 467| r467_10(bool) = Constant[1] :
|
||||
# 467| m467_11(bool) = Store[#temp467:11] : &:r467_9, r467_10
|
||||
#-----| Goto -> Block 3
|
||||
|
||||
# 467| Block 5
|
||||
# 467| r467_12(glval<bool>) = VariableAddress[a] :
|
||||
# 467| r467_13(bool) = Load[a] : &:r467_12, m461_6
|
||||
# 467| v467_14(void) = ConditionalBranch : r467_13
|
||||
#-----| False -> Block 2
|
||||
#-----| True -> Block 6
|
||||
|
||||
# 467| Block 6
|
||||
# 467| r467_15(glval<bool>) = VariableAddress[b] :
|
||||
# 467| r467_16(bool) = Load[b] : &:r467_15, m461_8
|
||||
# 467| v467_17(void) = ConditionalBranch : r467_16
|
||||
#-----| False -> Block 2
|
||||
#-----| True -> Block 4
|
||||
|
||||
# 468| Block 7
|
||||
# 468| r468_1(int) = Constant[2] :
|
||||
# 468| r468_2(glval<int>) = VariableAddress[x] :
|
||||
# 468| m468_3(int) = Store[x] : &:r468_2, r468_1
|
||||
#-----| Goto -> Block 6
|
||||
#-----| Goto -> Block 9
|
||||
|
||||
# 471| Block 5
|
||||
# 471| Block 8
|
||||
# 471| r471_1(int) = Constant[3] :
|
||||
# 471| r471_2(glval<int>) = VariableAddress[x] :
|
||||
# 471| m471_3(int) = Store[x] : &:r471_2, r471_1
|
||||
#-----| Goto -> Block 6
|
||||
#-----| Goto -> Block 9
|
||||
|
||||
# 473| Block 6
|
||||
# 473| Block 9
|
||||
# 473| v473_1(void) = NoOp :
|
||||
# 461| v461_9(void) = ReturnVoid :
|
||||
# 461| v461_10(void) = AliasedUse : m461_3
|
||||
|
||||
@@ -2398,16 +2398,27 @@
|
||||
| ir.cpp:461:22:461:22 | Address | &:r461_5 |
|
||||
| ir.cpp:461:30:461:30 | Address | &:r461_7 |
|
||||
| ir.cpp:462:9:462:9 | Address | &:r462_1 |
|
||||
| ir.cpp:463:9:463:10 | Condition | r463_3 |
|
||||
| ir.cpp:463:10:463:10 | Address | &:r463_1 |
|
||||
| ir.cpp:463:10:463:10 | Condition | r463_2 |
|
||||
| ir.cpp:463:10:463:10 | Load | m461_6 |
|
||||
| ir.cpp:463:10:463:10 | Unary | r463_2 |
|
||||
| ir.cpp:464:9:464:9 | Address | &:r464_2 |
|
||||
| ir.cpp:464:13:464:13 | StoreValue | r464_1 |
|
||||
| ir.cpp:467:11:467:11 | Address | &:r467_1 |
|
||||
| ir.cpp:467:11:467:11 | Condition | r467_2 |
|
||||
| ir.cpp:467:9:467:17 | Condition | r467_7 |
|
||||
| ir.cpp:467:11:467:11 | Address | &:r467_12 |
|
||||
| ir.cpp:467:11:467:11 | Condition | r467_13 |
|
||||
| ir.cpp:467:11:467:11 | Load | m461_6 |
|
||||
| ir.cpp:467:16:467:16 | Address | &:r467_4 |
|
||||
| ir.cpp:467:16:467:16 | Condition | r467_5 |
|
||||
| ir.cpp:467:11:467:16 | Address | &:r467_1 |
|
||||
| ir.cpp:467:11:467:16 | Address | &:r467_5 |
|
||||
| ir.cpp:467:11:467:16 | Address | &:r467_9 |
|
||||
| ir.cpp:467:11:467:16 | Load | m467_4 |
|
||||
| ir.cpp:467:11:467:16 | Phi | from 2:m467_3 |
|
||||
| ir.cpp:467:11:467:16 | Phi | from 4:m467_11 |
|
||||
| ir.cpp:467:11:467:16 | StoreValue | r467_2 |
|
||||
| ir.cpp:467:11:467:16 | StoreValue | r467_10 |
|
||||
| ir.cpp:467:11:467:16 | Unary | r467_6 |
|
||||
| ir.cpp:467:16:467:16 | Address | &:r467_15 |
|
||||
| ir.cpp:467:16:467:16 | Condition | r467_16 |
|
||||
| ir.cpp:467:16:467:16 | Load | m461_8 |
|
||||
| ir.cpp:468:9:468:9 | Address | &:r468_2 |
|
||||
| ir.cpp:468:13:468:13 | StoreValue | r468_1 |
|
||||
|
||||
@@ -2725,43 +2725,64 @@ ir.cpp:
|
||||
# 462| mu462_2(int) = Uninitialized[x] : &:r462_1
|
||||
# 463| r463_1(glval<bool>) = VariableAddress[a] :
|
||||
# 463| r463_2(bool) = Load[a] : &:r463_1, ~m?
|
||||
# 463| v463_3(void) = ConditionalBranch : r463_2
|
||||
#-----| False -> Block 1
|
||||
#-----| True -> Block 2
|
||||
# 463| r463_3(bool) = LogicalNot : r463_2
|
||||
# 463| v463_4(void) = ConditionalBranch : r463_3
|
||||
#-----| False -> Block 5
|
||||
#-----| True -> Block 1
|
||||
|
||||
# 464| Block 1
|
||||
# 464| r464_1(int) = Constant[1] :
|
||||
# 464| r464_2(glval<int>) = VariableAddress[x] :
|
||||
# 464| mu464_3(int) = Store[x] : &:r464_2, r464_1
|
||||
#-----| Goto -> Block 2
|
||||
#-----| Goto -> Block 5
|
||||
|
||||
# 467| Block 2
|
||||
# 467| r467_1(glval<bool>) = VariableAddress[a] :
|
||||
# 467| r467_2(bool) = Load[a] : &:r467_1, ~m?
|
||||
# 467| v467_3(void) = ConditionalBranch : r467_2
|
||||
#-----| False -> Block 4
|
||||
#-----| True -> Block 3
|
||||
# 467| r467_1(glval<bool>) = VariableAddress[#temp467:11] :
|
||||
# 467| r467_2(bool) = Constant[0] :
|
||||
# 467| mu467_3(bool) = Store[#temp467:11] : &:r467_1, r467_2
|
||||
#-----| Goto -> Block 3
|
||||
|
||||
# 467| Block 3
|
||||
# 467| r467_4(glval<bool>) = VariableAddress[b] :
|
||||
# 467| r467_5(bool) = Load[b] : &:r467_4, ~m?
|
||||
# 467| v467_6(void) = ConditionalBranch : r467_5
|
||||
#-----| False -> Block 4
|
||||
#-----| True -> Block 5
|
||||
# 467| r467_4(glval<bool>) = VariableAddress[#temp467:11] :
|
||||
# 467| r467_5(bool) = Load[#temp467:11] : &:r467_4, ~m?
|
||||
# 467| r467_6(bool) = LogicalNot : r467_5
|
||||
# 467| v467_7(void) = ConditionalBranch : r467_6
|
||||
#-----| False -> Block 8
|
||||
#-----| True -> Block 7
|
||||
|
||||
# 468| Block 4
|
||||
# 467| Block 4
|
||||
# 467| r467_8(glval<bool>) = VariableAddress[#temp467:11] :
|
||||
# 467| r467_9(bool) = Constant[1] :
|
||||
# 467| mu467_10(bool) = Store[#temp467:11] : &:r467_8, r467_9
|
||||
#-----| Goto -> Block 3
|
||||
|
||||
# 467| Block 5
|
||||
# 467| r467_11(glval<bool>) = VariableAddress[a] :
|
||||
# 467| r467_12(bool) = Load[a] : &:r467_11, ~m?
|
||||
# 467| v467_13(void) = ConditionalBranch : r467_12
|
||||
#-----| False -> Block 2
|
||||
#-----| True -> Block 6
|
||||
|
||||
# 467| Block 6
|
||||
# 467| r467_14(glval<bool>) = VariableAddress[b] :
|
||||
# 467| r467_15(bool) = Load[b] : &:r467_14, ~m?
|
||||
# 467| v467_16(void) = ConditionalBranch : r467_15
|
||||
#-----| False -> Block 2
|
||||
#-----| True -> Block 4
|
||||
|
||||
# 468| Block 7
|
||||
# 468| r468_1(int) = Constant[2] :
|
||||
# 468| r468_2(glval<int>) = VariableAddress[x] :
|
||||
# 468| mu468_3(int) = Store[x] : &:r468_2, r468_1
|
||||
#-----| Goto -> Block 6
|
||||
#-----| Goto -> Block 9
|
||||
|
||||
# 471| Block 5
|
||||
# 471| Block 8
|
||||
# 471| r471_1(int) = Constant[3] :
|
||||
# 471| r471_2(glval<int>) = VariableAddress[x] :
|
||||
# 471| mu471_3(int) = Store[x] : &:r471_2, r471_1
|
||||
#-----| Goto -> Block 6
|
||||
#-----| Goto -> Block 9
|
||||
|
||||
# 473| Block 6
|
||||
# 473| Block 9
|
||||
# 473| v473_1(void) = NoOp :
|
||||
# 461| v461_8(void) = ReturnVoid :
|
||||
# 461| v461_9(void) = AliasedUse : ~m?
|
||||
|
||||
@@ -1,2 +1,2 @@
|
||||
| test.cpp:466:10:466:15 | buffer | String operation depends on a $@ that may not be null terminated. | test.cpp:465:18:465:23 | buffer | user-provided value |
|
||||
| test.cpp:481:10:481:15 | buffer | String operation depends on a $@ that may not be null terminated. | test.cpp:480:9:480:14 | buffer | user-provided value |
|
||||
| test.cpp:466:10:466:15 | buffer | String operation depends on $@ that may not be null terminated. | test.cpp:465:18:465:23 | read output argument | buffer read by read |
|
||||
| test.cpp:481:10:481:15 | buffer | String operation depends on $@ that may not be null terminated. | test.cpp:480:9:480:14 | fread output argument | string read by fread |
|
||||
|
||||
@@ -14,18 +14,15 @@ edges
|
||||
| test.cpp:91:9:91:16 | fread output argument | test.cpp:93:17:93:24 | filename indirection |
|
||||
| test.cpp:93:11:93:14 | strncat output argument | test.cpp:94:45:94:48 | path indirection |
|
||||
| test.cpp:93:17:93:24 | filename indirection | test.cpp:93:11:93:14 | strncat output argument |
|
||||
| test.cpp:106:20:106:38 | call to getenv | test.cpp:107:33:107:36 | path indirection |
|
||||
| test.cpp:106:20:106:38 | call to getenv indirection | test.cpp:107:33:107:36 | path indirection |
|
||||
| test.cpp:107:31:107:31 | call to operator+ | test.cpp:108:18:108:22 | call to c_str indirection |
|
||||
| test.cpp:107:33:107:36 | path indirection | test.cpp:107:31:107:31 | call to operator+ |
|
||||
| test.cpp:113:20:113:38 | call to getenv | test.cpp:114:19:114:22 | path indirection |
|
||||
| test.cpp:113:20:113:38 | call to getenv indirection | test.cpp:114:19:114:22 | path indirection |
|
||||
| test.cpp:114:10:114:23 | call to operator+ | test.cpp:114:25:114:29 | call to c_str indirection |
|
||||
| test.cpp:114:10:114:23 | call to operator+ | test.cpp:114:25:114:29 | call to c_str indirection |
|
||||
| test.cpp:114:17:114:17 | call to operator+ | test.cpp:114:10:114:23 | call to operator+ |
|
||||
| test.cpp:114:19:114:22 | path indirection | test.cpp:114:10:114:23 | call to operator+ |
|
||||
| test.cpp:114:19:114:22 | path indirection | test.cpp:114:17:114:17 | call to operator+ |
|
||||
| test.cpp:119:20:119:38 | call to getenv | test.cpp:120:19:120:22 | path indirection |
|
||||
| test.cpp:119:20:119:38 | call to getenv indirection | test.cpp:120:19:120:22 | path indirection |
|
||||
| test.cpp:120:17:120:17 | call to operator+ | test.cpp:120:10:120:30 | call to data indirection |
|
||||
| test.cpp:120:19:120:22 | path indirection | test.cpp:120:17:120:17 | call to operator+ |
|
||||
@@ -89,12 +86,10 @@ nodes
|
||||
| test.cpp:93:11:93:14 | strncat output argument | semmle.label | strncat output argument |
|
||||
| test.cpp:93:17:93:24 | filename indirection | semmle.label | filename indirection |
|
||||
| test.cpp:94:45:94:48 | path indirection | semmle.label | path indirection |
|
||||
| test.cpp:106:20:106:38 | call to getenv | semmle.label | call to getenv |
|
||||
| test.cpp:106:20:106:38 | call to getenv indirection | semmle.label | call to getenv indirection |
|
||||
| test.cpp:107:31:107:31 | call to operator+ | semmle.label | call to operator+ |
|
||||
| test.cpp:107:33:107:36 | path indirection | semmle.label | path indirection |
|
||||
| test.cpp:108:18:108:22 | call to c_str indirection | semmle.label | call to c_str indirection |
|
||||
| test.cpp:113:20:113:38 | call to getenv | semmle.label | call to getenv |
|
||||
| test.cpp:113:20:113:38 | call to getenv indirection | semmle.label | call to getenv indirection |
|
||||
| test.cpp:114:10:114:23 | call to operator+ | semmle.label | call to operator+ |
|
||||
| test.cpp:114:10:114:23 | call to operator+ | semmle.label | call to operator+ |
|
||||
@@ -102,7 +97,6 @@ nodes
|
||||
| test.cpp:114:19:114:22 | path indirection | semmle.label | path indirection |
|
||||
| test.cpp:114:25:114:29 | call to c_str indirection | semmle.label | call to c_str indirection |
|
||||
| test.cpp:114:25:114:29 | call to c_str indirection | semmle.label | call to c_str indirection |
|
||||
| test.cpp:119:20:119:38 | call to getenv | semmle.label | call to getenv |
|
||||
| test.cpp:119:20:119:38 | call to getenv indirection | semmle.label | call to getenv indirection |
|
||||
| test.cpp:120:10:120:30 | call to data indirection | semmle.label | call to data indirection |
|
||||
| test.cpp:120:17:120:17 | call to operator+ | semmle.label | call to operator+ |
|
||||
@@ -156,13 +150,9 @@ subpaths
|
||||
| test.cpp:65:10:65:16 | command | test.cpp:62:9:62:16 | fread output argument | test.cpp:65:10:65:16 | command indirection | This argument to an OS command is derived from $@, dangerously concatenated into $@, and then passed to system(string). | test.cpp:62:9:62:16 | fread output argument | user input (string read by fread) | test.cpp:64:11:64:17 | strncat output argument | strncat output argument |
|
||||
| test.cpp:85:32:85:38 | command | test.cpp:82:9:82:16 | fread output argument | test.cpp:85:32:85:38 | command indirection | This argument to an OS command is derived from $@, dangerously concatenated into $@, and then passed to execl. | test.cpp:82:9:82:16 | fread output argument | user input (string read by fread) | test.cpp:84:11:84:17 | strncat output argument | strncat output argument |
|
||||
| test.cpp:94:45:94:48 | path | test.cpp:91:9:91:16 | fread output argument | test.cpp:94:45:94:48 | path indirection | This argument to an OS command is derived from $@, dangerously concatenated into $@, and then passed to execl. | test.cpp:91:9:91:16 | fread output argument | user input (string read by fread) | test.cpp:93:11:93:14 | strncat output argument | strncat output argument |
|
||||
| test.cpp:108:18:108:22 | call to c_str | test.cpp:106:20:106:38 | call to getenv | test.cpp:108:18:108:22 | call to c_str indirection | This argument to an OS command is derived from $@, dangerously concatenated into $@, and then passed to system(string). | test.cpp:106:20:106:38 | call to getenv | user input (an environment variable) | test.cpp:107:31:107:31 | call to operator+ | call to operator+ |
|
||||
| test.cpp:108:18:108:22 | call to c_str | test.cpp:106:20:106:38 | call to getenv indirection | test.cpp:108:18:108:22 | call to c_str indirection | This argument to an OS command is derived from $@, dangerously concatenated into $@, and then passed to system(string). | test.cpp:106:20:106:38 | call to getenv indirection | user input (an environment variable) | test.cpp:107:31:107:31 | call to operator+ | call to operator+ |
|
||||
| test.cpp:114:25:114:29 | call to c_str | test.cpp:113:20:113:38 | call to getenv | test.cpp:114:25:114:29 | call to c_str indirection | This argument to an OS command is derived from $@, dangerously concatenated into $@, and then passed to system(string). | test.cpp:113:20:113:38 | call to getenv | user input (an environment variable) | test.cpp:114:10:114:23 | call to operator+ | call to operator+ |
|
||||
| test.cpp:114:25:114:29 | call to c_str | test.cpp:113:20:113:38 | call to getenv | test.cpp:114:25:114:29 | call to c_str indirection | This argument to an OS command is derived from $@, dangerously concatenated into $@, and then passed to system(string). | test.cpp:113:20:113:38 | call to getenv | user input (an environment variable) | test.cpp:114:17:114:17 | call to operator+ | call to operator+ |
|
||||
| test.cpp:114:25:114:29 | call to c_str | test.cpp:113:20:113:38 | call to getenv indirection | test.cpp:114:25:114:29 | call to c_str indirection | This argument to an OS command is derived from $@, dangerously concatenated into $@, and then passed to system(string). | test.cpp:113:20:113:38 | call to getenv indirection | user input (an environment variable) | test.cpp:114:10:114:23 | call to operator+ | call to operator+ |
|
||||
| test.cpp:114:25:114:29 | call to c_str | test.cpp:113:20:113:38 | call to getenv indirection | test.cpp:114:25:114:29 | call to c_str indirection | This argument to an OS command is derived from $@, dangerously concatenated into $@, and then passed to system(string). | test.cpp:113:20:113:38 | call to getenv indirection | user input (an environment variable) | test.cpp:114:17:114:17 | call to operator+ | call to operator+ |
|
||||
| test.cpp:120:25:120:28 | call to data | test.cpp:119:20:119:38 | call to getenv | test.cpp:120:10:120:30 | call to data indirection | This argument to an OS command is derived from $@, dangerously concatenated into $@, and then passed to system(string). | test.cpp:119:20:119:38 | call to getenv | user input (an environment variable) | test.cpp:120:17:120:17 | call to operator+ | call to operator+ |
|
||||
| test.cpp:120:25:120:28 | call to data | test.cpp:119:20:119:38 | call to getenv indirection | test.cpp:120:10:120:30 | call to data indirection | This argument to an OS command is derived from $@, dangerously concatenated into $@, and then passed to system(string). | test.cpp:119:20:119:38 | call to getenv indirection | user input (an environment variable) | test.cpp:120:17:120:17 | call to operator+ | call to operator+ |
|
||||
| test.cpp:143:10:143:16 | command | test.cpp:140:9:140:11 | fread output argument | test.cpp:143:10:143:16 | command indirection | This argument to an OS command is derived from $@, dangerously concatenated into $@, and then passed to system(string). | test.cpp:140:9:140:11 | fread output argument | user input (string read by fread) | test.cpp:142:11:142:17 | sprintf output argument | sprintf output argument |
|
||||
| test.cpp:183:32:183:38 | command | test.cpp:174:9:174:16 | fread output argument | test.cpp:183:32:183:38 | command indirection | This argument to an OS command is derived from $@, dangerously concatenated into $@, and then passed to execl. | test.cpp:174:9:174:16 | fread output argument | user input (string read by fread) | test.cpp:177:13:177:17 | strncat output argument | strncat output argument |
|
||||
|
||||
@@ -1,31 +1,16 @@
|
||||
edges
|
||||
| char_connect_socket_w32_vsnprintf_01_bad.c:94:46:94:69 | recv output argument | char_connect_socket_w32_vsnprintf_01_bad.c:125:15:125:18 | data |
|
||||
| char_connect_socket_w32_vsnprintf_01_bad.c:94:46:94:69 | recv output argument | char_connect_socket_w32_vsnprintf_01_bad.c:125:15:125:18 | data |
|
||||
| char_connect_socket_w32_vsnprintf_01_bad.c:94:55:94:68 | ... + ... | char_connect_socket_w32_vsnprintf_01_bad.c:125:15:125:18 | data |
|
||||
| char_connect_socket_w32_vsnprintf_01_bad.c:94:55:94:68 | ... + ... | char_connect_socket_w32_vsnprintf_01_bad.c:125:15:125:18 | data |
|
||||
| char_console_fprintf_01_bad.c:30:23:30:35 | ... + ... | char_console_fprintf_01_bad.c:49:21:49:24 | data |
|
||||
| char_console_fprintf_01_bad.c:30:23:30:35 | ... + ... | char_console_fprintf_01_bad.c:49:21:49:24 | data |
|
||||
| char_console_fprintf_01_bad.c:30:23:30:35 | fgets output argument | char_console_fprintf_01_bad.c:49:21:49:24 | data |
|
||||
| char_console_fprintf_01_bad.c:30:23:30:35 | fgets output argument | char_console_fprintf_01_bad.c:49:21:49:24 | data |
|
||||
| char_environment_fprintf_01_bad.c:27:30:27:35 | call to getenv | char_environment_fprintf_01_bad.c:36:21:36:24 | data |
|
||||
| char_environment_fprintf_01_bad.c:27:30:27:35 | call to getenv | char_environment_fprintf_01_bad.c:36:21:36:24 | data |
|
||||
| char_environment_fprintf_01_bad.c:27:30:27:35 | call to getenv | char_environment_fprintf_01_bad.c:36:21:36:24 | data |
|
||||
| char_environment_fprintf_01_bad.c:27:30:27:35 | call to getenv | char_environment_fprintf_01_bad.c:36:21:36:24 | data |
|
||||
subpaths
|
||||
| char_connect_socket_w32_vsnprintf_01_bad.c:94:46:94:69 | recv output argument | char_connect_socket_w32_vsnprintf_01_bad.c:125:15:125:18 | data indirection |
|
||||
| char_console_fprintf_01_bad.c:30:23:30:35 | fgets output argument | char_console_fprintf_01_bad.c:49:21:49:24 | data indirection |
|
||||
| char_environment_fprintf_01_bad.c:27:30:27:35 | call to getenv indirection | char_environment_fprintf_01_bad.c:36:21:36:24 | data indirection |
|
||||
nodes
|
||||
| char_connect_socket_w32_vsnprintf_01_bad.c:94:46:94:69 | recv output argument | semmle.label | recv output argument |
|
||||
| char_connect_socket_w32_vsnprintf_01_bad.c:94:55:94:68 | ... + ... | semmle.label | ... + ... |
|
||||
| char_connect_socket_w32_vsnprintf_01_bad.c:125:15:125:18 | data | semmle.label | data |
|
||||
| char_connect_socket_w32_vsnprintf_01_bad.c:125:15:125:18 | data | semmle.label | data |
|
||||
| char_console_fprintf_01_bad.c:30:23:30:35 | ... + ... | semmle.label | ... + ... |
|
||||
| char_connect_socket_w32_vsnprintf_01_bad.c:125:15:125:18 | data indirection | semmle.label | data indirection |
|
||||
| char_console_fprintf_01_bad.c:30:23:30:35 | fgets output argument | semmle.label | fgets output argument |
|
||||
| char_console_fprintf_01_bad.c:49:21:49:24 | data | semmle.label | data |
|
||||
| char_console_fprintf_01_bad.c:49:21:49:24 | data | semmle.label | data |
|
||||
| char_environment_fprintf_01_bad.c:27:30:27:35 | call to getenv | semmle.label | call to getenv |
|
||||
| char_environment_fprintf_01_bad.c:27:30:27:35 | call to getenv | semmle.label | call to getenv |
|
||||
| char_environment_fprintf_01_bad.c:36:21:36:24 | data | semmle.label | data |
|
||||
| char_environment_fprintf_01_bad.c:36:21:36:24 | data | semmle.label | data |
|
||||
| char_console_fprintf_01_bad.c:49:21:49:24 | data indirection | semmle.label | data indirection |
|
||||
| char_environment_fprintf_01_bad.c:27:30:27:35 | call to getenv indirection | semmle.label | call to getenv indirection |
|
||||
| char_environment_fprintf_01_bad.c:36:21:36:24 | data indirection | semmle.label | data indirection |
|
||||
subpaths
|
||||
#select
|
||||
| char_connect_socket_w32_vsnprintf_01_bad.c:125:15:125:18 | data | char_connect_socket_w32_vsnprintf_01_bad.c:94:55:94:68 | ... + ... | char_connect_socket_w32_vsnprintf_01_bad.c:125:15:125:18 | data | The value of this argument may come from $@ and is being used as a formatting argument to badVaSink(data), which calls vsnprintf(format). | char_connect_socket_w32_vsnprintf_01_bad.c:94:55:94:68 | ... + ... | recv |
|
||||
| char_console_fprintf_01_bad.c:49:21:49:24 | data | char_console_fprintf_01_bad.c:30:23:30:35 | ... + ... | char_console_fprintf_01_bad.c:49:21:49:24 | data | The value of this argument may come from $@ and is being used as a formatting argument to fprintf(format). | char_console_fprintf_01_bad.c:30:23:30:35 | ... + ... | fgets |
|
||||
| char_environment_fprintf_01_bad.c:36:21:36:24 | data | char_environment_fprintf_01_bad.c:27:30:27:35 | call to getenv | char_environment_fprintf_01_bad.c:36:21:36:24 | data | The value of this argument may come from $@ and is being used as a formatting argument to fprintf(format). | char_environment_fprintf_01_bad.c:27:30:27:35 | call to getenv | getenv |
|
||||
| char_connect_socket_w32_vsnprintf_01_bad.c:125:15:125:18 | data indirection | char_connect_socket_w32_vsnprintf_01_bad.c:94:46:94:69 | recv output argument | char_connect_socket_w32_vsnprintf_01_bad.c:125:15:125:18 | data indirection | The value of this argument may come from $@ and is being used as a formatting argument to badVaSink(data), which calls vsnprintf(format). | char_connect_socket_w32_vsnprintf_01_bad.c:94:46:94:69 | recv output argument | buffer read by recv |
|
||||
| char_console_fprintf_01_bad.c:49:21:49:24 | data indirection | char_console_fprintf_01_bad.c:30:23:30:35 | fgets output argument | char_console_fprintf_01_bad.c:49:21:49:24 | data indirection | The value of this argument may come from $@ and is being used as a formatting argument to fprintf(format). | char_console_fprintf_01_bad.c:30:23:30:35 | fgets output argument | string read by fgets |
|
||||
| char_environment_fprintf_01_bad.c:36:21:36:24 | data indirection | char_environment_fprintf_01_bad.c:27:30:27:35 | call to getenv indirection | char_environment_fprintf_01_bad.c:36:21:36:24 | data indirection | The value of this argument may come from $@ and is being used as a formatting argument to fprintf(format). | char_environment_fprintf_01_bad.c:27:30:27:35 | call to getenv indirection | an environment variable |
|
||||
|
||||
@@ -164,7 +164,7 @@ int main(int argc, char **argv) {
|
||||
printf(i91);
|
||||
printWrapper(i91);
|
||||
|
||||
// BAD: i10 value comes from argv
|
||||
// BAD: i10 value comes from argv [NOT DETECTED]
|
||||
int i10 = (int) argv[1];
|
||||
printf((char *) i10);
|
||||
printWrapper((char *) i10);
|
||||
|
||||
@@ -1,208 +1,77 @@
|
||||
edges
|
||||
| argvLocal.c:95:9:95:12 | argv | argvLocal.c:95:9:95:15 | access to array |
|
||||
| argvLocal.c:95:9:95:12 | argv | argvLocal.c:95:9:95:15 | access to array |
|
||||
| argvLocal.c:95:9:95:12 | argv | argvLocal.c:95:9:95:15 | access to array |
|
||||
| argvLocal.c:95:9:95:12 | argv | argvLocal.c:95:9:95:15 | access to array |
|
||||
| argvLocal.c:96:15:96:18 | argv | argvLocal.c:96:15:96:21 | access to array |
|
||||
| argvLocal.c:96:15:96:18 | argv | argvLocal.c:96:15:96:21 | access to array |
|
||||
| argvLocal.c:96:15:96:18 | argv | argvLocal.c:96:15:96:21 | access to array |
|
||||
| argvLocal.c:96:15:96:18 | argv | argvLocal.c:96:15:96:21 | access to array |
|
||||
| argvLocal.c:100:7:100:10 | argv | argvLocal.c:101:9:101:10 | i1 |
|
||||
| argvLocal.c:100:7:100:10 | argv | argvLocal.c:101:9:101:10 | i1 |
|
||||
| argvLocal.c:100:7:100:10 | argv | argvLocal.c:101:9:101:10 | i1 |
|
||||
| argvLocal.c:100:7:100:10 | argv | argvLocal.c:101:9:101:10 | i1 |
|
||||
| argvLocal.c:100:7:100:10 | argv | argvLocal.c:102:15:102:16 | i1 |
|
||||
| argvLocal.c:100:7:100:10 | argv | argvLocal.c:102:15:102:16 | i1 |
|
||||
| argvLocal.c:100:7:100:10 | argv | argvLocal.c:102:15:102:16 | i1 |
|
||||
| argvLocal.c:100:7:100:10 | argv | argvLocal.c:102:15:102:16 | i1 |
|
||||
| argvLocal.c:100:7:100:10 | argv | argvLocal.c:144:9:144:10 | i7 |
|
||||
| argvLocal.c:100:7:100:10 | argv | argvLocal.c:144:9:144:10 | i7 |
|
||||
| argvLocal.c:100:7:100:10 | argv | argvLocal.c:144:9:144:10 | i7 |
|
||||
| argvLocal.c:100:7:100:10 | argv | argvLocal.c:144:9:144:10 | i7 |
|
||||
| argvLocal.c:100:7:100:10 | argv | argvLocal.c:145:15:145:16 | i7 |
|
||||
| argvLocal.c:100:7:100:10 | argv | argvLocal.c:145:15:145:16 | i7 |
|
||||
| argvLocal.c:100:7:100:10 | argv | argvLocal.c:145:15:145:16 | i7 |
|
||||
| argvLocal.c:100:7:100:10 | argv | argvLocal.c:145:15:145:16 | i7 |
|
||||
| argvLocal.c:105:14:105:17 | argv | argvLocal.c:106:9:106:13 | access to array |
|
||||
| argvLocal.c:105:14:105:17 | argv | argvLocal.c:106:9:106:13 | access to array |
|
||||
| argvLocal.c:105:14:105:17 | argv | argvLocal.c:106:9:106:13 | access to array |
|
||||
| argvLocal.c:105:14:105:17 | argv | argvLocal.c:106:9:106:13 | access to array |
|
||||
| argvLocal.c:105:14:105:17 | argv | argvLocal.c:107:15:107:19 | access to array |
|
||||
| argvLocal.c:105:14:105:17 | argv | argvLocal.c:107:15:107:19 | access to array |
|
||||
| argvLocal.c:105:14:105:17 | argv | argvLocal.c:107:15:107:19 | access to array |
|
||||
| argvLocal.c:105:14:105:17 | argv | argvLocal.c:107:15:107:19 | access to array |
|
||||
| argvLocal.c:105:14:105:17 | argv | argvLocal.c:110:9:110:11 | * ... |
|
||||
| argvLocal.c:105:14:105:17 | argv | argvLocal.c:110:9:110:11 | * ... |
|
||||
| argvLocal.c:105:14:105:17 | argv | argvLocal.c:110:9:110:11 | * ... |
|
||||
| argvLocal.c:105:14:105:17 | argv | argvLocal.c:110:9:110:11 | * ... |
|
||||
| argvLocal.c:105:14:105:17 | argv | argvLocal.c:111:15:111:17 | * ... |
|
||||
| argvLocal.c:105:14:105:17 | argv | argvLocal.c:111:15:111:17 | * ... |
|
||||
| argvLocal.c:105:14:105:17 | argv | argvLocal.c:111:15:111:17 | * ... |
|
||||
| argvLocal.c:105:14:105:17 | argv | argvLocal.c:111:15:111:17 | * ... |
|
||||
| argvLocal.c:115:13:115:16 | argv | argvLocal.c:116:9:116:10 | i3 |
|
||||
| argvLocal.c:115:13:115:16 | argv | argvLocal.c:116:9:116:10 | i3 |
|
||||
| argvLocal.c:115:13:115:16 | argv | argvLocal.c:116:9:116:10 | i3 |
|
||||
| argvLocal.c:115:13:115:16 | argv | argvLocal.c:116:9:116:10 | i3 |
|
||||
| argvLocal.c:115:13:115:16 | argv | argvLocal.c:117:15:117:16 | i3 |
|
||||
| argvLocal.c:115:13:115:16 | argv | argvLocal.c:117:15:117:16 | i3 |
|
||||
| argvLocal.c:115:13:115:16 | argv | argvLocal.c:117:15:117:16 | i3 |
|
||||
| argvLocal.c:115:13:115:16 | argv | argvLocal.c:117:15:117:16 | i3 |
|
||||
| argvLocal.c:115:13:115:16 | argv | argvLocal.c:121:9:121:10 | i4 |
|
||||
| argvLocal.c:115:13:115:16 | argv | argvLocal.c:121:9:121:10 | i4 |
|
||||
| argvLocal.c:115:13:115:16 | argv | argvLocal.c:121:9:121:10 | i4 |
|
||||
| argvLocal.c:115:13:115:16 | argv | argvLocal.c:121:9:121:10 | i4 |
|
||||
| argvLocal.c:115:13:115:16 | argv | argvLocal.c:122:15:122:16 | i4 |
|
||||
| argvLocal.c:115:13:115:16 | argv | argvLocal.c:122:15:122:16 | i4 |
|
||||
| argvLocal.c:115:13:115:16 | argv | argvLocal.c:122:15:122:16 | i4 |
|
||||
| argvLocal.c:115:13:115:16 | argv | argvLocal.c:122:15:122:16 | i4 |
|
||||
| argvLocal.c:115:13:115:16 | argv | argvLocal.c:135:9:135:10 | i4 |
|
||||
| argvLocal.c:115:13:115:16 | argv | argvLocal.c:135:9:135:10 | i4 |
|
||||
| argvLocal.c:115:13:115:16 | argv | argvLocal.c:135:9:135:12 | ... ++ |
|
||||
| argvLocal.c:115:13:115:16 | argv | argvLocal.c:135:9:135:12 | ... ++ |
|
||||
| argvLocal.c:115:13:115:16 | argv | argvLocal.c:135:9:135:12 | ... ++ |
|
||||
| argvLocal.c:115:13:115:16 | argv | argvLocal.c:135:9:135:12 | ... ++ |
|
||||
| argvLocal.c:115:13:115:16 | argv | argvLocal.c:136:15:136:18 | -- ... |
|
||||
| argvLocal.c:115:13:115:16 | argv | argvLocal.c:136:15:136:18 | -- ... |
|
||||
| argvLocal.c:115:13:115:16 | argv | argvLocal.c:136:15:136:18 | -- ... |
|
||||
| argvLocal.c:115:13:115:16 | argv | argvLocal.c:136:15:136:18 | -- ... |
|
||||
| argvLocal.c:115:13:115:16 | argv | argvLocal.c:136:17:136:18 | i4 |
|
||||
| argvLocal.c:115:13:115:16 | argv | argvLocal.c:136:17:136:18 | i4 |
|
||||
| argvLocal.c:126:10:126:13 | argv | argvLocal.c:127:9:127:10 | i5 |
|
||||
| argvLocal.c:126:10:126:13 | argv | argvLocal.c:127:9:127:10 | i5 |
|
||||
| argvLocal.c:126:10:126:13 | argv | argvLocal.c:127:9:127:10 | i5 |
|
||||
| argvLocal.c:126:10:126:13 | argv | argvLocal.c:127:9:127:10 | i5 |
|
||||
| argvLocal.c:126:10:126:13 | argv | argvLocal.c:128:15:128:16 | i5 |
|
||||
| argvLocal.c:126:10:126:13 | argv | argvLocal.c:128:15:128:16 | i5 |
|
||||
| argvLocal.c:126:10:126:13 | argv | argvLocal.c:128:15:128:16 | i5 |
|
||||
| argvLocal.c:126:10:126:13 | argv | argvLocal.c:128:15:128:16 | i5 |
|
||||
| argvLocal.c:126:10:126:13 | argv | argvLocal.c:131:9:131:14 | ... + ... |
|
||||
| argvLocal.c:126:10:126:13 | argv | argvLocal.c:131:9:131:14 | ... + ... |
|
||||
| argvLocal.c:126:10:126:13 | argv | argvLocal.c:131:9:131:14 | ... + ... |
|
||||
| argvLocal.c:126:10:126:13 | argv | argvLocal.c:131:9:131:14 | ... + ... |
|
||||
| argvLocal.c:126:10:126:13 | argv | argvLocal.c:132:15:132:20 | ... + ... |
|
||||
| argvLocal.c:126:10:126:13 | argv | argvLocal.c:132:15:132:20 | ... + ... |
|
||||
| argvLocal.c:126:10:126:13 | argv | argvLocal.c:132:15:132:20 | ... + ... |
|
||||
| argvLocal.c:126:10:126:13 | argv | argvLocal.c:132:15:132:20 | ... + ... |
|
||||
| argvLocal.c:126:10:126:13 | argv | argvLocal.c:139:9:139:26 | ... ? ... : ... |
|
||||
| argvLocal.c:126:10:126:13 | argv | argvLocal.c:139:9:139:26 | ... ? ... : ... |
|
||||
| argvLocal.c:126:10:126:13 | argv | argvLocal.c:139:9:139:26 | ... ? ... : ... |
|
||||
| argvLocal.c:126:10:126:13 | argv | argvLocal.c:139:9:139:26 | ... ? ... : ... |
|
||||
| argvLocal.c:126:10:126:13 | argv | argvLocal.c:140:15:140:32 | ... ? ... : ... |
|
||||
| argvLocal.c:126:10:126:13 | argv | argvLocal.c:140:15:140:32 | ... ? ... : ... |
|
||||
| argvLocal.c:126:10:126:13 | argv | argvLocal.c:140:15:140:32 | ... ? ... : ... |
|
||||
| argvLocal.c:126:10:126:13 | argv | argvLocal.c:140:15:140:32 | ... ? ... : ... |
|
||||
| argvLocal.c:149:11:149:14 | argv | argvLocal.c:150:9:150:10 | i8 |
|
||||
| argvLocal.c:149:11:149:14 | argv | argvLocal.c:150:9:150:10 | i8 |
|
||||
| argvLocal.c:149:11:149:14 | argv | argvLocal.c:150:9:150:10 | i8 |
|
||||
| argvLocal.c:149:11:149:14 | argv | argvLocal.c:150:9:150:10 | i8 |
|
||||
| argvLocal.c:149:11:149:14 | argv | argvLocal.c:151:15:151:16 | i8 |
|
||||
| argvLocal.c:149:11:149:14 | argv | argvLocal.c:151:15:151:16 | i8 |
|
||||
| argvLocal.c:149:11:149:14 | argv | argvLocal.c:151:15:151:16 | i8 |
|
||||
| argvLocal.c:149:11:149:14 | argv | argvLocal.c:151:15:151:16 | i8 |
|
||||
| argvLocal.c:168:18:168:21 | argv | argvLocal.c:169:9:169:20 | i10 |
|
||||
| argvLocal.c:168:18:168:21 | argv | argvLocal.c:169:9:169:20 | i10 |
|
||||
| argvLocal.c:168:18:168:21 | argv | argvLocal.c:169:18:169:20 | i10 |
|
||||
| argvLocal.c:168:18:168:21 | argv | argvLocal.c:169:18:169:20 | i10 |
|
||||
| argvLocal.c:168:18:168:21 | argv | argvLocal.c:170:15:170:26 | i10 |
|
||||
| argvLocal.c:168:18:168:21 | argv | argvLocal.c:170:15:170:26 | i10 |
|
||||
| argvLocal.c:168:18:168:21 | argv | argvLocal.c:170:24:170:26 | i10 |
|
||||
| argvLocal.c:168:18:168:21 | argv | argvLocal.c:170:24:170:26 | i10 |
|
||||
subpaths
|
||||
| argvLocal.c:13:27:13:30 | argv indirection | argvLocal.c:95:9:95:15 | access to array indirection |
|
||||
| argvLocal.c:13:27:13:30 | argv indirection | argvLocal.c:96:15:96:21 | access to array indirection |
|
||||
| argvLocal.c:13:27:13:30 | argv indirection | argvLocal.c:101:9:101:10 | i1 indirection |
|
||||
| argvLocal.c:13:27:13:30 | argv indirection | argvLocal.c:102:15:102:16 | i1 indirection |
|
||||
| argvLocal.c:13:27:13:30 | argv indirection | argvLocal.c:106:9:106:13 | access to array indirection |
|
||||
| argvLocal.c:13:27:13:30 | argv indirection | argvLocal.c:107:15:107:19 | access to array indirection |
|
||||
| argvLocal.c:13:27:13:30 | argv indirection | argvLocal.c:110:9:110:11 | * ... indirection |
|
||||
| argvLocal.c:13:27:13:30 | argv indirection | argvLocal.c:111:15:111:17 | * ... indirection |
|
||||
| argvLocal.c:13:27:13:30 | argv indirection | argvLocal.c:116:9:116:10 | i3 indirection |
|
||||
| argvLocal.c:13:27:13:30 | argv indirection | argvLocal.c:117:15:117:16 | i3 indirection |
|
||||
| argvLocal.c:13:27:13:30 | argv indirection | argvLocal.c:121:9:121:10 | i4 indirection |
|
||||
| argvLocal.c:13:27:13:30 | argv indirection | argvLocal.c:122:15:122:16 | i4 indirection |
|
||||
| argvLocal.c:13:27:13:30 | argv indirection | argvLocal.c:127:9:127:10 | i5 indirection |
|
||||
| argvLocal.c:13:27:13:30 | argv indirection | argvLocal.c:128:15:128:16 | i5 indirection |
|
||||
| argvLocal.c:13:27:13:30 | argv indirection | argvLocal.c:131:9:131:14 | ... + ... indirection |
|
||||
| argvLocal.c:13:27:13:30 | argv indirection | argvLocal.c:132:15:132:20 | ... + ... indirection |
|
||||
| argvLocal.c:13:27:13:30 | argv indirection | argvLocal.c:135:9:135:12 | ... ++ indirection |
|
||||
| argvLocal.c:13:27:13:30 | argv indirection | argvLocal.c:136:15:136:18 | -- ... indirection |
|
||||
| argvLocal.c:13:27:13:30 | argv indirection | argvLocal.c:139:9:139:26 | ... ? ... : ... indirection |
|
||||
| argvLocal.c:13:27:13:30 | argv indirection | argvLocal.c:140:15:140:32 | ... ? ... : ... indirection |
|
||||
| argvLocal.c:13:27:13:30 | argv indirection | argvLocal.c:144:9:144:10 | i7 indirection |
|
||||
| argvLocal.c:13:27:13:30 | argv indirection | argvLocal.c:145:15:145:16 | i7 indirection |
|
||||
| argvLocal.c:13:27:13:30 | argv indirection | argvLocal.c:150:9:150:10 | i8 indirection |
|
||||
| argvLocal.c:13:27:13:30 | argv indirection | argvLocal.c:151:15:151:16 | i8 indirection |
|
||||
nodes
|
||||
| argvLocal.c:95:9:95:12 | argv | semmle.label | argv |
|
||||
| argvLocal.c:95:9:95:12 | argv | semmle.label | argv |
|
||||
| argvLocal.c:95:9:95:15 | access to array | semmle.label | access to array |
|
||||
| argvLocal.c:95:9:95:15 | access to array | semmle.label | access to array |
|
||||
| argvLocal.c:96:15:96:18 | argv | semmle.label | argv |
|
||||
| argvLocal.c:96:15:96:18 | argv | semmle.label | argv |
|
||||
| argvLocal.c:96:15:96:21 | access to array | semmle.label | access to array |
|
||||
| argvLocal.c:96:15:96:21 | access to array | semmle.label | access to array |
|
||||
| argvLocal.c:100:7:100:10 | argv | semmle.label | argv |
|
||||
| argvLocal.c:100:7:100:10 | argv | semmle.label | argv |
|
||||
| argvLocal.c:101:9:101:10 | i1 | semmle.label | i1 |
|
||||
| argvLocal.c:101:9:101:10 | i1 | semmle.label | i1 |
|
||||
| argvLocal.c:102:15:102:16 | i1 | semmle.label | i1 |
|
||||
| argvLocal.c:102:15:102:16 | i1 | semmle.label | i1 |
|
||||
| argvLocal.c:105:14:105:17 | argv | semmle.label | argv |
|
||||
| argvLocal.c:105:14:105:17 | argv | semmle.label | argv |
|
||||
| argvLocal.c:106:9:106:13 | access to array | semmle.label | access to array |
|
||||
| argvLocal.c:106:9:106:13 | access to array | semmle.label | access to array |
|
||||
| argvLocal.c:107:15:107:19 | access to array | semmle.label | access to array |
|
||||
| argvLocal.c:107:15:107:19 | access to array | semmle.label | access to array |
|
||||
| argvLocal.c:110:9:110:11 | * ... | semmle.label | * ... |
|
||||
| argvLocal.c:110:9:110:11 | * ... | semmle.label | * ... |
|
||||
| argvLocal.c:111:15:111:17 | * ... | semmle.label | * ... |
|
||||
| argvLocal.c:111:15:111:17 | * ... | semmle.label | * ... |
|
||||
| argvLocal.c:115:13:115:16 | argv | semmle.label | argv |
|
||||
| argvLocal.c:115:13:115:16 | argv | semmle.label | argv |
|
||||
| argvLocal.c:116:9:116:10 | i3 | semmle.label | i3 |
|
||||
| argvLocal.c:116:9:116:10 | i3 | semmle.label | i3 |
|
||||
| argvLocal.c:117:15:117:16 | i3 | semmle.label | i3 |
|
||||
| argvLocal.c:117:15:117:16 | i3 | semmle.label | i3 |
|
||||
| argvLocal.c:121:9:121:10 | i4 | semmle.label | i4 |
|
||||
| argvLocal.c:121:9:121:10 | i4 | semmle.label | i4 |
|
||||
| argvLocal.c:122:15:122:16 | i4 | semmle.label | i4 |
|
||||
| argvLocal.c:122:15:122:16 | i4 | semmle.label | i4 |
|
||||
| argvLocal.c:126:10:126:13 | argv | semmle.label | argv |
|
||||
| argvLocal.c:126:10:126:13 | argv | semmle.label | argv |
|
||||
| argvLocal.c:127:9:127:10 | i5 | semmle.label | i5 |
|
||||
| argvLocal.c:127:9:127:10 | i5 | semmle.label | i5 |
|
||||
| argvLocal.c:128:15:128:16 | i5 | semmle.label | i5 |
|
||||
| argvLocal.c:128:15:128:16 | i5 | semmle.label | i5 |
|
||||
| argvLocal.c:131:9:131:14 | ... + ... | semmle.label | ... + ... |
|
||||
| argvLocal.c:131:9:131:14 | ... + ... | semmle.label | ... + ... |
|
||||
| argvLocal.c:132:15:132:20 | ... + ... | semmle.label | ... + ... |
|
||||
| argvLocal.c:132:15:132:20 | ... + ... | semmle.label | ... + ... |
|
||||
| argvLocal.c:135:9:135:10 | i4 | semmle.label | i4 |
|
||||
| argvLocal.c:135:9:135:12 | ... ++ | semmle.label | ... ++ |
|
||||
| argvLocal.c:135:9:135:12 | ... ++ | semmle.label | ... ++ |
|
||||
| argvLocal.c:136:15:136:18 | -- ... | semmle.label | -- ... |
|
||||
| argvLocal.c:136:15:136:18 | -- ... | semmle.label | -- ... |
|
||||
| argvLocal.c:136:17:136:18 | i4 | semmle.label | i4 |
|
||||
| argvLocal.c:139:9:139:26 | ... ? ... : ... | semmle.label | ... ? ... : ... |
|
||||
| argvLocal.c:139:9:139:26 | ... ? ... : ... | semmle.label | ... ? ... : ... |
|
||||
| argvLocal.c:140:15:140:32 | ... ? ... : ... | semmle.label | ... ? ... : ... |
|
||||
| argvLocal.c:140:15:140:32 | ... ? ... : ... | semmle.label | ... ? ... : ... |
|
||||
| argvLocal.c:144:9:144:10 | i7 | semmle.label | i7 |
|
||||
| argvLocal.c:144:9:144:10 | i7 | semmle.label | i7 |
|
||||
| argvLocal.c:145:15:145:16 | i7 | semmle.label | i7 |
|
||||
| argvLocal.c:145:15:145:16 | i7 | semmle.label | i7 |
|
||||
| argvLocal.c:149:11:149:14 | argv | semmle.label | argv |
|
||||
| argvLocal.c:149:11:149:14 | argv | semmle.label | argv |
|
||||
| argvLocal.c:150:9:150:10 | i8 | semmle.label | i8 |
|
||||
| argvLocal.c:150:9:150:10 | i8 | semmle.label | i8 |
|
||||
| argvLocal.c:151:15:151:16 | i8 | semmle.label | i8 |
|
||||
| argvLocal.c:151:15:151:16 | i8 | semmle.label | i8 |
|
||||
| argvLocal.c:168:18:168:21 | argv | semmle.label | argv |
|
||||
| argvLocal.c:168:18:168:21 | argv | semmle.label | argv |
|
||||
| argvLocal.c:169:9:169:20 | i10 | semmle.label | i10 |
|
||||
| argvLocal.c:169:18:169:20 | i10 | semmle.label | i10 |
|
||||
| argvLocal.c:170:15:170:26 | i10 | semmle.label | i10 |
|
||||
| argvLocal.c:170:24:170:26 | i10 | semmle.label | i10 |
|
||||
| argvLocal.c:13:27:13:30 | argv indirection | semmle.label | argv indirection |
|
||||
| argvLocal.c:95:9:95:15 | access to array indirection | semmle.label | access to array indirection |
|
||||
| argvLocal.c:96:15:96:21 | access to array indirection | semmle.label | access to array indirection |
|
||||
| argvLocal.c:101:9:101:10 | i1 indirection | semmle.label | i1 indirection |
|
||||
| argvLocal.c:102:15:102:16 | i1 indirection | semmle.label | i1 indirection |
|
||||
| argvLocal.c:106:9:106:13 | access to array indirection | semmle.label | access to array indirection |
|
||||
| argvLocal.c:107:15:107:19 | access to array indirection | semmle.label | access to array indirection |
|
||||
| argvLocal.c:110:9:110:11 | * ... indirection | semmle.label | * ... indirection |
|
||||
| argvLocal.c:111:15:111:17 | * ... indirection | semmle.label | * ... indirection |
|
||||
| argvLocal.c:116:9:116:10 | i3 indirection | semmle.label | i3 indirection |
|
||||
| argvLocal.c:117:15:117:16 | i3 indirection | semmle.label | i3 indirection |
|
||||
| argvLocal.c:121:9:121:10 | i4 indirection | semmle.label | i4 indirection |
|
||||
| argvLocal.c:122:15:122:16 | i4 indirection | semmle.label | i4 indirection |
|
||||
| argvLocal.c:127:9:127:10 | i5 indirection | semmle.label | i5 indirection |
|
||||
| argvLocal.c:128:15:128:16 | i5 indirection | semmle.label | i5 indirection |
|
||||
| argvLocal.c:131:9:131:14 | ... + ... indirection | semmle.label | ... + ... indirection |
|
||||
| argvLocal.c:132:15:132:20 | ... + ... indirection | semmle.label | ... + ... indirection |
|
||||
| argvLocal.c:135:9:135:12 | ... ++ indirection | semmle.label | ... ++ indirection |
|
||||
| argvLocal.c:136:15:136:18 | -- ... indirection | semmle.label | -- ... indirection |
|
||||
| argvLocal.c:139:9:139:26 | ... ? ... : ... indirection | semmle.label | ... ? ... : ... indirection |
|
||||
| argvLocal.c:140:15:140:32 | ... ? ... : ... indirection | semmle.label | ... ? ... : ... indirection |
|
||||
| argvLocal.c:144:9:144:10 | i7 indirection | semmle.label | i7 indirection |
|
||||
| argvLocal.c:145:15:145:16 | i7 indirection | semmle.label | i7 indirection |
|
||||
| argvLocal.c:150:9:150:10 | i8 indirection | semmle.label | i8 indirection |
|
||||
| argvLocal.c:151:15:151:16 | i8 indirection | semmle.label | i8 indirection |
|
||||
subpaths
|
||||
#select
|
||||
| argvLocal.c:95:9:95:15 | access to array | argvLocal.c:95:9:95:12 | argv | argvLocal.c:95:9:95:15 | access to array | The value of this argument may come from $@ and is being used as a formatting argument to printf(format). | argvLocal.c:95:9:95:12 | argv | argv |
|
||||
| argvLocal.c:96:15:96:21 | access to array | argvLocal.c:96:15:96:18 | argv | argvLocal.c:96:15:96:21 | access to array | The value of this argument may come from $@ and is being used as a formatting argument to printWrapper(correct), which calls printf(format). | argvLocal.c:96:15:96:18 | argv | argv |
|
||||
| argvLocal.c:101:9:101:10 | i1 | argvLocal.c:100:7:100:10 | argv | argvLocal.c:101:9:101:10 | i1 | The value of this argument may come from $@ and is being used as a formatting argument to printf(format). | argvLocal.c:100:7:100:10 | argv | argv |
|
||||
| argvLocal.c:102:15:102:16 | i1 | argvLocal.c:100:7:100:10 | argv | argvLocal.c:102:15:102:16 | i1 | The value of this argument may come from $@ and is being used as a formatting argument to printWrapper(correct), which calls printf(format). | argvLocal.c:100:7:100:10 | argv | argv |
|
||||
| argvLocal.c:106:9:106:13 | access to array | argvLocal.c:105:14:105:17 | argv | argvLocal.c:106:9:106:13 | access to array | The value of this argument may come from $@ and is being used as a formatting argument to printf(format). | argvLocal.c:105:14:105:17 | argv | argv |
|
||||
| argvLocal.c:107:15:107:19 | access to array | argvLocal.c:105:14:105:17 | argv | argvLocal.c:107:15:107:19 | access to array | The value of this argument may come from $@ and is being used as a formatting argument to printWrapper(correct), which calls printf(format). | argvLocal.c:105:14:105:17 | argv | argv |
|
||||
| argvLocal.c:110:9:110:11 | * ... | argvLocal.c:105:14:105:17 | argv | argvLocal.c:110:9:110:11 | * ... | The value of this argument may come from $@ and is being used as a formatting argument to printf(format). | argvLocal.c:105:14:105:17 | argv | argv |
|
||||
| argvLocal.c:111:15:111:17 | * ... | argvLocal.c:105:14:105:17 | argv | argvLocal.c:111:15:111:17 | * ... | The value of this argument may come from $@ and is being used as a formatting argument to printWrapper(correct), which calls printf(format). | argvLocal.c:105:14:105:17 | argv | argv |
|
||||
| argvLocal.c:116:9:116:10 | i3 | argvLocal.c:115:13:115:16 | argv | argvLocal.c:116:9:116:10 | i3 | The value of this argument may come from $@ and is being used as a formatting argument to printf(format). | argvLocal.c:115:13:115:16 | argv | argv |
|
||||
| argvLocal.c:117:15:117:16 | i3 | argvLocal.c:115:13:115:16 | argv | argvLocal.c:117:15:117:16 | i3 | The value of this argument may come from $@ and is being used as a formatting argument to printWrapper(correct), which calls printf(format). | argvLocal.c:115:13:115:16 | argv | argv |
|
||||
| argvLocal.c:121:9:121:10 | i4 | argvLocal.c:115:13:115:16 | argv | argvLocal.c:121:9:121:10 | i4 | The value of this argument may come from $@ and is being used as a formatting argument to printf(format). | argvLocal.c:115:13:115:16 | argv | argv |
|
||||
| argvLocal.c:122:15:122:16 | i4 | argvLocal.c:115:13:115:16 | argv | argvLocal.c:122:15:122:16 | i4 | The value of this argument may come from $@ and is being used as a formatting argument to printWrapper(correct), which calls printf(format). | argvLocal.c:115:13:115:16 | argv | argv |
|
||||
| argvLocal.c:127:9:127:10 | i5 | argvLocal.c:126:10:126:13 | argv | argvLocal.c:127:9:127:10 | i5 | The value of this argument may come from $@ and is being used as a formatting argument to printf(format). | argvLocal.c:126:10:126:13 | argv | argv |
|
||||
| argvLocal.c:128:15:128:16 | i5 | argvLocal.c:126:10:126:13 | argv | argvLocal.c:128:15:128:16 | i5 | The value of this argument may come from $@ and is being used as a formatting argument to printWrapper(correct), which calls printf(format). | argvLocal.c:126:10:126:13 | argv | argv |
|
||||
| argvLocal.c:131:9:131:14 | ... + ... | argvLocal.c:126:10:126:13 | argv | argvLocal.c:131:9:131:14 | ... + ... | The value of this argument may come from $@ and is being used as a formatting argument to printf(format). | argvLocal.c:126:10:126:13 | argv | argv |
|
||||
| argvLocal.c:132:15:132:20 | ... + ... | argvLocal.c:126:10:126:13 | argv | argvLocal.c:132:15:132:20 | ... + ... | The value of this argument may come from $@ and is being used as a formatting argument to printWrapper(correct), which calls printf(format). | argvLocal.c:126:10:126:13 | argv | argv |
|
||||
| argvLocal.c:135:9:135:12 | ... ++ | argvLocal.c:115:13:115:16 | argv | argvLocal.c:135:9:135:12 | ... ++ | The value of this argument may come from $@ and is being used as a formatting argument to printf(format). | argvLocal.c:115:13:115:16 | argv | argv |
|
||||
| argvLocal.c:136:15:136:18 | -- ... | argvLocal.c:115:13:115:16 | argv | argvLocal.c:136:15:136:18 | -- ... | The value of this argument may come from $@ and is being used as a formatting argument to printWrapper(correct), which calls printf(format). | argvLocal.c:115:13:115:16 | argv | argv |
|
||||
| argvLocal.c:139:9:139:26 | ... ? ... : ... | argvLocal.c:126:10:126:13 | argv | argvLocal.c:139:9:139:26 | ... ? ... : ... | The value of this argument may come from $@ and is being used as a formatting argument to printf(format). | argvLocal.c:126:10:126:13 | argv | argv |
|
||||
| argvLocal.c:140:15:140:32 | ... ? ... : ... | argvLocal.c:126:10:126:13 | argv | argvLocal.c:140:15:140:32 | ... ? ... : ... | The value of this argument may come from $@ and is being used as a formatting argument to printWrapper(correct), which calls printf(format). | argvLocal.c:126:10:126:13 | argv | argv |
|
||||
| argvLocal.c:144:9:144:10 | i7 | argvLocal.c:100:7:100:10 | argv | argvLocal.c:144:9:144:10 | i7 | The value of this argument may come from $@ and is being used as a formatting argument to printf(format). | argvLocal.c:100:7:100:10 | argv | argv |
|
||||
| argvLocal.c:145:15:145:16 | i7 | argvLocal.c:100:7:100:10 | argv | argvLocal.c:145:15:145:16 | i7 | The value of this argument may come from $@ and is being used as a formatting argument to printWrapper(correct), which calls printf(format). | argvLocal.c:100:7:100:10 | argv | argv |
|
||||
| argvLocal.c:150:9:150:10 | i8 | argvLocal.c:149:11:149:14 | argv | argvLocal.c:150:9:150:10 | i8 | The value of this argument may come from $@ and is being used as a formatting argument to printf(format). | argvLocal.c:149:11:149:14 | argv | argv |
|
||||
| argvLocal.c:151:15:151:16 | i8 | argvLocal.c:149:11:149:14 | argv | argvLocal.c:151:15:151:16 | i8 | The value of this argument may come from $@ and is being used as a formatting argument to printWrapper(correct), which calls printf(format). | argvLocal.c:149:11:149:14 | argv | argv |
|
||||
| argvLocal.c:169:18:169:20 | i10 | argvLocal.c:168:18:168:21 | argv | argvLocal.c:169:18:169:20 | i10 | The value of this argument may come from $@ and is being used as a formatting argument to printf(format). | argvLocal.c:168:18:168:21 | argv | argv |
|
||||
| argvLocal.c:170:24:170:26 | i10 | argvLocal.c:168:18:168:21 | argv | argvLocal.c:170:24:170:26 | i10 | The value of this argument may come from $@ and is being used as a formatting argument to printWrapper(correct), which calls printf(format). | argvLocal.c:168:18:168:21 | argv | argv |
|
||||
| argvLocal.c:95:9:95:15 | access to array indirection | argvLocal.c:13:27:13:30 | argv indirection | argvLocal.c:95:9:95:15 | access to array indirection | The value of this argument may come from $@ and is being used as a formatting argument to printf(format). | argvLocal.c:13:27:13:30 | argv indirection | a command-line argument |
|
||||
| argvLocal.c:96:15:96:21 | access to array indirection | argvLocal.c:13:27:13:30 | argv indirection | argvLocal.c:96:15:96:21 | access to array indirection | The value of this argument may come from $@ and is being used as a formatting argument to printWrapper(correct), which calls printf(format). | argvLocal.c:13:27:13:30 | argv indirection | a command-line argument |
|
||||
| argvLocal.c:101:9:101:10 | i1 indirection | argvLocal.c:13:27:13:30 | argv indirection | argvLocal.c:101:9:101:10 | i1 indirection | The value of this argument may come from $@ and is being used as a formatting argument to printf(format). | argvLocal.c:13:27:13:30 | argv indirection | a command-line argument |
|
||||
| argvLocal.c:102:15:102:16 | i1 indirection | argvLocal.c:13:27:13:30 | argv indirection | argvLocal.c:102:15:102:16 | i1 indirection | The value of this argument may come from $@ and is being used as a formatting argument to printWrapper(correct), which calls printf(format). | argvLocal.c:13:27:13:30 | argv indirection | a command-line argument |
|
||||
| argvLocal.c:106:9:106:13 | access to array indirection | argvLocal.c:13:27:13:30 | argv indirection | argvLocal.c:106:9:106:13 | access to array indirection | The value of this argument may come from $@ and is being used as a formatting argument to printf(format). | argvLocal.c:13:27:13:30 | argv indirection | a command-line argument |
|
||||
| argvLocal.c:107:15:107:19 | access to array indirection | argvLocal.c:13:27:13:30 | argv indirection | argvLocal.c:107:15:107:19 | access to array indirection | The value of this argument may come from $@ and is being used as a formatting argument to printWrapper(correct), which calls printf(format). | argvLocal.c:13:27:13:30 | argv indirection | a command-line argument |
|
||||
| argvLocal.c:110:9:110:11 | * ... indirection | argvLocal.c:13:27:13:30 | argv indirection | argvLocal.c:110:9:110:11 | * ... indirection | The value of this argument may come from $@ and is being used as a formatting argument to printf(format). | argvLocal.c:13:27:13:30 | argv indirection | a command-line argument |
|
||||
| argvLocal.c:111:15:111:17 | * ... indirection | argvLocal.c:13:27:13:30 | argv indirection | argvLocal.c:111:15:111:17 | * ... indirection | The value of this argument may come from $@ and is being used as a formatting argument to printWrapper(correct), which calls printf(format). | argvLocal.c:13:27:13:30 | argv indirection | a command-line argument |
|
||||
| argvLocal.c:116:9:116:10 | i3 indirection | argvLocal.c:13:27:13:30 | argv indirection | argvLocal.c:116:9:116:10 | i3 indirection | The value of this argument may come from $@ and is being used as a formatting argument to printf(format). | argvLocal.c:13:27:13:30 | argv indirection | a command-line argument |
|
||||
| argvLocal.c:117:15:117:16 | i3 indirection | argvLocal.c:13:27:13:30 | argv indirection | argvLocal.c:117:15:117:16 | i3 indirection | The value of this argument may come from $@ and is being used as a formatting argument to printWrapper(correct), which calls printf(format). | argvLocal.c:13:27:13:30 | argv indirection | a command-line argument |
|
||||
| argvLocal.c:121:9:121:10 | i4 indirection | argvLocal.c:13:27:13:30 | argv indirection | argvLocal.c:121:9:121:10 | i4 indirection | The value of this argument may come from $@ and is being used as a formatting argument to printf(format). | argvLocal.c:13:27:13:30 | argv indirection | a command-line argument |
|
||||
| argvLocal.c:122:15:122:16 | i4 indirection | argvLocal.c:13:27:13:30 | argv indirection | argvLocal.c:122:15:122:16 | i4 indirection | The value of this argument may come from $@ and is being used as a formatting argument to printWrapper(correct), which calls printf(format). | argvLocal.c:13:27:13:30 | argv indirection | a command-line argument |
|
||||
| argvLocal.c:127:9:127:10 | i5 indirection | argvLocal.c:13:27:13:30 | argv indirection | argvLocal.c:127:9:127:10 | i5 indirection | The value of this argument may come from $@ and is being used as a formatting argument to printf(format). | argvLocal.c:13:27:13:30 | argv indirection | a command-line argument |
|
||||
| argvLocal.c:128:15:128:16 | i5 indirection | argvLocal.c:13:27:13:30 | argv indirection | argvLocal.c:128:15:128:16 | i5 indirection | The value of this argument may come from $@ and is being used as a formatting argument to printWrapper(correct), which calls printf(format). | argvLocal.c:13:27:13:30 | argv indirection | a command-line argument |
|
||||
| argvLocal.c:131:9:131:14 | ... + ... indirection | argvLocal.c:13:27:13:30 | argv indirection | argvLocal.c:131:9:131:14 | ... + ... indirection | The value of this argument may come from $@ and is being used as a formatting argument to printf(format). | argvLocal.c:13:27:13:30 | argv indirection | a command-line argument |
|
||||
| argvLocal.c:132:15:132:20 | ... + ... indirection | argvLocal.c:13:27:13:30 | argv indirection | argvLocal.c:132:15:132:20 | ... + ... indirection | The value of this argument may come from $@ and is being used as a formatting argument to printWrapper(correct), which calls printf(format). | argvLocal.c:13:27:13:30 | argv indirection | a command-line argument |
|
||||
| argvLocal.c:135:9:135:12 | ... ++ indirection | argvLocal.c:13:27:13:30 | argv indirection | argvLocal.c:135:9:135:12 | ... ++ indirection | The value of this argument may come from $@ and is being used as a formatting argument to printf(format). | argvLocal.c:13:27:13:30 | argv indirection | a command-line argument |
|
||||
| argvLocal.c:136:15:136:18 | -- ... indirection | argvLocal.c:13:27:13:30 | argv indirection | argvLocal.c:136:15:136:18 | -- ... indirection | The value of this argument may come from $@ and is being used as a formatting argument to printWrapper(correct), which calls printf(format). | argvLocal.c:13:27:13:30 | argv indirection | a command-line argument |
|
||||
| argvLocal.c:139:9:139:26 | ... ? ... : ... indirection | argvLocal.c:13:27:13:30 | argv indirection | argvLocal.c:139:9:139:26 | ... ? ... : ... indirection | The value of this argument may come from $@ and is being used as a formatting argument to printf(format). | argvLocal.c:13:27:13:30 | argv indirection | a command-line argument |
|
||||
| argvLocal.c:140:15:140:32 | ... ? ... : ... indirection | argvLocal.c:13:27:13:30 | argv indirection | argvLocal.c:140:15:140:32 | ... ? ... : ... indirection | The value of this argument may come from $@ and is being used as a formatting argument to printWrapper(correct), which calls printf(format). | argvLocal.c:13:27:13:30 | argv indirection | a command-line argument |
|
||||
| argvLocal.c:144:9:144:10 | i7 indirection | argvLocal.c:13:27:13:30 | argv indirection | argvLocal.c:144:9:144:10 | i7 indirection | The value of this argument may come from $@ and is being used as a formatting argument to printf(format). | argvLocal.c:13:27:13:30 | argv indirection | a command-line argument |
|
||||
| argvLocal.c:145:15:145:16 | i7 indirection | argvLocal.c:13:27:13:30 | argv indirection | argvLocal.c:145:15:145:16 | i7 indirection | The value of this argument may come from $@ and is being used as a formatting argument to printWrapper(correct), which calls printf(format). | argvLocal.c:13:27:13:30 | argv indirection | a command-line argument |
|
||||
| argvLocal.c:150:9:150:10 | i8 indirection | argvLocal.c:13:27:13:30 | argv indirection | argvLocal.c:150:9:150:10 | i8 indirection | The value of this argument may come from $@ and is being used as a formatting argument to printf(format). | argvLocal.c:13:27:13:30 | argv indirection | a command-line argument |
|
||||
| argvLocal.c:151:15:151:16 | i8 indirection | argvLocal.c:13:27:13:30 | argv indirection | argvLocal.c:151:15:151:16 | i8 indirection | The value of this argument may come from $@ and is being used as a formatting argument to printWrapper(correct), which calls printf(format). | argvLocal.c:13:27:13:30 | argv indirection | a command-line argument |
|
||||
|
||||
@@ -1,88 +1,35 @@
|
||||
edges
|
||||
| funcsLocal.c:16:8:16:9 | fread output argument | funcsLocal.c:17:9:17:10 | i1 |
|
||||
| funcsLocal.c:16:8:16:9 | fread output argument | funcsLocal.c:17:9:17:10 | i1 |
|
||||
| funcsLocal.c:16:8:16:9 | fread output argument | funcsLocal.c:58:9:58:10 | e1 |
|
||||
| funcsLocal.c:16:8:16:9 | fread output argument | funcsLocal.c:58:9:58:10 | e1 |
|
||||
| funcsLocal.c:16:8:16:9 | i1 | funcsLocal.c:17:9:17:10 | i1 |
|
||||
| funcsLocal.c:16:8:16:9 | i1 | funcsLocal.c:17:9:17:10 | i1 |
|
||||
| funcsLocal.c:16:8:16:9 | i1 | funcsLocal.c:17:9:17:10 | i1 |
|
||||
| funcsLocal.c:16:8:16:9 | i1 | funcsLocal.c:17:9:17:10 | i1 |
|
||||
| funcsLocal.c:16:8:16:9 | i1 | funcsLocal.c:58:9:58:10 | e1 |
|
||||
| funcsLocal.c:16:8:16:9 | i1 | funcsLocal.c:58:9:58:10 | e1 |
|
||||
| funcsLocal.c:16:8:16:9 | i1 | funcsLocal.c:58:9:58:10 | e1 |
|
||||
| funcsLocal.c:16:8:16:9 | i1 | funcsLocal.c:58:9:58:10 | e1 |
|
||||
| funcsLocal.c:26:8:26:9 | fgets output argument | funcsLocal.c:27:9:27:10 | i3 |
|
||||
| funcsLocal.c:26:8:26:9 | fgets output argument | funcsLocal.c:27:9:27:10 | i3 |
|
||||
| funcsLocal.c:26:8:26:9 | i3 | funcsLocal.c:27:9:27:10 | i3 |
|
||||
| funcsLocal.c:26:8:26:9 | i3 | funcsLocal.c:27:9:27:10 | i3 |
|
||||
| funcsLocal.c:26:8:26:9 | i3 | funcsLocal.c:27:9:27:10 | i3 |
|
||||
| funcsLocal.c:26:8:26:9 | i3 | funcsLocal.c:27:9:27:10 | i3 |
|
||||
| funcsLocal.c:31:13:31:17 | call to fgets | funcsLocal.c:32:9:32:10 | i4 |
|
||||
| funcsLocal.c:31:13:31:17 | call to fgets | funcsLocal.c:32:9:32:10 | i4 |
|
||||
| funcsLocal.c:31:13:31:17 | call to fgets | funcsLocal.c:32:9:32:10 | i4 |
|
||||
| funcsLocal.c:31:13:31:17 | call to fgets | funcsLocal.c:32:9:32:10 | i4 |
|
||||
| funcsLocal.c:36:7:36:8 | gets output argument | funcsLocal.c:37:9:37:10 | i5 |
|
||||
| funcsLocal.c:36:7:36:8 | gets output argument | funcsLocal.c:37:9:37:10 | i5 |
|
||||
| funcsLocal.c:36:7:36:8 | i5 | funcsLocal.c:37:9:37:10 | i5 |
|
||||
| funcsLocal.c:36:7:36:8 | i5 | funcsLocal.c:37:9:37:10 | i5 |
|
||||
| funcsLocal.c:36:7:36:8 | i5 | funcsLocal.c:37:9:37:10 | i5 |
|
||||
| funcsLocal.c:36:7:36:8 | i5 | funcsLocal.c:37:9:37:10 | i5 |
|
||||
| funcsLocal.c:41:13:41:16 | call to gets | funcsLocal.c:42:9:42:10 | i6 |
|
||||
| funcsLocal.c:41:13:41:16 | call to gets | funcsLocal.c:42:9:42:10 | i6 |
|
||||
| funcsLocal.c:41:13:41:16 | call to gets | funcsLocal.c:42:9:42:10 | i6 |
|
||||
| funcsLocal.c:41:13:41:16 | call to gets | funcsLocal.c:42:9:42:10 | i6 |
|
||||
| funcsLocal.c:46:7:46:9 | * ... | funcsLocal.c:47:9:47:11 | * ... |
|
||||
| funcsLocal.c:46:7:46:9 | * ... | funcsLocal.c:47:9:47:11 | * ... |
|
||||
| funcsLocal.c:46:7:46:9 | * ... | funcsLocal.c:47:9:47:11 | * ... |
|
||||
| funcsLocal.c:46:7:46:9 | * ... | funcsLocal.c:47:9:47:11 | * ... |
|
||||
| funcsLocal.c:46:7:46:9 | gets output argument | funcsLocal.c:47:9:47:11 | * ... |
|
||||
| funcsLocal.c:46:7:46:9 | gets output argument | funcsLocal.c:47:9:47:11 | * ... |
|
||||
| funcsLocal.c:52:8:52:11 | call to gets | funcsLocal.c:53:9:53:11 | * ... |
|
||||
| funcsLocal.c:52:8:52:11 | call to gets | funcsLocal.c:53:9:53:11 | * ... |
|
||||
| funcsLocal.c:52:8:52:11 | call to gets | funcsLocal.c:53:9:53:11 | * ... |
|
||||
| funcsLocal.c:52:8:52:11 | call to gets | funcsLocal.c:53:9:53:11 | * ... |
|
||||
subpaths
|
||||
| funcsLocal.c:16:8:16:9 | fread output argument | funcsLocal.c:17:9:17:10 | i1 indirection |
|
||||
| funcsLocal.c:16:8:16:9 | fread output argument | funcsLocal.c:58:9:58:10 | e1 indirection |
|
||||
| funcsLocal.c:26:8:26:9 | fgets output argument | funcsLocal.c:27:9:27:10 | i3 indirection |
|
||||
| funcsLocal.c:31:13:31:17 | call to fgets indirection | funcsLocal.c:32:9:32:10 | i4 indirection |
|
||||
| funcsLocal.c:36:7:36:8 | gets output argument | funcsLocal.c:37:9:37:10 | i5 indirection |
|
||||
| funcsLocal.c:41:13:41:16 | call to gets indirection | funcsLocal.c:42:9:42:10 | i6 indirection |
|
||||
| funcsLocal.c:46:7:46:9 | gets output argument | funcsLocal.c:47:9:47:11 | * ... indirection |
|
||||
| funcsLocal.c:52:8:52:11 | call to gets indirection | funcsLocal.c:53:9:53:11 | * ... indirection |
|
||||
nodes
|
||||
| funcsLocal.c:16:8:16:9 | fread output argument | semmle.label | fread output argument |
|
||||
| funcsLocal.c:16:8:16:9 | i1 | semmle.label | i1 |
|
||||
| funcsLocal.c:16:8:16:9 | i1 | semmle.label | i1 |
|
||||
| funcsLocal.c:17:9:17:10 | i1 | semmle.label | i1 |
|
||||
| funcsLocal.c:17:9:17:10 | i1 | semmle.label | i1 |
|
||||
| funcsLocal.c:17:9:17:10 | i1 indirection | semmle.label | i1 indirection |
|
||||
| funcsLocal.c:26:8:26:9 | fgets output argument | semmle.label | fgets output argument |
|
||||
| funcsLocal.c:26:8:26:9 | i3 | semmle.label | i3 |
|
||||
| funcsLocal.c:26:8:26:9 | i3 | semmle.label | i3 |
|
||||
| funcsLocal.c:27:9:27:10 | i3 | semmle.label | i3 |
|
||||
| funcsLocal.c:27:9:27:10 | i3 | semmle.label | i3 |
|
||||
| funcsLocal.c:31:13:31:17 | call to fgets | semmle.label | call to fgets |
|
||||
| funcsLocal.c:31:13:31:17 | call to fgets | semmle.label | call to fgets |
|
||||
| funcsLocal.c:32:9:32:10 | i4 | semmle.label | i4 |
|
||||
| funcsLocal.c:32:9:32:10 | i4 | semmle.label | i4 |
|
||||
| funcsLocal.c:27:9:27:10 | i3 indirection | semmle.label | i3 indirection |
|
||||
| funcsLocal.c:31:13:31:17 | call to fgets indirection | semmle.label | call to fgets indirection |
|
||||
| funcsLocal.c:32:9:32:10 | i4 indirection | semmle.label | i4 indirection |
|
||||
| funcsLocal.c:36:7:36:8 | gets output argument | semmle.label | gets output argument |
|
||||
| funcsLocal.c:36:7:36:8 | i5 | semmle.label | i5 |
|
||||
| funcsLocal.c:36:7:36:8 | i5 | semmle.label | i5 |
|
||||
| funcsLocal.c:37:9:37:10 | i5 | semmle.label | i5 |
|
||||
| funcsLocal.c:37:9:37:10 | i5 | semmle.label | i5 |
|
||||
| funcsLocal.c:41:13:41:16 | call to gets | semmle.label | call to gets |
|
||||
| funcsLocal.c:41:13:41:16 | call to gets | semmle.label | call to gets |
|
||||
| funcsLocal.c:42:9:42:10 | i6 | semmle.label | i6 |
|
||||
| funcsLocal.c:42:9:42:10 | i6 | semmle.label | i6 |
|
||||
| funcsLocal.c:46:7:46:9 | * ... | semmle.label | * ... |
|
||||
| funcsLocal.c:46:7:46:9 | * ... | semmle.label | * ... |
|
||||
| funcsLocal.c:37:9:37:10 | i5 indirection | semmle.label | i5 indirection |
|
||||
| funcsLocal.c:41:13:41:16 | call to gets indirection | semmle.label | call to gets indirection |
|
||||
| funcsLocal.c:42:9:42:10 | i6 indirection | semmle.label | i6 indirection |
|
||||
| funcsLocal.c:46:7:46:9 | gets output argument | semmle.label | gets output argument |
|
||||
| funcsLocal.c:47:9:47:11 | * ... | semmle.label | * ... |
|
||||
| funcsLocal.c:47:9:47:11 | * ... | semmle.label | * ... |
|
||||
| funcsLocal.c:52:8:52:11 | call to gets | semmle.label | call to gets |
|
||||
| funcsLocal.c:52:8:52:11 | call to gets | semmle.label | call to gets |
|
||||
| funcsLocal.c:53:9:53:11 | * ... | semmle.label | * ... |
|
||||
| funcsLocal.c:53:9:53:11 | * ... | semmle.label | * ... |
|
||||
| funcsLocal.c:58:9:58:10 | e1 | semmle.label | e1 |
|
||||
| funcsLocal.c:58:9:58:10 | e1 | semmle.label | e1 |
|
||||
| funcsLocal.c:47:9:47:11 | * ... indirection | semmle.label | * ... indirection |
|
||||
| funcsLocal.c:52:8:52:11 | call to gets indirection | semmle.label | call to gets indirection |
|
||||
| funcsLocal.c:53:9:53:11 | * ... indirection | semmle.label | * ... indirection |
|
||||
| funcsLocal.c:58:9:58:10 | e1 indirection | semmle.label | e1 indirection |
|
||||
subpaths
|
||||
#select
|
||||
| funcsLocal.c:17:9:17:10 | i1 | funcsLocal.c:16:8:16:9 | i1 | funcsLocal.c:17:9:17:10 | i1 | The value of this argument may come from $@ and is being used as a formatting argument to printf(format). | funcsLocal.c:16:8:16:9 | i1 | fread |
|
||||
| funcsLocal.c:27:9:27:10 | i3 | funcsLocal.c:26:8:26:9 | i3 | funcsLocal.c:27:9:27:10 | i3 | The value of this argument may come from $@ and is being used as a formatting argument to printf(format). | funcsLocal.c:26:8:26:9 | i3 | fgets |
|
||||
| funcsLocal.c:32:9:32:10 | i4 | funcsLocal.c:31:13:31:17 | call to fgets | funcsLocal.c:32:9:32:10 | i4 | The value of this argument may come from $@ and is being used as a formatting argument to printf(format). | funcsLocal.c:31:13:31:17 | call to fgets | fgets |
|
||||
| funcsLocal.c:37:9:37:10 | i5 | funcsLocal.c:36:7:36:8 | i5 | funcsLocal.c:37:9:37:10 | i5 | The value of this argument may come from $@ and is being used as a formatting argument to printf(format). | funcsLocal.c:36:7:36:8 | i5 | gets |
|
||||
| funcsLocal.c:42:9:42:10 | i6 | funcsLocal.c:41:13:41:16 | call to gets | funcsLocal.c:42:9:42:10 | i6 | The value of this argument may come from $@ and is being used as a formatting argument to printf(format). | funcsLocal.c:41:13:41:16 | call to gets | gets |
|
||||
| funcsLocal.c:47:9:47:11 | * ... | funcsLocal.c:46:7:46:9 | * ... | funcsLocal.c:47:9:47:11 | * ... | The value of this argument may come from $@ and is being used as a formatting argument to printf(format). | funcsLocal.c:46:7:46:9 | * ... | gets |
|
||||
| funcsLocal.c:53:9:53:11 | * ... | funcsLocal.c:52:8:52:11 | call to gets | funcsLocal.c:53:9:53:11 | * ... | The value of this argument may come from $@ and is being used as a formatting argument to printf(format). | funcsLocal.c:52:8:52:11 | call to gets | gets |
|
||||
| funcsLocal.c:58:9:58:10 | e1 | funcsLocal.c:16:8:16:9 | i1 | funcsLocal.c:58:9:58:10 | e1 | The value of this argument may come from $@ and is being used as a formatting argument to printf(format). | funcsLocal.c:16:8:16:9 | i1 | fread |
|
||||
| funcsLocal.c:17:9:17:10 | i1 indirection | funcsLocal.c:16:8:16:9 | fread output argument | funcsLocal.c:17:9:17:10 | i1 indirection | The value of this argument may come from $@ and is being used as a formatting argument to printf(format). | funcsLocal.c:16:8:16:9 | fread output argument | string read by fread |
|
||||
| funcsLocal.c:27:9:27:10 | i3 indirection | funcsLocal.c:26:8:26:9 | fgets output argument | funcsLocal.c:27:9:27:10 | i3 indirection | The value of this argument may come from $@ and is being used as a formatting argument to printf(format). | funcsLocal.c:26:8:26:9 | fgets output argument | string read by fgets |
|
||||
| funcsLocal.c:32:9:32:10 | i4 indirection | funcsLocal.c:31:13:31:17 | call to fgets indirection | funcsLocal.c:32:9:32:10 | i4 indirection | The value of this argument may come from $@ and is being used as a formatting argument to printf(format). | funcsLocal.c:31:13:31:17 | call to fgets indirection | string read by fgets |
|
||||
| funcsLocal.c:37:9:37:10 | i5 indirection | funcsLocal.c:36:7:36:8 | gets output argument | funcsLocal.c:37:9:37:10 | i5 indirection | The value of this argument may come from $@ and is being used as a formatting argument to printf(format). | funcsLocal.c:36:7:36:8 | gets output argument | string read by gets |
|
||||
| funcsLocal.c:42:9:42:10 | i6 indirection | funcsLocal.c:41:13:41:16 | call to gets indirection | funcsLocal.c:42:9:42:10 | i6 indirection | The value of this argument may come from $@ and is being used as a formatting argument to printf(format). | funcsLocal.c:41:13:41:16 | call to gets indirection | string read by gets |
|
||||
| funcsLocal.c:47:9:47:11 | * ... indirection | funcsLocal.c:46:7:46:9 | gets output argument | funcsLocal.c:47:9:47:11 | * ... indirection | The value of this argument may come from $@ and is being used as a formatting argument to printf(format). | funcsLocal.c:46:7:46:9 | gets output argument | string read by gets |
|
||||
| funcsLocal.c:53:9:53:11 | * ... indirection | funcsLocal.c:52:8:52:11 | call to gets indirection | funcsLocal.c:53:9:53:11 | * ... indirection | The value of this argument may come from $@ and is being used as a formatting argument to printf(format). | funcsLocal.c:52:8:52:11 | call to gets indirection | string read by gets |
|
||||
| funcsLocal.c:58:9:58:10 | e1 indirection | funcsLocal.c:16:8:16:9 | fread output argument | funcsLocal.c:58:9:58:10 | e1 indirection | The value of this argument may come from $@ and is being used as a formatting argument to printf(format). | funcsLocal.c:16:8:16:9 | fread output argument | string read by fread |
|
||||
|
||||
@@ -1,42 +1,32 @@
|
||||
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: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: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:15:21:15:23 | val | 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:35:11:35:14 | copy | globalVars.c:15:21:15:23 | val |
|
||||
subpaths
|
||||
| globalVars.c:8:7:8:10 | copy indirection | globalVars.c:27:9:27:12 | copy indirection |
|
||||
| globalVars.c:8:7:8:10 | copy indirection | globalVars.c:30:15:30:18 | copy indirection |
|
||||
| globalVars.c:8:7:8:10 | copy indirection | globalVars.c:35:11:35:14 | copy indirection |
|
||||
| globalVars.c:9:7:9:11 | copy2 indirection | globalVars.c:38:9:38:13 | copy2 indirection |
|
||||
| globalVars.c:9:7:9:11 | copy2 indirection | globalVars.c:41:15:41:19 | copy2 indirection |
|
||||
| globalVars.c:9:7:9:11 | copy2 indirection | globalVars.c:50:9:50:13 | copy2 indirection |
|
||||
| globalVars.c:11:22:11:25 | argv indirection | globalVars.c:8:7:8:10 | copy indirection |
|
||||
| globalVars.c:15:21:15:23 | val indirection | globalVars.c:9:7:9:11 | copy2 indirection |
|
||||
| globalVars.c:23:27:23:30 | argv indirection | globalVars.c:24:11:24:14 | argv indirection |
|
||||
| globalVars.c:24:11:24:14 | argv indirection | globalVars.c:11:22:11:25 | argv indirection |
|
||||
| globalVars.c:35:11:35:14 | copy indirection | globalVars.c:15:21:15:23 | val indirection |
|
||||
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:15:21:15:23 | val | semmle.label | val |
|
||||
| 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: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:50:9:50:13 | copy2 | semmle.label | copy2 |
|
||||
| globalVars.c:50:9:50:13 | copy2 | semmle.label | copy2 |
|
||||
| globalVars.c:8:7:8:10 | copy indirection | semmle.label | copy indirection |
|
||||
| globalVars.c:9:7:9:11 | copy2 indirection | semmle.label | copy2 indirection |
|
||||
| globalVars.c:11:22:11:25 | argv indirection | semmle.label | argv indirection |
|
||||
| globalVars.c:15:21:15:23 | val indirection | semmle.label | val indirection |
|
||||
| globalVars.c:23:27:23:30 | argv indirection | semmle.label | argv indirection |
|
||||
| globalVars.c:24:11:24:14 | argv indirection | semmle.label | argv indirection |
|
||||
| globalVars.c:27:9:27:12 | copy indirection | semmle.label | copy indirection |
|
||||
| globalVars.c:30:15:30:18 | copy indirection | semmle.label | copy indirection |
|
||||
| globalVars.c:35:11:35:14 | copy indirection | semmle.label | copy indirection |
|
||||
| globalVars.c:38:9:38:13 | copy2 indirection | semmle.label | copy2 indirection |
|
||||
| globalVars.c:41:15:41:19 | copy2 indirection | semmle.label | copy2 indirection |
|
||||
| globalVars.c:50:9:50:13 | copy2 indirection | semmle.label | copy2 indirection |
|
||||
subpaths
|
||||
#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 |
|
||||
| globalVars.c:27:9:27:12 | copy indirection | globalVars.c:23:27:23:30 | argv indirection | globalVars.c:27:9:27:12 | copy indirection | The value of this argument may come from $@ and is being used as a formatting argument to printf(format). | globalVars.c:23:27:23:30 | argv indirection | a command-line argument |
|
||||
| globalVars.c:30:15:30:18 | copy indirection | globalVars.c:23:27:23:30 | argv indirection | globalVars.c:30:15:30:18 | copy indirection | 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:23:27:23:30 | argv indirection | a command-line argument |
|
||||
| globalVars.c:38:9:38:13 | copy2 indirection | globalVars.c:23:27:23:30 | argv indirection | globalVars.c:38:9:38:13 | copy2 indirection | The value of this argument may come from $@ and is being used as a formatting argument to printf(format). | globalVars.c:23:27:23:30 | argv indirection | a command-line argument |
|
||||
| globalVars.c:41:15:41:19 | copy2 indirection | globalVars.c:23:27:23:30 | argv indirection | globalVars.c:41:15:41:19 | copy2 indirection | 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:23:27:23:30 | argv indirection | a command-line argument |
|
||||
| globalVars.c:50:9:50:13 | copy2 indirection | globalVars.c:23:27:23:30 | argv indirection | globalVars.c:50:9:50:13 | copy2 indirection | The value of this argument may come from $@ and is being used as a formatting argument to printf(format). | globalVars.c:23:27:23:30 | argv indirection | a command-line argument |
|
||||
|
||||
@@ -1,103 +1,38 @@
|
||||
edges
|
||||
| ifs.c:61:8:61:11 | argv | ifs.c:62:9:62:10 | c7 |
|
||||
| ifs.c:61:8:61:11 | argv | ifs.c:62:9:62:10 | c7 |
|
||||
| ifs.c:61:8:61:11 | argv | ifs.c:62:9:62:10 | c7 |
|
||||
| ifs.c:61:8:61:11 | argv | ifs.c:62:9:62:10 | c7 |
|
||||
| ifs.c:68:8:68:11 | argv | ifs.c:69:9:69:10 | c8 |
|
||||
| ifs.c:68:8:68:11 | argv | ifs.c:69:9:69:10 | c8 |
|
||||
| ifs.c:68:8:68:11 | argv | ifs.c:69:9:69:10 | c8 |
|
||||
| ifs.c:68:8:68:11 | argv | ifs.c:69:9:69:10 | c8 |
|
||||
| ifs.c:74:8:74:11 | argv | ifs.c:75:9:75:10 | i1 |
|
||||
| ifs.c:74:8:74:11 | argv | ifs.c:75:9:75:10 | i1 |
|
||||
| ifs.c:74:8:74:11 | argv | ifs.c:75:9:75:10 | i1 |
|
||||
| ifs.c:74:8:74:11 | argv | ifs.c:75:9:75:10 | i1 |
|
||||
| ifs.c:80:8:80:11 | argv | ifs.c:81:9:81:10 | i2 |
|
||||
| ifs.c:80:8:80:11 | argv | ifs.c:81:9:81:10 | i2 |
|
||||
| ifs.c:80:8:80:11 | argv | ifs.c:81:9:81:10 | i2 |
|
||||
| ifs.c:80:8:80:11 | argv | ifs.c:81:9:81:10 | i2 |
|
||||
| ifs.c:86:8:86:11 | argv | ifs.c:87:9:87:10 | i3 |
|
||||
| ifs.c:86:8:86:11 | argv | ifs.c:87:9:87:10 | i3 |
|
||||
| ifs.c:86:8:86:11 | argv | ifs.c:87:9:87:10 | i3 |
|
||||
| ifs.c:86:8:86:11 | argv | ifs.c:87:9:87:10 | i3 |
|
||||
| ifs.c:92:8:92:11 | argv | ifs.c:93:9:93:10 | i4 |
|
||||
| ifs.c:92:8:92:11 | argv | ifs.c:93:9:93:10 | i4 |
|
||||
| ifs.c:92:8:92:11 | argv | ifs.c:93:9:93:10 | i4 |
|
||||
| ifs.c:92:8:92:11 | argv | ifs.c:93:9:93:10 | i4 |
|
||||
| ifs.c:98:8:98:11 | argv | ifs.c:99:9:99:10 | i5 |
|
||||
| ifs.c:98:8:98:11 | argv | ifs.c:99:9:99:10 | i5 |
|
||||
| ifs.c:98:8:98:11 | argv | ifs.c:99:9:99:10 | i5 |
|
||||
| ifs.c:98:8:98:11 | argv | ifs.c:99:9:99:10 | i5 |
|
||||
| ifs.c:105:8:105:11 | argv | ifs.c:106:9:106:10 | i6 |
|
||||
| ifs.c:105:8:105:11 | argv | ifs.c:106:9:106:10 | i6 |
|
||||
| ifs.c:105:8:105:11 | argv | ifs.c:106:9:106:10 | i6 |
|
||||
| ifs.c:105:8:105:11 | argv | ifs.c:106:9:106:10 | i6 |
|
||||
| ifs.c:111:8:111:11 | argv | ifs.c:112:9:112:10 | i7 |
|
||||
| ifs.c:111:8:111:11 | argv | ifs.c:112:9:112:10 | i7 |
|
||||
| ifs.c:111:8:111:11 | argv | ifs.c:112:9:112:10 | i7 |
|
||||
| ifs.c:111:8:111:11 | argv | ifs.c:112:9:112:10 | i7 |
|
||||
| ifs.c:117:8:117:11 | argv | ifs.c:118:9:118:10 | i8 |
|
||||
| ifs.c:117:8:117:11 | argv | ifs.c:118:9:118:10 | i8 |
|
||||
| ifs.c:117:8:117:11 | argv | ifs.c:118:9:118:10 | i8 |
|
||||
| ifs.c:117:8:117:11 | argv | ifs.c:118:9:118:10 | i8 |
|
||||
| ifs.c:123:8:123:11 | argv | ifs.c:124:9:124:10 | i9 |
|
||||
| ifs.c:123:8:123:11 | argv | ifs.c:124:9:124:10 | i9 |
|
||||
| ifs.c:123:8:123:11 | argv | ifs.c:124:9:124:10 | i9 |
|
||||
| ifs.c:123:8:123:11 | argv | ifs.c:124:9:124:10 | i9 |
|
||||
subpaths
|
||||
| ifs.c:16:27:16:30 | argv indirection | ifs.c:62:9:62:10 | c7 indirection |
|
||||
| ifs.c:16:27:16:30 | argv indirection | ifs.c:69:9:69:10 | c8 indirection |
|
||||
| ifs.c:16:27:16:30 | argv indirection | ifs.c:75:9:75:10 | i1 indirection |
|
||||
| ifs.c:16:27:16:30 | argv indirection | ifs.c:81:9:81:10 | i2 indirection |
|
||||
| ifs.c:16:27:16:30 | argv indirection | ifs.c:87:9:87:10 | i3 indirection |
|
||||
| ifs.c:16:27:16:30 | argv indirection | ifs.c:93:9:93:10 | i4 indirection |
|
||||
| ifs.c:16:27:16:30 | argv indirection | ifs.c:99:9:99:10 | i5 indirection |
|
||||
| ifs.c:16:27:16:30 | argv indirection | ifs.c:106:9:106:10 | i6 indirection |
|
||||
| ifs.c:16:27:16:30 | argv indirection | ifs.c:112:9:112:10 | i7 indirection |
|
||||
| ifs.c:16:27:16:30 | argv indirection | ifs.c:118:9:118:10 | i8 indirection |
|
||||
| ifs.c:16:27:16:30 | argv indirection | ifs.c:124:9:124:10 | i9 indirection |
|
||||
nodes
|
||||
| ifs.c:61:8:61:11 | argv | semmle.label | argv |
|
||||
| ifs.c:61:8:61:11 | argv | semmle.label | argv |
|
||||
| ifs.c:62:9:62:10 | c7 | semmle.label | c7 |
|
||||
| ifs.c:62:9:62:10 | c7 | semmle.label | c7 |
|
||||
| ifs.c:68:8:68:11 | argv | semmle.label | argv |
|
||||
| ifs.c:68:8:68:11 | argv | semmle.label | argv |
|
||||
| ifs.c:69:9:69:10 | c8 | semmle.label | c8 |
|
||||
| ifs.c:69:9:69:10 | c8 | semmle.label | c8 |
|
||||
| ifs.c:74:8:74:11 | argv | semmle.label | argv |
|
||||
| ifs.c:74:8:74:11 | argv | semmle.label | argv |
|
||||
| ifs.c:75:9:75:10 | i1 | semmle.label | i1 |
|
||||
| ifs.c:75:9:75:10 | i1 | semmle.label | i1 |
|
||||
| ifs.c:80:8:80:11 | argv | semmle.label | argv |
|
||||
| ifs.c:80:8:80:11 | argv | semmle.label | argv |
|
||||
| ifs.c:81:9:81:10 | i2 | semmle.label | i2 |
|
||||
| ifs.c:81:9:81:10 | i2 | semmle.label | i2 |
|
||||
| ifs.c:86:8:86:11 | argv | semmle.label | argv |
|
||||
| ifs.c:86:8:86:11 | argv | semmle.label | argv |
|
||||
| ifs.c:87:9:87:10 | i3 | semmle.label | i3 |
|
||||
| ifs.c:87:9:87:10 | i3 | semmle.label | i3 |
|
||||
| ifs.c:92:8:92:11 | argv | semmle.label | argv |
|
||||
| ifs.c:92:8:92:11 | argv | semmle.label | argv |
|
||||
| ifs.c:93:9:93:10 | i4 | semmle.label | i4 |
|
||||
| ifs.c:93:9:93:10 | i4 | semmle.label | i4 |
|
||||
| ifs.c:98:8:98:11 | argv | semmle.label | argv |
|
||||
| ifs.c:98:8:98:11 | argv | semmle.label | argv |
|
||||
| ifs.c:99:9:99:10 | i5 | semmle.label | i5 |
|
||||
| ifs.c:99:9:99:10 | i5 | semmle.label | i5 |
|
||||
| ifs.c:105:8:105:11 | argv | semmle.label | argv |
|
||||
| ifs.c:105:8:105:11 | argv | semmle.label | argv |
|
||||
| ifs.c:106:9:106:10 | i6 | semmle.label | i6 |
|
||||
| ifs.c:106:9:106:10 | i6 | semmle.label | i6 |
|
||||
| ifs.c:111:8:111:11 | argv | semmle.label | argv |
|
||||
| ifs.c:111:8:111:11 | argv | semmle.label | argv |
|
||||
| ifs.c:112:9:112:10 | i7 | semmle.label | i7 |
|
||||
| ifs.c:112:9:112:10 | i7 | semmle.label | i7 |
|
||||
| ifs.c:117:8:117:11 | argv | semmle.label | argv |
|
||||
| ifs.c:117:8:117:11 | argv | semmle.label | argv |
|
||||
| ifs.c:118:9:118:10 | i8 | semmle.label | i8 |
|
||||
| ifs.c:118:9:118:10 | i8 | semmle.label | i8 |
|
||||
| ifs.c:123:8:123:11 | argv | semmle.label | argv |
|
||||
| ifs.c:123:8:123:11 | argv | semmle.label | argv |
|
||||
| ifs.c:124:9:124:10 | i9 | semmle.label | i9 |
|
||||
| ifs.c:124:9:124:10 | i9 | semmle.label | i9 |
|
||||
| ifs.c:16:27:16:30 | argv indirection | semmle.label | argv indirection |
|
||||
| ifs.c:62:9:62:10 | c7 indirection | semmle.label | c7 indirection |
|
||||
| ifs.c:69:9:69:10 | c8 indirection | semmle.label | c8 indirection |
|
||||
| ifs.c:75:9:75:10 | i1 indirection | semmle.label | i1 indirection |
|
||||
| ifs.c:81:9:81:10 | i2 indirection | semmle.label | i2 indirection |
|
||||
| ifs.c:87:9:87:10 | i3 indirection | semmle.label | i3 indirection |
|
||||
| ifs.c:93:9:93:10 | i4 indirection | semmle.label | i4 indirection |
|
||||
| ifs.c:99:9:99:10 | i5 indirection | semmle.label | i5 indirection |
|
||||
| ifs.c:106:9:106:10 | i6 indirection | semmle.label | i6 indirection |
|
||||
| ifs.c:112:9:112:10 | i7 indirection | semmle.label | i7 indirection |
|
||||
| ifs.c:118:9:118:10 | i8 indirection | semmle.label | i8 indirection |
|
||||
| ifs.c:124:9:124:10 | i9 indirection | semmle.label | i9 indirection |
|
||||
subpaths
|
||||
#select
|
||||
| ifs.c:62:9:62:10 | c7 | ifs.c:61:8:61:11 | argv | ifs.c:62:9:62:10 | c7 | The value of this argument may come from $@ and is being used as a formatting argument to printf(format). | ifs.c:61:8:61:11 | argv | argv |
|
||||
| ifs.c:69:9:69:10 | c8 | ifs.c:68:8:68:11 | argv | ifs.c:69:9:69:10 | c8 | The value of this argument may come from $@ and is being used as a formatting argument to printf(format). | ifs.c:68:8:68:11 | argv | argv |
|
||||
| ifs.c:75:9:75:10 | i1 | ifs.c:74:8:74:11 | argv | ifs.c:75:9:75:10 | i1 | The value of this argument may come from $@ and is being used as a formatting argument to printf(format). | ifs.c:74:8:74:11 | argv | argv |
|
||||
| ifs.c:81:9:81:10 | i2 | ifs.c:80:8:80:11 | argv | ifs.c:81:9:81:10 | i2 | The value of this argument may come from $@ and is being used as a formatting argument to printf(format). | ifs.c:80:8:80:11 | argv | argv |
|
||||
| ifs.c:87:9:87:10 | i3 | ifs.c:86:8:86:11 | argv | ifs.c:87:9:87:10 | i3 | The value of this argument may come from $@ and is being used as a formatting argument to printf(format). | ifs.c:86:8:86:11 | argv | argv |
|
||||
| ifs.c:93:9:93:10 | i4 | ifs.c:92:8:92:11 | argv | ifs.c:93:9:93:10 | i4 | The value of this argument may come from $@ and is being used as a formatting argument to printf(format). | ifs.c:92:8:92:11 | argv | argv |
|
||||
| ifs.c:99:9:99:10 | i5 | ifs.c:98:8:98:11 | argv | ifs.c:99:9:99:10 | i5 | The value of this argument may come from $@ and is being used as a formatting argument to printf(format). | ifs.c:98:8:98:11 | argv | argv |
|
||||
| ifs.c:106:9:106:10 | i6 | ifs.c:105:8:105:11 | argv | ifs.c:106:9:106:10 | i6 | The value of this argument may come from $@ and is being used as a formatting argument to printf(format). | ifs.c:105:8:105:11 | argv | argv |
|
||||
| ifs.c:112:9:112:10 | i7 | ifs.c:111:8:111:11 | argv | ifs.c:112:9:112:10 | i7 | The value of this argument may come from $@ and is being used as a formatting argument to printf(format). | ifs.c:111:8:111:11 | argv | argv |
|
||||
| ifs.c:118:9:118:10 | i8 | ifs.c:117:8:117:11 | argv | ifs.c:118:9:118:10 | i8 | The value of this argument may come from $@ and is being used as a formatting argument to printf(format). | ifs.c:117:8:117:11 | argv | argv |
|
||||
| ifs.c:124:9:124:10 | i9 | ifs.c:123:8:123:11 | argv | ifs.c:124:9:124:10 | i9 | The value of this argument may come from $@ and is being used as a formatting argument to printf(format). | ifs.c:123:8:123:11 | argv | argv |
|
||||
| ifs.c:62:9:62:10 | c7 indirection | ifs.c:16:27:16:30 | argv indirection | ifs.c:62:9:62:10 | c7 indirection | The value of this argument may come from $@ and is being used as a formatting argument to printf(format). | ifs.c:16:27:16:30 | argv indirection | a command-line argument |
|
||||
| ifs.c:69:9:69:10 | c8 indirection | ifs.c:16:27:16:30 | argv indirection | ifs.c:69:9:69:10 | c8 indirection | The value of this argument may come from $@ and is being used as a formatting argument to printf(format). | ifs.c:16:27:16:30 | argv indirection | a command-line argument |
|
||||
| ifs.c:75:9:75:10 | i1 indirection | ifs.c:16:27:16:30 | argv indirection | ifs.c:75:9:75:10 | i1 indirection | The value of this argument may come from $@ and is being used as a formatting argument to printf(format). | ifs.c:16:27:16:30 | argv indirection | a command-line argument |
|
||||
| ifs.c:81:9:81:10 | i2 indirection | ifs.c:16:27:16:30 | argv indirection | ifs.c:81:9:81:10 | i2 indirection | The value of this argument may come from $@ and is being used as a formatting argument to printf(format). | ifs.c:16:27:16:30 | argv indirection | a command-line argument |
|
||||
| ifs.c:87:9:87:10 | i3 indirection | ifs.c:16:27:16:30 | argv indirection | ifs.c:87:9:87:10 | i3 indirection | The value of this argument may come from $@ and is being used as a formatting argument to printf(format). | ifs.c:16:27:16:30 | argv indirection | a command-line argument |
|
||||
| ifs.c:93:9:93:10 | i4 indirection | ifs.c:16:27:16:30 | argv indirection | ifs.c:93:9:93:10 | i4 indirection | The value of this argument may come from $@ and is being used as a formatting argument to printf(format). | ifs.c:16:27:16:30 | argv indirection | a command-line argument |
|
||||
| ifs.c:99:9:99:10 | i5 indirection | ifs.c:16:27:16:30 | argv indirection | ifs.c:99:9:99:10 | i5 indirection | The value of this argument may come from $@ and is being used as a formatting argument to printf(format). | ifs.c:16:27:16:30 | argv indirection | a command-line argument |
|
||||
| ifs.c:106:9:106:10 | i6 indirection | ifs.c:16:27:16:30 | argv indirection | ifs.c:106:9:106:10 | i6 indirection | The value of this argument may come from $@ and is being used as a formatting argument to printf(format). | ifs.c:16:27:16:30 | argv indirection | a command-line argument |
|
||||
| ifs.c:112:9:112:10 | i7 indirection | ifs.c:16:27:16:30 | argv indirection | ifs.c:112:9:112:10 | i7 indirection | The value of this argument may come from $@ and is being used as a formatting argument to printf(format). | ifs.c:16:27:16:30 | argv indirection | a command-line argument |
|
||||
| ifs.c:118:9:118:10 | i8 indirection | ifs.c:16:27:16:30 | argv indirection | ifs.c:118:9:118:10 | i8 indirection | The value of this argument may come from $@ and is being used as a formatting argument to printf(format). | ifs.c:16:27:16:30 | argv indirection | a command-line argument |
|
||||
| ifs.c:124:9:124:10 | i9 indirection | ifs.c:16:27:16:30 | argv indirection | ifs.c:124:9:124:10 | i9 indirection | The value of this argument may come from $@ and is being used as a formatting argument to printf(format). | ifs.c:16:27:16:30 | argv indirection | a command-line argument |
|
||||
|
||||
@@ -5,33 +5,22 @@ edges
|
||||
| test.cpp:39:27:39:30 | argv indirection | test.cpp:49:32:49:35 | size |
|
||||
| test.cpp:39:27:39:30 | argv indirection | test.cpp:50:17:50:30 | size |
|
||||
| test.cpp:39:27:39:30 | argv indirection | test.cpp:53:35:53:60 | ... * ... |
|
||||
| test.cpp:124:18:124:31 | call to getenv | test.cpp:128:24:128:41 | ... * ... |
|
||||
| test.cpp:124:18:124:31 | call to getenv indirection | test.cpp:128:24:128:41 | ... * ... |
|
||||
| test.cpp:133:19:133:32 | call to getenv | test.cpp:135:10:135:27 | ... * ... |
|
||||
| test.cpp:133:19:133:32 | call to getenv indirection | test.cpp:135:10:135:27 | ... * ... |
|
||||
| test.cpp:148:20:148:33 | call to getenv | test.cpp:152:11:152:28 | ... * ... |
|
||||
| test.cpp:148:20:148:33 | call to getenv indirection | test.cpp:152:11:152:28 | ... * ... |
|
||||
| test.cpp:209:8:209:23 | get_tainted_size indirection | test.cpp:241:9:241:24 | call to get_tainted_size |
|
||||
| test.cpp:211:14:211:27 | call to getenv | test.cpp:209:8:209:23 | get_tainted_size indirection |
|
||||
| test.cpp:211:14:211:27 | call to getenv indirection | test.cpp:209:8:209:23 | get_tainted_size indirection |
|
||||
| test.cpp:230:21:230:21 | s | test.cpp:231:21:231:21 | s |
|
||||
| test.cpp:237:24:237:37 | call to getenv | test.cpp:239:9:239:18 | local_size |
|
||||
| test.cpp:237:24:237:37 | call to getenv | test.cpp:245:11:245:20 | local_size |
|
||||
| test.cpp:237:24:237:37 | call to getenv | test.cpp:247:10:247:19 | local_size |
|
||||
| test.cpp:237:24:237:37 | call to getenv indirection | test.cpp:239:9:239:18 | local_size |
|
||||
| test.cpp:237:24:237:37 | call to getenv indirection | test.cpp:245:11:245:20 | local_size |
|
||||
| test.cpp:237:24:237:37 | call to getenv indirection | test.cpp:247:10:247:19 | local_size |
|
||||
| test.cpp:247:10:247:19 | local_size | test.cpp:230:21:230:21 | s |
|
||||
| test.cpp:250:20:250:27 | out_size | test.cpp:289:17:289:20 | get_size output argument |
|
||||
| test.cpp:250:20:250:27 | out_size | test.cpp:305:18:305:21 | get_size output argument |
|
||||
| test.cpp:251:18:251:31 | call to getenv | test.cpp:250:20:250:27 | out_size |
|
||||
| test.cpp:251:18:251:31 | call to getenv indirection | test.cpp:250:20:250:27 | out_size |
|
||||
| test.cpp:259:20:259:33 | call to getenv | test.cpp:263:11:263:29 | ... * ... |
|
||||
| test.cpp:259:20:259:33 | call to getenv indirection | test.cpp:263:11:263:29 | ... * ... |
|
||||
| test.cpp:289:17:289:20 | get_size output argument | test.cpp:291:11:291:28 | ... * ... |
|
||||
| test.cpp:305:18:305:21 | get_size output argument | test.cpp:308:10:308:27 | ... * ... |
|
||||
| test.cpp:353:18:353:31 | call to getenv | test.cpp:355:35:355:38 | size |
|
||||
| test.cpp:353:18:353:31 | call to getenv | test.cpp:356:35:356:38 | size |
|
||||
| test.cpp:353:18:353:31 | call to getenv indirection | test.cpp:355:35:355:38 | size |
|
||||
| test.cpp:353:18:353:31 | call to getenv indirection | test.cpp:356:35:356:38 | size |
|
||||
nodes
|
||||
@@ -42,37 +31,29 @@ nodes
|
||||
| test.cpp:49:32:49:35 | size | semmle.label | size |
|
||||
| test.cpp:50:17:50:30 | size | semmle.label | size |
|
||||
| test.cpp:53:35:53:60 | ... * ... | semmle.label | ... * ... |
|
||||
| test.cpp:124:18:124:31 | call to getenv | semmle.label | call to getenv |
|
||||
| test.cpp:124:18:124:31 | call to getenv indirection | semmle.label | call to getenv indirection |
|
||||
| test.cpp:128:24:128:41 | ... * ... | semmle.label | ... * ... |
|
||||
| test.cpp:133:19:133:32 | call to getenv | semmle.label | call to getenv |
|
||||
| test.cpp:133:19:133:32 | call to getenv indirection | semmle.label | call to getenv indirection |
|
||||
| test.cpp:135:10:135:27 | ... * ... | semmle.label | ... * ... |
|
||||
| test.cpp:148:20:148:33 | call to getenv | semmle.label | call to getenv |
|
||||
| test.cpp:148:20:148:33 | call to getenv indirection | semmle.label | call to getenv indirection |
|
||||
| test.cpp:152:11:152:28 | ... * ... | semmle.label | ... * ... |
|
||||
| test.cpp:209:8:209:23 | get_tainted_size indirection | semmle.label | get_tainted_size indirection |
|
||||
| test.cpp:211:14:211:27 | call to getenv | semmle.label | call to getenv |
|
||||
| test.cpp:211:14:211:27 | call to getenv indirection | semmle.label | call to getenv indirection |
|
||||
| test.cpp:230:21:230:21 | s | semmle.label | s |
|
||||
| test.cpp:231:21:231:21 | s | semmle.label | s |
|
||||
| test.cpp:237:24:237:37 | call to getenv | semmle.label | call to getenv |
|
||||
| test.cpp:237:24:237:37 | call to getenv indirection | semmle.label | call to getenv indirection |
|
||||
| test.cpp:239:9:239:18 | local_size | semmle.label | local_size |
|
||||
| test.cpp:241:9:241:24 | call to get_tainted_size | semmle.label | call to get_tainted_size |
|
||||
| test.cpp:245:11:245:20 | local_size | semmle.label | local_size |
|
||||
| test.cpp:247:10:247:19 | local_size | semmle.label | local_size |
|
||||
| test.cpp:250:20:250:27 | out_size | semmle.label | out_size |
|
||||
| test.cpp:251:18:251:31 | call to getenv | semmle.label | call to getenv |
|
||||
| test.cpp:251:18:251:31 | call to getenv indirection | semmle.label | call to getenv indirection |
|
||||
| test.cpp:259:20:259:33 | call to getenv | semmle.label | call to getenv |
|
||||
| test.cpp:259:20:259:33 | call to getenv indirection | semmle.label | call to getenv indirection |
|
||||
| test.cpp:263:11:263:29 | ... * ... | semmle.label | ... * ... |
|
||||
| test.cpp:289:17:289:20 | get_size output argument | semmle.label | get_size output argument |
|
||||
| test.cpp:291:11:291:28 | ... * ... | semmle.label | ... * ... |
|
||||
| test.cpp:305:18:305:21 | get_size output argument | semmle.label | get_size output argument |
|
||||
| test.cpp:308:10:308:27 | ... * ... | semmle.label | ... * ... |
|
||||
| test.cpp:353:18:353:31 | call to getenv | semmle.label | call to getenv |
|
||||
| test.cpp:353:18:353:31 | call to getenv indirection | semmle.label | call to getenv indirection |
|
||||
| test.cpp:355:35:355:38 | size | semmle.label | size |
|
||||
| test.cpp:356:35:356:38 | size | semmle.label | size |
|
||||
@@ -84,27 +65,15 @@ subpaths
|
||||
| test.cpp:49:25:49:30 | call to malloc | test.cpp:39:27:39:30 | argv indirection | test.cpp:49:32:49:35 | size | This allocation size is derived from $@ and might overflow. | test.cpp:39:27:39:30 | argv indirection | user input (a command-line argument) |
|
||||
| test.cpp:50:17:50:30 | new[] | test.cpp:39:27:39:30 | argv indirection | test.cpp:50:17:50:30 | size | This allocation size is derived from $@ and might overflow. | test.cpp:39:27:39:30 | argv indirection | user input (a command-line argument) |
|
||||
| test.cpp:53:21:53:27 | call to realloc | test.cpp:39:27:39:30 | argv indirection | test.cpp:53:35:53:60 | ... * ... | This allocation size is derived from $@ and might overflow. | test.cpp:39:27:39:30 | argv indirection | user input (a command-line argument) |
|
||||
| test.cpp:128:17:128:22 | call to malloc | test.cpp:124:18:124:31 | call to getenv | test.cpp:128:24:128:41 | ... * ... | This allocation size is derived from $@ and might overflow. | test.cpp:124:18:124:31 | call to getenv | user input (an environment variable) |
|
||||
| test.cpp:128:17:128:22 | call to malloc | test.cpp:124:18:124:31 | call to getenv indirection | test.cpp:128:24:128:41 | ... * ... | This allocation size is derived from $@ and might overflow. | test.cpp:124:18:124:31 | call to getenv indirection | user input (an environment variable) |
|
||||
| test.cpp:135:3:135:8 | call to malloc | test.cpp:133:19:133:32 | call to getenv | test.cpp:135:10:135:27 | ... * ... | This allocation size is derived from $@ and might overflow. | test.cpp:133:19:133:32 | call to getenv | user input (an environment variable) |
|
||||
| test.cpp:135:3:135:8 | call to malloc | test.cpp:133:19:133:32 | call to getenv indirection | test.cpp:135:10:135:27 | ... * ... | This allocation size is derived from $@ and might overflow. | test.cpp:133:19:133:32 | call to getenv indirection | user input (an environment variable) |
|
||||
| test.cpp:152:4:152:9 | call to malloc | test.cpp:148:20:148:33 | call to getenv | test.cpp:152:11:152:28 | ... * ... | This allocation size is derived from $@ and might overflow. | test.cpp:148:20:148:33 | call to getenv | user input (an environment variable) |
|
||||
| test.cpp:152:4:152:9 | call to malloc | test.cpp:148:20:148:33 | call to getenv indirection | test.cpp:152:11:152:28 | ... * ... | This allocation size is derived from $@ and might overflow. | test.cpp:148:20:148:33 | call to getenv indirection | user input (an environment variable) |
|
||||
| test.cpp:231:14:231:19 | call to malloc | test.cpp:237:24:237:37 | call to getenv | test.cpp:231:21:231:21 | s | This allocation size is derived from $@ and might overflow. | test.cpp:237:24:237:37 | call to getenv | user input (an environment variable) |
|
||||
| test.cpp:231:14:231:19 | call to malloc | test.cpp:237:24:237:37 | call to getenv indirection | test.cpp:231:21:231:21 | s | This allocation size is derived from $@ and might overflow. | test.cpp:237:24:237:37 | call to getenv indirection | user input (an environment variable) |
|
||||
| test.cpp:239:2:239:7 | call to malloc | test.cpp:237:24:237:37 | call to getenv | test.cpp:239:9:239:18 | local_size | This allocation size is derived from $@ and might overflow. | test.cpp:237:24:237:37 | call to getenv | user input (an environment variable) |
|
||||
| test.cpp:239:2:239:7 | call to malloc | test.cpp:237:24:237:37 | call to getenv indirection | test.cpp:239:9:239:18 | local_size | This allocation size is derived from $@ and might overflow. | test.cpp:237:24:237:37 | call to getenv indirection | user input (an environment variable) |
|
||||
| test.cpp:241:2:241:7 | call to malloc | test.cpp:211:14:211:27 | call to getenv | test.cpp:241:9:241:24 | call to get_tainted_size | This allocation size is derived from $@ and might overflow. | test.cpp:211:14:211:27 | call to getenv | user input (an environment variable) |
|
||||
| test.cpp:241:2:241:7 | call to malloc | test.cpp:211:14:211:27 | call to getenv indirection | test.cpp:241:9:241:24 | call to get_tainted_size | This allocation size is derived from $@ and might overflow. | test.cpp:211:14:211:27 | call to getenv indirection | user input (an environment variable) |
|
||||
| test.cpp:245:2:245:9 | call to my_alloc | test.cpp:237:24:237:37 | call to getenv | test.cpp:245:11:245:20 | local_size | This allocation size is derived from $@ and might overflow. | test.cpp:237:24:237:37 | call to getenv | user input (an environment variable) |
|
||||
| test.cpp:245:2:245:9 | call to my_alloc | test.cpp:237:24:237:37 | call to getenv indirection | test.cpp:245:11:245:20 | local_size | This allocation size is derived from $@ and might overflow. | test.cpp:237:24:237:37 | call to getenv indirection | user input (an environment variable) |
|
||||
| test.cpp:263:4:263:9 | call to malloc | test.cpp:259:20:259:33 | call to getenv | test.cpp:263:11:263:29 | ... * ... | This allocation size is derived from $@ and might overflow. | test.cpp:259:20:259:33 | call to getenv | user input (an environment variable) |
|
||||
| test.cpp:263:4:263:9 | call to malloc | test.cpp:259:20:259:33 | call to getenv indirection | test.cpp:263:11:263:29 | ... * ... | This allocation size is derived from $@ and might overflow. | test.cpp:259:20:259:33 | call to getenv indirection | user input (an environment variable) |
|
||||
| test.cpp:291:4:291:9 | call to malloc | test.cpp:251:18:251:31 | call to getenv | test.cpp:291:11:291:28 | ... * ... | This allocation size is derived from $@ and might overflow. | test.cpp:251:18:251:31 | call to getenv | user input (an environment variable) |
|
||||
| test.cpp:291:4:291:9 | call to malloc | test.cpp:251:18:251:31 | call to getenv indirection | test.cpp:291:11:291:28 | ... * ... | This allocation size is derived from $@ and might overflow. | test.cpp:251:18:251:31 | call to getenv indirection | user input (an environment variable) |
|
||||
| test.cpp:308:3:308:8 | call to malloc | test.cpp:251:18:251:31 | call to getenv | test.cpp:308:10:308:27 | ... * ... | This allocation size is derived from $@ and might overflow. | test.cpp:251:18:251:31 | call to getenv | user input (an environment variable) |
|
||||
| test.cpp:308:3:308:8 | call to malloc | test.cpp:251:18:251:31 | call to getenv indirection | test.cpp:308:10:308:27 | ... * ... | This allocation size is derived from $@ and might overflow. | test.cpp:251:18:251:31 | call to getenv indirection | user input (an environment variable) |
|
||||
| test.cpp:355:25:355:33 | call to MyMalloc1 | test.cpp:353:18:353:31 | call to getenv | test.cpp:355:35:355:38 | size | This allocation size is derived from $@ and might overflow. | test.cpp:353:18:353:31 | call to getenv | user input (an environment variable) |
|
||||
| test.cpp:355:25:355:33 | call to MyMalloc1 | test.cpp:353:18:353:31 | call to getenv indirection | test.cpp:355:35:355:38 | size | This allocation size is derived from $@ and might overflow. | test.cpp:353:18:353:31 | call to getenv indirection | user input (an environment variable) |
|
||||
| test.cpp:356:25:356:33 | call to MyMalloc2 | test.cpp:353:18:353:31 | call to getenv | test.cpp:356:35:356:38 | size | This allocation size is derived from $@ and might overflow. | test.cpp:353:18:353:31 | call to getenv | user input (an environment variable) |
|
||||
| test.cpp:356:25:356:33 | call to MyMalloc2 | test.cpp:353:18:353:31 | call to getenv indirection | test.cpp:356:35:356:38 | size | This allocation size is derived from $@ and might overflow. | test.cpp:353:18:353:31 | call to getenv indirection | user input (an environment variable) |
|
||||
|
||||
@@ -1,54 +1,26 @@
|
||||
edges
|
||||
| test.cpp:16:25:16:30 | call to getenv | test.cpp:20:14:20:20 | address |
|
||||
| test.cpp:16:25:16:30 | call to getenv | test.cpp:20:14:20:20 | address |
|
||||
| test.cpp:16:25:16:42 | call to getenv | test.cpp:20:14:20:20 | address |
|
||||
| test.cpp:16:25:16:42 | call to getenv | test.cpp:20:14:20:20 | address |
|
||||
| test.cpp:27:25:27:30 | call to getenv | test.cpp:31:14:31:20 | address |
|
||||
| test.cpp:27:25:27:30 | call to getenv | test.cpp:31:14:31:20 | address |
|
||||
| test.cpp:27:25:27:42 | call to getenv | test.cpp:31:14:31:20 | address |
|
||||
| test.cpp:27:25:27:42 | call to getenv | test.cpp:31:14:31:20 | address |
|
||||
| test.cpp:38:25:38:30 | call to getenv | test.cpp:42:14:42:20 | address |
|
||||
| test.cpp:38:25:38:30 | call to getenv | test.cpp:42:14:42:20 | address |
|
||||
| test.cpp:38:25:38:42 | call to getenv | test.cpp:42:14:42:20 | address |
|
||||
| test.cpp:38:25:38:42 | call to getenv | test.cpp:42:14:42:20 | address |
|
||||
| test.cpp:49:25:49:30 | call to getenv | test.cpp:52:14:52:20 | address |
|
||||
| test.cpp:49:25:49:30 | call to getenv | test.cpp:52:14:52:20 | address |
|
||||
| test.cpp:49:25:49:30 | call to getenv | test.cpp:56:14:56:20 | address |
|
||||
| test.cpp:49:25:49:30 | call to getenv | test.cpp:56:14:56:20 | address |
|
||||
| test.cpp:49:25:49:30 | call to getenv | test.cpp:60:14:60:20 | address |
|
||||
| test.cpp:49:25:49:30 | call to getenv | test.cpp:60:14:60:20 | address |
|
||||
| test.cpp:49:25:49:42 | call to getenv | test.cpp:52:14:52:20 | address |
|
||||
| test.cpp:49:25:49:42 | call to getenv | test.cpp:52:14:52:20 | address |
|
||||
| test.cpp:49:25:49:42 | call to getenv | test.cpp:56:14:56:20 | address |
|
||||
| test.cpp:49:25:49:42 | call to getenv | test.cpp:56:14:56:20 | address |
|
||||
| test.cpp:49:25:49:42 | call to getenv | test.cpp:60:14:60:20 | address |
|
||||
| test.cpp:49:25:49:42 | call to getenv | test.cpp:60:14:60:20 | address |
|
||||
subpaths
|
||||
| test.cpp:16:25:16:42 | call to getenv indirection | test.cpp:20:14:20:20 | address indirection |
|
||||
| test.cpp:27:25:27:42 | call to getenv indirection | test.cpp:31:14:31:20 | address indirection |
|
||||
| test.cpp:38:25:38:42 | call to getenv indirection | test.cpp:42:14:42:20 | address indirection |
|
||||
| test.cpp:49:25:49:42 | call to getenv indirection | test.cpp:52:14:52:20 | address indirection |
|
||||
| test.cpp:49:25:49:42 | call to getenv indirection | test.cpp:56:14:56:20 | address indirection |
|
||||
| test.cpp:49:25:49:42 | call to getenv indirection | test.cpp:60:14:60:20 | address indirection |
|
||||
nodes
|
||||
| test.cpp:16:25:16:30 | call to getenv | semmle.label | call to getenv |
|
||||
| test.cpp:16:25:16:42 | call to getenv | semmle.label | call to getenv |
|
||||
| test.cpp:20:14:20:20 | address | semmle.label | address |
|
||||
| test.cpp:20:14:20:20 | address | semmle.label | address |
|
||||
| test.cpp:27:25:27:30 | call to getenv | semmle.label | call to getenv |
|
||||
| test.cpp:27:25:27:42 | call to getenv | semmle.label | call to getenv |
|
||||
| test.cpp:31:14:31:20 | address | semmle.label | address |
|
||||
| test.cpp:31:14:31:20 | address | semmle.label | address |
|
||||
| test.cpp:38:25:38:30 | call to getenv | semmle.label | call to getenv |
|
||||
| test.cpp:38:25:38:42 | call to getenv | semmle.label | call to getenv |
|
||||
| test.cpp:42:14:42:20 | address | semmle.label | address |
|
||||
| test.cpp:42:14:42:20 | address | semmle.label | address |
|
||||
| test.cpp:49:25:49:30 | call to getenv | semmle.label | call to getenv |
|
||||
| test.cpp:49:25:49:42 | call to getenv | semmle.label | call to getenv |
|
||||
| test.cpp:52:14:52:20 | address | semmle.label | address |
|
||||
| test.cpp:52:14:52:20 | address | semmle.label | address |
|
||||
| test.cpp:56:14:56:20 | address | semmle.label | address |
|
||||
| test.cpp:56:14:56:20 | address | semmle.label | address |
|
||||
| test.cpp:60:14:60:20 | address | semmle.label | address |
|
||||
| test.cpp:60:14:60:20 | address | semmle.label | address |
|
||||
| test.cpp:16:25:16:42 | call to getenv indirection | semmle.label | call to getenv indirection |
|
||||
| test.cpp:20:14:20:20 | address indirection | semmle.label | address indirection |
|
||||
| test.cpp:27:25:27:42 | call to getenv indirection | semmle.label | call to getenv indirection |
|
||||
| test.cpp:31:14:31:20 | address indirection | semmle.label | address indirection |
|
||||
| test.cpp:38:25:38:42 | call to getenv indirection | semmle.label | call to getenv indirection |
|
||||
| test.cpp:42:14:42:20 | address indirection | semmle.label | address indirection |
|
||||
| test.cpp:49:25:49:42 | call to getenv indirection | semmle.label | call to getenv indirection |
|
||||
| test.cpp:52:14:52:20 | address indirection | semmle.label | address indirection |
|
||||
| test.cpp:56:14:56:20 | address indirection | semmle.label | address indirection |
|
||||
| test.cpp:60:14:60:20 | address indirection | semmle.label | address indirection |
|
||||
subpaths
|
||||
#select
|
||||
| test.cpp:20:7:20:12 | call to strcmp | test.cpp:16:25:16:30 | call to getenv | test.cpp:20:14:20:20 | address | Untrusted input $@ might be vulnerable to a spoofing attack. | test.cpp:16:25:16:30 | call to getenv | call to getenv |
|
||||
| test.cpp:31:7:31:12 | call to strcmp | test.cpp:27:25:27:30 | call to getenv | test.cpp:31:14:31:20 | address | Untrusted input $@ might be vulnerable to a spoofing attack. | test.cpp:27:25:27:30 | call to getenv | call to getenv |
|
||||
| test.cpp:42:7:42:12 | call to strcmp | test.cpp:38:25:38:30 | call to getenv | test.cpp:42:14:42:20 | address | Untrusted input $@ might be vulnerable to a spoofing attack. | test.cpp:38:25:38:30 | call to getenv | call to getenv |
|
||||
| test.cpp:52:7:52:12 | call to strcmp | test.cpp:49:25:49:30 | call to getenv | test.cpp:52:14:52:20 | address | Untrusted input $@ might be vulnerable to a spoofing attack. | test.cpp:49:25:49:30 | call to getenv | call to getenv |
|
||||
| test.cpp:56:7:56:12 | call to strcmp | test.cpp:49:25:49:30 | call to getenv | test.cpp:56:14:56:20 | address | Untrusted input $@ might be vulnerable to a spoofing attack. | test.cpp:49:25:49:30 | call to getenv | call to getenv |
|
||||
| test.cpp:60:7:60:12 | call to strcmp | test.cpp:49:25:49:30 | call to getenv | test.cpp:60:14:60:20 | address | Untrusted input $@ might be vulnerable to a spoofing attack. | test.cpp:49:25:49:30 | call to getenv | call to getenv |
|
||||
| test.cpp:20:7:20:12 | call to strcmp | test.cpp:16:25:16:42 | call to getenv indirection | test.cpp:20:14:20:20 | address indirection | Untrusted input $@ might be vulnerable to a spoofing attack. | test.cpp:16:25:16:42 | call to getenv indirection | an environment variable |
|
||||
| test.cpp:31:7:31:12 | call to strcmp | test.cpp:27:25:27:42 | call to getenv indirection | test.cpp:31:14:31:20 | address indirection | Untrusted input $@ might be vulnerable to a spoofing attack. | test.cpp:27:25:27:42 | call to getenv indirection | an environment variable |
|
||||
| test.cpp:42:7:42:12 | call to strcmp | test.cpp:38:25:38:42 | call to getenv indirection | test.cpp:42:14:42:20 | address indirection | Untrusted input $@ might be vulnerable to a spoofing attack. | test.cpp:38:25:38:42 | call to getenv indirection | an environment variable |
|
||||
| test.cpp:52:7:52:12 | call to strcmp | test.cpp:49:25:49:42 | call to getenv indirection | test.cpp:52:14:52:20 | address indirection | Untrusted input $@ might be vulnerable to a spoofing attack. | test.cpp:49:25:49:42 | call to getenv indirection | an environment variable |
|
||||
| test.cpp:56:7:56:12 | call to strcmp | test.cpp:49:25:49:42 | call to getenv indirection | test.cpp:56:14:56:20 | address indirection | Untrusted input $@ might be vulnerable to a spoofing attack. | test.cpp:49:25:49:42 | call to getenv indirection | an environment variable |
|
||||
| test.cpp:60:7:60:12 | call to strcmp | test.cpp:49:25:49:42 | call to getenv indirection | test.cpp:60:14:60:20 | address indirection | Untrusted input $@ might be vulnerable to a spoofing attack. | test.cpp:49:25:49:42 | call to getenv indirection | an environment variable |
|
||||
|
||||
@@ -0,0 +1,12 @@
|
||||
| test.cpp:165:34:165:38 | call to c_str | The underlying string object is destroyed after the call to 'c_str' returns. |
|
||||
| test.cpp:166:39:166:43 | call to c_str | The underlying string object is destroyed after the call to 'c_str' returns. |
|
||||
| test.cpp:167:44:167:48 | call to c_str | The underlying string object is destroyed after the call to 'c_str' returns. |
|
||||
| test.cpp:169:29:169:33 | call to c_str | The underlying string object is destroyed after the call to 'c_str' returns. |
|
||||
| test.cpp:178:37:178:41 | call to c_str | The underlying string object is destroyed after the call to 'c_str' returns. |
|
||||
| test.cpp:181:39:181:43 | call to c_str | The underlying string object is destroyed after the call to 'c_str' returns. |
|
||||
| test.cpp:183:37:183:41 | call to c_str | The underlying string object is destroyed after the call to 'c_str' returns. |
|
||||
| test.cpp:187:34:187:37 | call to data | The underlying string object is destroyed after the call to 'data' returns. |
|
||||
| test.cpp:188:39:188:42 | call to data | The underlying string object is destroyed after the call to 'data' returns. |
|
||||
| test.cpp:189:44:189:47 | call to data | The underlying string object is destroyed after the call to 'data' returns. |
|
||||
| test.cpp:191:29:191:32 | call to data | The underlying string object is destroyed after the call to 'data' returns. |
|
||||
| test.cpp:193:31:193:35 | call to c_str | The underlying string object is destroyed after the call to 'c_str' returns. |
|
||||
@@ -0,0 +1,2 @@
|
||||
|
||||
Security/CWE/CWE-416/UseOfStringAfterLifetimeEnds.ql
|
||||
@@ -0,0 +1,219 @@
|
||||
typedef unsigned long size_t;
|
||||
|
||||
namespace std {
|
||||
template<class T> struct remove_reference { typedef T type; };
|
||||
|
||||
template<class T> struct remove_reference<T &> { typedef T type; };
|
||||
|
||||
template<class T> struct remove_reference<T &&> { typedef T type; };
|
||||
|
||||
template<class T> using remove_reference_t = typename remove_reference<T>::type;
|
||||
|
||||
template< class T > std::remove_reference_t<T>&& move( T&& t );
|
||||
}
|
||||
|
||||
// --- iterator ---
|
||||
|
||||
namespace std {
|
||||
template<class T> struct remove_const { typedef T type; };
|
||||
|
||||
template<class T> struct remove_const<const T> { typedef T type; };
|
||||
|
||||
// `remove_const_t<T>` removes any `const` specifier from `T`
|
||||
template<class T> using remove_const_t = typename remove_const<T>::type;
|
||||
|
||||
struct ptrdiff_t;
|
||||
|
||||
template<class I> struct iterator_traits;
|
||||
|
||||
template <class Category,
|
||||
class value_type,
|
||||
class difference_type = ptrdiff_t,
|
||||
class pointer_type = value_type*,
|
||||
class reference_type = value_type&>
|
||||
struct iterator {
|
||||
typedef Category iterator_category;
|
||||
|
||||
iterator();
|
||||
iterator(iterator<Category, remove_const_t<value_type> > const &other); // non-const -> const conversion constructor
|
||||
|
||||
iterator &operator++();
|
||||
iterator operator++(int);
|
||||
iterator &operator--();
|
||||
iterator operator--(int);
|
||||
bool operator==(iterator other) const;
|
||||
bool operator!=(iterator other) const;
|
||||
reference_type operator*() const;
|
||||
pointer_type operator->() const;
|
||||
iterator operator+(int);
|
||||
iterator operator-(int);
|
||||
iterator &operator+=(int);
|
||||
iterator &operator-=(int);
|
||||
int operator-(iterator);
|
||||
reference_type operator[](int);
|
||||
};
|
||||
|
||||
struct input_iterator_tag {};
|
||||
struct forward_iterator_tag : public input_iterator_tag {};
|
||||
struct bidirectional_iterator_tag : public forward_iterator_tag {};
|
||||
struct random_access_iterator_tag : public bidirectional_iterator_tag {};
|
||||
}
|
||||
|
||||
// --- string ---
|
||||
|
||||
namespace std
|
||||
{
|
||||
template<class charT> struct char_traits;
|
||||
|
||||
typedef size_t streamsize;
|
||||
|
||||
template <class T> class allocator {
|
||||
public:
|
||||
allocator() throw();
|
||||
typedef size_t size_type;
|
||||
};
|
||||
|
||||
template<class charT, class traits = char_traits<charT>, class Allocator = allocator<charT> >
|
||||
class basic_string {
|
||||
public:
|
||||
using value_type = charT;
|
||||
using reference = value_type&;
|
||||
using const_reference = const value_type&;
|
||||
typedef typename Allocator::size_type size_type;
|
||||
static const size_type npos = -1;
|
||||
|
||||
explicit basic_string(const Allocator& a = Allocator());
|
||||
basic_string(const charT* s, const Allocator& a = Allocator());
|
||||
template<class InputIterator> basic_string(InputIterator begin, InputIterator end, const Allocator& a = Allocator());
|
||||
|
||||
const charT* c_str() const;
|
||||
charT* data() noexcept;
|
||||
size_t length() const;
|
||||
|
||||
typedef std::iterator<random_access_iterator_tag, charT> iterator;
|
||||
typedef std::iterator<random_access_iterator_tag, const charT> const_iterator;
|
||||
|
||||
iterator begin();
|
||||
iterator end();
|
||||
const_iterator begin() const;
|
||||
const_iterator end() const;
|
||||
const_iterator cbegin() const;
|
||||
const_iterator cend() const;
|
||||
|
||||
const_reference operator[](size_type pos) const;
|
||||
reference operator[](size_type pos);
|
||||
const_reference at(size_type n) const;
|
||||
reference at(size_type n);
|
||||
basic_string& insert(size_type pos, const basic_string& str);
|
||||
basic_string& insert(size_type pos, size_type n, charT c);
|
||||
basic_string& insert(size_type pos, const charT* s);
|
||||
iterator insert(const_iterator p, size_type n, charT c);
|
||||
template<class InputIterator> iterator insert(const_iterator p, InputIterator first, InputIterator last);
|
||||
basic_string& replace(size_type pos1, size_type n1, const basic_string& str);
|
||||
basic_string& replace(size_type pos1, size_type n1, size_type n2, charT c);
|
||||
};
|
||||
|
||||
template<class charT, class traits, class Allocator> basic_string<charT, traits, Allocator> operator+(const basic_string<charT, traits, Allocator>& lhs, const basic_string<charT, traits, Allocator>& rhs);
|
||||
template<class charT, class traits, class Allocator> basic_string<charT, traits, Allocator> operator+(const basic_string<charT, traits, Allocator>& lhs, const charT* rhs);
|
||||
|
||||
typedef basic_string<char> string;
|
||||
}
|
||||
|
||||
// --- vector ---
|
||||
|
||||
namespace std {
|
||||
template<class T, class Allocator = allocator<T>>
|
||||
class vector {
|
||||
public:
|
||||
using value_type = T;
|
||||
using reference = value_type&;
|
||||
using const_reference = const value_type&;
|
||||
using size_type = unsigned int;
|
||||
using iterator = std::iterator<random_access_iterator_tag, T>;
|
||||
using const_iterator = std::iterator<random_access_iterator_tag, const T>;
|
||||
|
||||
vector() noexcept(noexcept(Allocator()));
|
||||
explicit vector(const Allocator&) noexcept;
|
||||
explicit vector(size_type n, const Allocator& = Allocator());
|
||||
vector(size_type n, const T& value, const Allocator& = Allocator());
|
||||
template<class InputIterator, class IteratorCategory = typename InputIterator::iterator_category> vector(InputIterator first, InputIterator last, const Allocator& = Allocator());
|
||||
~vector();
|
||||
|
||||
void push_back(const T& x);
|
||||
void push_back(T&& x);
|
||||
|
||||
iterator insert(const_iterator position, const T& x);
|
||||
iterator insert(const_iterator position, T&& x);
|
||||
iterator insert(const_iterator position, size_type n, const T& x);
|
||||
template<class InputIterator> iterator insert(const_iterator position, InputIterator first, InputIterator last);
|
||||
|
||||
template <class... Args> iterator emplace (const_iterator position, Args&&... args);
|
||||
template <class... Args> void emplace_back (Args&&... args);
|
||||
};
|
||||
}
|
||||
|
||||
struct S {
|
||||
const char* s;
|
||||
};
|
||||
|
||||
void call_by_value(S);
|
||||
void call_by_cref(const S&);
|
||||
|
||||
void call(const char*);
|
||||
|
||||
const char* test1(bool b1, bool b2) {
|
||||
auto s1 = std::string("hello").c_str(); // BAD
|
||||
auto s2 = b1 ? std::string("hello").c_str() : ""; // BAD
|
||||
auto s3 = b2 ? "" : std::string("hello").c_str(); // BAD
|
||||
const char* s4;
|
||||
s4 = std::string("hello").c_str(); // BAD
|
||||
|
||||
call(std::string("hello").c_str()); // GOOD
|
||||
call(b1 ? std::string("hello").c_str() : ""); // GOOD
|
||||
call(b1 ? (b2 ? "" : std::string("hello").c_str()) : ""); // GOOD
|
||||
call_by_value({ std::string("hello").c_str() }); // GOOD
|
||||
call_by_cref({ std::string("hello").c_str() }); // GOOD
|
||||
|
||||
std::vector<const char*> v1;
|
||||
v1.push_back(std::string("hello").c_str()); // BAD
|
||||
|
||||
std::vector<S> v2;
|
||||
v2.push_back({ std::string("hello").c_str() }); // BAD
|
||||
|
||||
S s5[] = { { std::string("hello").c_str() } }; // BAD
|
||||
|
||||
char c = std::string("hello").c_str()[0]; // GOOD
|
||||
|
||||
auto s6 = std::string("hello").data(); // BAD
|
||||
auto s7 = b1 ? std::string("hello").data() : ""; // BAD
|
||||
auto s8 = b2 ? "" : std::string("hello").data(); // BAD
|
||||
char* s9;
|
||||
s9 = std::string("hello").data(); // BAD
|
||||
|
||||
return std::string("hello").c_str(); // BAD
|
||||
}
|
||||
|
||||
void test2(bool b1, bool b2) {
|
||||
std::string s("hello");
|
||||
auto s1 = s.c_str(); // GOOD
|
||||
auto s2 = b1 ? s.c_str() : ""; // GOOD
|
||||
auto s3 = b2 ? "" : s.c_str(); // GOOD
|
||||
const char* s4;
|
||||
s4 = s.c_str(); // GOOD
|
||||
|
||||
std::string& sRef = s;
|
||||
|
||||
auto s5 = sRef.c_str(); // GOOD
|
||||
auto s6 = b1 ? sRef.c_str() : ""; // GOOD
|
||||
auto s7 = b2 ? "" : sRef.c_str(); // GOOD
|
||||
const char* s8;
|
||||
s8 = sRef.c_str(); // GOOD
|
||||
|
||||
std::string&& sRefRef = std::string("hello");
|
||||
|
||||
auto s9 = sRefRef.c_str(); // GOOD
|
||||
auto s10 = b1 ? sRefRef.c_str() : ""; // GOOD
|
||||
auto s11 = b2 ? "" : sRefRef.c_str(); // GOOD
|
||||
const char* s12;
|
||||
s12 = sRefRef.c_str(); // GOOD
|
||||
}
|
||||
@@ -1,13 +1,8 @@
|
||||
edges
|
||||
| test.cpp:20:29:20:34 | call to getenv | test.cpp:24:10:24:35 | ! ... |
|
||||
| test.cpp:20:29:20:34 | call to getenv | test.cpp:24:11:24:16 | call to strcmp |
|
||||
| test.cpp:20:29:20:47 | call to getenv | test.cpp:24:10:24:35 | ! ... |
|
||||
| test.cpp:20:29:20:47 | call to getenv | test.cpp:24:11:24:16 | call to strcmp |
|
||||
subpaths
|
||||
| test.cpp:20:29:20:47 | call to getenv indirection | test.cpp:24:10:24:35 | ! ... |
|
||||
nodes
|
||||
| test.cpp:20:29:20:34 | call to getenv | semmle.label | call to getenv |
|
||||
| test.cpp:20:29:20:47 | call to getenv | semmle.label | call to getenv |
|
||||
| test.cpp:20:29:20:47 | call to getenv indirection | semmle.label | call to getenv indirection |
|
||||
| test.cpp:24:10:24:35 | ! ... | semmle.label | ! ... |
|
||||
| test.cpp:24:11:24:16 | call to strcmp | semmle.label | call to strcmp |
|
||||
subpaths
|
||||
#select
|
||||
| test.cpp:24:10:24:35 | ! ... | test.cpp:20:29:20:34 | call to getenv | test.cpp:24:10:24:35 | ! ... | Reliance on untrusted input $@ to raise privilege at $@. | test.cpp:20:29:20:34 | call to getenv | call to getenv | test.cpp:25:9:25:27 | ... = ... | ... = ... |
|
||||
| test.cpp:24:10:24:35 | ! ... | test.cpp:20:29:20:47 | call to getenv indirection | test.cpp:24:10:24:35 | ! ... | Reliance on $@ to raise privilege at $@. | test.cpp:20:29:20:47 | call to getenv indirection | an environment variable | test.cpp:25:9:25:27 | ... = ... | ... = ... |
|
||||
|
||||
@@ -15,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;
|
||||
@@ -69,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
|
||||
@@ -94,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
|
||||
@@ -109,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>
|
||||
@@ -135,6 +191,7 @@ namespace Semmle.Extraction.CSharp.DependencyFetching
|
||||
{
|
||||
var obj = JObject.Parse(json);
|
||||
AddPackageDependencies(obj, dependencies);
|
||||
AddFrameworkDependencies(obj, dependencies);
|
||||
return true;
|
||||
}
|
||||
catch (Exception e)
|
||||
|
||||
@@ -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()
|
||||
|
||||
@@ -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 });
|
||||
}
|
||||
}
|
||||
@@ -41,6 +41,7 @@ internal sealed class StubVisitor : SymbolVisitor
|
||||
(
|
||||
t1 is INamedTypeSymbol named1 &&
|
||||
t2 is INamedTypeSymbol named2 &&
|
||||
(!SymbolEqualityComparer.Default.Equals(named1, named1.ConstructedFrom) || !SymbolEqualityComparer.Default.Equals(named2, named2.ConstructedFrom)) &&
|
||||
EqualsModuloTupleElementNames(named1.ConstructedFrom, named2.ConstructedFrom) &&
|
||||
named1.TypeArguments.Length == named2.TypeArguments.Length &&
|
||||
named1.TypeArguments.Zip(named2.TypeArguments).All(p => EqualsModuloTupleElementNames(p.First, p.Second))
|
||||
|
||||
File diff suppressed because it is too large
Load Diff
@@ -0,0 +1,5 @@
|
||||
{
|
||||
"sdk": {
|
||||
"version": "7.0.102"
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,5 @@
|
||||
{
|
||||
"sdk": {
|
||||
"version": "7.0.102"
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,16 @@
|
||||
namespace test;
|
||||
|
||||
using System.Net;
|
||||
using Microsoft.AspNetCore.Mvc;
|
||||
using Microsoft.AspNetCore.Mvc.Razor;
|
||||
|
||||
public class UserData
|
||||
{
|
||||
public string Name { get; set; }
|
||||
}
|
||||
|
||||
public class TestController : Controller {
|
||||
public IActionResult Test(UserData tainted1) {
|
||||
return View("Test", tainted1);
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,8 @@
|
||||
@page
|
||||
|
||||
@model UserData
|
||||
|
||||
@if (Model != null)
|
||||
{
|
||||
<h3>Hello "@Html.Raw(Model.Name)"</h3>
|
||||
}
|
||||
@@ -0,0 +1,3 @@
|
||||
@using test
|
||||
|
||||
@addTagHelper *, Microsoft.AspNetCore.Mvc.TagHelpers
|
||||
@@ -0,0 +1 @@
|
||||
| Views/Test/Test.cshtml:7:27:7:36 | access to property Name | Controllers/TestController.cs:13:40:13:47 | tainted1 : UserData | Views/Test/Test.cshtml:7:27:7:36 | access to property Name | $@ flows to here and is written to HTML or JavaScript: Microsoft.AspNetCore.Mvc.ViewFeatures.HtmlHelper.Raw() method. | Controllers/TestController.cs:13:40:13:47 | tainted1 : UserData | User-provided value |
|
||||
@@ -0,0 +1,21 @@
|
||||
/**
|
||||
* @name Cross-site scripting
|
||||
* @description Writing user input directly to a web page
|
||||
* allows for a cross-site scripting vulnerability.
|
||||
* @kind path-problem
|
||||
* @problem.severity error
|
||||
* @security-severity 6.1
|
||||
* @precision high
|
||||
* @id cs/web/xss
|
||||
* @tags security
|
||||
* external/cwe/cwe-079
|
||||
* external/cwe/cwe-116
|
||||
*/
|
||||
|
||||
import csharp
|
||||
import semmle.code.csharp.security.dataflow.XSSQuery
|
||||
|
||||
// import PathGraph // exclude query predicates with output dependant on the absolute filepath the tests are run in
|
||||
from XssNode source, XssNode sink, string message
|
||||
where xssFlow(source, sink, message)
|
||||
select sink, source, sink, "$@ flows to here and " + message, source, "User-provided value"
|
||||
@@ -0,0 +1,9 @@
|
||||
<Project Sdk="Microsoft.NET.Sdk.Web">
|
||||
|
||||
<PropertyGroup>
|
||||
<TargetFramework>net7.0</TargetFramework>
|
||||
<Nullable>enable</Nullable>
|
||||
<ImplicitUsings>enable</ImplicitUsings>
|
||||
</PropertyGroup>
|
||||
|
||||
</Project>
|
||||
@@ -0,0 +1,6 @@
|
||||
import os
|
||||
from create_database_utils import *
|
||||
|
||||
|
||||
os.environ['CODEQL_EXTRACTOR_CSHARP_STANDALONE_EXTRACT_WEB_VIEWS'] = 'true'
|
||||
run_codeql_database_create(lang="csharp", extra_args=["--extractor-option=buildless=true", "--extractor-option=cil=false"])
|
||||
@@ -0,0 +1,5 @@
|
||||
{
|
||||
"sdk": {
|
||||
"version": "7.0.102"
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,5 @@
|
||||
{
|
||||
"sdk": {
|
||||
"version": "7.0.102"
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,5 @@
|
||||
{
|
||||
"sdk": {
|
||||
"version": "7.0.102"
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,5 @@
|
||||
{
|
||||
"sdk": {
|
||||
"version": "7.0.102"
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,5 @@
|
||||
{
|
||||
"sdk": {
|
||||
"version": "7.0.102"
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,5 @@
|
||||
{
|
||||
"sdk": {
|
||||
"version": "7.0.102"
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,5 @@
|
||||
{
|
||||
"sdk": {
|
||||
"version": "7.0.102"
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,5 @@
|
||||
{
|
||||
"sdk": {
|
||||
"version": "7.0.102"
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,5 @@
|
||||
{
|
||||
"sdk": {
|
||||
"version": "7.0.102"
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,5 @@
|
||||
{
|
||||
"sdk": {
|
||||
"version": "7.0.102"
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,5 @@
|
||||
{
|
||||
"sdk": {
|
||||
"version": "7.0.102"
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,5 @@
|
||||
{
|
||||
"sdk": {
|
||||
"version": "7.0.102"
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,5 @@
|
||||
{
|
||||
"sdk": {
|
||||
"version": "7.0.102"
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,5 @@
|
||||
{
|
||||
"sdk": {
|
||||
"version": "7.0.102"
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,5 @@
|
||||
{
|
||||
"sdk": {
|
||||
"version": "7.0.102"
|
||||
}
|
||||
}
|
||||
@@ -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() {
|
||||
|
||||
@@ -15,6 +15,7 @@ private import semmle.code.csharp.controlflow.Guards
|
||||
private import semmle.code.csharp.dispatch.Dispatch
|
||||
private import semmle.code.csharp.frameworks.EntityFramework
|
||||
private import semmle.code.csharp.frameworks.NHibernate
|
||||
private import semmle.code.csharp.frameworks.Razor
|
||||
private import semmle.code.csharp.frameworks.system.Collections
|
||||
private import semmle.code.csharp.frameworks.system.threading.Tasks
|
||||
private import semmle.code.cil.Ssa::Ssa as CilSsa
|
||||
|
||||
@@ -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;
|
||||
|
||||
|
||||
217
csharp/ql/lib/semmle/code/csharp/frameworks/Razor.qll
Normal file
217
csharp/ql/lib/semmle/code/csharp/frameworks/Razor.qll
Normal file
@@ -0,0 +1,217 @@
|
||||
/** Provides definitions and flow steps related to Razor pages. */
|
||||
|
||||
private import csharp
|
||||
private import codeql.util.Unit
|
||||
private import codeql.util.FilePath
|
||||
private import semmle.code.csharp.frameworks.microsoft.AspNetCore
|
||||
|
||||
/** A call to the `View` method */
|
||||
private class ViewCall extends MethodCall {
|
||||
ViewCall() {
|
||||
this.getTarget().hasFullyQualifiedName("Microsoft.AspNetCore.Mvc", "Controller", "View")
|
||||
}
|
||||
|
||||
/** Gets the `name` argument to this call, if any. */
|
||||
string getNameArgument() {
|
||||
exists(StringLiteral lit |
|
||||
this.getTarget().getParameter(0).getType() instanceof StringType and
|
||||
DataFlow::localExprFlow(lit, this.getArgument(0)) and
|
||||
result = lit.getValue()
|
||||
)
|
||||
}
|
||||
|
||||
/** Gets the `model` argument to this call, if any. */
|
||||
Expr getModelArgument() {
|
||||
exists(int i | i in [0 .. 1] |
|
||||
this.getTarget().getParameter(i).getType() instanceof ObjectType and
|
||||
result = this.getArgument(i)
|
||||
)
|
||||
}
|
||||
|
||||
/** Gets the MVC action method that this call is made from, if any. */
|
||||
Method getActionMethod() {
|
||||
result = this.getEnclosingCallable() and
|
||||
result = this.getController().getAnActionMethod()
|
||||
}
|
||||
|
||||
/**
|
||||
* Gets the action name that this call refers to, if any.
|
||||
* This is either the name argument, or the name of the action method calling this if there is no name argument.
|
||||
*/
|
||||
string getActionName() {
|
||||
result = this.getNameArgument()
|
||||
or
|
||||
not exists(this.getNameArgument()) and
|
||||
result = this.getActionMethod().getName()
|
||||
}
|
||||
|
||||
/** Gets the MVC controller that this call is made from, if any. */
|
||||
MicrosoftAspNetCoreMvcController getController() {
|
||||
result = this.getEnclosingCallable().getDeclaringType()
|
||||
}
|
||||
|
||||
/** Gets the name of the MVC controller that this call is made from, if any. */
|
||||
string getControllerName() { result + "Controller" = this.getController().getName() }
|
||||
|
||||
/** Gets the name of the Area that the controller of this call belongs to, if any. */
|
||||
string getAreaName() {
|
||||
exists(Attribute attr |
|
||||
attr = this.getController().getAnAttribute() and
|
||||
attr.getType().hasFullyQualifiedName("Microsoft.AspNetCore.Mvc", "AreaAttribute") and
|
||||
result = attr.getArgument(0).(StringLiteral).getValue()
|
||||
)
|
||||
}
|
||||
|
||||
/** `result` is `true` if this call is from a controller that is an Area, and `false` otherwise. */
|
||||
boolean hasArea() { if exists(this.getAreaName()) then result = true else result = false }
|
||||
}
|
||||
|
||||
/** A compiler-generated Razor page from a `.cshtml` file. */
|
||||
class RazorViewClass extends Class {
|
||||
AssemblyAttribute attr;
|
||||
|
||||
RazorViewClass() {
|
||||
exists(Class baseClass | baseClass = this.getBaseClass().getUnboundDeclaration() |
|
||||
baseClass.hasFullyQualifiedName("Microsoft.AspNetCore.Mvc.Razor", "RazorPage`1")
|
||||
or
|
||||
baseClass.hasFullyQualifiedName("Microsoft.AspNetCore.Mvc.RazorPages", "Page")
|
||||
) and
|
||||
attr.getFile() = this.getFile() and
|
||||
attr.getType()
|
||||
.hasFullyQualifiedName("Microsoft.AspNetCore.Razor.Hosting", "RazorCompiledItemAttribute")
|
||||
}
|
||||
|
||||
/**
|
||||
* Gets the filepath of the source file that this class was generated from.
|
||||
*
|
||||
* This is an absolute path if the database was extracted in standalone mode,
|
||||
* and is relative to to application root (the directory containing the .csproj file) otherwise.
|
||||
*/
|
||||
string getSourceFilepath() { result = attr.getArgument(2).(StringLiteral).getValue() }
|
||||
}
|
||||
|
||||
/**
|
||||
* Gets a possible prefix to be applied to view search paths to locate a Razor page.
|
||||
* This may be empty (for the case that the generated Razor page files contain paths relative to the application root),
|
||||
* or the absolute path of the directory containing the .csproj file (for the case that standalone extraction is used and the generated files contain absolute paths).
|
||||
*/
|
||||
private string getARazorPathPrefix() {
|
||||
result = ""
|
||||
or
|
||||
exists(File csproj |
|
||||
csproj.getExtension() = "csproj" and
|
||||
// possibly prepend '/' to match Windows absolute paths starting with `C:/` with paths appearing in the Razor file in standalone mode starting with `/C:/`
|
||||
result = ["/", ""] + csproj.getParentContainer().getAbsolutePath()
|
||||
)
|
||||
}
|
||||
|
||||
private class ViewCallJumpNode extends DataFlow::NonLocalJumpNode {
|
||||
RazorViewClass rp;
|
||||
|
||||
ViewCallJumpNode() {
|
||||
exists(ViewCall vc |
|
||||
viewCallRefersToPage(vc, rp) and
|
||||
this.asExpr() = vc.getModelArgument()
|
||||
)
|
||||
}
|
||||
|
||||
override DataFlow::Node getAJumpSuccessor(boolean preservesValue) {
|
||||
preservesValue = true and
|
||||
exists(PropertyAccess modelProp |
|
||||
result.asExpr() = modelProp and
|
||||
modelProp.getTarget().hasName("Model") and
|
||||
modelProp.getEnclosingCallable().getDeclaringType() = rp
|
||||
)
|
||||
}
|
||||
}
|
||||
|
||||
private predicate viewCallRefersToPage(ViewCall vc, RazorViewClass rp) {
|
||||
viewCallRefersToPageAbsolute(vc, rp) or
|
||||
viewCallRefersToPageRelative(vc, rp)
|
||||
}
|
||||
|
||||
bindingset[path]
|
||||
private string stripTilde(string path) { result = path.regexpReplaceAll("^~/", "/") }
|
||||
|
||||
private predicate viewCallRefersToPageAbsolute(ViewCall vc, RazorViewClass rp) {
|
||||
getARazorPathPrefix() + ["/", ""] + stripTilde(vc.getNameArgument()) = rp.getSourceFilepath()
|
||||
}
|
||||
|
||||
private predicate viewCallRefersToPageRelative(ViewCall vc, RazorViewClass rp) {
|
||||
rp = min(int i, RazorViewClass rp2 | matchesViewCallWithIndex(vc, rp2, i) | rp2 order by i)
|
||||
}
|
||||
|
||||
private predicate matchesViewCallWithIndex(ViewCall vc, RazorViewClass rp, int i) {
|
||||
exists(RelativeViewCallFilepath fp |
|
||||
fp.hasViewCallWithIndex(vc, i) and
|
||||
getARazorPathPrefix() + fp.getNormalizedPath() = rp.getSourceFilepath()
|
||||
)
|
||||
}
|
||||
|
||||
/** Gets the `i`th template for view discovery. */
|
||||
private string getViewSearchTemplate(int i, boolean isArea) {
|
||||
i = 0 and result = "/Areas/{2}/Views/{1}/{0}.cshtml" and isArea = true
|
||||
or
|
||||
i = 1 and result = "/Areas/{2}/Views/Shared/{0}.cshtml" and isArea = true
|
||||
or
|
||||
i = 2 and result = "/Views/{1}/{0}.cshtml" and isArea = false
|
||||
or
|
||||
i = 3 and result = "/Views/Shared/{0}.cshtml" and isArea = [true, false]
|
||||
or
|
||||
i = 4 and result = "/Pages/Shared/{0}.cshtml" and isArea = true
|
||||
or
|
||||
i = 5 and result = getAViewSearchTemplateInCode(isArea)
|
||||
}
|
||||
|
||||
/** Gets an additional template used for view discovery defined in code. */
|
||||
private string getAViewSearchTemplateInCode(boolean isArea) {
|
||||
exists(StringLiteral str, MethodCall addCall |
|
||||
addCall.getTarget().hasName("Add") and
|
||||
DataFlow::localExprFlow(str, addCall.getArgument(0)) and
|
||||
addCall.getQualifier() = getAViewLocationList(isArea) and
|
||||
result = str.getValue()
|
||||
)
|
||||
}
|
||||
|
||||
/** Gets a list expression containing view search locations */
|
||||
private Expr getAViewLocationList(boolean isArea) {
|
||||
exists(string name |
|
||||
result
|
||||
.(PropertyRead)
|
||||
.getProperty()
|
||||
.hasFullyQualifiedName("Microsoft.AspNetCore.Mvc.Razor", "RazorViewEngineOptions", name)
|
||||
|
|
||||
name = "ViewLocationFormats" and isArea = false
|
||||
or
|
||||
name = "AreaViewLocationFormats" and isArea = true
|
||||
// PageViewLocationFormats and AreaPageViewLocationFormats are used for calls within a page rather than a controller
|
||||
)
|
||||
}
|
||||
|
||||
/** A filepath that should be searched for a View call. */
|
||||
private class RelativeViewCallFilepath extends NormalizableFilepath {
|
||||
ViewCall vc_;
|
||||
int idx_;
|
||||
|
||||
RelativeViewCallFilepath() {
|
||||
exists(string template, string sub2, string sub1, string sub0 |
|
||||
template = getViewSearchTemplate(idx_, vc_.hasArea())
|
||||
|
|
||||
(
|
||||
if template.matches("%{2}%")
|
||||
then sub2 = template.replaceAll("{2}", vc_.getAreaName())
|
||||
else sub2 = template
|
||||
) and
|
||||
(
|
||||
if template.matches("%{1}%")
|
||||
then sub1 = sub2.replaceAll("{1}", vc_.getControllerName())
|
||||
else sub1 = sub2
|
||||
) and
|
||||
sub0 = sub1.replaceAll("{0}", vc_.getActionName()) and
|
||||
this = stripTilde(sub0)
|
||||
)
|
||||
}
|
||||
|
||||
/** Holds if this string is the `idx`th path that will be searched for the `vc` call. */
|
||||
predicate hasViewCallWithIndex(ViewCall vc, int idx) { vc = vc_ and idx = idx_ }
|
||||
}
|
||||
@@ -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
|
||||
|
||||
4
csharp/ql/src/change-notes/2023-10-24-xss-flow-steps.md
Normal file
4
csharp/ql/src/change-notes/2023-10-24-xss-flow-steps.md
Normal file
@@ -0,0 +1,4 @@
|
||||
---
|
||||
category: minorAnalysis
|
||||
---
|
||||
* Modelled additional flow steps to track flow from a `View` call in an MVC controller to the corresponding Razor View (`.cshtml`) file, which may result in additional results for queries such as `cs/web/xss`.
|
||||
@@ -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 |
|
||||
@@ -0,0 +1,10 @@
|
||||
import semmle.code.csharp.security.dataflow.flowsinks.ExternalLocationSink
|
||||
import semmle.code.csharp.commons.Diagnostics
|
||||
|
||||
from ExternalLocationSink sink
|
||||
where sink.getLocation().getFile().fromSource()
|
||||
select sink, sink.getExpr()
|
||||
|
||||
query predicate compilationErrors(CompilerError e) { any() }
|
||||
|
||||
query predicate methodCalls(MethodCall m) { any() }
|
||||
@@ -0,0 +1 @@
|
||||
semmle-extractor-options: --standalone
|
||||
@@ -0,0 +1,27 @@
|
||||
using A;
|
||||
using B;
|
||||
|
||||
namespace A
|
||||
{
|
||||
public interface ILogger { }
|
||||
}
|
||||
|
||||
namespace B
|
||||
{
|
||||
public interface ILogger { }
|
||||
}
|
||||
|
||||
public class C
|
||||
{
|
||||
public ILogger logger;
|
||||
|
||||
private void M(string s)
|
||||
{
|
||||
logger.Log(s);
|
||||
}
|
||||
|
||||
private static void Main()
|
||||
{
|
||||
new C().logger.Log("abc");
|
||||
}
|
||||
}
|
||||
Some files were not shown because too many files have changed in this diff Show More
Reference in New Issue
Block a user