mirror of
https://github.com/github/codeql.git
synced 2026-04-29 02:35:15 +02:00
Merge branch 'main' into xxe4
This commit is contained in:
@@ -38,8 +38,8 @@ class Function extends Declaration, ControlFlowNode, AccessHolder, @function {
|
||||
* int z = min(5, 7);
|
||||
* ```
|
||||
* The full signature of the function called on the last line would be
|
||||
* "min<int>(int, int) -> int", and the full signature of the uninstantiated
|
||||
* template on the first line would be "min<T>(T, T) -> T".
|
||||
* `min<int>(int, int) -> int`, and the full signature of the uninstantiated
|
||||
* template on the first line would be `min<T>(T, T) -> T`.
|
||||
*/
|
||||
string getFullSignature() {
|
||||
exists(string name, string templateArgs, string args |
|
||||
|
||||
@@ -49,9 +49,6 @@ class Expr extends StmtParent, @expr {
|
||||
/** Gets the enclosing variable of this expression, if any. */
|
||||
Variable getEnclosingVariable() { result = exprEnclosingElement(this) }
|
||||
|
||||
/** Gets the enclosing variable or function of this expression. */
|
||||
Declaration getEnclosingDeclaration() { result = exprEnclosingElement(this) }
|
||||
|
||||
/** Gets a child of this expression. */
|
||||
Expr getAChild() { exists(int n | result = this.getChild(n)) }
|
||||
|
||||
|
||||
@@ -16,7 +16,7 @@ class IRConfiguration extends TIRConfiguration {
|
||||
/**
|
||||
* Holds if IR should be created for function `func`. By default, holds for all functions.
|
||||
*/
|
||||
predicate shouldCreateIRForFunction(Language::Declaration func) { any() }
|
||||
predicate shouldCreateIRForFunction(Language::Function func) { any() }
|
||||
|
||||
/**
|
||||
* Holds if the strings used as part of an IR dump should be generated for function `func`.
|
||||
@@ -25,7 +25,7 @@ class IRConfiguration extends TIRConfiguration {
|
||||
* of debug strings for IR that will not be dumped. We still generate the actual IR for these
|
||||
* functions, however, to preserve the results of any interprocedural analysis.
|
||||
*/
|
||||
predicate shouldEvaluateDebugStringsForFunction(Language::Declaration func) { any() }
|
||||
predicate shouldEvaluateDebugStringsForFunction(Language::Function func) { any() }
|
||||
}
|
||||
|
||||
private newtype TIREscapeAnalysisConfiguration = MkIREscapeAnalysisConfiguration()
|
||||
|
||||
@@ -97,7 +97,7 @@ class IRBlockBase extends TIRBlock {
|
||||
/**
|
||||
* Gets the `Function` that contains this block.
|
||||
*/
|
||||
final Language::Declaration getEnclosingFunction() {
|
||||
final Language::Function getEnclosingFunction() {
|
||||
result = getFirstInstruction(this).getEnclosingFunction()
|
||||
}
|
||||
}
|
||||
|
||||
@@ -194,7 +194,7 @@ class Instruction extends Construction::TStageInstruction {
|
||||
/**
|
||||
* Gets the function that contains this instruction.
|
||||
*/
|
||||
final Language::Declaration getEnclosingFunction() {
|
||||
final Language::Function getEnclosingFunction() {
|
||||
result = this.getEnclosingIRFunction().getFunction()
|
||||
}
|
||||
|
||||
|
||||
@@ -26,20 +26,20 @@ class PrintIRConfiguration extends TPrintIRConfiguration {
|
||||
* Holds if the IR for `func` should be printed. By default, holds for all
|
||||
* functions.
|
||||
*/
|
||||
predicate shouldPrintFunction(Language::Declaration decl) { any() }
|
||||
predicate shouldPrintFunction(Language::Function func) { any() }
|
||||
}
|
||||
|
||||
/**
|
||||
* Override of `IRConfiguration` to only evaluate debug strings for the functions that are to be dumped.
|
||||
*/
|
||||
private class FilteredIRConfiguration extends IRConfiguration {
|
||||
override predicate shouldEvaluateDebugStringsForFunction(Language::Declaration func) {
|
||||
override predicate shouldEvaluateDebugStringsForFunction(Language::Function func) {
|
||||
shouldPrintFunction(func)
|
||||
}
|
||||
}
|
||||
|
||||
private predicate shouldPrintFunction(Language::Declaration decl) {
|
||||
exists(PrintIRConfiguration config | config.shouldPrintFunction(decl))
|
||||
private predicate shouldPrintFunction(Language::Function func) {
|
||||
exists(PrintIRConfiguration config | config.shouldPrintFunction(func))
|
||||
}
|
||||
|
||||
private string getAdditionalInstructionProperty(Instruction instr, string key) {
|
||||
|
||||
@@ -5,28 +5,23 @@
|
||||
private import IRFunctionBaseInternal
|
||||
|
||||
private newtype TIRFunction =
|
||||
TFunctionIRFunction(Language::Function func) { IRConstruction::Raw::functionHasIR(func) } or
|
||||
TVarInitIRFunction(Language::GlobalVariable var) { IRConstruction::Raw::varHasIRFunc(var) }
|
||||
MkIRFunction(Language::Function func) { IRConstruction::Raw::functionHasIR(func) }
|
||||
|
||||
/**
|
||||
* The IR for a function. This base class contains only the predicates that are the same between all
|
||||
* phases of the IR. Each instantiation of `IRFunction` extends this class.
|
||||
*/
|
||||
class IRFunctionBase extends TIRFunction {
|
||||
Language::Declaration decl;
|
||||
Language::Function func;
|
||||
|
||||
IRFunctionBase() {
|
||||
this = TFunctionIRFunction(decl)
|
||||
or
|
||||
this = TVarInitIRFunction(decl)
|
||||
}
|
||||
IRFunctionBase() { this = MkIRFunction(func) }
|
||||
|
||||
/** Gets a textual representation of this element. */
|
||||
final string toString() { result = "IR: " + decl.toString() }
|
||||
final string toString() { result = "IR: " + func.toString() }
|
||||
|
||||
/** Gets the function whose IR is represented. */
|
||||
final Language::Declaration getFunction() { result = decl }
|
||||
final Language::Function getFunction() { result = func }
|
||||
|
||||
/** Gets the location of the function. */
|
||||
final Language::Location getLocation() { result = decl.getLocation() }
|
||||
final Language::Location getLocation() { result = func.getLocation() }
|
||||
}
|
||||
|
||||
@@ -97,7 +97,7 @@ class IRBlockBase extends TIRBlock {
|
||||
/**
|
||||
* Gets the `Function` that contains this block.
|
||||
*/
|
||||
final Language::Declaration getEnclosingFunction() {
|
||||
final Language::Function getEnclosingFunction() {
|
||||
result = getFirstInstruction(this).getEnclosingFunction()
|
||||
}
|
||||
}
|
||||
|
||||
@@ -194,7 +194,7 @@ class Instruction extends Construction::TStageInstruction {
|
||||
/**
|
||||
* Gets the function that contains this instruction.
|
||||
*/
|
||||
final Language::Declaration getEnclosingFunction() {
|
||||
final Language::Function getEnclosingFunction() {
|
||||
result = this.getEnclosingIRFunction().getFunction()
|
||||
}
|
||||
|
||||
|
||||
@@ -26,20 +26,20 @@ class PrintIRConfiguration extends TPrintIRConfiguration {
|
||||
* Holds if the IR for `func` should be printed. By default, holds for all
|
||||
* functions.
|
||||
*/
|
||||
predicate shouldPrintFunction(Language::Declaration decl) { any() }
|
||||
predicate shouldPrintFunction(Language::Function func) { any() }
|
||||
}
|
||||
|
||||
/**
|
||||
* Override of `IRConfiguration` to only evaluate debug strings for the functions that are to be dumped.
|
||||
*/
|
||||
private class FilteredIRConfiguration extends IRConfiguration {
|
||||
override predicate shouldEvaluateDebugStringsForFunction(Language::Declaration func) {
|
||||
override predicate shouldEvaluateDebugStringsForFunction(Language::Function func) {
|
||||
shouldPrintFunction(func)
|
||||
}
|
||||
}
|
||||
|
||||
private predicate shouldPrintFunction(Language::Declaration decl) {
|
||||
exists(PrintIRConfiguration config | config.shouldPrintFunction(decl))
|
||||
private predicate shouldPrintFunction(Language::Function func) {
|
||||
exists(PrintIRConfiguration config | config.shouldPrintFunction(func))
|
||||
}
|
||||
|
||||
private string getAdditionalInstructionProperty(Instruction instr, string key) {
|
||||
|
||||
@@ -35,9 +35,6 @@ module Raw {
|
||||
cached
|
||||
predicate functionHasIR(Function func) { exists(getTranslatedFunction(func)) }
|
||||
|
||||
cached
|
||||
predicate varHasIRFunc(GlobalOrNamespaceVariable var) { any() } // TODO: restrict?
|
||||
|
||||
cached
|
||||
predicate hasInstruction(TranslatedElement element, InstructionTag tag) {
|
||||
element.hasInstruction(_, tag, _)
|
||||
@@ -49,18 +46,18 @@ module Raw {
|
||||
}
|
||||
|
||||
cached
|
||||
predicate hasTempVariable(Declaration decl, Locatable ast, TempVariableTag tag, CppType type) {
|
||||
predicate hasTempVariable(Function func, Locatable ast, TempVariableTag tag, CppType type) {
|
||||
exists(TranslatedElement element |
|
||||
element.getAst() = ast and
|
||||
decl = element.getFunction() and
|
||||
func = element.getFunction() and
|
||||
element.hasTempVariable(tag, type)
|
||||
)
|
||||
}
|
||||
|
||||
cached
|
||||
predicate hasStringLiteral(Declaration decl, Locatable ast, CppType type, StringLiteral literal) {
|
||||
predicate hasStringLiteral(Function func, Locatable ast, CppType type, StringLiteral literal) {
|
||||
literal = ast and
|
||||
literal.getEnclosingDeclaration() = decl and
|
||||
literal.getEnclosingFunction() = func and
|
||||
getTypeForPRValue(literal.getType()) = type
|
||||
}
|
||||
|
||||
|
||||
@@ -180,7 +180,7 @@ abstract class TranslatedSideEffects extends TranslatedElement {
|
||||
/** DEPRECATED: Alias for getAst */
|
||||
deprecated override Locatable getAST() { result = getAst() }
|
||||
|
||||
final override Declaration getFunction() { result = getExpr().getEnclosingDeclaration() }
|
||||
final override Function getFunction() { result = getExpr().getEnclosingFunction() }
|
||||
|
||||
final override TranslatedElement getChild(int i) {
|
||||
result =
|
||||
@@ -375,7 +375,7 @@ abstract class TranslatedSideEffect extends TranslatedElement {
|
||||
kind instanceof GotoEdge
|
||||
}
|
||||
|
||||
final override Declaration getFunction() { result = getParent().getFunction() }
|
||||
final override Function getFunction() { result = getParent().getFunction() }
|
||||
|
||||
final override Instruction getPrimaryInstructionForSideEffect(InstructionTag tag) {
|
||||
tag = OnlyInstructionTag() and
|
||||
@@ -436,6 +436,13 @@ abstract class TranslatedArgumentSideEffect extends TranslatedSideEffect {
|
||||
result = index
|
||||
}
|
||||
|
||||
/**
|
||||
* Gets the `TranslatedFunction` containing this expression.
|
||||
*/
|
||||
final TranslatedFunction getEnclosingFunction() {
|
||||
result = getTranslatedFunction(call.getEnclosingFunction())
|
||||
}
|
||||
|
||||
final override predicate sideEffectInstruction(Opcode opcode, CppType type) {
|
||||
opcode = sideEffectOpcode and
|
||||
(
|
||||
|
||||
@@ -67,8 +67,7 @@ private predicate ignoreExprAndDescendants(Expr expr) {
|
||||
exists(Initializer init, StaticStorageDurationVariable var |
|
||||
init = var.getInitializer() and
|
||||
not var.hasDynamicInitialization() and
|
||||
expr = init.getExpr().getFullyConverted() and
|
||||
not var instanceof GlobalOrNamespaceVariable
|
||||
expr = init.getExpr().getFullyConverted()
|
||||
)
|
||||
or
|
||||
// Ignore descendants of `__assume` expressions, since we translated these to `NoOp`.
|
||||
@@ -118,8 +117,7 @@ private predicate ignoreExprOnly(Expr expr) {
|
||||
// should not be translated.
|
||||
exists(NewOrNewArrayExpr new | expr = new.getAllocatorCall().getArgument(0))
|
||||
or
|
||||
not translateFunction(expr.getEnclosingFunction()) and
|
||||
not expr.getEnclosingVariable() instanceof GlobalOrNamespaceVariable
|
||||
not translateFunction(expr.getEnclosingFunction())
|
||||
or
|
||||
// We do not yet translate destructors properly, so for now we ignore the
|
||||
// destructor call. We do, however, translate the expression being
|
||||
@@ -664,8 +662,7 @@ newtype TTranslatedElement =
|
||||
opcode = getASideEffectOpcode(call, -1)
|
||||
} or
|
||||
// The side effect that initializes newly-allocated memory.
|
||||
TTranslatedAllocationSideEffect(AllocationExpr expr) { not ignoreSideEffects(expr) } or
|
||||
TTranslatedGlobalOrNamespaceVarInit(GlobalOrNamespaceVariable var) { var.hasInitializer() }
|
||||
TTranslatedAllocationSideEffect(AllocationExpr expr) { not ignoreSideEffects(expr) }
|
||||
|
||||
/**
|
||||
* Gets the index of the first explicitly initialized element in `initList`
|
||||
@@ -795,7 +792,7 @@ abstract class TranslatedElement extends TTranslatedElement {
|
||||
/**
|
||||
* Gets the `Function` that contains this element.
|
||||
*/
|
||||
abstract Declaration getFunction();
|
||||
abstract Function getFunction();
|
||||
|
||||
/**
|
||||
* Gets the successor instruction of the instruction that was generated by
|
||||
@@ -945,14 +942,3 @@ abstract class TranslatedElement extends TTranslatedElement {
|
||||
*/
|
||||
final TranslatedElement getParent() { result.getAChild() = this }
|
||||
}
|
||||
|
||||
/**
|
||||
* Represents the IR translation of a root element, either a function or a global variable.
|
||||
*/
|
||||
abstract class TranslatedRootElement extends TranslatedElement {
|
||||
TranslatedRootElement() {
|
||||
this instanceof TTranslatedFunction
|
||||
or
|
||||
this instanceof TTranslatedGlobalOrNamespaceVarInit
|
||||
}
|
||||
}
|
||||
|
||||
@@ -12,7 +12,6 @@ private import TranslatedElement
|
||||
private import TranslatedFunction
|
||||
private import TranslatedInitialization
|
||||
private import TranslatedStmt
|
||||
private import TranslatedGlobalVar
|
||||
import TranslatedCall
|
||||
|
||||
/**
|
||||
@@ -79,7 +78,7 @@ abstract class TranslatedExpr extends TranslatedElement {
|
||||
/** DEPRECATED: Alias for getAst */
|
||||
deprecated override Locatable getAST() { result = this.getAst() }
|
||||
|
||||
final override Declaration getFunction() { result = expr.getEnclosingDeclaration() }
|
||||
final override Function getFunction() { result = expr.getEnclosingFunction() }
|
||||
|
||||
/**
|
||||
* Gets the expression from which this `TranslatedExpr` is generated.
|
||||
@@ -89,10 +88,8 @@ abstract class TranslatedExpr extends TranslatedElement {
|
||||
/**
|
||||
* Gets the `TranslatedFunction` containing this expression.
|
||||
*/
|
||||
final TranslatedRootElement getEnclosingFunction() {
|
||||
final TranslatedFunction getEnclosingFunction() {
|
||||
result = getTranslatedFunction(expr.getEnclosingFunction())
|
||||
or
|
||||
result = getTranslatedVarInit(expr.getEnclosingVariable())
|
||||
}
|
||||
}
|
||||
|
||||
@@ -790,7 +787,7 @@ class TranslatedThisExpr extends TranslatedNonConstantExpr {
|
||||
|
||||
override IRVariable getInstructionVariable(InstructionTag tag) {
|
||||
tag = ThisAddressTag() and
|
||||
result = this.getEnclosingFunction().(TranslatedFunction).getThisVariable()
|
||||
result = this.getEnclosingFunction().getThisVariable()
|
||||
}
|
||||
}
|
||||
|
||||
@@ -2525,7 +2522,7 @@ class TranslatedVarArgsStart extends TranslatedNonConstantExpr {
|
||||
|
||||
final override IRVariable getInstructionVariable(InstructionTag tag) {
|
||||
tag = VarArgsStartEllipsisAddressTag() and
|
||||
result = this.getEnclosingFunction().(TranslatedFunction).getEllipsisVariable()
|
||||
result = this.getEnclosingFunction().getEllipsisVariable()
|
||||
}
|
||||
|
||||
final override Instruction getInstructionRegisterOperand(InstructionTag tag, OperandTag operandTag) {
|
||||
|
||||
@@ -58,7 +58,7 @@ predicate hasReturnValue(Function func) { not func.getUnspecifiedType() instance
|
||||
* Represents the IR translation of a function. This is the root elements for
|
||||
* all other elements associated with this function.
|
||||
*/
|
||||
class TranslatedFunction extends TranslatedRootElement, TTranslatedFunction {
|
||||
class TranslatedFunction extends TranslatedElement, TTranslatedFunction {
|
||||
Function func;
|
||||
|
||||
TranslatedFunction() { this = TTranslatedFunction(func) }
|
||||
|
||||
@@ -1,104 +0,0 @@
|
||||
import semmle.code.cpp.ir.implementation.raw.internal.TranslatedElement
|
||||
private import cpp
|
||||
private import semmle.code.cpp.ir.implementation.IRType
|
||||
private import semmle.code.cpp.ir.implementation.Opcode
|
||||
private import semmle.code.cpp.ir.implementation.internal.OperandTag
|
||||
private import semmle.code.cpp.ir.internal.CppType
|
||||
private import TranslatedInitialization
|
||||
private import InstructionTag
|
||||
|
||||
class TranslatedGlobalOrNamespaceVarInit extends TranslatedRootElement,
|
||||
TTranslatedGlobalOrNamespaceVarInit, InitializationContext {
|
||||
GlobalOrNamespaceVariable var;
|
||||
|
||||
TranslatedGlobalOrNamespaceVarInit() { this = TTranslatedGlobalOrNamespaceVarInit(var) }
|
||||
|
||||
override string toString() { result = var.toString() }
|
||||
|
||||
final override GlobalOrNamespaceVariable getAst() { result = var }
|
||||
|
||||
final override Declaration getFunction() { result = var }
|
||||
|
||||
final Location getLocation() { result = var.getLocation() }
|
||||
|
||||
override Instruction getFirstInstruction() { result = this.getInstruction(EnterFunctionTag()) }
|
||||
|
||||
override TranslatedElement getChild(int n) {
|
||||
n = 1 and
|
||||
result = getTranslatedInitialization(var.getInitializer().getExpr().getFullyConverted())
|
||||
}
|
||||
|
||||
override predicate hasInstruction(Opcode op, InstructionTag tag, CppType type) {
|
||||
op instanceof Opcode::EnterFunction and
|
||||
tag = EnterFunctionTag() and
|
||||
type = getVoidType()
|
||||
or
|
||||
op instanceof Opcode::AliasedDefinition and
|
||||
tag = AliasedDefinitionTag() and
|
||||
type = getUnknownType()
|
||||
or
|
||||
op instanceof Opcode::VariableAddress and
|
||||
tag = InitializerVariableAddressTag() and
|
||||
type = getTypeForGLValue(var.getType())
|
||||
or
|
||||
op instanceof Opcode::ReturnVoid and
|
||||
tag = ReturnTag() and
|
||||
type = getVoidType()
|
||||
or
|
||||
op instanceof Opcode::AliasedUse and
|
||||
tag = AliasedUseTag() and
|
||||
type = getVoidType()
|
||||
or
|
||||
op instanceof Opcode::ExitFunction and
|
||||
tag = ExitFunctionTag() and
|
||||
type = getVoidType()
|
||||
}
|
||||
|
||||
override Instruction getInstructionSuccessor(InstructionTag tag, EdgeKind kind) {
|
||||
kind instanceof GotoEdge and
|
||||
(
|
||||
tag = EnterFunctionTag() and
|
||||
result = getInstruction(AliasedDefinitionTag())
|
||||
or
|
||||
tag = AliasedDefinitionTag() and
|
||||
result = getInstruction(InitializerVariableAddressTag())
|
||||
or
|
||||
tag = InitializerVariableAddressTag() and
|
||||
result = getChild(1).getFirstInstruction()
|
||||
or
|
||||
tag = ReturnTag() and
|
||||
result = getInstruction(AliasedUseTag())
|
||||
or
|
||||
tag = AliasedUseTag() and
|
||||
result = getInstruction(ExitFunctionTag())
|
||||
)
|
||||
}
|
||||
|
||||
override Instruction getChildSuccessor(TranslatedElement child) {
|
||||
child = getChild(1) and
|
||||
result = getInstruction(ReturnTag())
|
||||
}
|
||||
|
||||
final override CppType getInstructionMemoryOperandType(
|
||||
InstructionTag tag, TypedOperandTag operandTag
|
||||
) {
|
||||
tag = AliasedUseTag() and
|
||||
operandTag instanceof SideEffectOperandTag and
|
||||
result = getUnknownType()
|
||||
}
|
||||
|
||||
override IRUserVariable getInstructionVariable(InstructionTag tag) {
|
||||
tag = InitializerVariableAddressTag() and
|
||||
result.getVariable() = var
|
||||
}
|
||||
|
||||
override Instruction getTargetAddress() {
|
||||
result = getInstruction(InitializerVariableAddressTag())
|
||||
}
|
||||
|
||||
override Type getTargetType() { result = var.getUnspecifiedType() }
|
||||
}
|
||||
|
||||
TranslatedGlobalOrNamespaceVarInit getTranslatedVarInit(GlobalOrNamespaceVariable var) {
|
||||
result.getAst() = var
|
||||
}
|
||||
@@ -137,10 +137,7 @@ abstract class TranslatedInitialization extends TranslatedElement, TTranslatedIn
|
||||
|
||||
final override string toString() { result = "init: " + expr.toString() }
|
||||
|
||||
final override Declaration getFunction() {
|
||||
result = expr.getEnclosingFunction() or
|
||||
result = expr.getEnclosingVariable().(GlobalOrNamespaceVariable)
|
||||
}
|
||||
final override Function getFunction() { result = expr.getEnclosingFunction() }
|
||||
|
||||
final override Locatable getAst() { result = expr }
|
||||
|
||||
@@ -489,10 +486,7 @@ abstract class TranslatedFieldInitialization extends TranslatedElement {
|
||||
/** DEPRECATED: Alias for getAst */
|
||||
deprecated override Locatable getAST() { result = getAst() }
|
||||
|
||||
final override Declaration getFunction() {
|
||||
result = ast.getEnclosingFunction() or
|
||||
result = ast.getEnclosingVariable().(GlobalOrNamespaceVariable)
|
||||
}
|
||||
final override Function getFunction() { result = ast.getEnclosingFunction() }
|
||||
|
||||
final override Instruction getFirstInstruction() { result = getInstruction(getFieldAddressTag()) }
|
||||
|
||||
@@ -639,11 +633,7 @@ abstract class TranslatedElementInitialization extends TranslatedElement {
|
||||
/** DEPRECATED: Alias for getAst */
|
||||
deprecated override Locatable getAST() { result = getAst() }
|
||||
|
||||
final override Declaration getFunction() {
|
||||
result = initList.getEnclosingFunction()
|
||||
or
|
||||
result = initList.getEnclosingVariable().(GlobalOrNamespaceVariable)
|
||||
}
|
||||
final override Function getFunction() { result = initList.getEnclosingFunction() }
|
||||
|
||||
final override Instruction getFirstInstruction() { result = getInstruction(getElementIndexTag()) }
|
||||
|
||||
|
||||
@@ -97,7 +97,7 @@ class IRBlockBase extends TIRBlock {
|
||||
/**
|
||||
* Gets the `Function` that contains this block.
|
||||
*/
|
||||
final Language::Declaration getEnclosingFunction() {
|
||||
final Language::Function getEnclosingFunction() {
|
||||
result = getFirstInstruction(this).getEnclosingFunction()
|
||||
}
|
||||
}
|
||||
|
||||
@@ -194,7 +194,7 @@ class Instruction extends Construction::TStageInstruction {
|
||||
/**
|
||||
* Gets the function that contains this instruction.
|
||||
*/
|
||||
final Language::Declaration getEnclosingFunction() {
|
||||
final Language::Function getEnclosingFunction() {
|
||||
result = this.getEnclosingIRFunction().getFunction()
|
||||
}
|
||||
|
||||
|
||||
@@ -26,20 +26,20 @@ class PrintIRConfiguration extends TPrintIRConfiguration {
|
||||
* Holds if the IR for `func` should be printed. By default, holds for all
|
||||
* functions.
|
||||
*/
|
||||
predicate shouldPrintFunction(Language::Declaration decl) { any() }
|
||||
predicate shouldPrintFunction(Language::Function func) { any() }
|
||||
}
|
||||
|
||||
/**
|
||||
* Override of `IRConfiguration` to only evaluate debug strings for the functions that are to be dumped.
|
||||
*/
|
||||
private class FilteredIRConfiguration extends IRConfiguration {
|
||||
override predicate shouldEvaluateDebugStringsForFunction(Language::Declaration func) {
|
||||
override predicate shouldEvaluateDebugStringsForFunction(Language::Function func) {
|
||||
shouldPrintFunction(func)
|
||||
}
|
||||
}
|
||||
|
||||
private predicate shouldPrintFunction(Language::Declaration decl) {
|
||||
exists(PrintIRConfiguration config | config.shouldPrintFunction(decl))
|
||||
private predicate shouldPrintFunction(Language::Function func) {
|
||||
exists(PrintIRConfiguration config | config.shouldPrintFunction(func))
|
||||
}
|
||||
|
||||
private string getAdditionalInstructionProperty(Instruction instr, string key) {
|
||||
|
||||
@@ -50,16 +50,12 @@ class AutomaticVariable = Cpp::StackVariable;
|
||||
|
||||
class StaticVariable = Cpp::Variable;
|
||||
|
||||
class GlobalVariable = Cpp::GlobalOrNamespaceVariable;
|
||||
|
||||
class Parameter = Cpp::Parameter;
|
||||
|
||||
class Field = Cpp::Field;
|
||||
|
||||
class BuiltInOperation = Cpp::BuiltInOperation;
|
||||
|
||||
class Declaration = Cpp::Declaration;
|
||||
|
||||
// TODO: Remove necessity for these.
|
||||
class Expr = Cpp::Expr;
|
||||
|
||||
|
||||
@@ -5,8 +5,6 @@
|
||||
|
||||
import cpp
|
||||
import semmle.code.cpp.controlflow.Dominance
|
||||
// `GlobalValueNumbering` is only imported to prevent IR re-evaluation.
|
||||
private import semmle.code.cpp.valuenumbering.GlobalValueNumbering
|
||||
import semmle.code.cpp.rangeanalysis.SimpleRangeAnalysis
|
||||
import semmle.code.cpp.rangeanalysis.RangeAnalysisUtils
|
||||
import semmle.code.cpp.controlflow.Guards
|
||||
|
||||
@@ -14,9 +14,6 @@
|
||||
*/
|
||||
|
||||
import cpp
|
||||
// We don't actually use the global value numbering library in this query, but without it we end up
|
||||
// recomputing the IR.
|
||||
private import semmle.code.cpp.valuenumbering.GlobalValueNumbering
|
||||
import semmle.code.cpp.ir.IR
|
||||
import semmle.code.cpp.ir.dataflow.MustFlow
|
||||
import PathGraph
|
||||
|
||||
@@ -2,7 +2,7 @@
|
||||
* @name Suspicious call to memset
|
||||
* @description Use of memset where the size argument is computed as the size of
|
||||
* some non-struct type. When initializing a buffer, you should specify
|
||||
* its size as <number of elements> * <size of one element> to ensure
|
||||
* its size as `<number of elements> * <size of one element>` to ensure
|
||||
* portability.
|
||||
* @kind problem
|
||||
* @id cpp/suspicious-call-to-memset
|
||||
|
||||
@@ -15,9 +15,6 @@
|
||||
*/
|
||||
|
||||
import cpp
|
||||
// We don't actually use the global value numbering library in this query, but without it we end up
|
||||
// recomputing the IR.
|
||||
import semmle.code.cpp.valuenumbering.GlobalValueNumbering
|
||||
import semmle.code.cpp.ir.IR
|
||||
import semmle.code.cpp.ir.dataflow.MustFlow
|
||||
import PathGraph
|
||||
|
||||
@@ -188,6 +188,42 @@ class CreateLSParser extends Function {
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* A call to a `libxml2` function that parses XML.
|
||||
*/
|
||||
class Libxml2ParseCall extends FunctionCall {
|
||||
int optionsArg;
|
||||
|
||||
Libxml2ParseCall() {
|
||||
exists(string fname | this.getTarget().getName() = fname |
|
||||
fname = "xmlCtxtUseOptions" and optionsArg = 1
|
||||
or
|
||||
fname = "xmlReadFile" and optionsArg = 2
|
||||
or
|
||||
fname = ["xmlCtxtReadFile", "xmlParseInNodeContext", "xmlReadDoc", "xmlReadFd"] and
|
||||
optionsArg = 3
|
||||
or
|
||||
fname = ["xmlCtxtReadDoc", "xmlCtxtReadFd", "xmlReadMemory"] and optionsArg = 4
|
||||
or
|
||||
fname = ["xmlCtxtReadMemory", "xmlReadIO"] and optionsArg = 5
|
||||
or
|
||||
fname = "xmlCtxtReadIO" and optionsArg = 6
|
||||
)
|
||||
}
|
||||
|
||||
/**
|
||||
* Gets the argument that specifies `xmlParserOption`s.
|
||||
*/
|
||||
Expr getOptions() { result = this.getArgument(optionsArg) }
|
||||
}
|
||||
|
||||
/**
|
||||
* An `xmlParserOption` for `libxml2` that is considered unsafe.
|
||||
*/
|
||||
class Libxml2BadOption extends EnumConstant {
|
||||
Libxml2BadOption() { this.getName() = ["XML_PARSE_NOENT", "XML_PARSE_DTDLOAD"] }
|
||||
}
|
||||
|
||||
/**
|
||||
* A configuration for tracking XML objects and their states.
|
||||
*/
|
||||
@@ -219,6 +255,23 @@ class XXEConfiguration extends DataFlow::Configuration {
|
||||
call.getThisArgument() and
|
||||
encodeXercesFlowState(flowstate, 0, 1) // default configuration
|
||||
)
|
||||
or
|
||||
// source is an `options` argument on a `libxml2` parse call that specifies
|
||||
// at least one unsafe option.
|
||||
//
|
||||
// note: we don't need to track an XML object for `libxml2`, so we don't
|
||||
// really need data flow. Nevertheless we jam it into this configuration,
|
||||
// with matching sources and sinks. This allows results to be presented by
|
||||
// the same query, in a consistent way as other results with flow paths.
|
||||
exists(Libxml2ParseCall call, Expr options |
|
||||
options = call.getOptions() and
|
||||
node.asExpr() = options and
|
||||
flowstate = "libxml2" and
|
||||
exists(Libxml2BadOption opt |
|
||||
globalValueNumber(options).getAnExpr().getValue().toInt().bitAnd(opt.getValue().toInt()) !=
|
||||
0
|
||||
)
|
||||
)
|
||||
}
|
||||
|
||||
override predicate isSink(DataFlow::Node node, string flowstate) {
|
||||
@@ -229,6 +282,13 @@ class XXEConfiguration extends DataFlow::Configuration {
|
||||
) and
|
||||
flowstate instanceof XercesFlowState and
|
||||
not encodeXercesFlowState(flowstate, 1, 1) // safe configuration
|
||||
or
|
||||
// sink is the `options` argument on a `libxml2` parse call.
|
||||
exists(Libxml2ParseCall call, Expr options |
|
||||
options = call.getOptions() and
|
||||
node.asExpr() = options and
|
||||
flowstate = "libxml2"
|
||||
)
|
||||
}
|
||||
|
||||
override predicate isAdditionalFlowStep(
|
||||
|
||||
@@ -0,0 +1,49 @@
|
||||
<!DOCTYPE qhelp PUBLIC "-//Semmle//qhelp//EN" "qhelp.dtd">
|
||||
<qhelp>
|
||||
<overview>
|
||||
<p>
|
||||
Using only a call to
|
||||
<code>pam_authenticate</code>
|
||||
to check the validity of a login can lead to authorization bypass vulnerabilities.
|
||||
</p>
|
||||
<p>
|
||||
A
|
||||
<code>pam_authenticate</code>
|
||||
only verifies the credentials of a user. It does not check if a user has an appropriate authorization to actually login. This means a user with a expired login or a password can still access the system.
|
||||
</p>
|
||||
|
||||
</overview>
|
||||
|
||||
<recommendation>
|
||||
<p>
|
||||
A call to
|
||||
<code>pam_authenticate</code>
|
||||
should be followed by a call to
|
||||
<code>pam_acct_mgmt</code>
|
||||
to check if a user is allowed to login.
|
||||
</p>
|
||||
</recommendation>
|
||||
|
||||
<example>
|
||||
<p>
|
||||
In the following example, the code only checks the credentials of a user. Hence, in this case, a user expired with expired creds can still login. This can be verified by creating a new user account, expiring it with
|
||||
<code>chage -E0 `username` </code>
|
||||
and then trying to log in.
|
||||
</p>
|
||||
<sample src="PamAuthorizationBad.cpp" />
|
||||
|
||||
<p>
|
||||
This can be avoided by calling
|
||||
<code>pam_acct_mgmt</code>
|
||||
call to verify access as has been done in the snippet shown below.
|
||||
</p>
|
||||
<sample src="PamAuthorizationGood.cpp" />
|
||||
</example>
|
||||
|
||||
<references>
|
||||
<li>
|
||||
Man-Page:
|
||||
<a href="https://man7.org/linux/man-pages/man3/pam_acct_mgmt.3.html">pam_acct_mgmt</a>
|
||||
</li>
|
||||
</references>
|
||||
</qhelp>
|
||||
@@ -0,0 +1,34 @@
|
||||
/**
|
||||
* @name PAM Authorization bypass
|
||||
* @description Only using `pam_authenticate` call to authenticate users can lead to authorization vulnerabilities.
|
||||
* @kind problem
|
||||
* @problem.severity error
|
||||
* @id cpp/pam-auth-bypass
|
||||
* @tags security
|
||||
* external/cwe/cwe-285
|
||||
*/
|
||||
|
||||
import cpp
|
||||
import semmle.code.cpp.dataflow.DataFlow
|
||||
import semmle.code.cpp.valuenumbering.GlobalValueNumbering
|
||||
|
||||
private class PamAuthCall extends FunctionCall {
|
||||
PamAuthCall() {
|
||||
exists(Function f | f.hasName("pam_authenticate") | f.getACallToThisFunction() = this)
|
||||
}
|
||||
}
|
||||
|
||||
private class PamActMgmtCall extends FunctionCall {
|
||||
PamActMgmtCall() {
|
||||
exists(Function f | f.hasName("pam_acct_mgmt") | f.getACallToThisFunction() = this)
|
||||
}
|
||||
}
|
||||
|
||||
from PamAuthCall pa, Expr handle
|
||||
where
|
||||
pa.getArgument(0) = handle and
|
||||
not exists(PamActMgmtCall pac |
|
||||
globalValueNumber(handle) = globalValueNumber(pac.getArgument(0)) or
|
||||
DataFlow::localExprFlow(handle, pac.getArgument(0))
|
||||
)
|
||||
select pa, "This PAM authentication call may be lead to an authorization bypass."
|
||||
@@ -0,0 +1,20 @@
|
||||
bool PamAuthGood(const std::string &username_in,
|
||||
const std::string &password_in,
|
||||
std::string &authenticated_username)
|
||||
{
|
||||
|
||||
struct pam_handle *pamh = nullptr; /* pam session handle */
|
||||
|
||||
const char *username = username_in.c_str();
|
||||
int err = pam_start("test", username,
|
||||
0, &pamh);
|
||||
if (err != PAM_SUCCESS)
|
||||
{
|
||||
return false;
|
||||
}
|
||||
|
||||
err = pam_authenticate(pamh, 0); // BAD
|
||||
if (err != PAM_SUCCESS)
|
||||
return err;
|
||||
return true;
|
||||
}
|
||||
@@ -0,0 +1,24 @@
|
||||
bool PamAuthGood(const std::string &username_in,
|
||||
const std::string &password_in,
|
||||
std::string &authenticated_username)
|
||||
{
|
||||
|
||||
struct pam_handle *pamh = nullptr; /* pam session handle */
|
||||
|
||||
const char *username = username_in.c_str();
|
||||
int err = pam_start("test", username,
|
||||
0, &pamh);
|
||||
if (err != PAM_SUCCESS)
|
||||
{
|
||||
return false;
|
||||
}
|
||||
|
||||
err = pam_authenticate(pamh, 0);
|
||||
if (err != PAM_SUCCESS)
|
||||
return err;
|
||||
|
||||
err = pam_acct_mgmt(pamh, 0); // GOOD
|
||||
if (err != PAM_SUCCESS)
|
||||
return err;
|
||||
return true;
|
||||
}
|
||||
@@ -0,0 +1 @@
|
||||
| test.cpp:29:11:29:26 | call to pam_authenticate | This PAM authentication call may be lead to an authorization bypass. |
|
||||
@@ -0,0 +1 @@
|
||||
experimental/Security/CWE/CWE-285/PamAuthorization.ql
|
||||
@@ -0,0 +1,59 @@
|
||||
#include "../../../../../library-tests/dataflow/taint-tests/stl.h"
|
||||
|
||||
using namespace std;
|
||||
|
||||
#define PAM_SUCCESS 1
|
||||
|
||||
typedef struct pam_handle
|
||||
{
|
||||
};
|
||||
int pam_start(std::string servicename, std::string username, int a, struct pam_handle **);
|
||||
int pam_authenticate(struct pam_handle *, int e);
|
||||
int pam_acct_mgmt(struct pam_handle *, int e);
|
||||
|
||||
bool PamAuthBad(const std::string &username_in,
|
||||
const std::string &password_in,
|
||||
std::string &authenticated_username)
|
||||
{
|
||||
|
||||
struct pam_handle *pamh = nullptr; /* pam session handle */
|
||||
|
||||
const char *username = username_in.c_str();
|
||||
int err = pam_start("test", username,
|
||||
0, &pamh);
|
||||
if (err != PAM_SUCCESS)
|
||||
{
|
||||
return false;
|
||||
}
|
||||
|
||||
err = pam_authenticate(pamh, 0);
|
||||
if (err != PAM_SUCCESS)
|
||||
return err;
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
bool PamAuthGood(const std::string &username_in,
|
||||
const std::string &password_in,
|
||||
std::string &authenticated_username)
|
||||
{
|
||||
|
||||
struct pam_handle *pamh = nullptr; /* pam session handle */
|
||||
|
||||
const char *username = username_in.c_str();
|
||||
int err = pam_start("test", username,
|
||||
0, &pamh);
|
||||
if (err != PAM_SUCCESS)
|
||||
{
|
||||
return false;
|
||||
}
|
||||
|
||||
err = pam_authenticate(pamh, 0);
|
||||
if (err != PAM_SUCCESS)
|
||||
return err;
|
||||
|
||||
err = pam_acct_mgmt(pamh, 0);
|
||||
if (err != PAM_SUCCESS)
|
||||
return err;
|
||||
return true;
|
||||
}
|
||||
@@ -1,18 +1,4 @@
|
||||
uniqueEnclosingCallable
|
||||
| globals.cpp:9:5:9:19 | Address | Node should have one enclosing callable but has 0. |
|
||||
| globals.cpp:9:5:9:19 | VariableAddress | Node should have one enclosing callable but has 0. |
|
||||
| globals.cpp:9:5:9:19 | VariableAddress [post update] | Node should have one enclosing callable but has 0. |
|
||||
| globals.cpp:9:23:9:23 | 0 | Node should have one enclosing callable but has 0. |
|
||||
| globals.cpp:9:23:9:23 | ChiPartial | Node should have one enclosing callable but has 0. |
|
||||
| globals.cpp:9:23:9:23 | Store | Node should have one enclosing callable but has 0. |
|
||||
| globals.cpp:9:23:9:23 | StoreValue | Node should have one enclosing callable but has 0. |
|
||||
| globals.cpp:16:12:16:26 | Address | Node should have one enclosing callable but has 0. |
|
||||
| globals.cpp:16:12:16:26 | VariableAddress | Node should have one enclosing callable but has 0. |
|
||||
| globals.cpp:16:12:16:26 | VariableAddress [post update] | Node should have one enclosing callable but has 0. |
|
||||
| globals.cpp:16:30:16:30 | 0 | Node should have one enclosing callable but has 0. |
|
||||
| globals.cpp:16:30:16:30 | ChiPartial | Node should have one enclosing callable but has 0. |
|
||||
| globals.cpp:16:30:16:30 | Store | Node should have one enclosing callable but has 0. |
|
||||
| globals.cpp:16:30:16:30 | StoreValue | Node should have one enclosing callable but has 0. |
|
||||
uniqueType
|
||||
uniqueNodeLocation
|
||||
| BarrierGuard.cpp:2:11:2:13 | (unnamed parameter 0) | Node should have one location but has 6. |
|
||||
@@ -213,9 +199,7 @@ postWithInFlow
|
||||
| example.c:28:22:28:25 | & ... [post update] | PostUpdateNode should not be the target of local flow. |
|
||||
| example.c:28:23:28:25 | pos [post update] | PostUpdateNode should not be the target of local flow. |
|
||||
| globals.cpp:5:9:5:13 | VariableAddress [post update] | PostUpdateNode should not be the target of local flow. |
|
||||
| globals.cpp:9:5:9:19 | VariableAddress [post update] | PostUpdateNode should not be the target of local flow. |
|
||||
| globals.cpp:13:5:13:19 | flowTestGlobal1 [post update] | PostUpdateNode should not be the target of local flow. |
|
||||
| globals.cpp:16:12:16:26 | VariableAddress [post update] | PostUpdateNode should not be the target of local flow. |
|
||||
| globals.cpp:23:5:23:19 | flowTestGlobal2 [post update] | PostUpdateNode should not be the target of local flow. |
|
||||
| lambdas.cpp:8:6:8:6 | VariableAddress [post update] | PostUpdateNode should not be the target of local flow. |
|
||||
| lambdas.cpp:9:6:9:6 | VariableAddress [post update] | PostUpdateNode should not be the target of local flow. |
|
||||
|
||||
@@ -12,11 +12,4 @@ predicate locationIsInStandardHeaders(Location loc) {
|
||||
*
|
||||
* This predicate excludes functions defined in standard headers.
|
||||
*/
|
||||
predicate shouldDumpFunction(Declaration decl) {
|
||||
not locationIsInStandardHeaders(decl.getLocation()) and
|
||||
(
|
||||
not decl instanceof Variable
|
||||
or
|
||||
decl.(GlobalOrNamespaceVariable).hasInitializer()
|
||||
)
|
||||
}
|
||||
predicate shouldDumpFunction(Function func) { not locationIsInStandardHeaders(func.getLocation()) }
|
||||
|
||||
@@ -1754,16 +1754,4 @@ int implicit_copy_constructor_test(
|
||||
CopyConstructorTestVirtualClass cy = y;
|
||||
}
|
||||
|
||||
int global_1;
|
||||
|
||||
int global_2 = 1;
|
||||
|
||||
const int global_3 = 2;
|
||||
|
||||
constructor_only global_4(1);
|
||||
|
||||
constructor_only global_5 = constructor_only(2);
|
||||
|
||||
char *global_string = "global string";
|
||||
|
||||
// semmle-extractor-options: -std=c++17 --clang
|
||||
|
||||
@@ -4743,16 +4743,6 @@
|
||||
| ir.cpp:1034:6:1034:20 | ChiTotal | total:m1034_2 |
|
||||
| ir.cpp:1034:6:1034:20 | SideEffect | m1034_3 |
|
||||
| ir.cpp:1035:15:1035:15 | Address | &:r1035_1 |
|
||||
| ir.cpp:1038:6:1038:8 | Address | &:r1038_3 |
|
||||
| ir.cpp:1038:6:1038:8 | SideEffect | ~m1038_9 |
|
||||
| ir.cpp:1038:12:1038:18 | Address | &:r1038_4 |
|
||||
| ir.cpp:1038:12:1038:18 | Address | &:r1038_4 |
|
||||
| ir.cpp:1038:12:1038:18 | ChiPartial | partial:m1038_5 |
|
||||
| ir.cpp:1038:12:1038:18 | ChiPartial | partial:m1038_8 |
|
||||
| ir.cpp:1038:12:1038:18 | ChiTotal | total:m1038_2 |
|
||||
| ir.cpp:1038:12:1038:18 | ChiTotal | total:m1038_6 |
|
||||
| ir.cpp:1038:12:1038:18 | Load | ~m1038_6 |
|
||||
| ir.cpp:1038:12:1038:18 | StoreValue | r1038_7 |
|
||||
| ir.cpp:1038:14:1038:14 | Address | &:r1038_5 |
|
||||
| ir.cpp:1038:14:1038:14 | Address | &:r1038_5 |
|
||||
| ir.cpp:1038:14:1038:14 | Address | &:r1038_5 |
|
||||
@@ -8225,43 +8215,6 @@
|
||||
| ir.cpp:1754:42:1754:42 | SideEffect | ~m1752_4 |
|
||||
| ir.cpp:1754:42:1754:42 | Unary | r1754_5 |
|
||||
| ir.cpp:1754:42:1754:42 | Unary | r1754_6 |
|
||||
| ir.cpp:1759:5:1759:12 | Address | &:r1759_3 |
|
||||
| ir.cpp:1759:5:1759:12 | SideEffect | ~m1759_6 |
|
||||
| ir.cpp:1759:16:1759:16 | ChiPartial | partial:m1759_5 |
|
||||
| ir.cpp:1759:16:1759:16 | ChiTotal | total:m1759_2 |
|
||||
| ir.cpp:1759:16:1759:16 | StoreValue | r1759_4 |
|
||||
| ir.cpp:1761:11:1761:18 | Address | &:r1761_3 |
|
||||
| ir.cpp:1761:11:1761:18 | SideEffect | ~m1761_6 |
|
||||
| ir.cpp:1761:22:1761:22 | ChiPartial | partial:m1761_5 |
|
||||
| ir.cpp:1761:22:1761:22 | ChiTotal | total:m1761_2 |
|
||||
| ir.cpp:1761:22:1761:22 | StoreValue | r1761_4 |
|
||||
| ir.cpp:1763:18:1763:25 | Address | &:r1763_3 |
|
||||
| ir.cpp:1763:18:1763:25 | Arg(this) | this:r1763_3 |
|
||||
| ir.cpp:1763:18:1763:25 | SideEffect | ~m1763_10 |
|
||||
| ir.cpp:1763:27:1763:27 | Arg(0) | 0:r1763_5 |
|
||||
| ir.cpp:1763:27:1763:28 | CallTarget | func:r1763_4 |
|
||||
| ir.cpp:1763:27:1763:28 | ChiPartial | partial:m1763_7 |
|
||||
| ir.cpp:1763:27:1763:28 | ChiPartial | partial:m1763_9 |
|
||||
| ir.cpp:1763:27:1763:28 | ChiTotal | total:m1763_2 |
|
||||
| ir.cpp:1763:27:1763:28 | ChiTotal | total:m1763_8 |
|
||||
| ir.cpp:1763:27:1763:28 | SideEffect | ~m1763_2 |
|
||||
| ir.cpp:1765:18:1765:25 | Address | &:r1765_3 |
|
||||
| ir.cpp:1765:18:1765:25 | Arg(this) | this:r1765_3 |
|
||||
| ir.cpp:1765:18:1765:25 | SideEffect | ~m1765_10 |
|
||||
| ir.cpp:1765:28:1765:47 | CallTarget | func:r1765_4 |
|
||||
| ir.cpp:1765:28:1765:47 | ChiPartial | partial:m1765_7 |
|
||||
| ir.cpp:1765:28:1765:47 | ChiPartial | partial:m1765_9 |
|
||||
| ir.cpp:1765:28:1765:47 | ChiTotal | total:m1765_2 |
|
||||
| ir.cpp:1765:28:1765:47 | ChiTotal | total:m1765_8 |
|
||||
| ir.cpp:1765:28:1765:47 | SideEffect | ~m1765_2 |
|
||||
| ir.cpp:1765:46:1765:46 | Arg(0) | 0:r1765_5 |
|
||||
| ir.cpp:1767:7:1767:19 | Address | &:r1767_3 |
|
||||
| ir.cpp:1767:7:1767:19 | SideEffect | ~m1767_8 |
|
||||
| ir.cpp:1767:23:1767:37 | ChiPartial | partial:m1767_7 |
|
||||
| ir.cpp:1767:23:1767:37 | ChiTotal | total:m1767_2 |
|
||||
| ir.cpp:1767:23:1767:37 | StoreValue | r1767_6 |
|
||||
| ir.cpp:1767:23:1767:37 | Unary | r1767_4 |
|
||||
| ir.cpp:1767:23:1767:37 | Unary | r1767_5 |
|
||||
| perf-regression.cpp:6:3:6:5 | Address | &:r6_5 |
|
||||
| perf-regression.cpp:6:3:6:5 | Address | &:r6_5 |
|
||||
| perf-regression.cpp:6:3:6:5 | Address | &:r6_7 |
|
||||
@@ -8505,34 +8458,6 @@
|
||||
| smart_ptr.cpp:47:43:47:63 | SideEffect | ~m47_16 |
|
||||
| smart_ptr.cpp:47:43:47:63 | Unary | r47_5 |
|
||||
| smart_ptr.cpp:47:43:47:63 | Unary | r47_6 |
|
||||
| struct_init.cpp:9:13:9:25 | Left | r9_3 |
|
||||
| struct_init.cpp:9:13:9:25 | Left | r9_3 |
|
||||
| struct_init.cpp:9:13:9:25 | SideEffect | ~m11_10 |
|
||||
| struct_init.cpp:9:31:12:1 | Right | r9_4 |
|
||||
| struct_init.cpp:9:31:12:1 | Right | r9_6 |
|
||||
| struct_init.cpp:9:31:12:1 | Unary | r9_5 |
|
||||
| struct_init.cpp:9:31:12:1 | Unary | r9_5 |
|
||||
| struct_init.cpp:9:31:12:1 | Unary | r9_7 |
|
||||
| struct_init.cpp:9:31:12:1 | Unary | r9_7 |
|
||||
| struct_init.cpp:10:5:10:21 | Address | &:r10_1 |
|
||||
| struct_init.cpp:10:5:10:21 | Address | &:r10_6 |
|
||||
| struct_init.cpp:10:7:10:9 | ChiPartial | partial:m10_4 |
|
||||
| struct_init.cpp:10:7:10:9 | ChiTotal | total:m9_2 |
|
||||
| struct_init.cpp:10:7:10:9 | StoreValue | r10_3 |
|
||||
| struct_init.cpp:10:7:10:9 | Unary | r10_2 |
|
||||
| struct_init.cpp:10:12:10:19 | ChiPartial | partial:m10_8 |
|
||||
| struct_init.cpp:10:12:10:19 | ChiTotal | total:m10_5 |
|
||||
| struct_init.cpp:10:12:10:19 | StoreValue | r10_7 |
|
||||
| struct_init.cpp:11:5:11:22 | Address | &:r11_1 |
|
||||
| struct_init.cpp:11:5:11:22 | Address | &:r11_6 |
|
||||
| struct_init.cpp:11:7:11:9 | ChiPartial | partial:m11_4 |
|
||||
| struct_init.cpp:11:7:11:9 | ChiTotal | total:m10_9 |
|
||||
| struct_init.cpp:11:7:11:9 | StoreValue | r11_3 |
|
||||
| struct_init.cpp:11:7:11:9 | Unary | r11_2 |
|
||||
| struct_init.cpp:11:12:11:20 | ChiPartial | partial:m11_9 |
|
||||
| struct_init.cpp:11:12:11:20 | ChiTotal | total:m11_5 |
|
||||
| struct_init.cpp:11:12:11:20 | StoreValue | r11_8 |
|
||||
| struct_init.cpp:11:13:11:20 | Unary | r11_7 |
|
||||
| struct_init.cpp:16:6:16:20 | ChiPartial | partial:m16_3 |
|
||||
| struct_init.cpp:16:6:16:20 | ChiTotal | total:m16_2 |
|
||||
| struct_init.cpp:16:6:16:20 | SideEffect | ~m17_5 |
|
||||
|
||||
@@ -5650,19 +5650,6 @@ ir.cpp:
|
||||
# 1034| v1034_5(void) = AliasedUse : ~m?
|
||||
# 1034| v1034_6(void) = ExitFunction :
|
||||
|
||||
# 1038| (lambda [] type at line 1038, col. 12) lam
|
||||
# 1038| Block 0
|
||||
# 1038| v1038_1(void) = EnterFunction :
|
||||
# 1038| mu1038_2(unknown) = AliasedDefinition :
|
||||
# 1038| r1038_3(glval<decltype([...](...){...})>) = VariableAddress :
|
||||
# 1038| r1038_4(glval<decltype([...](...){...})>) = VariableAddress :
|
||||
# 1038| mu1038_5(decltype([...](...){...})) = Uninitialized : &:r1038_4
|
||||
# 1038| r1038_6(decltype([...](...){...})) = Load[?] : &:r1038_4, ~m?
|
||||
# 1038| mu1038_7(decltype([...](...){...})) = Store[?] : &:r1038_3, r1038_6
|
||||
# 1038| v1038_8(void) = ReturnVoid :
|
||||
# 1038| v1038_9(void) = AliasedUse : ~m?
|
||||
# 1038| v1038_10(void) = ExitFunction :
|
||||
|
||||
# 1038| void (lambda [] type at line 1038, col. 12)::operator()() const
|
||||
# 1038| Block 0
|
||||
# 1038| v1038_1(void) = EnterFunction :
|
||||
@@ -9431,69 +9418,6 @@ ir.cpp:
|
||||
# 1750| v1750_6(void) = AliasedUse : ~m?
|
||||
# 1750| v1750_7(void) = ExitFunction :
|
||||
|
||||
# 1759| int global_2
|
||||
# 1759| Block 0
|
||||
# 1759| v1759_1(void) = EnterFunction :
|
||||
# 1759| mu1759_2(unknown) = AliasedDefinition :
|
||||
# 1759| r1759_3(glval<int>) = VariableAddress :
|
||||
# 1759| r1759_4(int) = Constant[1] :
|
||||
# 1759| mu1759_5(int) = Store[?] : &:r1759_3, r1759_4
|
||||
# 1759| v1759_6(void) = ReturnVoid :
|
||||
# 1759| v1759_7(void) = AliasedUse : ~m?
|
||||
# 1759| v1759_8(void) = ExitFunction :
|
||||
|
||||
# 1761| int const global_3
|
||||
# 1761| Block 0
|
||||
# 1761| v1761_1(void) = EnterFunction :
|
||||
# 1761| mu1761_2(unknown) = AliasedDefinition :
|
||||
# 1761| r1761_3(glval<int>) = VariableAddress :
|
||||
# 1761| r1761_4(int) = Constant[2] :
|
||||
# 1761| mu1761_5(int) = Store[?] : &:r1761_3, r1761_4
|
||||
# 1761| v1761_6(void) = ReturnVoid :
|
||||
# 1761| v1761_7(void) = AliasedUse : ~m?
|
||||
# 1761| v1761_8(void) = ExitFunction :
|
||||
|
||||
# 1763| constructor_only global_4
|
||||
# 1763| Block 0
|
||||
# 1763| v1763_1(void) = EnterFunction :
|
||||
# 1763| mu1763_2(unknown) = AliasedDefinition :
|
||||
# 1763| r1763_3(glval<constructor_only>) = VariableAddress :
|
||||
# 1763| r1763_4(glval<unknown>) = FunctionAddress[constructor_only] :
|
||||
# 1763| r1763_5(int) = Constant[1] :
|
||||
# 1763| v1763_6(void) = Call[constructor_only] : func:r1763_4, this:r1763_3, 0:r1763_5
|
||||
# 1763| mu1763_7(unknown) = ^CallSideEffect : ~m?
|
||||
# 1763| mu1763_8(constructor_only) = ^IndirectMayWriteSideEffect[-1] : &:r1763_3
|
||||
# 1763| v1763_9(void) = ReturnVoid :
|
||||
# 1763| v1763_10(void) = AliasedUse : ~m?
|
||||
# 1763| v1763_11(void) = ExitFunction :
|
||||
|
||||
# 1765| constructor_only global_5
|
||||
# 1765| Block 0
|
||||
# 1765| v1765_1(void) = EnterFunction :
|
||||
# 1765| mu1765_2(unknown) = AliasedDefinition :
|
||||
# 1765| r1765_3(glval<constructor_only>) = VariableAddress :
|
||||
# 1765| r1765_4(glval<unknown>) = FunctionAddress[constructor_only] :
|
||||
# 1765| r1765_5(int) = Constant[2] :
|
||||
# 1765| v1765_6(void) = Call[constructor_only] : func:r1765_4, this:r1765_3, 0:r1765_5
|
||||
# 1765| mu1765_7(unknown) = ^CallSideEffect : ~m?
|
||||
# 1765| mu1765_8(constructor_only) = ^IndirectMayWriteSideEffect[-1] : &:r1765_3
|
||||
# 1765| v1765_9(void) = ReturnVoid :
|
||||
# 1765| v1765_10(void) = AliasedUse : ~m?
|
||||
# 1765| v1765_11(void) = ExitFunction :
|
||||
|
||||
# 1767| char* global_string
|
||||
# 1767| Block 0
|
||||
# 1767| v1767_1(void) = EnterFunction :
|
||||
# 1767| mu1767_2(unknown) = AliasedDefinition :
|
||||
# 1767| r1767_3(glval<char *>) = VariableAddress :
|
||||
# 1767| r1767_4(glval<char[14]>) = StringConstant :
|
||||
# 1767| r1767_5(char *) = Convert : r1767_4
|
||||
# 1767| r1767_6(char *) = Convert : r1767_5
|
||||
# 1767| mu1767_7(char *) = Store[?] : &:r1767_3, r1767_6
|
||||
# 1767| v1767_8(void) = ReturnVoid :
|
||||
# 1767| v1767_9(void) = AliasedUse : ~m?
|
||||
# 1767| v1767_10(void) = ExitFunction :
|
||||
|
||||
perf-regression.cpp:
|
||||
# 6| void Big::Big()
|
||||
# 6| Block 0
|
||||
@@ -9715,34 +9639,6 @@ smart_ptr.cpp:
|
||||
# 28| v28_6(void) = ExitFunction :
|
||||
|
||||
struct_init.cpp:
|
||||
# 9| Info infos_in_file[]
|
||||
# 9| Block 0
|
||||
# 9| v9_1(void) = EnterFunction :
|
||||
# 9| mu9_2(unknown) = AliasedDefinition :
|
||||
# 9| r9_3(glval<Info[]>) = VariableAddress :
|
||||
# 9| r9_4(int) = Constant[0] :
|
||||
# 9| r9_5(glval<Info>) = PointerAdd[16] : r9_3, r9_4
|
||||
# 10| r10_1(glval<char *>) = FieldAddress[name] : r9_5
|
||||
# 10| r10_2(glval<char[2]>) = StringConstant :
|
||||
# 10| r10_3(char *) = Convert : r10_2
|
||||
# 10| mu10_4(char *) = Store[?] : &:r10_1, r10_3
|
||||
# 10| r10_5(glval<..(*)(..)>) = FieldAddress[handler] : r9_5
|
||||
# 10| r10_6(..(*)(..)) = FunctionAddress[handler1] :
|
||||
# 10| mu10_7(..(*)(..)) = Store[?] : &:r10_5, r10_6
|
||||
# 9| r9_6(int) = Constant[1] :
|
||||
# 9| r9_7(glval<Info>) = PointerAdd[16] : r9_3, r9_6
|
||||
# 11| r11_1(glval<char *>) = FieldAddress[name] : r9_7
|
||||
# 11| r11_2(glval<char[2]>) = StringConstant :
|
||||
# 11| r11_3(char *) = Convert : r11_2
|
||||
# 11| mu11_4(char *) = Store[?] : &:r11_1, r11_3
|
||||
# 11| r11_5(glval<..(*)(..)>) = FieldAddress[handler] : r9_7
|
||||
# 11| r11_6(glval<..()(..)>) = FunctionAddress[handler2] :
|
||||
# 11| r11_7(..(*)(..)) = CopyValue : r11_6
|
||||
# 11| mu11_8(..(*)(..)) = Store[?] : &:r11_5, r11_7
|
||||
# 9| v9_8(void) = ReturnVoid :
|
||||
# 9| v9_9(void) = AliasedUse : ~m?
|
||||
# 9| v9_10(void) = ExitFunction :
|
||||
|
||||
# 16| void let_info_escape(Info*)
|
||||
# 16| Block 0
|
||||
# 16| v16_1(void) = EnterFunction :
|
||||
|
||||
@@ -7,5 +7,5 @@ private import semmle.code.cpp.ir.implementation.raw.PrintIR
|
||||
private import PrintConfig
|
||||
|
||||
private class PrintConfig extends PrintIRConfiguration {
|
||||
override predicate shouldPrintFunction(Declaration decl) { shouldDumpFunction(decl) }
|
||||
override predicate shouldPrintFunction(Function func) { shouldDumpFunction(func) }
|
||||
}
|
||||
|
||||
@@ -1234,8 +1234,6 @@ ssa.cpp:
|
||||
# 268| v268_14(void) = AliasedUse : ~m269_7
|
||||
# 268| v268_15(void) = ExitFunction :
|
||||
|
||||
# 274| Point* pp
|
||||
|
||||
# 275| void EscapedButNotConflated(bool, Point, int)
|
||||
# 275| Block 0
|
||||
# 275| v275_1(void) = EnterFunction :
|
||||
|
||||
@@ -1229,8 +1229,6 @@ ssa.cpp:
|
||||
# 268| v268_14(void) = AliasedUse : ~m269_7
|
||||
# 268| v268_15(void) = ExitFunction :
|
||||
|
||||
# 274| Point* pp
|
||||
|
||||
# 275| void EscapedButNotConflated(bool, Point, int)
|
||||
# 275| Block 0
|
||||
# 275| v275_1(void) = EnterFunction :
|
||||
|
||||
@@ -1140,8 +1140,6 @@ ssa.cpp:
|
||||
# 268| v268_13(void) = AliasedUse : ~m?
|
||||
# 268| v268_14(void) = ExitFunction :
|
||||
|
||||
# 274| Point* pp
|
||||
|
||||
# 275| void EscapedButNotConflated(bool, Point, int)
|
||||
# 275| Block 0
|
||||
# 275| v275_1(void) = EnterFunction :
|
||||
|
||||
@@ -1140,8 +1140,6 @@ ssa.cpp:
|
||||
# 268| v268_13(void) = AliasedUse : ~m?
|
||||
# 268| v268_14(void) = ExitFunction :
|
||||
|
||||
# 274| Point* pp
|
||||
|
||||
# 275| void EscapedButNotConflated(bool, Point, int)
|
||||
# 275| Block 0
|
||||
# 275| v275_1(void) = EnterFunction :
|
||||
|
||||
@@ -4,8 +4,6 @@ unexpectedOperand
|
||||
duplicateOperand
|
||||
missingPhiOperand
|
||||
missingOperandType
|
||||
| cpp11.cpp:36:18:36:18 | ChiTotal | Operand 'ChiTotal' of instruction 'Chi' is missing a type in function '$@'. | cpp11.cpp:36:5:36:14 | int global_int | int global_int |
|
||||
| misc.c:210:24:210:28 | ChiTotal | Operand 'ChiTotal' of instruction 'Chi' is missing a type in function '$@'. | misc.c:210:5:210:20 | int global_with_init | int global_with_init |
|
||||
duplicateChiOperand
|
||||
sideEffectWithoutPrimary
|
||||
instructionWithoutSuccessor
|
||||
@@ -93,8 +91,6 @@ useNotDominatedByDefinition
|
||||
switchInstructionWithoutDefaultEdge
|
||||
notMarkedAsConflated
|
||||
wronglyMarkedAsConflated
|
||||
| cpp11.cpp:36:18:36:18 | Chi: 5 | Instruction 'Chi: 5' should not be marked as having a conflated result in function '$@'. | cpp11.cpp:36:5:36:14 | int global_int | int global_int |
|
||||
| misc.c:210:24:210:28 | Chi: ... + ... | Instruction 'Chi: ... + ...' should not be marked as having a conflated result in function '$@'. | misc.c:210:5:210:20 | int global_with_init | int global_with_init |
|
||||
invalidOverlap
|
||||
nonUniqueEnclosingIRFunction
|
||||
fieldAddressOnNonPointer
|
||||
|
||||
@@ -1,45 +1,4 @@
|
||||
uniqueEnclosingCallable
|
||||
| cpp11.cpp:35:11:35:22 | Address | Node should have one enclosing callable but has 0. |
|
||||
| cpp11.cpp:35:11:35:22 | AliasedDefinition | Node should have one enclosing callable but has 0. |
|
||||
| cpp11.cpp:35:11:35:22 | VariableAddress | Node should have one enclosing callable but has 0. |
|
||||
| cpp11.cpp:35:11:35:22 | VariableAddress [post update] | Node should have one enclosing callable but has 0. |
|
||||
| cpp11.cpp:35:26:35:26 | 5 | Node should have one enclosing callable but has 0. |
|
||||
| cpp11.cpp:35:26:35:26 | ChiPartial | Node should have one enclosing callable but has 0. |
|
||||
| cpp11.cpp:35:26:35:26 | ChiTotal | Node should have one enclosing callable but has 0. |
|
||||
| cpp11.cpp:35:26:35:26 | Store | Node should have one enclosing callable but has 0. |
|
||||
| cpp11.cpp:35:26:35:26 | StoreValue | Node should have one enclosing callable but has 0. |
|
||||
| cpp11.cpp:36:5:36:14 | Address | Node should have one enclosing callable but has 0. |
|
||||
| cpp11.cpp:36:5:36:14 | VariableAddress | Node should have one enclosing callable but has 0. |
|
||||
| cpp11.cpp:36:5:36:14 | VariableAddress [post update] | Node should have one enclosing callable but has 0. |
|
||||
| cpp11.cpp:36:18:36:18 | 5 | Node should have one enclosing callable but has 0. |
|
||||
| cpp11.cpp:36:18:36:18 | ChiPartial | Node should have one enclosing callable but has 0. |
|
||||
| cpp11.cpp:36:18:36:18 | Store | Node should have one enclosing callable but has 0. |
|
||||
| cpp11.cpp:36:18:36:18 | StoreValue | Node should have one enclosing callable but has 0. |
|
||||
| misc.c:10:5:10:13 | Address | Node should have one enclosing callable but has 0. |
|
||||
| misc.c:10:5:10:13 | AliasedDefinition | Node should have one enclosing callable but has 0. |
|
||||
| misc.c:10:5:10:13 | VariableAddress | Node should have one enclosing callable but has 0. |
|
||||
| misc.c:10:5:10:13 | VariableAddress [post update] | Node should have one enclosing callable but has 0. |
|
||||
| misc.c:10:17:10:17 | 1 | Node should have one enclosing callable but has 0. |
|
||||
| misc.c:10:17:10:17 | ChiPartial | Node should have one enclosing callable but has 0. |
|
||||
| misc.c:10:17:10:17 | ChiTotal | Node should have one enclosing callable but has 0. |
|
||||
| misc.c:10:17:10:17 | Store | Node should have one enclosing callable but has 0. |
|
||||
| misc.c:10:17:10:17 | StoreValue | Node should have one enclosing callable but has 0. |
|
||||
| misc.c:11:5:11:13 | Address | Node should have one enclosing callable but has 0. |
|
||||
| misc.c:11:5:11:13 | AliasedDefinition | Node should have one enclosing callable but has 0. |
|
||||
| misc.c:11:5:11:13 | VariableAddress | Node should have one enclosing callable but has 0. |
|
||||
| misc.c:11:5:11:13 | VariableAddress [post update] | Node should have one enclosing callable but has 0. |
|
||||
| misc.c:11:17:11:21 | ... + ... | Node should have one enclosing callable but has 0. |
|
||||
| misc.c:11:17:11:21 | ChiPartial | Node should have one enclosing callable but has 0. |
|
||||
| misc.c:11:17:11:21 | ChiTotal | Node should have one enclosing callable but has 0. |
|
||||
| misc.c:11:17:11:21 | Store | Node should have one enclosing callable but has 0. |
|
||||
| misc.c:11:17:11:21 | StoreValue | Node should have one enclosing callable but has 0. |
|
||||
| misc.c:210:5:210:20 | Address | Node should have one enclosing callable but has 0. |
|
||||
| misc.c:210:5:210:20 | VariableAddress | Node should have one enclosing callable but has 0. |
|
||||
| misc.c:210:5:210:20 | VariableAddress [post update] | Node should have one enclosing callable but has 0. |
|
||||
| misc.c:210:24:210:28 | ... + ... | Node should have one enclosing callable but has 0. |
|
||||
| misc.c:210:24:210:28 | ChiPartial | Node should have one enclosing callable but has 0. |
|
||||
| misc.c:210:24:210:28 | Store | Node should have one enclosing callable but has 0. |
|
||||
| misc.c:210:24:210:28 | StoreValue | Node should have one enclosing callable but has 0. |
|
||||
uniqueType
|
||||
uniqueNodeLocation
|
||||
| aggregateinitializer.c:1:6:1:6 | AliasedDefinition | Node should have one location but has 20. |
|
||||
@@ -1663,8 +1622,6 @@ postWithInFlow
|
||||
| cpp11.cpp:28:21:28:34 | temporary object [post update] | PostUpdateNode should not be the target of local flow. |
|
||||
| cpp11.cpp:29:7:29:16 | VariableAddress [post update] | PostUpdateNode should not be the target of local flow. |
|
||||
| cpp11.cpp:31:5:31:13 | VariableAddress [post update] | PostUpdateNode should not be the target of local flow. |
|
||||
| cpp11.cpp:35:11:35:22 | VariableAddress [post update] | PostUpdateNode should not be the target of local flow. |
|
||||
| cpp11.cpp:36:5:36:14 | VariableAddress [post update] | PostUpdateNode should not be the target of local flow. |
|
||||
| cpp11.cpp:56:14:56:15 | VariableAddress [post update] | PostUpdateNode should not be the target of local flow. |
|
||||
| cpp11.cpp:56:14:56:15 | VariableAddress [post update] | PostUpdateNode should not be the target of local flow. |
|
||||
| cpp11.cpp:60:15:60:16 | VariableAddress [post update] | PostUpdateNode should not be the target of local flow. |
|
||||
@@ -2273,8 +2230,6 @@ postWithInFlow
|
||||
| ltrbinopexpr.c:37:5:37:5 | VariableAddress [post update] | PostUpdateNode should not be the target of local flow. |
|
||||
| ltrbinopexpr.c:39:5:39:5 | VariableAddress [post update] | PostUpdateNode should not be the target of local flow. |
|
||||
| ltrbinopexpr.c:40:5:40:5 | VariableAddress [post update] | PostUpdateNode should not be the target of local flow. |
|
||||
| misc.c:10:5:10:13 | VariableAddress [post update] | PostUpdateNode should not be the target of local flow. |
|
||||
| misc.c:11:5:11:13 | VariableAddress [post update] | PostUpdateNode should not be the target of local flow. |
|
||||
| misc.c:18:5:18:5 | i [post update] | PostUpdateNode should not be the target of local flow. |
|
||||
| misc.c:19:5:19:5 | i [post update] | PostUpdateNode should not be the target of local flow. |
|
||||
| misc.c:20:7:20:7 | VariableAddress [post update] | PostUpdateNode should not be the target of local flow. |
|
||||
@@ -2334,7 +2289,6 @@ postWithInFlow
|
||||
| misc.c:200:24:200:27 | args [post update] | PostUpdateNode should not be the target of local flow. |
|
||||
| misc.c:200:24:200:27 | array to pointer conversion [post update] | PostUpdateNode should not be the target of local flow. |
|
||||
| misc.c:208:1:208:3 | VariableAddress [post update] | PostUpdateNode should not be the target of local flow. |
|
||||
| misc.c:210:5:210:20 | VariableAddress [post update] | PostUpdateNode should not be the target of local flow. |
|
||||
| misc.c:216:3:216:26 | VariableAddress [post update] | PostUpdateNode should not be the target of local flow. |
|
||||
| misc.c:220:3:220:5 | * ... [post update] | PostUpdateNode should not be the target of local flow. |
|
||||
| misc.c:220:4:220:5 | VariableAddress [post update] | PostUpdateNode should not be the target of local flow. |
|
||||
|
||||
@@ -1,15 +1,18 @@
|
||||
| test.cpp:5:3:5:13 | ... = ... | test.cpp:5:3:5:13 | ... = ... | AST only |
|
||||
| test.cpp:6:3:6:13 | ... = ... | test.cpp:6:3:6:13 | ... = ... | AST only |
|
||||
| test.cpp:7:3:7:7 | ... = ... | test.cpp:7:3:7:7 | ... = ... | AST only |
|
||||
| test.cpp:10:16:10:16 | 1 | test.cpp:10:16:10:16 | 1 | AST only |
|
||||
| test.cpp:16:3:16:24 | ... = ... | test.cpp:16:3:16:24 | ... = ... | AST only |
|
||||
| test.cpp:17:3:17:24 | ... = ... | test.cpp:17:3:17:24 | ... = ... | AST only |
|
||||
| test.cpp:18:3:18:7 | ... = ... | test.cpp:18:3:18:7 | ... = ... | AST only |
|
||||
| test.cpp:21:16:21:16 | 2 | test.cpp:21:16:21:16 | 2 | AST only |
|
||||
| test.cpp:29:3:29:3 | x | test.cpp:31:3:31:3 | x | IR only |
|
||||
| test.cpp:29:3:29:24 | ... = ... | test.cpp:29:3:29:24 | ... = ... | AST only |
|
||||
| test.cpp:30:3:30:17 | call to change_global02 | test.cpp:30:3:30:17 | call to change_global02 | AST only |
|
||||
| test.cpp:31:3:31:3 | x | test.cpp:29:3:29:3 | x | IR only |
|
||||
| test.cpp:31:3:31:24 | ... = ... | test.cpp:31:3:31:24 | ... = ... | AST only |
|
||||
| test.cpp:32:3:32:7 | ... = ... | test.cpp:32:3:32:7 | ... = ... | AST only |
|
||||
| test.cpp:35:16:35:16 | 3 | test.cpp:35:16:35:16 | 3 | AST only |
|
||||
| test.cpp:43:3:43:3 | x | test.cpp:45:3:45:3 | x | IR only |
|
||||
| test.cpp:43:3:43:24 | ... = ... | test.cpp:43:3:43:24 | ... = ... | AST only |
|
||||
| test.cpp:43:7:43:24 | ... + ... | test.cpp:45:7:45:24 | ... + ... | IR only |
|
||||
|
||||
@@ -69,23 +69,6 @@ test.cpp:
|
||||
# 1| v1_10(void) = AliasedUse : m1_3
|
||||
# 1| v1_11(void) = ExitFunction :
|
||||
|
||||
# 10| int global01
|
||||
# 10| Block 0
|
||||
# 10| v10_1(void) = EnterFunction :
|
||||
# 10| m10_2(unknown) = AliasedDefinition :
|
||||
# 10| valnum = unique
|
||||
# 10| r10_3(glval<int>) = VariableAddress[global01] :
|
||||
# 10| valnum = unique
|
||||
# 10| r10_4(int) = Constant[1] :
|
||||
# 10| valnum = m10_5, r10_4
|
||||
# 10| m10_5(int) = Store[global01] : &:r10_3, r10_4
|
||||
# 10| valnum = m10_5, r10_4
|
||||
# 10| m10_6(unknown) = Chi : total:~m?, partial:m10_5
|
||||
# 10| valnum = unique
|
||||
# 10| v10_7(void) = ReturnVoid :
|
||||
# 10| v10_8(void) = AliasedUse : ~m10_2
|
||||
# 10| v10_9(void) = ExitFunction :
|
||||
|
||||
# 12| void test01(int, int)
|
||||
# 12| Block 0
|
||||
# 12| v12_1(void) = EnterFunction :
|
||||
@@ -168,23 +151,6 @@ test.cpp:
|
||||
# 12| v12_10(void) = AliasedUse : m12_3
|
||||
# 12| v12_11(void) = ExitFunction :
|
||||
|
||||
# 21| int global02
|
||||
# 21| Block 0
|
||||
# 21| v21_1(void) = EnterFunction :
|
||||
# 21| m21_2(unknown) = AliasedDefinition :
|
||||
# 21| valnum = unique
|
||||
# 21| r21_3(glval<int>) = VariableAddress[global02] :
|
||||
# 21| valnum = unique
|
||||
# 21| r21_4(int) = Constant[2] :
|
||||
# 21| valnum = m21_5, r21_4
|
||||
# 21| m21_5(int) = Store[global02] : &:r21_3, r21_4
|
||||
# 21| valnum = m21_5, r21_4
|
||||
# 21| m21_6(unknown) = Chi : total:~m?, partial:m21_5
|
||||
# 21| valnum = unique
|
||||
# 21| v21_7(void) = ReturnVoid :
|
||||
# 21| v21_8(void) = AliasedUse : ~m21_2
|
||||
# 21| v21_9(void) = ExitFunction :
|
||||
|
||||
# 25| void test02(int, int)
|
||||
# 25| Block 0
|
||||
# 25| v25_1(void) = EnterFunction :
|
||||
@@ -274,23 +240,6 @@ test.cpp:
|
||||
# 25| v25_10(void) = AliasedUse : ~m30_4
|
||||
# 25| v25_11(void) = ExitFunction :
|
||||
|
||||
# 35| int global03
|
||||
# 35| Block 0
|
||||
# 35| v35_1(void) = EnterFunction :
|
||||
# 35| m35_2(unknown) = AliasedDefinition :
|
||||
# 35| valnum = unique
|
||||
# 35| r35_3(glval<int>) = VariableAddress[global03] :
|
||||
# 35| valnum = unique
|
||||
# 35| r35_4(int) = Constant[3] :
|
||||
# 35| valnum = m35_5, r35_4
|
||||
# 35| m35_5(int) = Store[global03] : &:r35_3, r35_4
|
||||
# 35| valnum = m35_5, r35_4
|
||||
# 35| m35_6(unknown) = Chi : total:~m?, partial:m35_5
|
||||
# 35| valnum = unique
|
||||
# 35| v35_7(void) = ReturnVoid :
|
||||
# 35| v35_8(void) = AliasedUse : ~m35_2
|
||||
# 35| v35_9(void) = ExitFunction :
|
||||
|
||||
# 39| void test03(int, int, int*)
|
||||
# 39| Block 0
|
||||
# 39| v39_1(void) = EnterFunction :
|
||||
@@ -941,10 +890,6 @@ test.cpp:
|
||||
# 124| v124_13(void) = AliasedUse : m124_3
|
||||
# 124| v124_14(void) = ExitFunction :
|
||||
|
||||
# 132| A* global_a
|
||||
|
||||
# 133| int global_n
|
||||
|
||||
# 135| void test_read_global_same()
|
||||
# 135| Block 0
|
||||
# 135| v135_1(void) = EnterFunction :
|
||||
|
||||
@@ -45,6 +45,17 @@ nodes
|
||||
| tests.cpp:51:23:51:43 | XercesDOMParser output argument | semmle.label | XercesDOMParser output argument |
|
||||
| tests.cpp:53:2:53:2 | p | semmle.label | p |
|
||||
| tests.cpp:54:2:54:2 | p | semmle.label | p |
|
||||
| tests4.cpp:26:34:26:48 | (int)... | semmle.label | (int)... |
|
||||
| tests4.cpp:36:34:36:50 | (int)... | semmle.label | (int)... |
|
||||
| tests4.cpp:46:34:46:68 | ... \| ... | semmle.label | ... \| ... |
|
||||
| tests4.cpp:77:34:77:38 | flags | semmle.label | flags |
|
||||
| tests4.cpp:130:39:130:55 | (int)... | semmle.label | (int)... |
|
||||
| tests.cpp:33:23:33:43 | XercesDOMParser output argument | semmle.label | XercesDOMParser output argument |
|
||||
| tests.cpp:35:2:35:2 | p | semmle.label | p |
|
||||
| tests.cpp:46:23:46:43 | XercesDOMParser output argument | semmle.label | XercesDOMParser output argument |
|
||||
| tests.cpp:49:2:49:2 | p | semmle.label | p |
|
||||
| tests.cpp:53:19:53:19 | VariableAddress [post update] | semmle.label | VariableAddress [post update] |
|
||||
| tests.cpp:53:23:53:43 | XercesDOMParser output argument | semmle.label | XercesDOMParser output argument |
|
||||
| tests.cpp:55:2:55:2 | p | semmle.label | p |
|
||||
| tests.cpp:56:2:56:2 | p | semmle.label | p |
|
||||
| tests.cpp:56:2:56:2 | p | semmle.label | p |
|
||||
@@ -82,3 +93,20 @@ subpaths
|
||||
| tests.cpp:104:3:104:3 | q | tests.cpp:100:24:100:44 | XercesDOMParser output argument | tests.cpp:104:3:104:3 | q | This $@ is not configured to prevent an XML external entity (XXE) attack. | tests.cpp:100:24:100:44 | XercesDOMParser output argument | XML parser |
|
||||
| tests.cpp:113:2:113:2 | p | tests.cpp:122:23:122:43 | XercesDOMParser output argument | tests.cpp:113:2:113:2 | p | This $@ is not configured to prevent an XML external entity (XXE) attack. | tests.cpp:122:23:122:43 | XercesDOMParser output argument | XML parser |
|
||||
| tests.cpp:117:2:117:2 | p | tests.cpp:122:23:122:43 | XercesDOMParser output argument | tests.cpp:117:2:117:2 | p | This $@ is not configured to prevent an XML external entity (XXE) attack. | tests.cpp:122:23:122:43 | XercesDOMParser output argument | XML parser |
|
||||
| tests4.cpp:26:34:26:48 | (int)... | tests4.cpp:26:34:26:48 | (int)... | tests4.cpp:26:34:26:48 | (int)... | This $@ is not configured to prevent an XML external entity (XXE) attack. | tests4.cpp:26:34:26:48 | (int)... | XML parser |
|
||||
| tests4.cpp:36:34:36:50 | (int)... | tests4.cpp:36:34:36:50 | (int)... | tests4.cpp:36:34:36:50 | (int)... | This $@ is not configured to prevent an XML external entity (XXE) attack. | tests4.cpp:36:34:36:50 | (int)... | XML parser |
|
||||
| tests4.cpp:46:34:46:68 | ... \| ... | tests4.cpp:46:34:46:68 | ... \| ... | tests4.cpp:46:34:46:68 | ... \| ... | This $@ is not configured to prevent an XML external entity (XXE) attack. | tests4.cpp:46:34:46:68 | ... \| ... | XML parser |
|
||||
| tests4.cpp:77:34:77:38 | flags | tests4.cpp:77:34:77:38 | flags | tests4.cpp:77:34:77:38 | flags | This $@ is not configured to prevent an XML external entity (XXE) attack. | tests4.cpp:77:34:77:38 | flags | XML parser |
|
||||
| tests4.cpp:130:39:130:55 | (int)... | tests4.cpp:130:39:130:55 | (int)... | tests4.cpp:130:39:130:55 | (int)... | This $@ is not configured to prevent an XML external entity (XXE) attack. | tests4.cpp:130:39:130:55 | (int)... | XML parser |
|
||||
| tests.cpp:35:2:35:2 | p | tests.cpp:33:23:33:43 | XercesDOMParser output argument | tests.cpp:35:2:35:2 | p | This $@ is not configured to prevent an XML external entity (XXE) attack. | tests.cpp:33:23:33:43 | XercesDOMParser output argument | XML parser |
|
||||
| tests.cpp:49:2:49:2 | p | tests.cpp:46:23:46:43 | XercesDOMParser output argument | tests.cpp:49:2:49:2 | p | This $@ is not configured to prevent an XML external entity (XXE) attack. | tests.cpp:46:23:46:43 | XercesDOMParser output argument | XML parser |
|
||||
| tests.cpp:57:2:57:2 | p | tests.cpp:53:23:53:43 | XercesDOMParser output argument | tests.cpp:57:2:57:2 | p | This $@ is not configured to prevent an XML external entity (XXE) attack. | tests.cpp:53:23:53:43 | XercesDOMParser output argument | XML parser |
|
||||
| tests.cpp:74:2:74:2 | p | tests.cpp:69:23:69:43 | XercesDOMParser output argument | tests.cpp:74:2:74:2 | p | This $@ is not configured to prevent an XML external entity (XXE) attack. | tests.cpp:69:23:69:43 | XercesDOMParser output argument | XML parser |
|
||||
| tests.cpp:78:2:78:2 | p | tests.cpp:69:23:69:43 | XercesDOMParser output argument | tests.cpp:78:2:78:2 | p | This $@ is not configured to prevent an XML external entity (XXE) attack. | tests.cpp:69:23:69:43 | XercesDOMParser output argument | XML parser |
|
||||
| tests.cpp:87:2:87:2 | p | tests.cpp:84:23:84:43 | XercesDOMParser output argument | tests.cpp:87:2:87:2 | p | This $@ is not configured to prevent an XML external entity (XXE) attack. | tests.cpp:84:23:84:43 | XercesDOMParser output argument | XML parser |
|
||||
| tests.cpp:98:2:98:2 | p | tests.cpp:91:23:91:43 | XercesDOMParser output argument | tests.cpp:98:2:98:2 | p | This $@ is not configured to prevent an XML external entity (XXE) attack. | tests.cpp:91:23:91:43 | XercesDOMParser output argument | XML parser |
|
||||
| tests.cpp:106:3:106:3 | q | tests.cpp:103:24:103:44 | XercesDOMParser output argument | tests.cpp:106:3:106:3 | q | This $@ is not configured to prevent an XML external entity (XXE) attack. | tests.cpp:103:24:103:44 | XercesDOMParser output argument | XML parser |
|
||||
| tests.cpp:122:3:122:3 | q | tests.cpp:118:24:118:44 | XercesDOMParser output argument | tests.cpp:122:3:122:3 | q | This $@ is not configured to prevent an XML external entity (XXE) attack. | tests.cpp:118:24:118:44 | XercesDOMParser output argument | XML parser |
|
||||
| tests.cpp:131:2:131:2 | p | tests.cpp:140:23:140:43 | XercesDOMParser output argument | tests.cpp:131:2:131:2 | p | This $@ is not configured to prevent an XML external entity (XXE) attack. | tests.cpp:140:23:140:43 | XercesDOMParser output argument | XML parser |
|
||||
| tests.cpp:135:2:135:2 | p | tests.cpp:140:23:140:43 | XercesDOMParser output argument | tests.cpp:135:2:135:2 | p | This $@ is not configured to prevent an XML external entity (XXE) attack. | tests.cpp:140:23:140:43 | XercesDOMParser output argument | XML parser |
|
||||
| tests.cpp:152:2:152:2 | p | tests.cpp:150:19:150:32 | call to createLSParser | tests.cpp:152:2:152:2 | p | This $@ is not configured to prevent an XML external entity (XXE) attack. | tests.cpp:150:19:150:32 | call to createLSParser | XML parser |
|
||||
|
||||
@@ -1,5 +1,7 @@
|
||||
// library/common functions for rule CWE-611
|
||||
|
||||
#define NULL (0)
|
||||
|
||||
class SecurityManager;
|
||||
class InputSource;
|
||||
|
||||
@@ -20,3 +22,4 @@ class XMLUni
|
||||
public:
|
||||
static const XMLCh fgXercesDisableDefaultEntityResolution[];
|
||||
};
|
||||
|
||||
|
||||
135
cpp/ql/test/query-tests/Security/CWE/CWE-611/tests4.cpp
Normal file
135
cpp/ql/test/query-tests/Security/CWE/CWE-611/tests4.cpp
Normal file
@@ -0,0 +1,135 @@
|
||||
// test cases for rule CWE-611 (libxml2)
|
||||
|
||||
#include "tests.h"
|
||||
|
||||
// ---
|
||||
|
||||
enum xmlParserOption
|
||||
{
|
||||
XML_PARSE_NOENT = 2,
|
||||
XML_PARSE_DTDLOAD = 4,
|
||||
XML_PARSE_OPTION_HARMLESS = 8
|
||||
};
|
||||
|
||||
class xmlDoc;
|
||||
|
||||
xmlDoc *xmlReadFile(const char *fileName, const char *encoding, int flags);
|
||||
xmlDoc *xmlReadMemory(const char *ptr, int sz, const char *url, const char *encoding, int flags);
|
||||
|
||||
void xmlFreeDoc(xmlDoc *ptr);
|
||||
|
||||
// ---
|
||||
|
||||
void test4_1(const char *fileName) {
|
||||
xmlDoc *p;
|
||||
|
||||
p = xmlReadFile(fileName, NULL, XML_PARSE_NOENT); // BAD (parser not correctly configured)
|
||||
if (p != NULL)
|
||||
{
|
||||
xmlFreeDoc(p);
|
||||
}
|
||||
}
|
||||
|
||||
void test4_2(const char *fileName) {
|
||||
xmlDoc *p;
|
||||
|
||||
p = xmlReadFile(fileName, NULL, XML_PARSE_DTDLOAD); // BAD (parser not correctly configured)
|
||||
if (p != NULL)
|
||||
{
|
||||
xmlFreeDoc(p);
|
||||
}
|
||||
}
|
||||
|
||||
void test4_3(const char *fileName) {
|
||||
xmlDoc *p;
|
||||
|
||||
p = xmlReadFile(fileName, NULL, XML_PARSE_NOENT | XML_PARSE_DTDLOAD); // BAD (parser not correctly configured)
|
||||
if (p != NULL)
|
||||
{
|
||||
xmlFreeDoc(p);
|
||||
}
|
||||
}
|
||||
|
||||
void test4_4(const char *fileName) {
|
||||
xmlDoc *p;
|
||||
|
||||
p = xmlReadFile(fileName, NULL, 0); // GOOD
|
||||
if (p != NULL)
|
||||
{
|
||||
xmlFreeDoc(p);
|
||||
}
|
||||
}
|
||||
|
||||
void test4_5(const char *fileName) {
|
||||
xmlDoc *p;
|
||||
|
||||
p = xmlReadFile(fileName, NULL, XML_PARSE_OPTION_HARMLESS); // GOOD
|
||||
if (p != NULL)
|
||||
{
|
||||
xmlFreeDoc(p);
|
||||
}
|
||||
}
|
||||
|
||||
void test4_6(const char *fileName) {
|
||||
xmlDoc *p;
|
||||
int flags = XML_PARSE_NOENT;
|
||||
|
||||
p = xmlReadFile(fileName, NULL, flags); // BAD (parser not correctly configured)
|
||||
if (p != NULL)
|
||||
{
|
||||
xmlFreeDoc(p);
|
||||
}
|
||||
}
|
||||
|
||||
void test4_7(const char *fileName) {
|
||||
xmlDoc *p;
|
||||
int flags = 0;
|
||||
|
||||
p = xmlReadFile(fileName, NULL, flags); // GOOD
|
||||
if (p != NULL)
|
||||
{
|
||||
xmlFreeDoc(p);
|
||||
}
|
||||
}
|
||||
|
||||
void test4_8(const char *fileName) {
|
||||
xmlDoc *p;
|
||||
int flags = XML_PARSE_OPTION_HARMLESS;
|
||||
|
||||
p = xmlReadFile(fileName, NULL, flags | XML_PARSE_NOENT); // BAD (parser not correctly configured) [NOT DETECTED]
|
||||
if (p != NULL)
|
||||
{
|
||||
xmlFreeDoc(p);
|
||||
}
|
||||
}
|
||||
|
||||
void test4_9(const char *fileName) {
|
||||
xmlDoc *p;
|
||||
int flags = XML_PARSE_NOENT;
|
||||
|
||||
p = xmlReadFile(fileName, NULL, flags | XML_PARSE_OPTION_HARMLESS); // BAD (parser not correctly configured) [NOT DETECTED]
|
||||
if (p != NULL)
|
||||
{
|
||||
xmlFreeDoc(p);
|
||||
}
|
||||
}
|
||||
|
||||
void test4_10(const char *ptr, int sz) {
|
||||
xmlDoc *p;
|
||||
|
||||
p = xmlReadMemory(ptr, sz, "", NULL, 0); // GOOD
|
||||
if (p != NULL)
|
||||
{
|
||||
xmlFreeDoc(p);
|
||||
}
|
||||
}
|
||||
|
||||
void test4_11(const char *ptr, int sz) {
|
||||
xmlDoc *p;
|
||||
|
||||
p = xmlReadMemory(ptr, sz, "", NULL, XML_PARSE_DTDLOAD); // BAD (parser not correctly configured)
|
||||
if (p != NULL)
|
||||
{
|
||||
xmlFreeDoc(p);
|
||||
}
|
||||
}
|
||||
Reference in New Issue
Block a user