diff --git a/cpp/ql/lib/semmle/code/cpp/ir/dataflow/internal/DataFlowPrivate.qll b/cpp/ql/lib/semmle/code/cpp/ir/dataflow/internal/DataFlowPrivate.qll index 4936533d3518..5f90a820e97c 100644 --- a/cpp/ql/lib/semmle/code/cpp/ir/dataflow/internal/DataFlowPrivate.qll +++ b/cpp/ql/lib/semmle/code/cpp/ir/dataflow/internal/DataFlowPrivate.qll @@ -500,21 +500,25 @@ OutNode getAnOutNode(DataFlowCall call, ReturnKind kind) { */ predicate jumpStep(Node n1, Node n2) { exists(Cpp::GlobalOrNamespaceVariable v | - v = - n1.asInstruction() - .(StoreInstruction) - .getResultAddress() - .(VariableAddressInstruction) - .getAstVariable() and - v = n2.asVariable() + exists(Ssa::GlobalUse globalUse | + v = globalUse.getVariable() and + n1.(FinalGlobalValue).getGlobalUse() = globalUse + | + globalUse.getIndirectionIndex() = 1 and + v = n2.asVariable() + or + v = n2.asIndirectVariable(globalUse.getIndirectionIndex()) + ) or - v = - n2.asInstruction() - .(LoadInstruction) - .getSourceAddress() - .(VariableAddressInstruction) - .getAstVariable() and - v = n1.asVariable() + exists(Ssa::GlobalDef globalDef | + v = globalDef.getVariable() and + n2.(InitialGlobalValue).getGlobalDef() = globalDef + | + globalDef.getIndirectionIndex() = 1 and + v = n1.asVariable() + or + v = n1.asIndirectVariable(globalDef.getIndirectionIndex()) + ) ) } @@ -696,6 +700,10 @@ predicate nodeIsHidden(Node n) { n instanceof OperandNode and not n instanceof ArgumentNode and not n.asOperand() instanceof StoreValueOperand + or + n instanceof FinalGlobalValue + or + n instanceof InitialGlobalValue } class LambdaCallKind = Unit; diff --git a/cpp/ql/lib/semmle/code/cpp/ir/dataflow/internal/DataFlowUtil.qll b/cpp/ql/lib/semmle/code/cpp/ir/dataflow/internal/DataFlowUtil.qll index 3b362a22b1e1..7ee36571586d 100644 --- a/cpp/ql/lib/semmle/code/cpp/ir/dataflow/internal/DataFlowUtil.qll +++ b/cpp/ql/lib/semmle/code/cpp/ir/dataflow/internal/DataFlowUtil.qll @@ -32,7 +32,9 @@ private import DataFlowImplCommon as DataFlowImplCommon cached private newtype TIRDataFlowNode = TNode0(Node0Impl node) { DataFlowImplCommon::forceCachingInSameStage() } or - TVariableNode(Variable var) or + TVariableNode(Variable var, int indirectionIndex) { + indirectionIndex = [1 .. Ssa::getMaxIndirectionsForType(var.getUnspecifiedType())] + } or TPostFieldUpdateNode(FieldAddress operand, int indirectionIndex) { indirectionIndex = [1 .. Ssa::countIndirectionsForCppType(operand.getObjectAddress().getResultLanguageType())] @@ -52,7 +54,9 @@ private newtype TIRDataFlowNode = use.getParameter() = p and use.getIndirectionIndex() = indirectionIndex ) - } + } or + TFinalGlobalValue(Ssa::GlobalUse globalUse) or + TInitialGlobalValue(Ssa::GlobalDef globalUse) /** * An operand that is defined by a `FieldAddressInstruction`. @@ -279,7 +283,20 @@ class Node extends TIRDataFlowNode { * Gets the variable corresponding to this node, if any. This can be used for * modeling flow in and out of global variables. */ - Variable asVariable() { result = this.(VariableNode).getVariable() } + Variable asVariable() { this = TVariableNode(result, 1) } + + /** + * Gets the `indirectionIndex`'th indirection of this node's underlying variable, if any. + * + * This can be used for modeling flow in and out of global variables. + */ + Variable asIndirectVariable(int indirectionIndex) { + indirectionIndex > 1 and + this = TVariableNode(result, indirectionIndex) + } + + /** Gets an indirection of this node's underlying variable, if any. */ + Variable asIndirectVariable() { result = this.asIndirectVariable(_) } /** * Gets the expression that is partially defined by this node, if any. @@ -509,6 +526,66 @@ class SideEffectOperandNode extends Node, IndirectOperand { Expr getArgument() { result = call.getArgument(argumentIndex).getUnconvertedResultExpression() } } +/** + * INTERNAL: do not use. + * + * A node representing the value of a global variable just before returning + * from a function body. + */ +class FinalGlobalValue extends Node, TFinalGlobalValue { + Ssa::GlobalUse globalUse; + + FinalGlobalValue() { this = TFinalGlobalValue(globalUse) } + + /** Gets the underlying SSA use. */ + Ssa::GlobalUse getGlobalUse() { result = globalUse } + + override Declaration getEnclosingCallable() { result = this.getFunction() } + + override Declaration getFunction() { result = globalUse.getIRFunction().getFunction() } + + override DataFlowType getType() { + exists(int indirectionIndex | + indirectionIndex = globalUse.getIndirectionIndex() and + result = getTypeImpl(globalUse.getUnspecifiedType(), indirectionIndex - 1) + ) + } + + final override Location getLocationImpl() { result = globalUse.getLocation() } + + override string toStringImpl() { result = globalUse.toString() } +} + +/** + * INTERNAL: do not use. + * + * A node representing the value of a global variable just after entering + * a function body. + */ +class InitialGlobalValue extends Node, TInitialGlobalValue { + Ssa::GlobalDef globalDef; + + InitialGlobalValue() { this = TInitialGlobalValue(globalDef) } + + /** Gets the underlying SSA definition. */ + Ssa::GlobalDef getGlobalDef() { result = globalDef } + + override Declaration getEnclosingCallable() { result = this.getFunction() } + + override Declaration getFunction() { result = globalDef.getIRFunction().getFunction() } + + override DataFlowType getType() { + exists(int indirectionIndex | + indirectionIndex = globalDef.getIndirectionIndex() and + result = getTypeImpl(globalDef.getUnspecifiedType(), indirectionIndex) + ) + } + + final override Location getLocationImpl() { result = globalDef.getLocation() } + + override string toStringImpl() { result = globalDef.toString() } +} + /** * INTERNAL: do not use. * @@ -1192,12 +1269,16 @@ class DefinitionByReferenceNode extends IndirectArgumentOutNode { */ class VariableNode extends Node, TVariableNode { Variable v; + int indirectionIndex; - VariableNode() { this = TVariableNode(v) } + VariableNode() { this = TVariableNode(v, indirectionIndex) } /** Gets the variable corresponding to this node. */ Variable getVariable() { result = v } + /** Gets the indirection index of this node. */ + int getIndirectionIndex() { result = indirectionIndex } + override Declaration getFunction() { none() } override Declaration getEnclosingCallable() { @@ -1209,11 +1290,23 @@ class VariableNode extends Node, TVariableNode { result = v } - override DataFlowType getType() { result = v.getType() } + override DataFlowType getType() { + result = getTypeImpl(v.getUnspecifiedType(), indirectionIndex - 1) + } - final override Location getLocationImpl() { result = v.getLocation() } + final override Location getLocationImpl() { + // Certain variables (such as parameters) can have multiple locations. + // When there's a unique location we use that one, but if multiple locations + // exist we default to an unknown location. + result = unique( | | v.getLocation()) + or + not exists(unique( | | v.getLocation())) and + result instanceof UnknownDefaultLocation + } - override string toStringImpl() { result = v.toString() } + override string toStringImpl() { + if indirectionIndex = 1 then result = v.toString() else result = v.toString() + " indirection" + } } /** @@ -1256,7 +1349,9 @@ DefinitionByReferenceNode definitionByReferenceNodeFromArgument(Expr argument) { } /** Gets the `VariableNode` corresponding to the variable `v`. */ -VariableNode variableNode(Variable v) { result.getVariable() = v } +VariableNode variableNode(Variable v) { + result.getVariable() = v and result.getIndirectionIndex() = 1 +} /** * DEPRECATED: See UninitializedNode. diff --git a/cpp/ql/lib/semmle/code/cpp/ir/dataflow/internal/DefaultTaintTrackingImpl.qll b/cpp/ql/lib/semmle/code/cpp/ir/dataflow/internal/DefaultTaintTrackingImpl.qll index 646ae143ae17..b6a7d93474b8 100644 --- a/cpp/ql/lib/semmle/code/cpp/ir/dataflow/internal/DefaultTaintTrackingImpl.qll +++ b/cpp/ql/lib/semmle/code/cpp/ir/dataflow/internal/DefaultTaintTrackingImpl.qll @@ -624,6 +624,8 @@ module TaintedWithPath { private predicate isGlobalVariablePathNode(WrapPathNode n) { n.inner().getNode().asVariable() instanceof GlobalOrNamespaceVariable + or + n.inner().getNode().asIndirectVariable() instanceof GlobalOrNamespaceVariable } private predicate edgesWithoutGlobals(PathNode a, PathNode b) { diff --git a/cpp/ql/lib/semmle/code/cpp/ir/dataflow/internal/SsaInternals.qll b/cpp/ql/lib/semmle/code/cpp/ir/dataflow/internal/SsaInternals.qll index a6ad919a2a27..bf9ce406249d 100644 --- a/cpp/ql/lib/semmle/code/cpp/ir/dataflow/internal/SsaInternals.qll +++ b/cpp/ql/lib/semmle/code/cpp/ir/dataflow/internal/SsaInternals.qll @@ -34,10 +34,19 @@ private module SourceVariables { bindingset[ind] SourceVariable() { any() } + /** Gets a textual representation of this element. */ abstract string toString(); + /** + * Gets the number of loads performed on the base source variable + * to reach the value of this source variable. + */ int getIndirection() { result = ind } + /** + * Gets the base source variable (i.e., the variable without any + * indirections) of this source variable. + */ abstract BaseSourceVariable getBaseVariable(); } @@ -111,15 +120,40 @@ predicate hasRawIndirectInstruction(Instruction instr, int indirectionIndex) { cached private newtype TDefOrUseImpl = TDefImpl(Operand address, int indirectionIndex) { - isDef(_, _, address, _, _, indirectionIndex) and - // We only include the definition if the SSA pruning stage - // concluded that the definition is live after the write. - any(SsaInternals0::Def def).getAddressOperand() = address + exists(Instruction base | isDef(_, _, address, base, _, indirectionIndex) | + // We only include the definition if the SSA pruning stage + // concluded that the definition is live after the write. + any(SsaInternals0::Def def).getAddressOperand() = address + or + // Since the pruning stage doesn't know about global variables we can't use the above check to + // rule out dead assignments to globals. + base.(VariableAddressInstruction).getAstVariable() instanceof Cpp::GlobalOrNamespaceVariable + ) } or TUseImpl(Operand operand, int indirectionIndex) { isUse(_, operand, _, _, indirectionIndex) and not isDef(_, _, operand, _, _, _) } or + TGlobalUse(Cpp::GlobalOrNamespaceVariable v, IRFunction f, int indirectionIndex) { + // Represents a final "use" of a global variable to ensure that + // the assignment to a global variable isn't ruled out as dead. + exists(VariableAddressInstruction vai, int defIndex | + vai.getEnclosingIRFunction() = f and + vai.getAstVariable() = v and + isDef(_, _, _, vai, _, defIndex) and + indirectionIndex = [0 .. defIndex] + 1 + ) + } or + TGlobalDef(Cpp::GlobalOrNamespaceVariable v, IRFunction f, int indirectionIndex) { + // Represents the initial "definition" of a global variable when entering + // a function body. + exists(VariableAddressInstruction vai | + vai.getEnclosingIRFunction() = f and + vai.getAstVariable() = v and + isUse(_, _, vai, _, indirectionIndex) and + not isDef(_, _, vai.getAUse(), _, _, _) + ) + } or TIteratorDef( Operand iteratorAddress, BaseSourceVariableInstruction container, int indirectionIndex ) { @@ -167,6 +201,10 @@ abstract private class DefOrUseImpl extends TDefOrUseImpl { /** Holds if this definition or use has index `index` in block `block`. */ abstract predicate hasIndexInBlock(IRBlock block, int index); + /** + * Holds if this definition (or use) has index `index` in block `block`, + * and is a definition (or use) of the variable `sv` + */ final predicate hasIndexInBlock(IRBlock block, int index, SourceVariable sv) { this.hasIndexInBlock(block, index) and sv = this.getSourceVariable() @@ -191,12 +229,16 @@ abstract private class DefOrUseImpl extends TDefOrUseImpl { */ abstract BaseSourceVariableInstruction getBase(); + /** + * Gets the base source variable (i.e., the variable without + * any indirection) of this definition or use. + */ final BaseSourceVariable getBaseSourceVariable() { this.getBase().getBaseSourceVariable() = result } /** Gets the variable that is defined or used. */ - final SourceVariable getSourceVariable() { + SourceVariable getSourceVariable() { exists(BaseSourceVariable v, int ind | sourceVariableHasBaseAndIndex(result, v, ind) and defOrUseHasSourceVariable(this, v, ind) @@ -314,6 +356,8 @@ abstract private class OperandBasedUse extends UseImpl { operand.getUse() = block.getInstruction(index) } + final Operand getOperand() { result = operand } + final override Cpp::Location getLocation() { result = operand.getLocation() } } @@ -343,6 +387,14 @@ private class IteratorUse extends OperandBasedUse, TIteratorUse { override Node getNode() { nodeHasOperand(result, operand, ind) } } +pragma[nomagic] +private predicate finalParameterNodeHasParameterAndIndex( + FinalParameterNode n, Parameter p, int indirectionIndex +) { + n.getParameter() = p and + n.getIndirectionIndex() = indirectionIndex +} + class FinalParameterUse extends UseImpl, TFinalParameterUse { Parameter p; @@ -350,10 +402,7 @@ class FinalParameterUse extends UseImpl, TFinalParameterUse { Parameter getParameter() { result = p } - override Node getNode() { - result.(FinalParameterNode).getParameter() = p and - result.(FinalParameterNode).getIndirectionIndex() = ind - } + override Node getNode() { finalParameterNodeHasParameterAndIndex(result, p, ind) } override int getIndirection() { result = ind + 1 } @@ -397,6 +446,97 @@ class FinalParameterUse extends UseImpl, TFinalParameterUse { } } +class GlobalUse extends UseImpl, TGlobalUse { + Cpp::GlobalOrNamespaceVariable global; + IRFunction f; + + GlobalUse() { this = TGlobalUse(global, f, ind) } + + override FinalGlobalValue getNode() { result.getGlobalUse() = this } + + override int getIndirection() { result = ind + 1 } + + /** Gets the global variable associated with this use. */ + Cpp::GlobalOrNamespaceVariable getVariable() { result = global } + + /** Gets the `IRFunction` whose body is exited from after this use. */ + IRFunction getIRFunction() { result = f } + + final override predicate hasIndexInBlock(IRBlock block, int index) { + exists(ExitFunctionInstruction exit | + exit = f.getExitFunctionInstruction() and + block.getInstruction(index) = exit + ) + } + + override SourceVariable getSourceVariable() { sourceVariableIsGlobal(result, global, f, ind) } + + final override Cpp::Location getLocation() { result = f.getLocation() } + + /** + * Gets the type of this use after specifiers have been deeply stripped + * and typedefs have been resolved. + */ + Type getUnspecifiedType() { result = global.getUnspecifiedType() } + + override predicate isCertain() { any() } + + override BaseSourceVariableInstruction getBase() { none() } +} + +class GlobalDef extends TGlobalDef { + Cpp::GlobalOrNamespaceVariable global; + IRFunction f; + int indirectionIndex; + + GlobalDef() { this = TGlobalDef(global, f, indirectionIndex) } + + /** Gets the global variable associated with this definition. */ + Cpp::GlobalOrNamespaceVariable getVariable() { result = global } + + /** Gets the `IRFunction` whose body is evaluated after this definition. */ + IRFunction getIRFunction() { result = f } + + /** Gets the global variable associated with this definition. */ + int getIndirectionIndex() { result = indirectionIndex } + + /** Holds if this definition or use has index `index` in block `block`. */ + final predicate hasIndexInBlock(IRBlock block, int index) { + exists(EnterFunctionInstruction enter | + enter = f.getEnterFunctionInstruction() and + block.getInstruction(index) = enter + ) + } + + /** Gets the global variable associated with this definition. */ + SourceVariable getSourceVariable() { sourceVariableIsGlobal(result, global, f, indirectionIndex) } + + /** + * Holds if this definition has index `index` in block `block`, and + * is a definition of the variable `sv` + */ + final predicate hasIndexInBlock(IRBlock block, int index, SourceVariable sv) { + this.hasIndexInBlock(block, index) and + sv = this.getSourceVariable() + } + + /** Gets the location of this element. */ + final Cpp::Location getLocation() { result = f.getLocation() } + + /** Gets a textual representation of this element. */ + string toString() { + if indirectionIndex = 0 + then result = global.toString() + else result = global.toString() + " indirection" + } + + /** + * Gets the type of this use after specifiers have been deeply stripped + * and typedefs have been resolved. + */ + Type getUnspecifiedType() { result = global.getUnspecifiedType() } +} + /** * Holds if `defOrUse1` is a definition which is first read by `use`, * or if `defOrUse1` is a use and `use` is a next subsequent use. @@ -423,7 +563,20 @@ predicate adjacentDefRead(DefOrUse defOrUse1, UseOrPhi use) { ) } -private predicate useToNode(UseOrPhi use, Node nodeTo) { nodeTo = use.getNode() } +/** + * Holds if `globalDef` represents the initial definition of a global variable that + * flows to `useOrPhi`. + */ +private predicate globalDefToUse(GlobalDef globalDef, UseOrPhi useOrPhi) { + exists(IRBlock bb1, int i1, IRBlock bb2, int i2, SourceVariable v | + globalDef.hasIndexInBlock(bb1, i1, v) and + adjacentDefRead(_, pragma[only_bind_into](bb1), pragma[only_bind_into](i1), + pragma[only_bind_into](bb2), pragma[only_bind_into](i2)) and + useOrPhi.asDefOrUse().hasIndexInBlock(bb2, i2, v) + ) +} + +private predicate useToNode(UseOrPhi use, Node nodeTo) { use.getNode() = nodeTo } pragma[noinline] predicate outNodeHasAddressAndIndex( @@ -510,6 +663,14 @@ private predicate ssaFlowImpl(Node nodeFrom, Node nodeTo, boolean uncertain) { adjacentDefRead(defOrUse1, use) and useToNode(use, nodeTo) ) + or + // Initial global variable value to a first use + exists(GlobalDef globalDef, UseOrPhi use | + nodeFrom.(InitialGlobalValue).getGlobalDef() = globalDef and + globalDefToUse(globalDef, use) and + useToNode(use, nodeTo) and + uncertain = false + ) } /** @@ -584,6 +745,17 @@ private predicate variableWriteCand(IRBlock bb, int i, SourceVariable v) { ) } +private predicate sourceVariableIsGlobal( + SourceVariable sv, Cpp::GlobalOrNamespaceVariable global, IRFunction func, int indirectionIndex +) { + exists(IRVariable irVar, BaseIRVariable base | + sourceVariableHasBaseAndIndex(sv, base, indirectionIndex) and + irVar = base.getIRVariable() and + irVar.getEnclosingIRFunction() = func and + global = irVar.getAst() + ) +} + private module SsaInput implements SsaImplCommon::InputSig { import InputSigCommon import SourceVariables @@ -594,10 +766,18 @@ private module SsaInput implements SsaImplCommon::InputSig { */ predicate variableWrite(IRBlock bb, int i, SourceVariable v, boolean certain) { DataFlowImplCommon::forceCachingInSameStage() and - variableWriteCand(bb, i, v) and + ( + variableWriteCand(bb, i, v) or + sourceVariableIsGlobal(v, _, _, _) + ) and exists(DefImpl def | def.hasIndexInBlock(bb, i, v) | if def.isCertain() then certain = true else certain = false ) + or + exists(GlobalDef global | + global.hasIndexInBlock(bb, i, v) and + certain = true + ) } /** @@ -608,6 +788,11 @@ private module SsaInput implements SsaImplCommon::InputSig { exists(UseImpl use | use.hasIndexInBlock(bb, i, v) | if use.isCertain() then certain = true else certain = false ) + or + exists(GlobalUse global | + global.hasIndexInBlock(bb, i, v) and + certain = true + ) } } diff --git a/cpp/ql/lib/semmle/code/cpp/ir/dataflow/internal/SsaInternalsCommon.qll b/cpp/ql/lib/semmle/code/cpp/ir/dataflow/internal/SsaInternalsCommon.qll index 1649185309d8..d848525d99c1 100644 --- a/cpp/ql/lib/semmle/code/cpp/ir/dataflow/internal/SsaInternalsCommon.qll +++ b/cpp/ql/lib/semmle/code/cpp/ir/dataflow/internal/SsaInternalsCommon.qll @@ -325,8 +325,10 @@ newtype TBaseSourceVariable = TBaseCallVariable(AllocationInstruction call) abstract class BaseSourceVariable extends TBaseSourceVariable { + /** Gets a textual representation of this element. */ abstract string toString(); + /** Gets the type of this base source variable. */ abstract DataFlowType getType(); } @@ -441,6 +443,7 @@ predicate isModifiableAt(CppType cppType, int indirectionIndex) { } abstract class BaseSourceVariableInstruction extends Instruction { + /** Gets the base source variable accessed by this instruction. */ abstract BaseSourceVariable getBaseSourceVariable(); } diff --git a/cpp/ql/test/library-tests/dataflow/dataflow-tests/dataflow-consistency.expected b/cpp/ql/test/library-tests/dataflow/dataflow-tests/dataflow-consistency.expected index fb5f66883119..025801f6b40c 100644 --- a/cpp/ql/test/library-tests/dataflow/dataflow-tests/dataflow-consistency.expected +++ b/cpp/ql/test/library-tests/dataflow/dataflow-tests/dataflow-consistency.expected @@ -105,6 +105,8 @@ postWithInFlow | test.cpp:542:6:542:6 | p [inner post update] | PostUpdateNode should not be the target of local flow. | | test.cpp:548:25:548:25 | x [inner post update] | PostUpdateNode should not be the target of local flow. | | test.cpp:552:25:552:25 | y [inner post update] | PostUpdateNode should not be the target of local flow. | +| test.cpp:562:5:562:13 | globalInt [post update] | PostUpdateNode should not be the target of local flow. | +| test.cpp:576:5:576:13 | globalInt [post update] | PostUpdateNode should not be the target of local flow. | viableImplInCallContextTooLarge uniqueParameterNodeAtPosition uniqueParameterNodePosition diff --git a/cpp/ql/test/library-tests/dataflow/dataflow-tests/dataflow-ir-consistency.expected b/cpp/ql/test/library-tests/dataflow/dataflow-tests/dataflow-ir-consistency.expected index d5982ae31ab4..caffafacef8f 100644 --- a/cpp/ql/test/library-tests/dataflow/dataflow-tests/dataflow-ir-consistency.expected +++ b/cpp/ql/test/library-tests/dataflow/dataflow-tests/dataflow-ir-consistency.expected @@ -5,22 +5,7 @@ uniqueEnclosingCallable | globals.cpp:16:12:16:26 | flowTestGlobal2 indirection | 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. | -| acrossLinkTargets.cpp:2:11:2:13 | (unnamed parameter 0) | Node should have one location but has 6. | -| clang.cpp:4:11:4:13 | (unnamed parameter 0) | Node should have one location but has 6. | -| clang.cpp:4:27:4:35 | (unnamed parameter 0) | Node should have one location but has 2. | -| clang.cpp:4:51:4:53 | (unnamed parameter 0) | Node should have one location but has 2. | -| dispatch.cpp:2:11:2:13 | (unnamed parameter 0) | Node should have one location but has 6. | -| file://:0:0:0:0 | (unnamed parameter 0) | Node should have one location but has 0. | -| file://:0:0:0:0 | (unnamed parameter 0) | Node should have one location but has 0. | -| file://:0:0:0:0 | (unnamed parameter 0) | Node should have one location but has 0. | -| file://:0:0:0:0 | (unnamed parameter 0) | Node should have one location but has 0. | -| globals.cpp:2:11:2:13 | (unnamed parameter 0) | Node should have one location but has 6. | -| test.cpp:2:11:2:13 | (unnamed parameter 0) | Node should have one location but has 6. | -| test.cpp:2:27:2:35 | (unnamed parameter 0) | Node should have one location but has 2. | -| test.cpp:2:51:2:53 | (unnamed parameter 0) | Node should have one location but has 2. | missingLocation -| Nodes without location: 4 | uniqueNodeToString missingToString parameterCallable diff --git a/cpp/ql/test/library-tests/dataflow/dataflow-tests/test.cpp b/cpp/ql/test/library-tests/dataflow/dataflow-tests/test.cpp index f2be988548b7..39f0488de2b4 100644 --- a/cpp/ql/test/library-tests/dataflow/dataflow-tests/test.cpp +++ b/cpp/ql/test/library-tests/dataflow/dataflow-tests/test.cpp @@ -552,3 +552,29 @@ void test_sink_then_source() { sink_then_source_2(&y, y); } } + +int* indirect_source(); + +namespace IndirectFlowThroughGlobals { + int* globalInt; + + void taintGlobal() { + globalInt = indirect_source(); + } + + void f() { + sink(*globalInt); // $ ir=562:17 ir=576:17 // tainted or clean? Not sure. + taintGlobal(); + sink(*globalInt); // $ ir=562:17 MISSING: ast=562:17 SPURIOUS: ir=576:17 + } + + void calledAfterTaint() { + sink(*globalInt); // $ ir=576:17 MISSING: ast=576:17 SPURIOUS: ir=562:17 + } + + void taintAndCall() { + globalInt = indirect_source(); + calledAfterTaint(); + sink(*globalInt); // $ ir=576:17 MISSING: ast=576:17 SPURIOUS: ir=562:17 + } +} \ No newline at end of file diff --git a/cpp/ql/test/library-tests/dataflow/dataflow-tests/test.ql b/cpp/ql/test/library-tests/dataflow/dataflow-tests/test.ql index 82128fe371c4..2b7927a3a154 100644 --- a/cpp/ql/test/library-tests/dataflow/dataflow-tests/test.ql +++ b/cpp/ql/test/library-tests/dataflow/dataflow-tests/test.ql @@ -24,6 +24,8 @@ module AstTest { or source.asParameter().getName().matches("source%") or + source.asExpr().(FunctionCall).getTarget().getName() = "indirect_source" + or source.(DataFlow::DefinitionByReferenceNode).getParameter().getName().matches("ref_source%") or // Track uninitialized variables @@ -67,6 +69,8 @@ module IRTest { override predicate isSource(DataFlow::Node source) { source.asExpr().(FunctionCall).getTarget().getName() = "source" or + source.asIndirectExpr(1).(FunctionCall).getTarget().getName() = "indirect_source" + or source.asParameter().getName().matches("source%") or source.(DataFlow::DefinitionByReferenceNode).getParameter().getName().matches("ref_source%") diff --git a/cpp/ql/test/library-tests/dataflow/fields/dataflow-ir-consistency.expected b/cpp/ql/test/library-tests/dataflow/fields/dataflow-ir-consistency.expected index ee60bb89963e..1e9c150b01b3 100644 --- a/cpp/ql/test/library-tests/dataflow/fields/dataflow-ir-consistency.expected +++ b/cpp/ql/test/library-tests/dataflow/fields/dataflow-ir-consistency.expected @@ -1,16 +1,7 @@ uniqueEnclosingCallable uniqueType uniqueNodeLocation -| E.cpp:15:31:15:33 | buf | Node should have one location but has 2. | -| aliasing.cpp:2:11:2:13 | (unnamed parameter 0) | Node should have one location but has 2. | -| conflated.cpp:2:11:2:13 | (unnamed parameter 0) | Node should have one location but has 2. | -| conflated.cpp:14:22:14:25 | buf | Node should have one location but has 2. | -| file://:0:0:0:0 | (unnamed parameter 0) | Node should have one location but has 0. | -| file://:0:0:0:0 | (unnamed parameter 0) | Node should have one location but has 0. | -| file://:0:0:0:0 | (unnamed parameter 0) | Node should have one location but has 0. | -| file://:0:0:0:0 | (unnamed parameter 0) | Node should have one location but has 0. | missingLocation -| Nodes without location: 4 | uniqueNodeToString missingToString parameterCallable diff --git a/cpp/ql/test/query-tests/Security/CWE/CWE-134/semmle/consts/NonConstantFormat.expected b/cpp/ql/test/query-tests/Security/CWE/CWE-134/semmle/consts/NonConstantFormat.expected index 8f63ffb72d86..6a4d7c8d7a99 100644 --- a/cpp/ql/test/query-tests/Security/CWE/CWE-134/semmle/consts/NonConstantFormat.expected +++ b/cpp/ql/test/query-tests/Security/CWE/CWE-134/semmle/consts/NonConstantFormat.expected @@ -8,6 +8,7 @@ | consts.cpp:112:9:112:10 | v6 | The format string argument to printf should be constant to prevent security issues and other potential errors. | | consts.cpp:116:9:116:13 | access to array | The format string argument to printf should be constant to prevent security issues and other potential errors. | | consts.cpp:121:9:121:10 | v8 | The format string argument to printf should be constant to prevent security issues and other potential errors. | +| consts.cpp:126:9:126:27 | call to nonConstFuncToArray | The format string argument to printf should be constant to prevent security issues and other potential errors. | | consts.cpp:130:9:130:10 | v9 | The format string argument to printf should be constant to prevent security issues and other potential errors. | | consts.cpp:135:9:135:11 | v10 | The format string argument to printf should be constant to prevent security issues and other potential errors. | | consts.cpp:140:9:140:11 | v11 | The format string argument to printf should be constant to prevent security issues and other potential errors. | diff --git a/cpp/ql/test/query-tests/Security/CWE/CWE-134/semmle/globalVars/UncontrolledFormatString.expected b/cpp/ql/test/query-tests/Security/CWE/CWE-134/semmle/globalVars/UncontrolledFormatString.expected index a01a3f4b5cbb..33015407b831 100644 --- a/cpp/ql/test/query-tests/Security/CWE/CWE-134/semmle/globalVars/UncontrolledFormatString.expected +++ b/cpp/ql/test/query-tests/Security/CWE/CWE-134/semmle/globalVars/UncontrolledFormatString.expected @@ -1,61 +1,45 @@ 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: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: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:11:22:11:25 | argv | globalVars.c:12:2:12:15 | ... = ... | -| globalVars.c:12:2:12:15 | ... = ... | globalVars.c:8:7:8:10 | copy | -| globalVars.c:15:21:15:23 | val | globalVars.c:16:2:16:12 | ... = ... | -| globalVars.c:16:2:16:12 | ... = ... | globalVars.c:9:7:9:11 | 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:27:9:27:12 | copy | globalVars.c:27:9:27:12 | copy | -| globalVars.c:27:9:27:12 | copy | globalVars.c:27:9:27:12 | copy | -| globalVars.c:27:9:27:12 | copy | globalVars.c:27:9:27:12 | copy | -| globalVars.c:30:15:30:18 | copy | globalVars.c:30:15:30:18 | copy | -| globalVars.c:30:15:30:18 | copy | globalVars.c:30:15:30:18 | copy | | globalVars.c:35:11:35:14 | copy | globalVars.c:15:21:15:23 | val | -| globalVars.c:35:11:35:14 | copy | globalVars.c:35:11:35:14 | copy | -| globalVars.c:38:9:38:13 | copy2 | globalVars.c:38:9:38:13 | copy2 | -| globalVars.c:38:9:38:13 | copy2 | globalVars.c:38:9:38:13 | copy2 | -| globalVars.c:38:9:38:13 | copy2 | globalVars.c:38:9:38:13 | copy2 | -| globalVars.c:41:15:41:19 | copy2 | globalVars.c:41:15:41:19 | copy2 | -| globalVars.c:41:15:41:19 | copy2 | globalVars.c:41:15:41:19 | copy2 | -| globalVars.c:50:9:50:13 | copy2 | globalVars.c:50:9:50:13 | copy2 | -| globalVars.c:50:9:50:13 | copy2 | globalVars.c:50:9:50:13 | copy2 | -| globalVars.c:50:9:50:13 | copy2 | globalVars.c:50:9:50:13 | copy2 | subpaths nodes | globalVars.c:8:7:8:10 | copy | semmle.label | copy | | globalVars.c:9:7:9:11 | copy2 | semmle.label | copy2 | | globalVars.c:11:22:11:25 | argv | semmle.label | argv | -| globalVars.c:12:2:12:15 | ... = ... | semmle.label | ... = ... | | globalVars.c:15:21:15:23 | val | semmle.label | val | -| globalVars.c:16:2:16:12 | ... = ... | semmle.label | ... = ... | | globalVars.c:24:11:24:14 | argv | semmle.label | argv | | globalVars.c:24:11:24:14 | argv | semmle.label | argv | | globalVars.c:27:9:27:12 | copy | semmle.label | copy | | globalVars.c:27:9:27:12 | copy | semmle.label | copy | | globalVars.c:27:9:27:12 | copy | semmle.label | copy | -| globalVars.c:27:9:27:12 | copy | semmle.label | copy | | globalVars.c:30:15:30:18 | copy | semmle.label | copy | | globalVars.c:30:15:30:18 | copy | semmle.label | copy | -| globalVars.c:30:15:30:18 | copy | semmle.label | copy | -| globalVars.c:35:11:35:14 | 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:38:9:38:13 | copy2 | semmle.label | copy2 | -| globalVars.c:38:9:38:13 | copy2 | semmle.label | copy2 | -| globalVars.c:41:15:41:19 | copy2 | semmle.label | copy2 | | globalVars.c:41:15:41:19 | copy2 | semmle.label | copy2 | | globalVars.c:41:15:41:19 | copy2 | semmle.label | copy2 | | globalVars.c:50:9:50:13 | 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:50:9:50:13 | copy2 | semmle.label | copy2 | #select | globalVars.c:27:9:27:12 | copy | globalVars.c:24:11:24:14 | argv | globalVars.c:27:9:27:12 | copy | The value of this argument may come from $@ and is being used as a formatting argument to printf(format). | globalVars.c:24:11:24:14 | argv | argv | | globalVars.c:30:15:30:18 | copy | globalVars.c:24:11:24:14 | argv | globalVars.c:30:15:30:18 | copy | The value of this argument may come from $@ and is being used as a formatting argument to printWrapper(str), which calls printf(format). | globalVars.c:24:11:24:14 | argv | argv | diff --git a/cpp/ql/test/query-tests/Security/CWE/CWE-134/semmle/globalVars/UncontrolledFormatStringThroughGlobalVar.expected b/cpp/ql/test/query-tests/Security/CWE/CWE-134/semmle/globalVars/UncontrolledFormatStringThroughGlobalVar.expected index a01a3f4b5cbb..8ac81fd9e6d4 100644 --- a/cpp/ql/test/query-tests/Security/CWE/CWE-134/semmle/globalVars/UncontrolledFormatStringThroughGlobalVar.expected +++ b/cpp/ql/test/query-tests/Security/CWE/CWE-134/semmle/globalVars/UncontrolledFormatStringThroughGlobalVar.expected @@ -1,12 +1,30 @@ 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:27:9:27:12 | copy | +| globalVars.c:8:7:8:10 | copy | globalVars.c:27:9:27:12 | copy | +| globalVars.c:8:7:8:10 | copy | globalVars.c:30:15:30:18 | copy | | globalVars.c:8:7:8:10 | copy | globalVars.c:30:15:30:18 | copy | +| globalVars.c:8:7:8:10 | copy | globalVars.c:30:15:30:18 | copy | +| globalVars.c:8:7:8:10 | copy | globalVars.c:33:15:33:18 | copy | +| globalVars.c:8:7:8:10 | copy | globalVars.c:35:11:35:14 | copy | | globalVars.c: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:38:9:38:13 | copy2 | +| globalVars.c:9:7:9:11 | copy2 | globalVars.c:38:9:38:13 | copy2 | +| globalVars.c:9:7:9:11 | copy2 | globalVars.c:41:15:41:19 | copy2 | +| globalVars.c:9:7:9:11 | copy2 | globalVars.c:41:15:41:19 | copy2 | | globalVars.c:9:7:9:11 | copy2 | globalVars.c:41:15:41:19 | copy2 | +| globalVars.c:9:7:9:11 | copy2 | globalVars.c:44:15:44:19 | copy2 | +| globalVars.c:9:7:9:11 | copy2 | globalVars.c:50:9:50:13 | copy2 | +| globalVars.c:9:7:9:11 | copy2 | globalVars.c:50:9:50:13 | copy2 | +| globalVars.c:9:7:9:11 | copy2 | globalVars.c:50:9:50:13 | copy2 | | globalVars.c:9:7:9:11 | copy2 | globalVars.c:50:9:50:13 | copy2 | +| globalVars.c:11:22:11:25 | argv | globalVars.c:8:7:8:10 | copy | | globalVars.c:11:22:11:25 | argv | globalVars.c:12:2:12:15 | ... = ... | | globalVars.c:12:2:12:15 | ... = ... | globalVars.c:8:7:8:10 | copy | +| globalVars.c:15:21:15:23 | val | globalVars.c:9:7:9:11 | copy2 | | globalVars.c:15:21:15:23 | val | globalVars.c:16:2:16:12 | ... = ... | | globalVars.c:16:2:16:12 | ... = ... | globalVars.c:9:7:9:11 | copy2 | | globalVars.c:24:11:24:14 | argv | globalVars.c:11:22:11:25 | argv | @@ -14,15 +32,31 @@ edges | globalVars.c:27:9:27:12 | copy | globalVars.c:27:9:27:12 | copy | | globalVars.c:27:9:27:12 | copy | globalVars.c:27:9:27:12 | copy | | globalVars.c:27:9:27:12 | copy | globalVars.c:27:9:27:12 | copy | +| globalVars.c:27:9:27:12 | copy | globalVars.c:30:15:30:18 | copy | +| globalVars.c:27:9:27:12 | copy | globalVars.c:30:15:30:18 | copy | +| globalVars.c:27:9:27:12 | copy | globalVars.c:35:11:35:14 | copy | | globalVars.c:30:15:30:18 | copy | globalVars.c:30:15:30:18 | copy | | globalVars.c:30:15:30:18 | copy | globalVars.c:30:15:30:18 | copy | +| globalVars.c:30:15:30:18 | copy | globalVars.c:35:11:35:14 | copy | +| globalVars.c:33:15:33:18 | copy | globalVars.c:35:11:35:14 | copy | | globalVars.c:35:11:35:14 | copy | globalVars.c:15:21:15:23 | val | | globalVars.c:35:11:35:14 | copy | globalVars.c:35:11:35:14 | copy | | globalVars.c:38:9:38:13 | copy2 | globalVars.c:38:9:38:13 | copy2 | | globalVars.c:38:9:38:13 | copy2 | globalVars.c:38:9:38:13 | copy2 | | globalVars.c:38:9:38:13 | copy2 | globalVars.c:38:9:38:13 | copy2 | +| globalVars.c:38:9:38:13 | copy2 | globalVars.c:41:15:41:19 | copy2 | +| globalVars.c:38:9:38:13 | copy2 | globalVars.c:41:15:41:19 | copy2 | +| globalVars.c:38:9:38:13 | copy2 | globalVars.c:50:9:50:13 | copy2 | +| globalVars.c:38:9:38:13 | copy2 | globalVars.c:50:9:50:13 | copy2 | +| globalVars.c:38:9:38:13 | copy2 | globalVars.c:50:9:50:13 | copy2 | | globalVars.c:41:15:41:19 | copy2 | globalVars.c:41:15:41:19 | copy2 | | globalVars.c:41:15:41:19 | copy2 | globalVars.c:41:15:41:19 | copy2 | +| globalVars.c:41:15:41:19 | copy2 | globalVars.c:50:9:50:13 | copy2 | +| globalVars.c:41:15:41:19 | copy2 | globalVars.c:50:9:50:13 | copy2 | +| globalVars.c:41:15:41:19 | copy2 | globalVars.c:50:9:50:13 | copy2 | +| globalVars.c:44:15:44:19 | copy2 | globalVars.c:50:9:50:13 | copy2 | +| globalVars.c:44:15:44:19 | copy2 | globalVars.c:50:9:50:13 | copy2 | +| globalVars.c:44:15:44:19 | copy2 | globalVars.c:50:9:50:13 | copy2 | | globalVars.c:50:9:50:13 | copy2 | globalVars.c:50:9:50:13 | copy2 | | globalVars.c:50:9:50:13 | copy2 | globalVars.c:50:9:50:13 | copy2 | | globalVars.c:50:9:50:13 | copy2 | globalVars.c:50:9:50:13 | copy2 | @@ -43,6 +77,7 @@ nodes | globalVars.c:30:15:30:18 | copy | semmle.label | copy | | globalVars.c:30:15:30:18 | copy | semmle.label | copy | | globalVars.c:30:15:30:18 | copy | semmle.label | copy | +| globalVars.c:33:15:33:18 | copy | semmle.label | copy | | globalVars.c:35:11:35:14 | copy | semmle.label | copy | | globalVars.c:35:11:35:14 | copy | semmle.label | copy | | globalVars.c:38:9:38:13 | copy2 | semmle.label | copy2 | @@ -52,6 +87,7 @@ nodes | globalVars.c:41:15:41:19 | copy2 | semmle.label | copy2 | | globalVars.c:41:15:41:19 | copy2 | semmle.label | copy2 | | globalVars.c:41:15:41:19 | copy2 | semmle.label | copy2 | +| globalVars.c:44:15:44:19 | copy2 | semmle.label | copy2 | | globalVars.c:50:9:50:13 | copy2 | semmle.label | copy2 | | globalVars.c:50:9:50:13 | copy2 | semmle.label | copy2 | | globalVars.c:50:9:50:13 | copy2 | semmle.label | copy2 | diff --git a/cpp/ql/test/query-tests/Security/CWE/CWE-319/UseOfHttp/UseOfHttp.expected b/cpp/ql/test/query-tests/Security/CWE/CWE-319/UseOfHttp/UseOfHttp.expected index 6d5cc34e0751..2ebb9d168e45 100644 --- a/cpp/ql/test/query-tests/Security/CWE/CWE-319/UseOfHttp/UseOfHttp.expected +++ b/cpp/ql/test/query-tests/Security/CWE/CWE-319/UseOfHttp/UseOfHttp.expected @@ -2,9 +2,8 @@ edges | test.cpp:11:26:11:28 | url | test.cpp:15:30:15:32 | url | | test.cpp:11:26:11:28 | url indirection | test.cpp:15:30:15:32 | url | | test.cpp:24:13:24:17 | url_g | test.cpp:38:11:38:15 | url_g | -| test.cpp:24:21:24:40 | array to pointer conversion | test.cpp:24:13:24:17 | url_g | -| test.cpp:24:21:24:40 | http://example.com | test.cpp:24:21:24:40 | array to pointer conversion | -| test.cpp:24:21:24:40 | http://example.com | test.cpp:24:21:24:40 | array to pointer conversion | +| test.cpp:24:21:24:40 | http://example.com | test.cpp:24:13:24:17 | url_g | +| test.cpp:24:21:24:40 | http://example.com | test.cpp:24:13:24:17 | url_g | | test.cpp:28:10:28:29 | http://example.com | test.cpp:11:26:11:28 | url | | test.cpp:28:10:28:29 | http://example.com | test.cpp:28:10:28:29 | http://example.com | | test.cpp:35:23:35:42 | http://example.com | test.cpp:39:11:39:15 | url_l | @@ -14,7 +13,6 @@ edges | test.cpp:36:26:36:45 | http://example.com | test.cpp:40:11:40:17 | access to array indirection | | test.cpp:36:26:36:45 | http://example.com | test.cpp:40:11:40:17 | access to array indirection | | test.cpp:38:11:38:15 | url_g | test.cpp:11:26:11:28 | url | -| test.cpp:38:11:38:15 | url_g | test.cpp:38:11:38:15 | url_g | | test.cpp:39:11:39:15 | url_l | test.cpp:11:26:11:28 | url | | test.cpp:40:11:40:17 | access to array | test.cpp:11:26:11:28 | url | | test.cpp:40:11:40:17 | access to array indirection | test.cpp:11:26:11:28 | url indirection | @@ -37,7 +35,6 @@ nodes | test.cpp:11:26:11:28 | url indirection | semmle.label | url indirection | | test.cpp:15:30:15:32 | url | semmle.label | url | | test.cpp:24:13:24:17 | url_g | semmle.label | url_g | -| test.cpp:24:21:24:40 | array to pointer conversion | semmle.label | array to pointer conversion | | test.cpp:24:21:24:40 | http://example.com | semmle.label | http://example.com | | test.cpp:24:21:24:40 | http://example.com | semmle.label | http://example.com | | test.cpp:28:10:28:29 | http://example.com | semmle.label | http://example.com | @@ -47,7 +44,6 @@ nodes | test.cpp:36:26:36:45 | http://example.com | semmle.label | http://example.com | | test.cpp:36:26:36:45 | http://example.com | semmle.label | http://example.com | | test.cpp:38:11:38:15 | url_g | semmle.label | url_g | -| test.cpp:38:11:38:15 | url_g | semmle.label | url_g | | test.cpp:39:11:39:15 | url_l | semmle.label | url_l | | test.cpp:40:11:40:17 | access to array | semmle.label | access to array | | test.cpp:40:11:40:17 | access to array indirection | semmle.label | access to array indirection | diff --git a/cpp/ql/test/query-tests/Security/CWE/CWE-497/semmle/tests/ExposedSystemData.expected b/cpp/ql/test/query-tests/Security/CWE/CWE-497/semmle/tests/ExposedSystemData.expected index 91cac0e287a8..e0e3e33c271f 100644 --- a/cpp/ql/test/query-tests/Security/CWE/CWE-497/semmle/tests/ExposedSystemData.expected +++ b/cpp/ql/test/query-tests/Security/CWE/CWE-497/semmle/tests/ExposedSystemData.expected @@ -1,13 +1,11 @@ edges | tests2.cpp:50:13:50:19 | global1 | tests2.cpp:82:14:82:20 | global1 | | tests2.cpp:50:23:50:43 | call to mysql_get_client_info | tests2.cpp:50:13:50:19 | global1 | -| tests2.cpp:50:23:50:43 | call to mysql_get_client_info | tests2.cpp:50:23:50:43 | call to mysql_get_client_info | | tests2.cpp:63:13:63:18 | call to getenv | tests2.cpp:63:13:63:26 | call to getenv | | tests2.cpp:64:13:64:18 | call to getenv | tests2.cpp:64:13:64:26 | call to getenv | | tests2.cpp:65:13:65:18 | call to getenv | tests2.cpp:65:13:65:30 | call to getenv | | tests2.cpp:66:13:66:18 | call to getenv | tests2.cpp:66:13:66:34 | call to getenv | | tests2.cpp:78:18:78:38 | call to mysql_get_client_info | tests2.cpp:81:14:81:19 | buffer | -| tests2.cpp:82:14:82:20 | global1 | tests2.cpp:82:14:82:20 | global1 | | tests2.cpp:91:42:91:45 | str1 | tests2.cpp:93:14:93:17 | str1 | | tests2.cpp:101:8:101:15 | call to getpwuid | tests2.cpp:102:14:102:15 | pw | | tests2.cpp:109:3:109:36 | ... = ... | tests2.cpp:109:6:109:8 | c1 indirection [post update] [ptr] | @@ -30,7 +28,6 @@ edges nodes | tests2.cpp:50:13:50:19 | global1 | semmle.label | global1 | | tests2.cpp:50:23:50:43 | call to mysql_get_client_info | semmle.label | call to mysql_get_client_info | -| tests2.cpp:50:23:50:43 | call to mysql_get_client_info | semmle.label | call to mysql_get_client_info | | tests2.cpp:63:13:63:18 | call to getenv | semmle.label | call to getenv | | tests2.cpp:63:13:63:18 | call to getenv | semmle.label | call to getenv | | tests2.cpp:63:13:63:26 | call to getenv | semmle.label | call to getenv | @@ -47,7 +44,6 @@ nodes | tests2.cpp:80:14:80:34 | call to mysql_get_client_info | semmle.label | call to mysql_get_client_info | | tests2.cpp:81:14:81:19 | buffer | semmle.label | buffer | | tests2.cpp:82:14:82:20 | global1 | semmle.label | global1 | -| tests2.cpp:82:14:82:20 | global1 | semmle.label | global1 | | tests2.cpp:91:42:91:45 | str1 | semmle.label | str1 | | tests2.cpp:93:14:93:17 | str1 | semmle.label | str1 | | tests2.cpp:101:8:101:15 | call to getpwuid | semmle.label | call to getpwuid | diff --git a/cpp/ql/test/query-tests/Security/CWE/CWE-497/semmle/tests/PotentiallyExposedSystemData.expected b/cpp/ql/test/query-tests/Security/CWE/CWE-497/semmle/tests/PotentiallyExposedSystemData.expected index 183de494f123..cc9ae83d2a3d 100644 --- a/cpp/ql/test/query-tests/Security/CWE/CWE-497/semmle/tests/PotentiallyExposedSystemData.expected +++ b/cpp/ql/test/query-tests/Security/CWE/CWE-497/semmle/tests/PotentiallyExposedSystemData.expected @@ -5,12 +5,9 @@ edges | tests.cpp:57:18:57:23 | call to getenv | tests.cpp:57:18:57:39 | call to getenv | | tests.cpp:58:41:58:46 | call to getenv | tests.cpp:58:41:58:62 | call to getenv | | tests.cpp:59:43:59:48 | call to getenv | tests.cpp:59:43:59:64 | call to getenv | -| tests.cpp:62:7:62:18 | global_token | tests.cpp:69:17:69:28 | global_token | | tests.cpp:62:7:62:18 | global_token | tests.cpp:71:27:71:38 | global_token | +| tests.cpp:62:7:62:18 | global_token | tests.cpp:73:27:73:31 | maybe | | tests.cpp:62:22:62:27 | call to getenv | tests.cpp:62:7:62:18 | global_token | -| tests.cpp:62:22:62:27 | call to getenv | tests.cpp:62:22:62:27 | call to getenv | -| tests.cpp:69:17:69:28 | global_token | tests.cpp:73:27:73:31 | maybe | -| tests.cpp:71:27:71:38 | global_token | tests.cpp:71:27:71:38 | global_token | | tests.cpp:86:29:86:31 | msg | tests.cpp:88:15:88:17 | msg | | tests.cpp:97:13:97:18 | call to getenv | tests.cpp:97:13:97:34 | call to getenv | | tests.cpp:97:13:97:18 | call to getenv | tests.cpp:97:13:97:34 | call to getenv | @@ -48,9 +45,6 @@ nodes | tests.cpp:59:43:59:64 | call to getenv | semmle.label | call to getenv | | tests.cpp:62:7:62:18 | global_token | semmle.label | global_token | | tests.cpp:62:22:62:27 | call to getenv | semmle.label | call to getenv | -| tests.cpp:62:22:62:27 | call to getenv | semmle.label | call to getenv | -| tests.cpp:69:17:69:28 | global_token | semmle.label | global_token | -| tests.cpp:71:27:71:38 | global_token | semmle.label | global_token | | tests.cpp:71:27:71:38 | global_token | semmle.label | global_token | | tests.cpp:73:27:73:31 | maybe | semmle.label | maybe | | tests.cpp:86:29:86:31 | msg | semmle.label | msg | diff --git a/cpp/ql/test/query-tests/Security/CWE/CWE-611/XXE.expected b/cpp/ql/test/query-tests/Security/CWE/CWE-611/XXE.expected index cacfd2102e34..632bc727ae44 100644 --- a/cpp/ql/test/query-tests/Security/CWE/CWE-611/XXE.expected +++ b/cpp/ql/test/query-tests/Security/CWE/CWE-611/XXE.expected @@ -8,6 +8,8 @@ edges | tests5.cpp:27:25:27:38 | call to createLSParser indirection | tests5.cpp:29:2:29:2 | p indirection | | tests5.cpp:40:25:40:38 | call to createLSParser indirection | tests5.cpp:43:2:43:2 | p indirection | | tests5.cpp:55:25:55:38 | call to createLSParser indirection | tests5.cpp:59:2:59:2 | p indirection | +| tests5.cpp:63:21:63:24 | g_p2 indirection | tests5.cpp:77:2:77:5 | g_p2 indirection | +| tests5.cpp:70:17:70:30 | call to createLSParser indirection | tests5.cpp:63:21:63:24 | g_p2 indirection | | tests5.cpp:81:25:81:38 | call to createLSParser indirection | tests5.cpp:83:2:83:2 | p indirection | | tests5.cpp:81:25:81:38 | call to createLSParser indirection | tests5.cpp:83:2:83:2 | p indirection | | tests5.cpp:83:2:83:2 | p indirection | tests5.cpp:85:2:85:2 | p indirection | @@ -65,6 +67,9 @@ nodes | tests5.cpp:43:2:43:2 | p indirection | semmle.label | p indirection | | tests5.cpp:55:25:55:38 | call to createLSParser indirection | semmle.label | call to createLSParser indirection | | tests5.cpp:59:2:59:2 | p indirection | semmle.label | p indirection | +| tests5.cpp:63:21:63:24 | g_p2 indirection | semmle.label | g_p2 indirection | +| tests5.cpp:70:17:70:30 | call to createLSParser indirection | semmle.label | call to createLSParser indirection | +| tests5.cpp:77:2:77:5 | g_p2 indirection | semmle.label | g_p2 indirection | | tests5.cpp:81:25:81:38 | call to createLSParser indirection | semmle.label | call to createLSParser indirection | | tests5.cpp:83:2:83:2 | p indirection | semmle.label | p indirection | | tests5.cpp:83:2:83:2 | p indirection | semmle.label | p indirection | @@ -124,6 +129,7 @@ subpaths | tests5.cpp:29:2:29:2 | p indirection | tests5.cpp:27:25:27:38 | call to createLSParser indirection | tests5.cpp:29:2:29:2 | p indirection | This $@ is not configured to prevent an XML external entity (XXE) attack. | tests5.cpp:27:25:27:38 | call to createLSParser indirection | XML parser | | tests5.cpp:43:2:43:2 | p indirection | tests5.cpp:40:25:40:38 | call to createLSParser indirection | tests5.cpp:43:2:43:2 | p indirection | This $@ is not configured to prevent an XML external entity (XXE) attack. | tests5.cpp:40:25:40:38 | call to createLSParser indirection | XML parser | | tests5.cpp:59:2:59:2 | p indirection | tests5.cpp:55:25:55:38 | call to createLSParser indirection | tests5.cpp:59:2:59:2 | p indirection | This $@ is not configured to prevent an XML external entity (XXE) attack. | tests5.cpp:55:25:55:38 | call to createLSParser indirection | XML parser | +| tests5.cpp:77:2:77:5 | g_p2 indirection | tests5.cpp:70:17:70:30 | call to createLSParser indirection | tests5.cpp:77:2:77:5 | g_p2 indirection | This $@ is not configured to prevent an XML external entity (XXE) attack. | tests5.cpp:70:17:70:30 | call to createLSParser indirection | XML parser | | tests5.cpp:83:2:83:2 | p indirection | tests5.cpp:81:25:81:38 | call to createLSParser indirection | tests5.cpp:83:2:83:2 | p indirection | This $@ is not configured to prevent an XML external entity (XXE) attack. | tests5.cpp:81:25:81:38 | call to createLSParser indirection | XML parser | | tests5.cpp:89:2:89:2 | p indirection | tests5.cpp:81:25:81:38 | call to createLSParser indirection | tests5.cpp:89:2:89:2 | p indirection | This $@ is not configured to prevent an XML external entity (XXE) attack. | tests5.cpp:81:25:81:38 | call to createLSParser indirection | XML parser | | tests.cpp:17:2:17:2 | p indirection | tests.cpp:15:23:15:43 | call to XercesDOMParser | tests.cpp:17:2:17:2 | p indirection | This $@ is not configured to prevent an XML external entity (XXE) attack. | tests.cpp:15:23:15:43 | call to XercesDOMParser | XML parser |