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 7d4bb6f58663..2a7dfbb8208e 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 @@ -55,29 +55,12 @@ private newtype TIRDataFlowNode = TFinalParameterNode(Parameter p, int indirectionIndex) { exists(Ssa::FinalParameterUse use | use.getParameter() = p and - use.getIndirectionIndex() = indirectionIndex and - parameterIsRedefined(p) + use.getIndirectionIndex() = indirectionIndex ) } or TFinalGlobalValue(Ssa::GlobalUse globalUse) or TInitialGlobalValue(Ssa::GlobalDef globalUse) -/** - * Holds if the value of `*p` (or `**p`, `***p`, etc.) is redefined somewhere in the body - * of the enclosing function of `p`. - * - * Only parameters satisfying this predicate will generate a `FinalParameterNode` transferring - * flow out of the function. - */ -private predicate parameterIsRedefined(Parameter p) { - exists(Ssa::Def def | - def.getSourceVariable().getBaseVariable().(Ssa::BaseIRVariable).getIRVariable().getAst() = p and - def.getIndirectionIndex() = 0 and - def.getIndirection() > 1 and - not def.getValue().asInstruction() instanceof InitializeParameterInstruction - ) -} - /** * An operand that is defined by a `FieldAddressInstruction`. */ 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 8a5e8d203198..69ace9f890e4 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 @@ -4,7 +4,11 @@ private import DataFlowUtil private import DataFlowImplCommon as DataFlowImplCommon private import semmle.code.cpp.models.interfaces.Allocation as Alloc private import semmle.code.cpp.models.interfaces.DataFlow as DataFlow +private import semmle.code.cpp.models.interfaces.Taint as Taint +private import semmle.code.cpp.models.interfaces.PartialFlow as PartialFlow +private import semmle.code.cpp.models.interfaces.FunctionInputsAndOutputs as FIO private import semmle.code.cpp.ir.internal.IRCppLanguage +private import semmle.code.cpp.ir.dataflow.internal.ModelUtil private import DataFlowPrivate private import ssa0.SsaInternals as SsaInternals0 import SsaInternalsCommon @@ -138,12 +142,11 @@ private newtype TDefOrUseImpl = isIteratorUse(container, iteratorAddress, _, indirectionIndex) } or TFinalParameterUse(Parameter p, int indirectionIndex) { - // Avoid creating parameter nodes if there is no definitions of the variable other than the initializaion. - exists(SsaInternals0::Def def | - def.getSourceVariable().getBaseVariable().(BaseIRVariable).getIRVariable().getAst() = p and - not def.getValue().asInstruction() instanceof InitializeParameterInstruction and - underlyingTypeIsModifiableAt(p.getUnderlyingType(), indirectionIndex) - ) + underlyingTypeIsModifiableAt(p.getUnderlyingType(), indirectionIndex) and + // Only create an SSA read for the final use of a parameter if there's + // actually a body of the enclosing function. If there's no function body + // then we'll never need to flow out of the function anyway. + p.getFunction().hasDefinition() } private predicate isGlobalUse( @@ -796,10 +799,58 @@ private Node getAPriorDefinition(SsaDefOrUse defOrUse) { ) } +private predicate inOut(FIO::FunctionInput input, FIO::FunctionOutput output) { + exists(int indirectionIndex | + input.isQualifierObject(indirectionIndex) and + output.isQualifierObject(indirectionIndex) + or + exists(int i | + input.isParameterDeref(i, indirectionIndex) and + output.isParameterDeref(i, indirectionIndex) + ) + ) +} + +/** + * Holds if there should not be use-use flow out of `n`. That is, `n` is + * an out-barrier to use-use flow. This includes: + * + * - an input to a call that would be assumed to have use-use flow to the same + * argument as an output, but this flow should be blocked because the + * function is modeled with another flow to that output (for example the + * first argument of `strcpy`). + * - a conversion that flows to such an input. + */ +private predicate modeledFlowBarrier(Node n) { + exists( + FIO::FunctionInput input, FIO::FunctionOutput output, CallInstruction call, + PartialFlow::PartialFlowFunction partialFlowFunc + | + n = callInput(call, input) and + inOut(input, output) and + exists(callOutput(call, output)) and + partialFlowFunc = call.getStaticCallTarget() and + not partialFlowFunc.isPartialWrite(output) + | + call.getStaticCallTarget().(DataFlow::DataFlowFunction).hasDataFlow(_, output) + or + call.getStaticCallTarget().(Taint::TaintFunction).hasTaintFlow(_, output) + ) + or + exists(Operand operand, Instruction instr, Node n0, int indirectionIndex | + modeledFlowBarrier(n0) and + nodeHasInstruction(n0, instr, indirectionIndex) and + conversionFlow(operand, instr, false, _) and + nodeHasOperand(n, operand, indirectionIndex) + ) +} + /** Holds if there is def-use or use-use flow from `nodeFrom` to `nodeTo`. */ predicate ssaFlow(Node nodeFrom, Node nodeTo) { exists(Node nFrom, boolean uncertain, SsaDefOrUse defOrUse | - ssaFlowImpl(defOrUse, nFrom, nodeTo, uncertain) and nodeFrom != nodeTo + ssaFlowImpl(defOrUse, nFrom, nodeTo, uncertain) and + not modeledFlowBarrier(nFrom) and + nodeFrom != nodeTo | if uncertain = true then nodeFrom = [nFrom, getAPriorDefinition(defOrUse)] else nodeFrom = nFrom ) diff --git a/cpp/ql/lib/semmle/code/cpp/models/implementations/GetDelim.qll b/cpp/ql/lib/semmle/code/cpp/models/implementations/GetDelim.qll index 4415dd0c3fc4..9689c2f8a3b3 100644 --- a/cpp/ql/lib/semmle/code/cpp/models/implementations/GetDelim.qll +++ b/cpp/ql/lib/semmle/code/cpp/models/implementations/GetDelim.qll @@ -15,6 +15,8 @@ private class GetDelimFunction extends TaintFunction, AliasFunction, SideEffectF i.isParameter(3) and o.isParameterDeref(0) } + override predicate isPartialWrite(FunctionOutput o) { o.isParameterDeref(3) } + override predicate parameterNeverEscapes(int index) { index = [0, 1, 3] } override predicate parameterEscapesOnlyViaReturn(int index) { none() } diff --git a/cpp/ql/lib/semmle/code/cpp/models/implementations/Gets.qll b/cpp/ql/lib/semmle/code/cpp/models/implementations/Gets.qll index 1c227684e4f5..c0e2c0c45381 100644 --- a/cpp/ql/lib/semmle/code/cpp/models/implementations/Gets.qll +++ b/cpp/ql/lib/semmle/code/cpp/models/implementations/Gets.qll @@ -27,6 +27,8 @@ private class FgetsFunction extends DataFlowFunction, TaintFunction, ArrayFuncti output.isReturnValue() } + override predicate isPartialWrite(FunctionOutput output) { output.isParameterDeref(2) } + override predicate hasTaintFlow(FunctionInput input, FunctionOutput output) { input.isParameter(2) and output.isParameterDeref(0) diff --git a/cpp/ql/lib/semmle/code/cpp/models/implementations/Inet.qll b/cpp/ql/lib/semmle/code/cpp/models/implementations/Inet.qll index e75c38216f46..f61b13dc5680 100644 --- a/cpp/ql/lib/semmle/code/cpp/models/implementations/Inet.qll +++ b/cpp/ql/lib/semmle/code/cpp/models/implementations/Inet.qll @@ -20,6 +20,8 @@ private class InetAton extends TaintFunction, ArrayFunction { output.isParameterDeref(1) } + override predicate isPartialWrite(FunctionOutput output) { output.isParameterDeref(1) } + override predicate hasArrayInput(int bufParam) { bufParam = 0 } override predicate hasArrayOutput(int bufParam) { bufParam = 1 } diff --git a/cpp/ql/lib/semmle/code/cpp/models/implementations/StdContainer.qll b/cpp/ql/lib/semmle/code/cpp/models/implementations/StdContainer.qll index 1fb42010caf4..877dc5d3ac48 100644 --- a/cpp/ql/lib/semmle/code/cpp/models/implementations/StdContainer.qll +++ b/cpp/ql/lib/semmle/code/cpp/models/implementations/StdContainer.qll @@ -118,6 +118,8 @@ private class StdSequenceContainerData extends TaintFunction { input.isReturnValueDeref() and output.isQualifierObject() } + + override predicate isPartialWrite(FunctionOutput output) { output.isQualifierObject() } } /** @@ -147,6 +149,8 @@ private class StdSequenceContainerPushModel extends StdSequenceContainerPush, Ta input.isParameterDeref(0) and output.isQualifierObject() } + + override predicate isPartialWrite(FunctionOutput output) { output.isQualifierObject() } } /** @@ -207,6 +211,8 @@ private class StdSequenceContainerInsertModel extends StdSequenceContainerInsert output.isReturnValue() ) } + + override predicate isPartialWrite(FunctionOutput output) { output.isQualifierObject() } } /** @@ -263,6 +269,8 @@ private class StdSequenceContainerAt extends TaintFunction { input.isReturnValueDeref() and output.isQualifierObject() } + + override predicate isPartialWrite(FunctionOutput output) { output.isQualifierObject() } } /** @@ -297,6 +305,8 @@ private class StdSequenceEmplaceModel extends StdSequenceEmplace, TaintFunction output.isReturnValue() ) } + + override predicate isPartialWrite(FunctionOutput output) { output.isQualifierObject() } } /** @@ -335,6 +345,8 @@ private class StdSequenceEmplaceBackModel extends StdSequenceEmplaceBack, TaintF input.isParameterDeref([0 .. this.getNumberOfParameters() - 1]) and output.isQualifierObject() } + + override predicate isPartialWrite(FunctionOutput output) { output.isQualifierObject() } } /** diff --git a/cpp/ql/lib/semmle/code/cpp/models/implementations/StdMap.qll b/cpp/ql/lib/semmle/code/cpp/models/implementations/StdMap.qll index 9dc220e79afc..b6d869d7bea4 100644 --- a/cpp/ql/lib/semmle/code/cpp/models/implementations/StdMap.qll +++ b/cpp/ql/lib/semmle/code/cpp/models/implementations/StdMap.qll @@ -3,6 +3,7 @@ */ import semmle.code.cpp.models.interfaces.Taint +import semmle.code.cpp.models.interfaces.DataFlow import semmle.code.cpp.models.interfaces.Iterator /** @@ -53,6 +54,8 @@ private class StdMapInsert extends TaintFunction { output.isReturnValue() ) } + + override predicate isPartialWrite(FunctionOutput output) { output.isQualifierObject() } } /** @@ -75,6 +78,8 @@ private class StdMapEmplace extends TaintFunction { input.isQualifierObject() and output.isReturnValue() } + + override predicate isPartialWrite(FunctionOutput output) { output.isQualifierObject() } } /** @@ -102,6 +107,8 @@ private class StdMapTryEmplace extends TaintFunction { input.isQualifierObject() and output.isReturnValue() } + + override predicate isPartialWrite(FunctionOutput output) { output.isQualifierObject() } } /** @@ -115,6 +122,8 @@ private class StdMapMerge extends TaintFunction { input.isParameterDeref(0) and output.isQualifierObject() } + + override predicate isPartialWrite(FunctionOutput output) { output.isQualifierObject() } } /** @@ -132,6 +141,8 @@ private class StdMapAt extends TaintFunction { input.isReturnValueDeref() and output.isQualifierObject() } + + override predicate isPartialWrite(FunctionOutput output) { output.isQualifierObject() } } /** diff --git a/cpp/ql/lib/semmle/code/cpp/models/implementations/StdSet.qll b/cpp/ql/lib/semmle/code/cpp/models/implementations/StdSet.qll index bd2ba99aff00..8fe7fb930c2c 100644 --- a/cpp/ql/lib/semmle/code/cpp/models/implementations/StdSet.qll +++ b/cpp/ql/lib/semmle/code/cpp/models/implementations/StdSet.qll @@ -61,6 +61,8 @@ private class StdSetInsert extends TaintFunction { output.isReturnValue() ) } + + override predicate isPartialWrite(FunctionOutput output) { output.isQualifierObject() } } /** @@ -82,6 +84,8 @@ private class StdSetEmplace extends TaintFunction { input.isQualifierObject() and output.isReturnValue() } + + override predicate isPartialWrite(FunctionOutput output) { output.isQualifierObject() } } /** @@ -95,6 +99,8 @@ private class StdSetMerge extends TaintFunction { input.isParameterDeref(0) and output.isQualifierObject() } + + override predicate isPartialWrite(FunctionOutput output) { output.isQualifierObject() } } /** diff --git a/cpp/ql/lib/semmle/code/cpp/models/implementations/StdString.qll b/cpp/ql/lib/semmle/code/cpp/models/implementations/StdString.qll index 9ddf87085dfb..e22468745790 100644 --- a/cpp/ql/lib/semmle/code/cpp/models/implementations/StdString.qll +++ b/cpp/ql/lib/semmle/code/cpp/models/implementations/StdString.qll @@ -129,6 +129,8 @@ private class StdStringDataModel extends StdStringData, StdStringTaintFunction { input.isReturnValueDeref() and output.isQualifierObject() } + + override predicate isPartialWrite(FunctionOutput output) { output.isQualifierObject() } } /** @@ -142,6 +144,8 @@ private class StdStringPush extends StdStringTaintFunction { input.isParameter(0) and output.isQualifierObject() } + + override predicate isPartialWrite(FunctionOutput output) { output.isQualifierObject() } } /** @@ -204,6 +208,8 @@ private class StdStringAppend extends StdStringTaintFunction { input.isReturnValueDeref() and output.isQualifierObject() } + + override predicate isPartialWrite(FunctionOutput output) { output.isQualifierObject() } } /** @@ -237,6 +243,8 @@ private class StdStringInsert extends StdStringTaintFunction { input.isReturnValueDeref() and output.isQualifierObject() } + + override predicate isPartialWrite(FunctionOutput output) { output.isQualifierObject() } } /** @@ -305,6 +313,8 @@ private class StdStringAt extends StdStringTaintFunction { input.isReturnValueDeref() and output.isQualifierObject() } + + override predicate isPartialWrite(FunctionOutput output) { output.isQualifierObject() } } /** @@ -338,6 +348,8 @@ private class StdIStreamIn extends DataFlowFunction, TaintFunction { input.isReturnValueDeref() and output.isQualifierObject() } + + override predicate isPartialWrite(FunctionOutput output) { output.isQualifierObject() } } /** @@ -358,6 +370,8 @@ private class StdIStreamInNonMember extends DataFlowFunction, TaintFunction { output.isReturnValueDeref() } + override predicate isPartialWrite(FunctionOutput output) { output.isQualifierObject() } + override predicate hasTaintFlow(FunctionInput input, FunctionOutput output) { // flow from first parameter to second parameter input.isParameterDeref(0) and @@ -403,6 +417,8 @@ private class StdIStreamRead extends DataFlowFunction, TaintFunction { output.isReturnValueDeref() } + override predicate isPartialWrite(FunctionOutput output) { output.isQualifierObject() } + override predicate hasTaintFlow(FunctionInput input, FunctionOutput output) { // flow from qualifier to first parameter input.isQualifierObject() and @@ -442,6 +458,8 @@ private class StdIStreamPutBack extends DataFlowFunction, TaintFunction { output.isReturnValueDeref() } + override predicate isPartialWrite(FunctionOutput output) { output.isQualifierObject() } + override predicate hasTaintFlow(FunctionInput input, FunctionOutput output) { // flow from first parameter (value or pointer) to qualifier input.isParameter(0) and @@ -478,6 +496,8 @@ private class StdIStreamGetLine extends DataFlowFunction, TaintFunction { output.isReturnValueDeref() } + override predicate isPartialWrite(FunctionOutput output) { output.isQualifierObject() } + override predicate hasTaintFlow(FunctionInput input, FunctionOutput output) { // flow from qualifier to first parameter input.isQualifierObject() and @@ -540,6 +560,8 @@ private class StdOStreamOut extends DataFlowFunction, TaintFunction { output.isReturnValueDeref() } + override predicate isPartialWrite(FunctionOutput output) { output.isQualifierObject() } + override predicate hasTaintFlow(FunctionInput input, FunctionOutput output) { // flow from first parameter (value or pointer) to qualifier input.isParameter(0) and @@ -579,6 +601,8 @@ private class StdOStreamOutNonMember extends DataFlowFunction, TaintFunction { output.isReturnValueDeref() } + override predicate isPartialWrite(FunctionOutput output) { output.isParameterDeref(0) } + override predicate hasTaintFlow(FunctionInput input, FunctionOutput output) { // flow from second parameter to first parameter input.isParameterDeref(1) and @@ -672,6 +696,8 @@ private class StdStreamFunction extends DataFlowFunction, TaintFunction { output.isReturnValueDeref() } + override predicate isPartialWrite(FunctionOutput output) { output.isQualifierObject() } + override predicate hasTaintFlow(FunctionInput input, FunctionOutput output) { // reverse flow from returned reference to the qualifier input.isReturnValueDeref() and diff --git a/cpp/ql/lib/semmle/code/cpp/models/implementations/Strcrement.qll b/cpp/ql/lib/semmle/code/cpp/models/implementations/Strcrement.qll index 8f6c17aae547..a4070c2f9078 100644 --- a/cpp/ql/lib/semmle/code/cpp/models/implementations/Strcrement.qll +++ b/cpp/ql/lib/semmle/code/cpp/models/implementations/Strcrement.qll @@ -36,6 +36,8 @@ private class Strcrement extends ArrayFunction, TaintFunction, SideEffectFunctio input.isParameter(index) and output.isReturnValue() or input.isParameterDeref(index) and output.isReturnValueDeref() + or + input.isParameterDeref(index) and output.isParameterDeref(index) ) } diff --git a/cpp/ql/lib/semmle/code/cpp/models/interfaces/DataFlow.qll b/cpp/ql/lib/semmle/code/cpp/models/interfaces/DataFlow.qll index b30861254dc5..7b78a0787b87 100644 --- a/cpp/ql/lib/semmle/code/cpp/models/interfaces/DataFlow.qll +++ b/cpp/ql/lib/semmle/code/cpp/models/interfaces/DataFlow.qll @@ -10,6 +10,7 @@ import semmle.code.cpp.Function import FunctionInputsAndOutputs import semmle.code.cpp.models.Models +import PartialFlow /** * A library function for which a value is or may be copied from a parameter @@ -18,7 +19,7 @@ import semmle.code.cpp.models.Models * Note that this does not include partial copying of values or partial writes * to destinations; that is covered by `TaintModel.qll`. */ -abstract class DataFlowFunction extends Function { +abstract class DataFlowFunction extends PartialFlowFunction { /** * Holds if data can be copied from the argument, qualifier, or buffer * represented by `input` to the return value or buffer represented by diff --git a/cpp/ql/lib/semmle/code/cpp/models/interfaces/PartialFlow.qll b/cpp/ql/lib/semmle/code/cpp/models/interfaces/PartialFlow.qll new file mode 100644 index 000000000000..0afa8943d671 --- /dev/null +++ b/cpp/ql/lib/semmle/code/cpp/models/interfaces/PartialFlow.qll @@ -0,0 +1,31 @@ +/** + * Provides an abstract class to override the implicit assumption that a + * dataflow/taint-tracking model always fully override the parameters they are + * are modeled as writing to. To use this QL library, create a QL class + * extending `PartialFlowFunction` with a characteristic predicate that selects + * the function or set of functions you are modeling and override the + * `isPartialWrite` predicate. + * + * Note: Since both `DataFlowFunction` and `TaintFunction` extend this class + * you don't need to explicitly add this as a base class if your QL class + * already extends either `DataFlowFunction` or `TaintFunction`. + */ + +import semmle.code.cpp.Function +import FunctionInputsAndOutputs +import semmle.code.cpp.models.Models + +/** + * A function that may update part of a `FunctionOutput`. + * + * For example, the destination argument of `strcat` only updates part of the + * argument. + */ +abstract class PartialFlowFunction extends Function { + /** + * Holds if the write to output does not overwrite the entire value that was + * there before, or does not do so reliably. For example the destination + * argument of `strcat` is modified but not overwritten. + */ + predicate isPartialWrite(FunctionOutput output) { none() } +} diff --git a/cpp/ql/lib/semmle/code/cpp/models/interfaces/Taint.qll b/cpp/ql/lib/semmle/code/cpp/models/interfaces/Taint.qll index 05a5d9f1c28b..e7b507a2f7e0 100644 --- a/cpp/ql/lib/semmle/code/cpp/models/interfaces/Taint.qll +++ b/cpp/ql/lib/semmle/code/cpp/models/interfaces/Taint.qll @@ -10,6 +10,7 @@ import semmle.code.cpp.Function import FunctionInputsAndOutputs import semmle.code.cpp.models.Models +import PartialFlow /** * A library function for which a taint-tracking library should propagate taint @@ -23,7 +24,7 @@ import semmle.code.cpp.models.Models * altered (for example copying a string with `strncpy`), this is also considered * data flow. */ -abstract class TaintFunction extends Function { +abstract class TaintFunction extends PartialFlowFunction { /** * Holds if data passed into the argument, qualifier, or buffer represented by * `input` influences the return value or buffer represented by `output` diff --git a/cpp/ql/src/change-notes/2024-02-16-modelled-functions-block-flow.md b/cpp/ql/src/change-notes/2024-02-16-modelled-functions-block-flow.md new file mode 100644 index 000000000000..d6ef3c3e0569 --- /dev/null +++ b/cpp/ql/src/change-notes/2024-02-16-modelled-functions-block-flow.md @@ -0,0 +1,4 @@ +--- +category: minorAnalysis +--- +* The new C/C++ dataflow and taint-tracking libraries (`semmle.code.cpp.dataflow.new.DataFlow` and `semmle.code.cpp.dataflow.new.TaintTracking`) now implicitly assume that dataflow and taint modelled via `DataFlowFunction` and `TaintFunction` always fully overwrite their buffers and thus act as flow barriers. As a result, many dataflow and taint-tracking queries now produce fewer false positives. To remove this assumption and go back to the previous behavior for a given model, one can override the new `isPartialWrite` predicate. diff --git a/cpp/ql/test/experimental/query-tests/Security/CWE/CWE-193/array-access/ArrayAccessProductFlow.expected b/cpp/ql/test/experimental/query-tests/Security/CWE/CWE-193/array-access/ArrayAccessProductFlow.expected index bb062dac2181..96f5e711fd54 100644 --- a/cpp/ql/test/experimental/query-tests/Security/CWE/CWE-193/array-access/ArrayAccessProductFlow.expected +++ b/cpp/ql/test/experimental/query-tests/Security/CWE/CWE-193/array-access/ArrayAccessProductFlow.expected @@ -33,11 +33,14 @@ edges | test.cpp:76:20:76:29 | *call to mk_array_p [p] | test.cpp:83:9:83:11 | *arr [p] | provenance | | | test.cpp:79:9:79:11 | *arr [p] | test.cpp:79:14:79:14 | p | provenance | | | test.cpp:83:9:83:11 | *arr [p] | test.cpp:83:14:83:14 | p | provenance | | +| test.cpp:87:28:87:30 | *arr [p] | test.cpp:87:28:87:30 | *arr [p] | provenance | | | test.cpp:87:28:87:30 | *arr [p] | test.cpp:89:9:89:11 | *arr [p] | provenance | | | test.cpp:87:28:87:30 | *arr [p] | test.cpp:93:9:93:11 | *arr [p] | provenance | | | test.cpp:89:9:89:11 | *arr [p] | test.cpp:89:14:89:14 | p | provenance | | | test.cpp:93:9:93:11 | *arr [p] | test.cpp:93:14:93:14 | p | provenance | | | test.cpp:98:18:98:27 | *call to mk_array_p [p] | test.cpp:87:28:87:30 | *arr [p] | provenance | | +| test.cpp:98:18:98:27 | *call to mk_array_p [p] | test.cpp:98:18:98:27 | test6_callee output argument [p] | provenance | | +| test.cpp:98:18:98:27 | test6_callee output argument [p] | test.cpp:98:18:98:27 | *call to mk_array_p [p] | provenance | | nodes | test.cpp:4:17:4:22 | call to malloc | semmle.label | call to malloc | | test.cpp:6:9:6:11 | arr | semmle.label | arr | @@ -77,12 +80,15 @@ nodes | test.cpp:83:9:83:11 | *arr [p] | semmle.label | *arr [p] | | test.cpp:83:14:83:14 | p | semmle.label | p | | test.cpp:87:28:87:30 | *arr [p] | semmle.label | *arr [p] | +| test.cpp:87:28:87:30 | *arr [p] | semmle.label | *arr [p] | | test.cpp:89:9:89:11 | *arr [p] | semmle.label | *arr [p] | | test.cpp:89:14:89:14 | p | semmle.label | p | | test.cpp:93:9:93:11 | *arr [p] | semmle.label | *arr [p] | | test.cpp:93:14:93:14 | p | semmle.label | p | | test.cpp:98:18:98:27 | *call to mk_array_p [p] | semmle.label | *call to mk_array_p [p] | +| test.cpp:98:18:98:27 | test6_callee output argument [p] | semmle.label | test6_callee output argument [p] | subpaths +| test.cpp:98:18:98:27 | *call to mk_array_p [p] | test.cpp:87:28:87:30 | *arr [p] | test.cpp:87:28:87:30 | *arr [p] | test.cpp:98:18:98:27 | test6_callee output argument [p] | #select | test.cpp:10:9:10:11 | arr | test.cpp:4:17:4:22 | call to malloc | test.cpp:10:9:10:11 | arr | Off-by one error allocated at $@ bounded by $@. | test.cpp:4:17:4:22 | call to malloc | call to malloc | test.cpp:4:24:4:27 | size | size | | test.cpp:10:9:10:11 | arr | test.cpp:4:17:4:22 | call to malloc | test.cpp:10:9:10:11 | arr | Off-by one error allocated at $@ bounded by $@. | test.cpp:4:17:4:22 | call to malloc | call to malloc | test.cpp:4:24:4:27 | size | size | diff --git a/cpp/ql/test/include/iterator.h b/cpp/ql/test/include/iterator.h index 77758bfa8da6..5cd7f2312842 100644 --- a/cpp/ql/test/include/iterator.h +++ b/cpp/ql/test/include/iterator.h @@ -65,7 +65,7 @@ namespace std { }; template - constexpr back_insert_iterator back_inserter(Container& x) { + constexpr back_insert_iterator back_inserter(Container& x) { // $ ir-def=*x return back_insert_iterator(x); } @@ -89,7 +89,7 @@ namespace std { constexpr front_insert_iterator operator++(int); }; template - constexpr front_insert_iterator front_inserter(Container& x) { + constexpr front_insert_iterator front_inserter(Container& x) { // $ ir-def=*x return front_insert_iterator(x); } } diff --git a/cpp/ql/test/library-tests/dataflow/dataflow-tests/BarrierGuard.cpp b/cpp/ql/test/library-tests/dataflow/dataflow-tests/BarrierGuard.cpp index 74cc86e5c140..0e9c9f1bc778 100644 --- a/cpp/ql/test/library-tests/dataflow/dataflow-tests/BarrierGuard.cpp +++ b/cpp/ql/test/library-tests/dataflow/dataflow-tests/BarrierGuard.cpp @@ -56,7 +56,7 @@ void bg_stackstruct(XY s1, XY s2) { } } -void bg_structptr(XY *p1, XY *p2) { // $ ast-def=p1 ast-def=p2 +void bg_structptr(XY *p1, XY *p2) { // $ ast-def=p1 ast-def=p2 ir-def=*p1 ir-def=*p2 p1->x = source(); if (guarded(p1->x)) { sink(p1->x); // $ SPURIOUS: ast diff --git a/cpp/ql/test/library-tests/dataflow/dataflow-tests/clang.cpp b/cpp/ql/test/library-tests/dataflow/dataflow-tests/clang.cpp index 499e8b8a62b8..7b4759ec0bfc 100644 --- a/cpp/ql/test/library-tests/dataflow/dataflow-tests/clang.cpp +++ b/cpp/ql/test/library-tests/dataflow/dataflow-tests/clang.cpp @@ -8,7 +8,7 @@ struct twoIntFields { int getFirst() { return m1; } }; -void following_pointers( // $ ast-def=sourceStruct1_ptr +void following_pointers( // $ ast-def=sourceStruct1_ptr ir-def=*cleanArray1 ir-def=*sourceArray1 ir-def=*sourceStruct1_ptr int sourceArray1[], int cleanArray1[], twoIntFields sourceStruct1, diff --git a/cpp/ql/test/library-tests/dataflow/dataflow-tests/dispatch.cpp b/cpp/ql/test/library-tests/dataflow/dataflow-tests/dispatch.cpp index ff22b0d12b71..105212ccca67 100644 --- a/cpp/ql/test/library-tests/dataflow/dataflow-tests/dispatch.cpp +++ b/cpp/ql/test/library-tests/dataflow/dataflow-tests/dispatch.cpp @@ -25,7 +25,7 @@ struct Bottom : Middle { void notSink(int x) override { } }; -void VirtualDispatch(Bottom *bottomPtr, Bottom &bottomRef) { // $ ast-def=bottomPtr ast-def=bottomRef +void VirtualDispatch(Bottom *bottomPtr, Bottom &bottomRef) { // $ ast-def=bottomPtr ast-def=bottomRef ir-def=*bottomPtr ir-def=*bottomRef Top *topPtr = bottomPtr, &topRef = bottomRef; sink(topPtr->isSource1()); // $ ir MISSING: ast @@ -65,11 +65,11 @@ Top *allocateBottom() { return new Bottom(); } -void callSinkByPointer(Top *top) { // $ ast-def=top +void callSinkByPointer(Top *top) { // $ ast-def=top ir-def=*top top->isSink(source()); // leads to MISSING from ast } -void callSinkByReference(Top &top) { // $ ast-def=top +void callSinkByReference(Top &top) { // $ ast-def=top ir-def=*top top.isSink(source()); // leads to MISSING from ast } @@ -81,11 +81,11 @@ void globalVirtualDispatch() { x->isSink(source()); // $ MISSING: ast,ir } -Top *identity(Top *top) { // $ ast-def=top +Top *identity(Top *top) { // $ ast-def=top ir-def=*top return top; } -void callIdentityFunctions(Top *top, Bottom *bottom) { // $ ast-def=bottom ast-def=top +void callIdentityFunctions(Top *top, Bottom *bottom) { // $ ast-def=bottom ast-def=top ir-def=*bottom ir-def=*top identity(bottom)->isSink(source()); // $ MISSING: ast,ir identity(top)->isSink(source()); // no flow } @@ -120,7 +120,7 @@ namespace virtual_inheritance { struct Bottom : Middle { }; - void VirtualDispatch(Bottom *bottomPtr, Bottom &bottomRef) { // $ ast-def=bottomPtr ast-def=bottomRef + void VirtualDispatch(Bottom *bottomPtr, Bottom &bottomRef) { // $ ast-def=bottomPtr ast-def=bottomRef ir-def=*bottomPtr ir-def=*bottomRef // Because the inheritance from `Top` is virtual, the following casts go // directly from `Bottom` to `Top`, skipping `Middle`. That means we don't // get flow from a `Middle` value to the call qualifier. diff --git a/cpp/ql/test/library-tests/dataflow/dataflow-tests/example.c b/cpp/ql/test/library-tests/dataflow/dataflow-tests/example.c index ad01145cde79..6e80ec619725 100644 --- a/cpp/ql/test/library-tests/dataflow/dataflow-tests/example.c +++ b/cpp/ql/test/library-tests/dataflow/dataflow-tests/example.c @@ -12,7 +12,7 @@ typedef struct char isTrue; } MyBool; -void myTest_with_local_flow(MyBool *b, int pos) // $ ast-def=b +void myTest_with_local_flow(MyBool *b, int pos) // $ ast-def=b ir-def=*b { MyCoords coords = {0}; diff --git a/cpp/ql/test/library-tests/dataflow/dataflow-tests/flowOut.cpp b/cpp/ql/test/library-tests/dataflow/dataflow-tests/flowOut.cpp index 826fc5425032..d6a06361524e 100644 --- a/cpp/ql/test/library-tests/dataflow/dataflow-tests/flowOut.cpp +++ b/cpp/ql/test/library-tests/dataflow/dataflow-tests/flowOut.cpp @@ -7,7 +7,7 @@ void source_ref(int *toTaint) { // $ ir-def=*toTaint ast-def=toTaint void source_ref(char *toTaint) { // $ ir-def=*toTaint ast-def=toTaint *toTaint = source(); } -void modify_copy(int* ptr) { // $ ast-def=ptr +void modify_copy(int* ptr) { // $ ast-def=ptr ir-def=*ptr int deref = *ptr; int* other = &deref; source_ref(other); @@ -19,7 +19,7 @@ void test_output_copy() { sink(x); // clean } -void modify(int* ptr) { // $ ast-def=ptr +void modify(int* ptr) { // $ ast-def=ptr ir-def=*ptr int* deref = ptr; int* other = &*deref; source_ref(other); @@ -31,7 +31,7 @@ void test_output() { sink(x); // $ ir MISSING: ast } -void modify_copy_of_pointer(int* p, unsigned len) { // $ ast-def=p +void modify_copy_of_pointer(int* p, unsigned len) { // $ ast-def=p ir-def=*p int* p2 = new int[len]; for(unsigned i = 0; i < len; ++i) { p2[i] = p[i]; @@ -46,7 +46,7 @@ void test_modify_copy_of_pointer() { sink(x[0]); // $ SPURIOUS: ast // clean } -void modify_pointer(int* p, unsigned len) { // $ ast-def=p +void modify_pointer(int* p, unsigned len) { // $ ast-def=p ir-def=*p int** p2 = &p; for(unsigned i = 0; i < len; ++i) { *p2[i] = p[i]; @@ -63,17 +63,17 @@ void test_modify_of_pointer() { char* strdup(const char* p); -void modify_copy_via_strdup(char* p) { // $ ast-def=p +void modify_copy_via_strdup(char* p) { // $ ast-def=p ir-def=*p char* p2 = strdup(p); source_ref(p2); } -void test_modify_copy_via_strdup(char* p) { // $ ast-def=p +void test_modify_copy_via_strdup(char* p) { // $ ast-def=p ir-def=*p modify_copy_via_strdup(p); sink(*p); // clean } -int* deref(int** p) { // $ ast-def=p +int* deref(int** p) { // $ ast-def=p ir-def=*p ir-def=**p int* q = *p; return q; } @@ -90,7 +90,7 @@ void addtaint1(int* q) { // $ ast-def=q ir-def=*q *q = source(); } -void addtaint2(int** p) { // $ ast-def=p +void addtaint2(int** p) { // $ ast-def=p ir-def=*p ir-def=**p int* q = *p; addtaint1(q); } @@ -106,13 +106,13 @@ using size_t = decltype(sizeof(int)); void* memcpy(void* dest, const void* src, size_t); -void modify_copy_via_memcpy(char* p) { // $ ast-def=p +void modify_copy_via_memcpy(char* p) { // $ ast-def=p ir-def=*p char* dest; char* p2 = (char*)memcpy(dest, p, 10); source_ref(p2); } -void test_modify_copy_via_memcpy(char* p) { // $ ast-def=p +void test_modify_copy_via_memcpy(char* p) { // $ ast-def=p ir-def=*p modify_copy_via_memcpy(p); sink(*p); // clean } @@ -134,14 +134,14 @@ void source_ref_ref(char** toTaint) { // $ ast-def=toTaint ir-def=*toTaint ir-de // This function copies the value of **p into a new location **p2 and then // taints **p. Thus, **p does not contain tainted data after returning from // this function. -void modify_copy_via_strdup_ptr_001(char** p) { // $ ast-def=p +void modify_copy_via_strdup_ptr_001(char** p) { // $ ast-def=p ir-def=*p ir-def=**p // **p -> **p2 char** p2 = strdup_ptr_001(p); // source -> **p2 source_ref_ref(p2); } -void test_modify_copy_via_strdup_001(char** p) { // $ ast-def=p +void test_modify_copy_via_strdup_001(char** p) { // $ ast-def=p ir-def=*p ir-def=**p modify_copy_via_strdup_ptr_001(p); sink(**p); // clean } @@ -149,14 +149,14 @@ void test_modify_copy_via_strdup_001(char** p) { // $ ast-def=p // This function copies the value of *p into a new location *p2 and then // taints **p2. Thus, **p contains tainted data after returning from this // function. -void modify_copy_via_strdup_ptr_011(char** p) { // $ ast-def=p +void modify_copy_via_strdup_ptr_011(char** p) { // $ ast-def=p ir-def=*p ir-def=**p // **p -> **p2 and *p -> *p2 char** p2 = strdup_ptr_011(p); // source -> **p2 source_ref_ref(p2); } -void test_modify_copy_via_strdup_011(char** p) { // $ ast-def=p +void test_modify_copy_via_strdup_011(char** p) { // $ ast-def=p ir-def=*p ir-def=**p modify_copy_via_strdup_ptr_011(p); sink(**p); // $ ir MISSING: ast } @@ -171,7 +171,7 @@ void source_ref_2(char** toTaint) { // $ ast-def=toTaint ir-def=*toTaint ir-def= // This function copies the value of p into a new location p2 and then // taints *p2. Thus, *p contains tainted data after returning from this // function. -void modify_copy_via_strdup_ptr_111_taint_ind(char** p) { // $ ast-def=p +void modify_copy_via_strdup_ptr_111_taint_ind(char** p) { // $ ast-def=p ir-def=*p ir-def=**p // **p -> **p2, *p -> *p2, and p -> p2 char** p2 = strdup_ptr_111(p); // source -> *p2 @@ -180,7 +180,7 @@ void modify_copy_via_strdup_ptr_111_taint_ind(char** p) { // $ ast-def=p void sink(char*); -void test_modify_copy_via_strdup_111_taint_ind(char** p) { // $ ast-def=p +void test_modify_copy_via_strdup_111_taint_ind(char** p) { // $ ast-def=p ir-def=*p ir-def=**p modify_copy_via_strdup_ptr_111_taint_ind(p); sink(*p); // $ ir MISSING: ast } @@ -188,7 +188,7 @@ void test_modify_copy_via_strdup_111_taint_ind(char** p) { // $ ast-def=p // This function copies the value of p into a new location p2 and then // taints **p2. Thus, **p contains tainted data after returning from this // function. -void modify_copy_via_strdup_ptr_111_taint_ind_ind(char** p) { // $ ast-def=p +void modify_copy_via_strdup_ptr_111_taint_ind_ind(char** p) { // $ ast-def=p ir-def=*p ir-def=**p // **p -> **p2, *p -> *p2, and p -> p2 char** p2 = strdup_ptr_111(p); // source -> **p2 @@ -197,7 +197,7 @@ void modify_copy_via_strdup_ptr_111_taint_ind_ind(char** p) { // $ ast-def=p void sink(char*); -void test_modify_copy_via_strdup_111_taint_ind_ind(char** p) { // $ ast-def=p +void test_modify_copy_via_strdup_111_taint_ind_ind(char** p) { // $ ast-def=p ir-def=*p ir-def=**p modify_copy_via_strdup_ptr_111_taint_ind_ind(p); sink(**p); // $ ir MISSING: ast } \ No newline at end of file diff --git a/cpp/ql/test/library-tests/dataflow/dataflow-tests/lambdas.cpp b/cpp/ql/test/library-tests/dataflow/dataflow-tests/lambdas.cpp index 645c41896c45..d0687994b457 100644 --- a/cpp/ql/test/library-tests/dataflow/dataflow-tests/lambdas.cpp +++ b/cpp/ql/test/library-tests/dataflow/dataflow-tests/lambdas.cpp @@ -37,7 +37,7 @@ void test_lambdas() }; d(t, u); - auto e = [](int &a, int &b, int &c) { // $ ast-def=a ast-def=b ast-def=c ir-def=*c + auto e = [](int &a, int &b, int &c) { // $ ast-def=a ast-def=b ast-def=c ir-def=*c ir-def=*a ir-def=*b sink(a); // $ ast,ir sink(b); c = source(); diff --git a/cpp/ql/test/library-tests/dataflow/dataflow-tests/ref.cpp b/cpp/ql/test/library-tests/dataflow/dataflow-tests/ref.cpp index 1fda792dd26b..3f8d77a7b2b0 100644 --- a/cpp/ql/test/library-tests/dataflow/dataflow-tests/ref.cpp +++ b/cpp/ql/test/library-tests/dataflow/dataflow-tests/ref.cpp @@ -12,7 +12,7 @@ namespace withoutFields { } template - void assignWrapper(T &lhs, T rhs) { // $ ast-def=lhs ast-def=lhs + void assignWrapper(T &lhs, T rhs) { // $ ast-def=lhs ast-def=lhs ir-def=*lhs assign(lhs, rhs); } @@ -71,15 +71,15 @@ namespace withFields { int val; }; - void assign(Int &lhs, int rhs) { // $ ast-def=lhs + void assign(Int &lhs, int rhs) { // $ ast-def=lhs ir-def=*lhs lhs.val = rhs; } - void assignWrapper(Int &lhs, int rhs) { // $ ast-def=lhs + void assignWrapper(Int &lhs, int rhs) { // $ ast-def=lhs ir-def=*lhs assign(lhs, rhs); } - void notAssign(Int &lhs, int rhs) { // $ ast-def=lhs + void notAssign(Int &lhs, int rhs) { // $ ast-def=lhs ir-def=*lhs lhs.val = rhs; // Field flow ignores that the field is subsequently overwritten, leading // to false flow here. @@ -90,14 +90,14 @@ namespace withFields { } } - void sourceToParam(Int &out) { // $ ast-def=out + void sourceToParam(Int &out) { // $ ast-def=out ir-def=*out out.val = source(); if (arbitrary) { out.val = 1; } } - void sourceToParamWrapper(Int &out) { // $ ast-def=out + void sourceToParamWrapper(Int &out) { // $ ast-def=out ir-def=*out if (arbitrary) { sourceToParam(out); } else { @@ -105,7 +105,7 @@ namespace withFields { } } - void notSource(Int &out) { // $ ast-def=out + void notSource(Int &out) { // $ ast-def=out ir-def=*out out.val = source(); // Field flow ignores that the field is subsequently overwritten, leading // to false flow here. diff --git a/cpp/ql/test/library-tests/dataflow/dataflow-tests/self_parameter_flow.cpp b/cpp/ql/test/library-tests/dataflow/dataflow-tests/self_parameter_flow.cpp index 2298e644b05f..fe415ebab776 100644 --- a/cpp/ql/test/library-tests/dataflow/dataflow-tests/self_parameter_flow.cpp +++ b/cpp/ql/test/library-tests/dataflow/dataflow-tests/self_parameter_flow.cpp @@ -3,12 +3,12 @@ void incr(unsigned char **ps) // $ ast-def=ps ir-def=*ps ir-def=**ps *ps += 1; } -void callincr(unsigned char *s) // $ ast-def=s +void callincr(unsigned char *s) // $ ast-def=s ir-def=*s { incr(&s); } -void test(unsigned char *s) // $ ast-def=s +void test(unsigned char *s) // $ ast-def=s ir-def=*s { callincr(s); // $ flow } \ No newline at end of file diff --git a/cpp/ql/test/library-tests/dataflow/dataflow-tests/test-source-sink.expected b/cpp/ql/test/library-tests/dataflow/dataflow-tests/test-source-sink.expected index 2d33f47ba604..c9f90a60b6e4 100644 --- a/cpp/ql/test/library-tests/dataflow/dataflow-tests/test-source-sink.expected +++ b/cpp/ql/test/library-tests/dataflow/dataflow-tests/test-source-sink.expected @@ -238,8 +238,6 @@ irFlow | test.cpp:382:48:382:54 | source1 | test.cpp:385:8:385:10 | tmp | | test.cpp:388:53:388:59 | source1 | test.cpp:392:8:392:10 | tmp | | test.cpp:388:53:388:59 | source1 | test.cpp:394:10:394:12 | tmp | -| test.cpp:399:7:399:9 | definition of tmp | test.cpp:401:8:401:10 | tmp | -| test.cpp:405:7:405:9 | definition of tmp | test.cpp:408:8:408:10 | tmp | | test.cpp:416:7:416:11 | definition of local | test.cpp:418:8:418:12 | local | | test.cpp:417:16:417:20 | intRefSource output argument | test.cpp:418:8:418:12 | local | | test.cpp:422:7:422:11 | definition of local | test.cpp:424:8:424:12 | local | @@ -266,6 +264,7 @@ irFlow | test.cpp:576:17:576:31 | *call to indirect_source | test.cpp:568:10:568:19 | * ... | | test.cpp:576:17:576:31 | *call to indirect_source | test.cpp:572:10:572:19 | * ... | | test.cpp:576:17:576:31 | *call to indirect_source | test.cpp:578:10:578:19 | * ... | +| test.cpp:583:11:583:16 | call to source | test.cpp:590:8:590:8 | x | | test.cpp:594:12:594:26 | *call to indirect_source | test.cpp:597:8:597:13 | * ... | | test.cpp:601:20:601:20 | intPointerSource output argument | test.cpp:603:8:603:9 | * ... | | test.cpp:607:20:607:20 | intPointerSource output argument | test.cpp:609:8:609:9 | * ... | 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 e29619a6800f..b36c289aaf1d 100644 --- a/cpp/ql/test/library-tests/dataflow/dataflow-tests/test.cpp +++ b/cpp/ql/test/library-tests/dataflow/dataflow-tests/test.cpp @@ -63,7 +63,7 @@ namespace std { template T&& move(T& t) noexcept; // simplified signature } -void identityOperations(int* source1) { // $ ast-def=source1 +void identityOperations(int* source1) { // $ ast-def=source1 ir-def=*source1 const int *x1 = std::move(source1); int* x2 = const_cast(x1); int* x3 = (x2); @@ -398,14 +398,14 @@ void flowThroughMemcpy_blockvar_with_local_flow(int source1, int b) { void cleanedByMemcpy_ssa(int clean1) { // currently modeled with BlockVar, not SSA int tmp; memcpy(&tmp, &clean1, sizeof tmp); - sink(tmp); // $ SPURIOUS: ast,ir + sink(tmp); // $ SPURIOUS: ast } void cleanedByMemcpy_blockvar(int clean1) { int tmp; int *capture = &tmp; memcpy(&tmp, &clean1, sizeof tmp); - sink(tmp); // $ SPURIOUS: ast,ir + sink(tmp); // $ SPURIOUS: ast } void intRefSource(int &ref_source); @@ -484,7 +484,7 @@ struct MyStruct { int* content; }; -void local_field_flow_def_by_ref_steps_with_local_flow(MyStruct * s) { // $ ast-def=s +void local_field_flow_def_by_ref_steps_with_local_flow(MyStruct * s) { // $ ast-def=s ir-def=*s writes_to_content(s->content); int* p_content = s->content; sink(*p_content); @@ -521,12 +521,12 @@ void uncertain_definition() { sink(stackArray[0]); // $ ast=519:19 ir SPURIOUS: ast=517:7 } -void set_through_const_pointer(int x, const int **e) // $ ast-def=e ir-def=**e ir-def=*e +void set_through_const_pointer(int x, const int **e) // $ ast-def=e ir-def=*e ir-def=**e { *e = &x; } -void test_set_through_const_pointer(int *e) // $ ast-def=e +void test_set_through_const_pointer(int *e) // $ ast-def=e ir-def=*e { set_through_const_pointer(source(), &e); sink(*e); // $ ir MISSING: ast @@ -579,7 +579,7 @@ namespace IndirectFlowThroughGlobals { } } -void write_to_param(int* x) { // $ ast-def=x +void write_to_param(int* x) { // $ ast-def=x ir-def=*x int s = source(); x = &s; } @@ -587,7 +587,7 @@ void write_to_param(int* x) { // $ ast-def=x void test_write_to_param() { int x = 0; write_to_param(&x); - sink(x); // $ SPURIOUS: ast + sink(x); // $ SPURIOUS: ast,ir } void test_indirect_flow_to_array() { @@ -609,7 +609,7 @@ void test_def_by_ref_followed_by_uncertain_write_pointer(int* p) { // $ ast-def= sink(*p); // $ ir MISSING: ast } -void test_flow_through_void_double_pointer(int *p) // $ ast-def=p +void test_flow_through_void_double_pointer(int *p) // $ ast-def=p ir-def=*p { intPointerSource(p); void* q = (void*)&p; @@ -695,11 +695,11 @@ void increment_buf(int** buf) { // $ ast-def=buf ir-def=*buf ir-def=**buf sink(buf); // $ SPURIOUS: ast } -void call_increment_buf(int** buf) { // $ ast-def=buf +void call_increment_buf(int** buf) { // $ ast-def=buf ir-def=*buf ir-def=**buf increment_buf(buf); } -void test_conflation_regression(int* source) { // $ ast-def=source +void test_conflation_regression(int* source) { // $ ast-def=source ir-def=*source int* buf = source; call_increment_buf(&buf); } @@ -709,13 +709,13 @@ void write_to_star_star_p(unsigned char **p) // $ ast-def=p ir-def=**p ir-def=*p **p = 0; } -void write_to_star_buf(unsigned char *buf) // $ ast-def=buf +void write_to_star_buf(unsigned char *buf) // $ ast-def=buf ir-def=*buf { unsigned char *c = buf; write_to_star_star_p(&c); } -void test_write_to_star_buf(unsigned char *source) // $ ast-def=source +void test_write_to_star_buf(unsigned char *source) // $ ast-def=source ir-def=*source { write_to_star_buf(source); sink(*source); // clean @@ -1041,7 +1041,7 @@ namespace test_gettext { void* memset(void*, int, size_t); -void memset_test(char* buf) { // $ ast-def=buf +void memset_test(char* buf) { // $ ast-def=buf ir-def=*buf memset(buf, source(), 10); sink(*buf); // $ ir MISSING: ast } \ No newline at end of file diff --git a/cpp/ql/test/library-tests/dataflow/fields/ir-path-flow.expected b/cpp/ql/test/library-tests/dataflow/fields/ir-path-flow.expected index 770a70f2a1d6..2fff7b5403c5 100644 --- a/cpp/ql/test/library-tests/dataflow/fields/ir-path-flow.expected +++ b/cpp/ql/test/library-tests/dataflow/fields/ir-path-flow.expected @@ -52,13 +52,17 @@ edges | A.cpp:103:14:103:14 | *c [a] | A.cpp:120:12:120:13 | *c1 [a] | provenance | | | A.cpp:107:12:107:13 | *c1 [a] | A.cpp:107:12:107:16 | a | provenance | | | A.cpp:120:12:120:13 | *c1 [a] | A.cpp:120:12:120:16 | a | provenance | | +| A.cpp:124:14:124:14 | *b [c] | A.cpp:131:8:131:8 | f7 output argument [c] | provenance | | +| A.cpp:126:5:126:5 | set output argument [c] | A.cpp:124:14:124:14 | *b [c] | provenance | | | A.cpp:126:5:126:5 | set output argument [c] | A.cpp:131:8:131:8 | f7 output argument [c] | provenance | | | A.cpp:126:12:126:18 | new | A.cpp:27:17:27:17 | c | provenance | | | A.cpp:126:12:126:18 | new | A.cpp:126:5:126:5 | set output argument [c] | provenance | | | A.cpp:126:12:126:18 | new | A.cpp:126:12:126:18 | new | provenance | | | A.cpp:131:8:131:8 | f7 output argument [c] | A.cpp:132:10:132:10 | *b [c] | provenance | | | A.cpp:132:10:132:10 | *b [c] | A.cpp:132:10:132:13 | c | provenance | | +| A.cpp:140:13:140:13 | *b [c] | A.cpp:151:18:151:18 | D output argument [c] | provenance | | | A.cpp:140:13:140:13 | b | A.cpp:143:7:143:31 | ... = ... | provenance | | +| A.cpp:142:7:142:7 | *b [post update] [c] | A.cpp:140:13:140:13 | *b [c] | provenance | | | A.cpp:142:7:142:7 | *b [post update] [c] | A.cpp:143:7:143:31 | *... = ... [c] | provenance | | | A.cpp:142:7:142:7 | *b [post update] [c] | A.cpp:151:18:151:18 | D output argument [c] | provenance | | | A.cpp:142:7:142:20 | ... = ... | A.cpp:142:7:142:7 | *b [post update] [c] | provenance | | @@ -70,12 +74,20 @@ edges | A.cpp:143:7:143:31 | ... = ... | A.cpp:143:7:143:10 | *this [post update] [b] | provenance | | | A.cpp:143:25:143:31 | new | A.cpp:143:7:143:31 | ... = ... | provenance | | | A.cpp:150:12:150:18 | new | A.cpp:151:18:151:18 | b | provenance | | +| A.cpp:151:12:151:24 | call to D [*b, c] | A.cpp:152:10:152:10 | *d [*b, c] | provenance | | | A.cpp:151:12:151:24 | call to D [*b, c] | A.cpp:153:10:153:10 | *d [*b, c] | provenance | | | A.cpp:151:12:151:24 | call to D [b] | A.cpp:152:10:152:10 | *d [b] | provenance | | | A.cpp:151:18:151:18 | D output argument [c] | A.cpp:154:10:154:10 | *b [c] | provenance | | | A.cpp:151:18:151:18 | b | A.cpp:140:13:140:13 | b | provenance | | | A.cpp:151:18:151:18 | b | A.cpp:151:12:151:24 | call to D [b] | provenance | | +| A.cpp:152:10:152:10 | *d [*b, c] | A.cpp:152:10:152:13 | *b [c] | provenance | | +| A.cpp:152:10:152:10 | *d [*b, c] | A.cpp:152:13:152:13 | *b [c] | provenance | | | A.cpp:152:10:152:10 | *d [b] | A.cpp:152:10:152:13 | b | provenance | | +| A.cpp:152:10:152:10 | *d [post update] [*b, c] | A.cpp:153:10:153:10 | *d [*b, c] | provenance | | +| A.cpp:152:10:152:13 | *b [c] | A.cpp:152:10:152:13 | sink output argument [c] | provenance | | +| A.cpp:152:10:152:13 | *b [c] | A.cpp:173:26:173:26 | *o [c] | provenance | | +| A.cpp:152:10:152:13 | sink output argument [c] | A.cpp:152:10:152:10 | *d [post update] [*b, c] | provenance | | +| A.cpp:152:13:152:13 | *b [c] | A.cpp:152:10:152:13 | *b [c] | provenance | | | A.cpp:153:10:153:10 | *d [*b, c] | A.cpp:153:13:153:13 | *b [c] | provenance | | | A.cpp:153:13:153:13 | *b [c] | A.cpp:153:10:153:16 | c | provenance | | | A.cpp:154:10:154:10 | *b [c] | A.cpp:154:10:154:13 | c | provenance | | @@ -98,6 +110,7 @@ edges | A.cpp:167:47:167:50 | *next [*next, head] | A.cpp:167:44:167:44 | *l [*next, head] | provenance | | | A.cpp:167:47:167:50 | *next [head] | A.cpp:169:12:169:12 | *l [head] | provenance | | | A.cpp:169:12:169:12 | *l [head] | A.cpp:169:12:169:18 | head | provenance | | +| A.cpp:173:26:173:26 | *o [c] | A.cpp:173:26:173:26 | *o [c] | provenance | | | A.cpp:181:15:181:21 | newHead | A.cpp:183:7:183:20 | ... = ... | provenance | | | A.cpp:181:32:181:35 | *next [*next, head] | A.cpp:184:7:184:23 | *... = ... [*next, head] | provenance | | | A.cpp:181:32:181:35 | *next [head] | A.cpp:184:7:184:23 | *... = ... [head] | provenance | | @@ -200,9 +213,13 @@ edges | E.cpp:30:23:30:26 | *data [post update] [*buffer] | E.cpp:30:21:30:21 | *p [post update] [data, *buffer] | provenance | | | E.cpp:32:10:32:10 | *b [*buffer] | E.cpp:32:13:32:18 | *buffer | provenance | | | E.cpp:33:18:33:19 | *& ... [data, *buffer] | E.cpp:19:27:19:27 | *p [data, *buffer] | provenance | | +| aliasing.cpp:8:23:8:23 | *s [m1] | aliasing.cpp:25:17:25:19 | pointerSetter output argument [m1] | provenance | | +| aliasing.cpp:9:3:9:3 | *s [post update] [m1] | aliasing.cpp:8:23:8:23 | *s [m1] | provenance | | | aliasing.cpp:9:3:9:3 | *s [post update] [m1] | aliasing.cpp:25:17:25:19 | pointerSetter output argument [m1] | provenance | | | aliasing.cpp:9:3:9:22 | ... = ... | aliasing.cpp:9:3:9:3 | *s [post update] [m1] | provenance | | | aliasing.cpp:9:11:9:20 | call to user_input | aliasing.cpp:9:3:9:22 | ... = ... | provenance | | +| aliasing.cpp:12:25:12:25 | *s [m1] | aliasing.cpp:26:19:26:20 | referenceSetter output argument [m1] | provenance | | +| aliasing.cpp:13:3:13:3 | *s [post update] [m1] | aliasing.cpp:12:25:12:25 | *s [m1] | provenance | | | aliasing.cpp:13:3:13:3 | *s [post update] [m1] | aliasing.cpp:26:19:26:20 | referenceSetter output argument [m1] | provenance | | | aliasing.cpp:13:3:13:21 | ... = ... | aliasing.cpp:13:3:13:3 | *s [post update] [m1] | provenance | | | aliasing.cpp:13:10:13:19 | call to user_input | aliasing.cpp:13:3:13:21 | ... = ... | provenance | | @@ -313,6 +330,7 @@ edges | arrays.cpp:50:10:50:17 | *indirect [*ptr, data] | arrays.cpp:50:20:50:22 | *ptr [data] | provenance | | | arrays.cpp:50:20:50:22 | *ptr [data] | arrays.cpp:50:8:50:25 | *access to array [data] | provenance | | | by_reference.cpp:11:48:11:52 | value | by_reference.cpp:12:5:12:16 | ... = ... | provenance | | +| by_reference.cpp:12:5:12:5 | *s [post update] [a] | by_reference.cpp:11:39:11:39 | *s [a] | provenance | | | by_reference.cpp:12:5:12:16 | ... = ... | by_reference.cpp:12:5:12:5 | *s [post update] [a] | provenance | | | by_reference.cpp:15:26:15:30 | value | by_reference.cpp:16:5:16:19 | ... = ... | provenance | | | by_reference.cpp:16:5:16:19 | ... = ... | by_reference.cpp:16:5:16:8 | *this [post update] [a] | provenance | | @@ -356,12 +374,22 @@ edges | by_reference.cpp:68:21:68:30 | call to user_input | by_reference.cpp:68:17:68:18 | nonMemberSetA output argument [a] | provenance | | | by_reference.cpp:69:22:69:23 | *& ... [a] | by_reference.cpp:31:46:31:46 | *s [a] | provenance | | | by_reference.cpp:69:22:69:23 | *& ... [a] | by_reference.cpp:69:8:69:20 | call to nonMemberGetA | provenance | | +| by_reference.cpp:83:31:83:35 | *inner [a] | by_reference.cpp:102:21:102:39 | taint_inner_a_ptr output argument [a] | provenance | | +| by_reference.cpp:83:31:83:35 | *inner [a] | by_reference.cpp:103:27:103:35 | taint_inner_a_ptr output argument [a] | provenance | | +| by_reference.cpp:83:31:83:35 | *inner [a] | by_reference.cpp:106:21:106:41 | taint_inner_a_ptr output argument [a] | provenance | | +| by_reference.cpp:83:31:83:35 | *inner [a] | by_reference.cpp:107:29:107:37 | taint_inner_a_ptr output argument [a] | provenance | | +| by_reference.cpp:84:3:84:7 | *inner [post update] [a] | by_reference.cpp:83:31:83:35 | *inner [a] | provenance | | | by_reference.cpp:84:3:84:7 | *inner [post update] [a] | by_reference.cpp:102:21:102:39 | taint_inner_a_ptr output argument [a] | provenance | | | by_reference.cpp:84:3:84:7 | *inner [post update] [a] | by_reference.cpp:103:27:103:35 | taint_inner_a_ptr output argument [a] | provenance | | | by_reference.cpp:84:3:84:7 | *inner [post update] [a] | by_reference.cpp:106:21:106:41 | taint_inner_a_ptr output argument [a] | provenance | | | by_reference.cpp:84:3:84:7 | *inner [post update] [a] | by_reference.cpp:107:29:107:37 | taint_inner_a_ptr output argument [a] | provenance | | | by_reference.cpp:84:3:84:25 | ... = ... | by_reference.cpp:84:3:84:7 | *inner [post update] [a] | provenance | | | by_reference.cpp:84:14:84:23 | call to user_input | by_reference.cpp:84:3:84:25 | ... = ... | provenance | | +| by_reference.cpp:87:31:87:35 | *inner [a] | by_reference.cpp:122:21:122:38 | taint_inner_a_ref output argument [a] | provenance | | +| by_reference.cpp:87:31:87:35 | *inner [a] | by_reference.cpp:123:21:123:36 | taint_inner_a_ref output argument [a] | provenance | | +| by_reference.cpp:87:31:87:35 | *inner [a] | by_reference.cpp:126:21:126:40 | taint_inner_a_ref output argument [a] | provenance | | +| by_reference.cpp:87:31:87:35 | *inner [a] | by_reference.cpp:127:21:127:38 | taint_inner_a_ref output argument [a] | provenance | | +| by_reference.cpp:88:3:88:7 | *inner [post update] [a] | by_reference.cpp:87:31:87:35 | *inner [a] | provenance | | | by_reference.cpp:88:3:88:7 | *inner [post update] [a] | by_reference.cpp:122:21:122:38 | taint_inner_a_ref output argument [a] | provenance | | | by_reference.cpp:88:3:88:7 | *inner [post update] [a] | by_reference.cpp:123:21:123:36 | taint_inner_a_ref output argument [a] | provenance | | | by_reference.cpp:88:3:88:7 | *inner [post update] [a] | by_reference.cpp:126:21:126:40 | taint_inner_a_ref output argument [a] | provenance | | @@ -614,8 +642,10 @@ edges | qualifiers.cpp:9:21:9:25 | value | qualifiers.cpp:9:30:9:44 | ... = ... | provenance | | | qualifiers.cpp:9:30:9:44 | ... = ... | qualifiers.cpp:9:30:9:33 | *this [post update] [a] | provenance | | | qualifiers.cpp:12:40:12:44 | value | qualifiers.cpp:12:49:12:64 | ... = ... | provenance | | +| qualifiers.cpp:12:49:12:53 | *inner [post update] [a] | qualifiers.cpp:12:27:12:31 | *inner [a] | provenance | | | qualifiers.cpp:12:49:12:64 | ... = ... | qualifiers.cpp:12:49:12:53 | *inner [post update] [a] | provenance | | | qualifiers.cpp:13:42:13:46 | value | qualifiers.cpp:13:51:13:65 | ... = ... | provenance | | +| qualifiers.cpp:13:51:13:55 | *inner [post update] [a] | qualifiers.cpp:13:29:13:33 | *inner [a] | provenance | | | qualifiers.cpp:13:51:13:65 | ... = ... | qualifiers.cpp:13:51:13:55 | *inner [post update] [a] | provenance | | | qualifiers.cpp:22:5:22:9 | getInner output argument [*inner, a] | qualifiers.cpp:23:10:23:14 | *outer [*inner, a] | provenance | | | qualifiers.cpp:22:5:22:38 | ... = ... | qualifiers.cpp:22:11:22:18 | *call to getInner [post update] [a] | provenance | | @@ -716,6 +746,7 @@ edges | simple.cpp:103:24:103:24 | x | simple.cpp:104:14:104:14 | x | provenance | | | simple.cpp:108:17:108:26 | call to user_input | simple.cpp:109:43:109:43 | x | provenance | | | simple.cpp:109:43:109:43 | x | simple.cpp:103:24:103:24 | x | provenance | | +| struct_init.c:14:24:14:25 | *ab [a] | struct_init.c:14:24:14:25 | *ab [a] | provenance | | | struct_init.c:14:24:14:25 | *ab [a] | struct_init.c:15:8:15:9 | *ab [a] | provenance | | | struct_init.c:15:8:15:9 | *ab [a] | struct_init.c:15:12:15:12 | a | provenance | | | struct_init.c:20:13:20:14 | *definition of ab [a] | struct_init.c:22:8:22:9 | *ab [a] | provenance | | @@ -726,6 +757,8 @@ edges | struct_init.c:20:20:20:29 | call to user_input | struct_init.c:20:20:20:29 | call to user_input | provenance | | | struct_init.c:22:8:22:9 | *ab [a] | struct_init.c:22:11:22:11 | a | provenance | | | struct_init.c:24:10:24:12 | *& ... [a] | struct_init.c:14:24:14:25 | *ab [a] | provenance | | +| struct_init.c:24:10:24:12 | *& ... [a] | struct_init.c:24:10:24:12 | absink output argument [a] | provenance | | +| struct_init.c:24:10:24:12 | absink output argument [a] | struct_init.c:28:5:28:7 | *& ... [a] | provenance | | | struct_init.c:26:16:26:20 | *definition of outer [nestedAB, a] | struct_init.c:31:8:31:12 | *outer [nestedAB, a] | provenance | | | struct_init.c:26:16:26:20 | *definition of outer [nestedAB, a] | struct_init.c:36:11:36:15 | *outer [nestedAB, a] | provenance | | | struct_init.c:26:16:26:20 | *definition of outer [post update] [*pointerAB, a] | struct_init.c:33:8:33:12 | *outer [*pointerAB, a] | provenance | | @@ -805,12 +838,14 @@ nodes | A.cpp:107:12:107:16 | a | semmle.label | a | | A.cpp:120:12:120:13 | *c1 [a] | semmle.label | *c1 [a] | | A.cpp:120:12:120:16 | a | semmle.label | a | +| A.cpp:124:14:124:14 | *b [c] | semmle.label | *b [c] | | A.cpp:126:5:126:5 | set output argument [c] | semmle.label | set output argument [c] | | A.cpp:126:12:126:18 | new | semmle.label | new | | A.cpp:126:12:126:18 | new | semmle.label | new | | A.cpp:131:8:131:8 | f7 output argument [c] | semmle.label | f7 output argument [c] | | A.cpp:132:10:132:10 | *b [c] | semmle.label | *b [c] | | A.cpp:132:10:132:13 | c | semmle.label | c | +| A.cpp:140:13:140:13 | *b [c] | semmle.label | *b [c] | | A.cpp:140:13:140:13 | b | semmle.label | b | | A.cpp:142:7:142:7 | *b [post update] [c] | semmle.label | *b [post update] [c] | | A.cpp:142:7:142:20 | ... = ... | semmle.label | ... = ... | @@ -827,8 +862,13 @@ nodes | A.cpp:151:12:151:24 | call to D [b] | semmle.label | call to D [b] | | A.cpp:151:18:151:18 | D output argument [c] | semmle.label | D output argument [c] | | A.cpp:151:18:151:18 | b | semmle.label | b | +| A.cpp:152:10:152:10 | *d [*b, c] | semmle.label | *d [*b, c] | | A.cpp:152:10:152:10 | *d [b] | semmle.label | *d [b] | +| A.cpp:152:10:152:10 | *d [post update] [*b, c] | semmle.label | *d [post update] [*b, c] | +| A.cpp:152:10:152:13 | *b [c] | semmle.label | *b [c] | | A.cpp:152:10:152:13 | b | semmle.label | b | +| A.cpp:152:10:152:13 | sink output argument [c] | semmle.label | sink output argument [c] | +| A.cpp:152:13:152:13 | *b [c] | semmle.label | *b [c] | | A.cpp:153:10:153:10 | *d [*b, c] | semmle.label | *d [*b, c] | | A.cpp:153:10:153:16 | c | semmle.label | c | | A.cpp:153:13:153:13 | *b [c] | semmle.label | *b [c] | @@ -851,6 +891,8 @@ nodes | A.cpp:167:47:167:50 | *next [head] | semmle.label | *next [head] | | A.cpp:169:12:169:12 | *l [head] | semmle.label | *l [head] | | A.cpp:169:12:169:18 | head | semmle.label | head | +| A.cpp:173:26:173:26 | *o [c] | semmle.label | *o [c] | +| A.cpp:173:26:173:26 | *o [c] | semmle.label | *o [c] | | A.cpp:181:15:181:21 | newHead | semmle.label | newHead | | A.cpp:181:32:181:35 | *next [*next, head] | semmle.label | *next [*next, head] | | A.cpp:181:32:181:35 | *next [head] | semmle.label | *next [head] | @@ -964,9 +1006,11 @@ nodes | E.cpp:32:10:32:10 | *b [*buffer] | semmle.label | *b [*buffer] | | E.cpp:32:13:32:18 | *buffer | semmle.label | *buffer | | E.cpp:33:18:33:19 | *& ... [data, *buffer] | semmle.label | *& ... [data, *buffer] | +| aliasing.cpp:8:23:8:23 | *s [m1] | semmle.label | *s [m1] | | aliasing.cpp:9:3:9:3 | *s [post update] [m1] | semmle.label | *s [post update] [m1] | | aliasing.cpp:9:3:9:22 | ... = ... | semmle.label | ... = ... | | aliasing.cpp:9:11:9:20 | call to user_input | semmle.label | call to user_input | +| aliasing.cpp:12:25:12:25 | *s [m1] | semmle.label | *s [m1] | | aliasing.cpp:13:3:13:3 | *s [post update] [m1] | semmle.label | *s [post update] [m1] | | aliasing.cpp:13:3:13:21 | ... = ... | semmle.label | ... = ... | | aliasing.cpp:13:10:13:19 | call to user_input | semmle.label | call to user_input | @@ -1084,6 +1128,7 @@ nodes | arrays.cpp:50:10:50:17 | *indirect [*ptr, data] | semmle.label | *indirect [*ptr, data] | | arrays.cpp:50:20:50:22 | *ptr [data] | semmle.label | *ptr [data] | | arrays.cpp:50:27:50:30 | data | semmle.label | data | +| by_reference.cpp:11:39:11:39 | *s [a] | semmle.label | *s [a] | | by_reference.cpp:11:48:11:52 | value | semmle.label | value | | by_reference.cpp:12:5:12:5 | *s [post update] [a] | semmle.label | *s [post update] [a] | | by_reference.cpp:12:5:12:16 | ... = ... | semmle.label | ... = ... | @@ -1128,9 +1173,11 @@ nodes | by_reference.cpp:68:21:68:30 | call to user_input | semmle.label | call to user_input | | by_reference.cpp:69:8:69:20 | call to nonMemberGetA | semmle.label | call to nonMemberGetA | | by_reference.cpp:69:22:69:23 | *& ... [a] | semmle.label | *& ... [a] | +| by_reference.cpp:83:31:83:35 | *inner [a] | semmle.label | *inner [a] | | by_reference.cpp:84:3:84:7 | *inner [post update] [a] | semmle.label | *inner [post update] [a] | | by_reference.cpp:84:3:84:25 | ... = ... | semmle.label | ... = ... | | by_reference.cpp:84:14:84:23 | call to user_input | semmle.label | call to user_input | +| by_reference.cpp:87:31:87:35 | *inner [a] | semmle.label | *inner [a] | | by_reference.cpp:88:3:88:7 | *inner [post update] [a] | semmle.label | *inner [post update] [a] | | by_reference.cpp:88:3:88:24 | ... = ... | semmle.label | ... = ... | | by_reference.cpp:88:13:88:22 | call to user_input | semmle.label | call to user_input | @@ -1393,9 +1440,11 @@ nodes | qualifiers.cpp:9:21:9:25 | value | semmle.label | value | | qualifiers.cpp:9:30:9:33 | *this [post update] [a] | semmle.label | *this [post update] [a] | | qualifiers.cpp:9:30:9:44 | ... = ... | semmle.label | ... = ... | +| qualifiers.cpp:12:27:12:31 | *inner [a] | semmle.label | *inner [a] | | qualifiers.cpp:12:40:12:44 | value | semmle.label | value | | qualifiers.cpp:12:49:12:53 | *inner [post update] [a] | semmle.label | *inner [post update] [a] | | qualifiers.cpp:12:49:12:64 | ... = ... | semmle.label | ... = ... | +| qualifiers.cpp:13:29:13:33 | *inner [a] | semmle.label | *inner [a] | | qualifiers.cpp:13:42:13:46 | value | semmle.label | value | | qualifiers.cpp:13:51:13:55 | *inner [post update] [a] | semmle.label | *inner [post update] [a] | | qualifiers.cpp:13:51:13:65 | ... = ... | semmle.label | ... = ... | @@ -1507,6 +1556,7 @@ nodes | simple.cpp:108:17:108:26 | call to user_input | semmle.label | call to user_input | | simple.cpp:109:43:109:43 | x | semmle.label | x | | struct_init.c:14:24:14:25 | *ab [a] | semmle.label | *ab [a] | +| struct_init.c:14:24:14:25 | *ab [a] | semmle.label | *ab [a] | | struct_init.c:15:8:15:9 | *ab [a] | semmle.label | *ab [a] | | struct_init.c:15:12:15:12 | a | semmle.label | a | | struct_init.c:20:13:20:14 | *definition of ab [a] | semmle.label | *definition of ab [a] | @@ -1516,6 +1566,7 @@ nodes | struct_init.c:22:8:22:9 | *ab [a] | semmle.label | *ab [a] | | struct_init.c:22:11:22:11 | a | semmle.label | a | | struct_init.c:24:10:24:12 | *& ... [a] | semmle.label | *& ... [a] | +| struct_init.c:24:10:24:12 | absink output argument [a] | semmle.label | absink output argument [a] | | struct_init.c:26:16:26:20 | *definition of outer [nestedAB, a] | semmle.label | *definition of outer [nestedAB, a] | | struct_init.c:26:16:26:20 | *definition of outer [post update] [*pointerAB, a] | semmle.label | *definition of outer [post update] [*pointerAB, a] | | struct_init.c:26:16:26:20 | *definition of outer [post update] [nestedAB, a] | semmle.label | *definition of outer [post update] [nestedAB, a] | @@ -1552,6 +1603,7 @@ subpaths | A.cpp:90:15:90:15 | c | A.cpp:27:17:27:17 | c | A.cpp:27:22:27:25 | *this [post update] [c] | A.cpp:90:7:90:8 | set output argument [c] | | A.cpp:126:12:126:18 | new | A.cpp:27:17:27:17 | c | A.cpp:27:22:27:25 | *this [post update] [c] | A.cpp:126:5:126:5 | set output argument [c] | | A.cpp:151:18:151:18 | b | A.cpp:140:13:140:13 | b | A.cpp:143:7:143:10 | *this [post update] [b] | A.cpp:151:12:151:24 | call to D [b] | +| A.cpp:152:10:152:13 | *b [c] | A.cpp:173:26:173:26 | *o [c] | A.cpp:173:26:173:26 | *o [c] | A.cpp:152:10:152:13 | sink output argument [c] | | A.cpp:160:29:160:29 | b | A.cpp:181:15:181:21 | newHead | A.cpp:183:7:183:10 | *this [post update] [head] | A.cpp:160:18:160:60 | call to MyList [head] | | A.cpp:161:38:161:39 | *l1 [head] | A.cpp:181:32:181:35 | *next [head] | A.cpp:184:7:184:10 | *this [post update] [*next, head] | A.cpp:161:18:161:40 | call to MyList [*next, head] | | A.cpp:162:38:162:39 | *l2 [*next, head] | A.cpp:181:32:181:35 | *next [*next, head] | A.cpp:184:7:184:10 | *this [post update] [*next, *next, head] | A.cpp:162:18:162:40 | call to MyList [*next, *next, head] | @@ -1564,6 +1616,7 @@ subpaths | D.cpp:37:21:37:21 | e | D.cpp:11:24:11:24 | e | D.cpp:11:29:11:32 | *this [post update] [elem] | D.cpp:37:8:37:10 | setElem output argument [elem] | | D.cpp:51:27:51:27 | e | D.cpp:11:24:11:24 | e | D.cpp:11:29:11:32 | *this [post update] [elem] | D.cpp:51:8:51:14 | setElem output argument [elem] | | by_reference.cpp:20:23:20:27 | value | by_reference.cpp:15:26:15:30 | value | by_reference.cpp:16:5:16:8 | *this [post update] [a] | by_reference.cpp:20:5:20:8 | setDirectly output argument [a] | +| by_reference.cpp:24:25:24:29 | value | by_reference.cpp:11:48:11:52 | value | by_reference.cpp:11:39:11:39 | *s [a] | by_reference.cpp:24:19:24:22 | nonMemberSetA output argument [a] | | by_reference.cpp:24:25:24:29 | value | by_reference.cpp:11:48:11:52 | value | by_reference.cpp:12:5:12:5 | *s [post update] [a] | by_reference.cpp:24:19:24:22 | nonMemberSetA output argument [a] | | by_reference.cpp:40:12:40:15 | *this [a] | by_reference.cpp:35:9:35:19 | *this [a] | by_reference.cpp:35:9:35:19 | *getDirectly | by_reference.cpp:40:18:40:28 | call to getDirectly | | by_reference.cpp:44:26:44:29 | *this [a] | by_reference.cpp:31:46:31:46 | *s [a] | by_reference.cpp:31:16:31:28 | *nonMemberGetA | by_reference.cpp:44:12:44:24 | call to nonMemberGetA | @@ -1573,6 +1626,7 @@ subpaths | by_reference.cpp:57:8:57:8 | *s [a] | by_reference.cpp:39:9:39:21 | *this [a] | by_reference.cpp:39:9:39:21 | *getIndirectly | by_reference.cpp:57:10:57:22 | call to getIndirectly | | by_reference.cpp:62:25:62:34 | call to user_input | by_reference.cpp:23:34:23:38 | value | by_reference.cpp:24:19:24:22 | nonMemberSetA output argument [a] | by_reference.cpp:62:3:62:3 | setThroughNonMember output argument [a] | | by_reference.cpp:63:8:63:8 | *s [a] | by_reference.cpp:43:9:43:27 | *this [a] | by_reference.cpp:43:9:43:27 | *getThroughNonMember | by_reference.cpp:63:10:63:28 | call to getThroughNonMember | +| by_reference.cpp:68:21:68:30 | call to user_input | by_reference.cpp:11:48:11:52 | value | by_reference.cpp:11:39:11:39 | *s [a] | by_reference.cpp:68:17:68:18 | nonMemberSetA output argument [a] | | by_reference.cpp:68:21:68:30 | call to user_input | by_reference.cpp:11:48:11:52 | value | by_reference.cpp:12:5:12:5 | *s [post update] [a] | by_reference.cpp:68:17:68:18 | nonMemberSetA output argument [a] | | by_reference.cpp:69:22:69:23 | *& ... [a] | by_reference.cpp:31:46:31:46 | *s [a] | by_reference.cpp:31:16:31:28 | *nonMemberGetA | by_reference.cpp:69:8:69:20 | call to nonMemberGetA | | complex.cpp:42:16:42:16 | *f [a_] | complex.cpp:9:7:9:7 | *this [a_] | complex.cpp:9:7:9:7 | *a | complex.cpp:42:18:42:18 | call to a | @@ -1588,7 +1642,9 @@ subpaths | constructors.cpp:36:11:36:20 | call to user_input | constructors.cpp:23:13:23:13 | a | constructors.cpp:23:5:23:7 | *this [post update] [a_] | constructors.cpp:36:9:36:9 | call to Foo [a_] | | constructors.cpp:36:25:36:34 | call to user_input | constructors.cpp:23:20:23:20 | b | constructors.cpp:23:5:23:7 | *this [post update] [b_] | constructors.cpp:36:9:36:9 | call to Foo [b_] | | qualifiers.cpp:27:28:27:37 | call to user_input | qualifiers.cpp:9:21:9:25 | value | qualifiers.cpp:9:30:9:33 | *this [post update] [a] | qualifiers.cpp:27:11:27:18 | setA output argument [a] | +| qualifiers.cpp:32:35:32:44 | call to user_input | qualifiers.cpp:12:40:12:44 | value | qualifiers.cpp:12:27:12:31 | *inner [a] | qualifiers.cpp:32:23:32:30 | pointerSetA output argument [a] | | qualifiers.cpp:32:35:32:44 | call to user_input | qualifiers.cpp:12:40:12:44 | value | qualifiers.cpp:12:49:12:53 | *inner [post update] [a] | qualifiers.cpp:32:23:32:30 | pointerSetA output argument [a] | +| qualifiers.cpp:37:38:37:47 | call to user_input | qualifiers.cpp:13:42:13:46 | value | qualifiers.cpp:13:29:13:33 | *inner [a] | qualifiers.cpp:37:19:37:35 | referenceSetA output argument [a] | | qualifiers.cpp:37:38:37:47 | call to user_input | qualifiers.cpp:13:42:13:46 | value | qualifiers.cpp:13:51:13:55 | *inner [post update] [a] | qualifiers.cpp:37:19:37:35 | referenceSetA output argument [a] | | simple.cpp:28:10:28:10 | *f [a_] | simple.cpp:18:9:18:9 | *this [a_] | simple.cpp:18:9:18:9 | *a | simple.cpp:28:12:28:12 | call to a | | simple.cpp:29:10:29:10 | *f [b_] | simple.cpp:19:9:19:9 | *this [b_] | simple.cpp:19:9:19:9 | *b | simple.cpp:29:12:29:12 | call to b | @@ -1597,6 +1653,7 @@ subpaths | simple.cpp:41:12:41:21 | call to user_input | simple.cpp:20:19:20:19 | a | simple.cpp:20:24:20:25 | *this [post update] [a_] | simple.cpp:41:5:41:5 | setA output argument [a_] | | simple.cpp:42:12:42:21 | call to user_input | simple.cpp:21:19:21:19 | b | simple.cpp:21:24:21:25 | *this [post update] [b_] | simple.cpp:42:5:42:5 | setB output argument [b_] | | simple.cpp:84:14:84:20 | *this [f2, f1] | simple.cpp:78:9:78:15 | *this [f2, f1] | simple.cpp:78:9:78:15 | *getf2f1 | simple.cpp:84:14:84:20 | call to getf2f1 | +| struct_init.c:24:10:24:12 | *& ... [a] | struct_init.c:14:24:14:25 | *ab [a] | struct_init.c:14:24:14:25 | *ab [a] | struct_init.c:24:10:24:12 | absink output argument [a] | #select | A.cpp:43:10:43:12 | *& ... | A.cpp:41:15:41:21 | new | A.cpp:43:10:43:12 | *& ... | *& ... flows from $@ | A.cpp:41:15:41:21 | new | new | | A.cpp:49:10:49:13 | c | A.cpp:47:12:47:18 | new | A.cpp:49:10:49:13 | c | c flows from $@ | A.cpp:47:12:47:18 | new | new | diff --git a/cpp/ql/test/library-tests/dataflow/taint-tests/localTaint.expected b/cpp/ql/test/library-tests/dataflow/taint-tests/localTaint.expected index cebf91d6f593..54fd7cd8883c 100644 --- a/cpp/ql/test/library-tests/dataflow/taint-tests/localTaint.expected +++ b/cpp/ql/test/library-tests/dataflow/taint-tests/localTaint.expected @@ -6490,6 +6490,7 @@ WARNING: Module TaintTracking has been deprecated and may be removed in future ( | taint.cpp:607:10:607:16 | call to _strinc | taint.cpp:609:8:609:12 | dest1 | | | taint.cpp:607:18:607:23 | source | taint.cpp:607:10:607:16 | call to _strinc | TAINT | | taint.cpp:607:26:607:31 | locale | taint.cpp:607:10:607:16 | call to _strinc | TAINT | +| taint.cpp:607:26:607:31 | locale | taint.cpp:607:26:607:31 | ref arg locale | TAINT | | taint.cpp:607:26:607:31 | ref arg locale | taint.cpp:606:82:606:87 | locale | | | taint.cpp:607:26:607:31 | ref arg locale | taint.cpp:611:25:611:30 | locale | | | taint.cpp:608:7:608:11 | ref arg dest1 | taint.cpp:606:52:606:56 | dest1 | | @@ -6501,6 +6502,7 @@ WARNING: Module TaintTracking has been deprecated and may be removed in future ( | taint.cpp:611:10:611:16 | call to _strinc | taint.cpp:613:8:613:12 | dest2 | | | taint.cpp:611:18:611:22 | clean | taint.cpp:611:10:611:16 | call to _strinc | TAINT | | taint.cpp:611:25:611:30 | locale | taint.cpp:611:10:611:16 | call to _strinc | TAINT | +| taint.cpp:611:25:611:30 | locale | taint.cpp:611:25:611:30 | ref arg locale | TAINT | | taint.cpp:611:25:611:30 | ref arg locale | taint.cpp:606:82:606:87 | locale | | | taint.cpp:612:7:612:11 | ref arg dest2 | taint.cpp:606:65:606:69 | dest2 | | | taint.cpp:612:7:612:11 | ref arg dest2 | taint.cpp:613:8:613:12 | dest2 | | @@ -6657,6 +6659,23 @@ WARNING: Module TaintTracking has been deprecated and may be removed in future ( | taint.cpp:745:27:745:32 | buffer | taint.cpp:745:19:745:25 | call to realloc | TAINT | | taint.cpp:746:9:746:15 | * ... | taint.cpp:746:8:746:15 | * ... | TAINT | | taint.cpp:746:10:746:15 | buffer | taint.cpp:746:9:746:15 | * ... | TAINT | +| taint.cpp:751:31:751:34 | path | taint.cpp:751:31:751:34 | path | | +| taint.cpp:751:31:751:34 | path | taint.cpp:752:10:752:13 | path | | +| taint.cpp:751:31:751:34 | path | taint.cpp:753:10:753:13 | path | | +| taint.cpp:751:43:751:46 | data | taint.cpp:751:43:751:46 | data | | +| taint.cpp:751:43:751:46 | data | taint.cpp:753:22:753:25 | data | | +| taint.cpp:752:10:752:13 | ref arg path | taint.cpp:751:31:751:34 | path | | +| taint.cpp:752:10:752:13 | ref arg path | taint.cpp:753:10:753:13 | path | | +| taint.cpp:752:16:752:19 | %s | taint.cpp:752:10:752:13 | ref arg path | TAINT | +| taint.cpp:752:22:752:26 | abc | taint.cpp:752:10:752:13 | ref arg path | TAINT | +| taint.cpp:753:10:753:13 | ref arg path | taint.cpp:751:31:751:34 | path | | +| taint.cpp:753:16:753:19 | %s | taint.cpp:753:10:753:13 | ref arg path | TAINT | +| taint.cpp:753:22:753:25 | data | taint.cpp:753:10:753:13 | ref arg path | TAINT | +| taint.cpp:753:22:753:25 | ref arg data | taint.cpp:751:43:751:46 | data | | +| taint.cpp:757:7:757:10 | path | taint.cpp:758:21:758:24 | path | | +| taint.cpp:757:7:757:10 | path | taint.cpp:759:8:759:11 | path | | +| taint.cpp:758:21:758:24 | ref arg path | taint.cpp:759:8:759:11 | path | | +| taint.cpp:759:8:759:11 | path | taint.cpp:759:7:759:11 | * ... | | | vector.cpp:16:43:16:49 | source1 | vector.cpp:17:26:17:32 | source1 | | | vector.cpp:16:43:16:49 | source1 | vector.cpp:31:38:31:44 | source1 | | | vector.cpp:17:21:17:33 | call to vector | vector.cpp:19:14:19:14 | v | | diff --git a/cpp/ql/test/library-tests/dataflow/taint-tests/map.cpp b/cpp/ql/test/library-tests/dataflow/taint-tests/map.cpp index 8eeb80a0f83e..555f39779bf2 100644 --- a/cpp/ql/test/library-tests/dataflow/taint-tests/map.cpp +++ b/cpp/ql/test/library-tests/dataflow/taint-tests/map.cpp @@ -71,11 +71,11 @@ void test_pair() sink(i.second); // $ MISSING: ast,ir sink(i); // $ ast,ir sink(j.first); - sink(j.second); // $ SPURIOUS: ast,ir - sink(j); // $ SPURIOUS: ast,ir + sink(j.second); // $ SPURIOUS: ast + sink(j); // $ SPURIOUS: ast sink(k.first); - sink(k.second); // $ SPURIOUS: ast,ir - sink(k); // $ SPURIOUS: ast,ir + sink(k.second); // $ SPURIOUS: ast + sink(k); // $ SPURIOUS: ast sink(l.first); sink(l.second); // $ MISSING: ast,ir sink(l); // $ ast,ir @@ -196,10 +196,10 @@ void test_map() sink(m18); // $ ast,ir m15.swap(m16); m17.swap(m18); - sink(m15); // $ SPURIOUS: ast,ir + sink(m15); // $ SPURIOUS: ast sink(m16); // $ ast,ir sink(m17); // $ ast,ir - sink(m18); // $ SPURIOUS: ast,ir + sink(m18); // $ SPURIOUS: ast // merge std::map m19, m20, m21, m22; @@ -345,10 +345,10 @@ void test_unordered_map() sink(m18); // $ ast,ir m15.swap(m16); m17.swap(m18); - sink(m15); // $ SPURIOUS: ast,ir + sink(m15); // $ SPURIOUS: ast sink(m16); // $ ast,ir sink(m17); // $ ast,ir - sink(m18); // $ SPURIOUS: ast,ir + sink(m18); // $ SPURIOUS: ast // merge std::unordered_map m19, m20, m21, m22; diff --git a/cpp/ql/test/library-tests/dataflow/taint-tests/set.cpp b/cpp/ql/test/library-tests/dataflow/taint-tests/set.cpp index c6c19d90089b..7c906fb72d21 100644 --- a/cpp/ql/test/library-tests/dataflow/taint-tests/set.cpp +++ b/cpp/ql/test/library-tests/dataflow/taint-tests/set.cpp @@ -81,10 +81,10 @@ void test_set() sink(s15); // $ ast,ir s12.swap(s13); s14.swap(s15); - sink(s12); // $ SPURIOUS: ast,ir + sink(s12); // $ SPURIOUS: ast sink(s13); // $ ast,ir sink(s14); // $ ast,ir - sink(s15); // $ SPURIOUS: ast,ir + sink(s15); // $ SPURIOUS: ast // merge std::set s16, s17, s18, s19; @@ -193,10 +193,10 @@ void test_unordered_set() sink(s15); // $ ast,ir s12.swap(s13); s14.swap(s15); - sink(s12); // $ SPURIOUS: ast,ir + sink(s12); // $ SPURIOUS: ast sink(s13); // $ ast,ir sink(s14); // $ ast,ir - sink(s15); // $ SPURIOUS: ast,ir + sink(s15); // $ SPURIOUS: ast // merge std::unordered_set s16, s17, s18, s19; diff --git a/cpp/ql/test/library-tests/dataflow/taint-tests/string.cpp b/cpp/ql/test/library-tests/dataflow/taint-tests/string.cpp index e2b99945724a..dc92a0664be4 100644 --- a/cpp/ql/test/library-tests/dataflow/taint-tests/string.cpp +++ b/cpp/ql/test/library-tests/dataflow/taint-tests/string.cpp @@ -203,7 +203,7 @@ void test_string_assign() { sink(s5); // $ ast,ir sink(s6.assign(s1)); - sink(s6); // $ SPURIOUS: ast,ir + sink(s6); // $ SPURIOUS: ast } void test_string_insert() { @@ -280,9 +280,9 @@ void test_string_swap() { s4.swap(s3); sink(s1); // $ ast,ir - sink(s2); // $ SPURIOUS: ast,ir + sink(s2); // $ SPURIOUS: ast sink(s3); // $ ast,ir - sink(s4); // $ SPURIOUS: ast,ir + sink(s4); // $ SPURIOUS: ast } void test_string_clear() { @@ -495,7 +495,7 @@ void test_string_iterator_methods() sink(h); // $ ast,ir sink(s6.assign(s5.cbegin(), s5.cend())); - sink(s6); // $ SPURIOUS: ast,ir + sink(s6); // $ SPURIOUS: ast } } diff --git a/cpp/ql/test/library-tests/dataflow/taint-tests/stringstream.cpp b/cpp/ql/test/library-tests/dataflow/taint-tests/stringstream.cpp index a84b3606f922..ca17fb4b3e71 100644 --- a/cpp/ql/test/library-tests/dataflow/taint-tests/stringstream.cpp +++ b/cpp/ql/test/library-tests/dataflow/taint-tests/stringstream.cpp @@ -50,7 +50,7 @@ void test_stringstream_string(int amount) ss7.str(source()); ss7.str("abc"); // (overwrites) sink(ss6); // $ ast,ir - sink(ss7); // $ SPURIOUS: ast,ir + sink(ss7); // $ SPURIOUS: ast sink(ss8.put('a')); sink(ss9.put(ns_char::source())); // $ ast,ir @@ -118,9 +118,9 @@ void test_stringstream_swap() ss4.swap(ss3); sink(ss1); // $ ast,ir - sink(ss2); // $ SPURIOUS: ast,ir + sink(ss2); // $ SPURIOUS: ast sink(ss3); // $ ast,ir - sink(ss4); // $ SPURIOUS: ast,ir + sink(ss4); // $ SPURIOUS: ast } void test_stringstream_in() @@ -217,7 +217,7 @@ void test_getline() sink(ss1.getline(b3, 1000)); sink(b1); sink(b2); // $ ast,ir - sink(b3); // $ SPURIOUS: ast,ir + sink(b3); // $ SPURIOUS: ast sink(ss1.getline(b4, 1000, ' ')); sink(ss2.getline(b5, 1000, ' ')); // $ ast,ir @@ -225,7 +225,7 @@ void test_getline() sink(ss1.getline(b6, 1000, ' ')); sink(b4); sink(b5); // $ ast,ir - sink(b6); // $ SPURIOUS: ast,ir + sink(b6); // $ SPURIOUS: ast sink(ss2.getline(b7, 1000).getline(b8, 1000)); // $ ast,ir sink(b7); // $ ast,ir @@ -237,7 +237,7 @@ void test_getline() sink(getline(ss1, s3)); sink(s1); sink(s2); // $ ast,ir - sink(s3); // $ SPURIOUS: ast,ir + sink(s3); // $ SPURIOUS: ast sink(getline(ss1, s4, ' ')); sink(getline(ss2, s5, ' ')); // $ ast,ir @@ -245,7 +245,7 @@ void test_getline() sink(getline(ss1, s6, ' ')); sink(s4); sink(s5); // $ ast,ir - sink(s6); // $ SPURIOUS: ast,ir + sink(s6); // $ SPURIOUS: ast sink(getline(getline(ss2, s7), s8)); // $ ast,ir sink(s7); // $ ast,ir diff --git a/cpp/ql/test/library-tests/dataflow/taint-tests/taint.cpp b/cpp/ql/test/library-tests/dataflow/taint-tests/taint.cpp index eeefa6dd427b..0ba45b6f30ab 100644 --- a/cpp/ql/test/library-tests/dataflow/taint-tests/taint.cpp +++ b/cpp/ql/test/library-tests/dataflow/taint-tests/taint.cpp @@ -212,7 +212,7 @@ void test_swap() { std::swap(x, y); - sink(x); // $ SPURIOUS: ast,ir + sink(x); // $ SPURIOUS: ast sink(y); // $ ast,ir } @@ -744,4 +744,17 @@ void test_realloc_2_indirections(int **buffer) { **buffer = source(); buffer = (int**)realloc(buffer, 16); sink(**buffer); // $ ir MISSING: ast +} + +int sprintf(char *, const char *, ...); + +void call_sprintf_twice(char* path, char* data) { + sprintf(path, "%s", "abc"); + sprintf(path, "%s", data); +} + +void test_call_sprintf() { + char path[10]; + call_sprintf_twice(path, indirect_source()); + sink(*path); // $ ast,ir } \ No newline at end of file diff --git a/cpp/ql/test/library-tests/dataflow/taint-tests/vector.cpp b/cpp/ql/test/library-tests/dataflow/taint-tests/vector.cpp index a26ac8f05132..2728be23e2ef 100644 --- a/cpp/ql/test/library-tests/dataflow/taint-tests/vector.cpp +++ b/cpp/ql/test/library-tests/dataflow/taint-tests/vector.cpp @@ -114,10 +114,10 @@ void test_vector_swap() { v1.swap(v2); v3.swap(v4); - sink(v1); // $ SPURIOUS: ast,ir + sink(v1); // $ SPURIOUS: ast sink(v2); // $ ast,ir sink(v3); // $ ast,ir - sink(v4); // $ SPURIOUS: ast,ir + sink(v4); // $ SPURIOUS: ast } void test_vector_clear() { @@ -138,7 +138,7 @@ void test_vector_clear() { sink(v1); // $ SPURIOUS: ast,ir sink(v2); // $ ast,ir - sink(v3); // $ ast,ir + sink(v3); // $ SPURIOUS: ast sink(v4); } diff --git a/cpp/ql/test/query-tests/Security/CWE/CWE-078/semmle/ExecTainted/ExecTainted.expected b/cpp/ql/test/query-tests/Security/CWE/CWE-078/semmle/ExecTainted/ExecTainted.expected index d50edce5f2fa..a52bd778a04f 100644 --- a/cpp/ql/test/query-tests/Security/CWE/CWE-078/semmle/ExecTainted/ExecTainted.expected +++ b/cpp/ql/test/query-tests/Security/CWE/CWE-078/semmle/ExecTainted/ExecTainted.expected @@ -46,6 +46,8 @@ edges | test.cpp:187:11:187:15 | strncat output argument | test.cpp:188:20:188:24 | *flags | provenance | | | test.cpp:187:18:187:25 | *filename | test.cpp:187:11:187:15 | strncat output argument | provenance | | | test.cpp:187:18:187:25 | *filename | test.cpp:187:11:187:15 | strncat output argument | provenance | | +| test.cpp:188:11:188:17 | strncat output argument | test.cpp:186:19:186:25 | *command | provenance | | +| test.cpp:188:11:188:17 | strncat output argument | test.cpp:186:19:186:25 | *command | provenance | | | test.cpp:188:20:188:24 | *flags | test.cpp:188:11:188:17 | strncat output argument | provenance | | | test.cpp:188:20:188:24 | *flags | test.cpp:188:11:188:17 | strncat output argument | provenance | | | test.cpp:194:9:194:16 | fread output argument | test.cpp:196:26:196:33 | *filename | provenance | | @@ -57,9 +59,6 @@ edges | test.cpp:218:9:218:16 | fread output argument | test.cpp:220:19:220:26 | *filename | provenance | | | test.cpp:220:10:220:16 | strncat output argument | test.cpp:220:10:220:16 | strncat output argument | provenance | | | test.cpp:220:10:220:16 | strncat output argument | test.cpp:220:10:220:16 | strncat output argument | provenance | | -| test.cpp:220:10:220:16 | strncat output argument | test.cpp:220:10:220:16 | strncat output argument | provenance | | -| test.cpp:220:10:220:16 | strncat output argument | test.cpp:222:32:222:38 | *command | provenance | | -| test.cpp:220:10:220:16 | strncat output argument | test.cpp:222:32:222:38 | *command | provenance | | | test.cpp:220:10:220:16 | strncat output argument | test.cpp:222:32:222:38 | *command | provenance | | | test.cpp:220:10:220:16 | strncat output argument | test.cpp:222:32:222:38 | *command | provenance | | | test.cpp:220:19:220:26 | *filename | test.cpp:220:10:220:16 | strncat output argument | provenance | | @@ -118,6 +117,8 @@ nodes | test.cpp:183:32:183:38 | *command | semmle.label | *command | | test.cpp:183:32:183:38 | *command | semmle.label | *command | | test.cpp:183:32:183:38 | *command | semmle.label | *command | +| test.cpp:186:19:186:25 | *command | semmle.label | *command | +| test.cpp:186:19:186:25 | *command | semmle.label | *command | | test.cpp:186:47:186:54 | *filename | semmle.label | *filename | | test.cpp:187:11:187:15 | strncat output argument | semmle.label | strncat output argument | | test.cpp:187:11:187:15 | strncat output argument | semmle.label | strncat output argument | @@ -142,6 +143,8 @@ nodes | test.cpp:222:32:222:38 | *command | semmle.label | *command | | test.cpp:222:32:222:38 | *command | semmle.label | *command | subpaths +| test.cpp:196:26:196:33 | *filename | test.cpp:186:47:186:54 | *filename | test.cpp:186:19:186:25 | *command | test.cpp:196:10:196:16 | concat output argument | +| test.cpp:196:26:196:33 | *filename | test.cpp:186:47:186:54 | *filename | test.cpp:186:19:186:25 | *command | test.cpp:196:10:196:16 | concat output argument | | test.cpp:196:26:196:33 | *filename | test.cpp:186:47:186:54 | *filename | test.cpp:188:11:188:17 | strncat output argument | test.cpp:196:10:196:16 | concat output argument | | test.cpp:196:26:196:33 | *filename | test.cpp:186:47:186:54 | *filename | test.cpp:188:11:188:17 | strncat output argument | test.cpp:196:10:196:16 | concat output argument | #select diff --git a/cpp/ql/test/query-tests/Security/CWE/CWE-119/SAMATE/OverrunWriteProductFlow.expected b/cpp/ql/test/query-tests/Security/CWE/CWE-119/SAMATE/OverrunWriteProductFlow.expected index 21e6445c8fd1..db6712b11d34 100644 --- a/cpp/ql/test/query-tests/Security/CWE/CWE-119/SAMATE/OverrunWriteProductFlow.expected +++ b/cpp/ql/test/query-tests/Security/CWE/CWE-119/SAMATE/OverrunWriteProductFlow.expected @@ -47,6 +47,7 @@ edges | test.cpp:222:15:222:20 | buffer | test.cpp:214:24:214:24 | p | provenance | | | test.cpp:228:27:228:54 | call to malloc | test.cpp:232:10:232:15 | buffer | provenance | | | test.cpp:235:40:235:45 | buffer | test.cpp:236:5:236:26 | ... = ... | provenance | | +| test.cpp:236:5:236:9 | *p_str [post update] [string] | test.cpp:235:27:235:31 | *p_str [string] | provenance | | | test.cpp:236:5:236:26 | ... = ... | test.cpp:236:5:236:9 | *p_str [post update] [string] | provenance | | | test.cpp:241:20:241:38 | call to malloc | test.cpp:242:22:242:27 | buffer | provenance | | | test.cpp:242:16:242:19 | set_string output argument [string] | test.cpp:243:12:243:14 | *str [string] | provenance | | @@ -110,6 +111,7 @@ nodes | test.cpp:222:15:222:20 | buffer | semmle.label | buffer | | test.cpp:228:27:228:54 | call to malloc | semmle.label | call to malloc | | test.cpp:232:10:232:15 | buffer | semmle.label | buffer | +| test.cpp:235:27:235:31 | *p_str [string] | semmle.label | *p_str [string] | | test.cpp:235:40:235:45 | buffer | semmle.label | buffer | | test.cpp:236:5:236:9 | *p_str [post update] [string] | semmle.label | *p_str [post update] [string] | | test.cpp:236:5:236:26 | ... = ... | semmle.label | ... = ... | @@ -126,6 +128,7 @@ nodes | test.cpp:264:13:264:30 | call to malloc | semmle.label | call to malloc | | test.cpp:266:12:266:12 | p | semmle.label | p | subpaths +| test.cpp:242:22:242:27 | buffer | test.cpp:235:40:235:45 | buffer | test.cpp:235:27:235:31 | *p_str [string] | test.cpp:242:16:242:19 | set_string output argument [string] | | test.cpp:242:22:242:27 | buffer | test.cpp:235:40:235:45 | buffer | test.cpp:236:5:236:9 | *p_str [post update] [string] | test.cpp:242:16:242:19 | set_string output argument [string] | #select | test.cpp:42:5:42:11 | call to strncpy | test.cpp:18:19:18:24 | call to malloc | test.cpp:42:18:42:23 | string | This write may overflow $@ by 1 element. | test.cpp:42:18:42:23 | string | string | diff --git a/cpp/ql/test/query-tests/Security/CWE/CWE-119/semmle/tests/OverflowDestination.expected b/cpp/ql/test/query-tests/Security/CWE/CWE-119/semmle/tests/OverflowDestination.expected index fa6e1c36b538..b3eb5bbca978 100644 --- a/cpp/ql/test/query-tests/Security/CWE/CWE-119/semmle/tests/OverflowDestination.expected +++ b/cpp/ql/test/query-tests/Security/CWE/CWE-119/semmle/tests/OverflowDestination.expected @@ -3,11 +3,14 @@ edges | main.cpp:7:33:7:36 | **argv | overflowdestination.cpp:23:45:23:48 | **argv | provenance | | | overflowdestination.cpp:23:45:23:48 | **argv | overflowdestination.cpp:30:17:30:20 | *arg1 | provenance | | | overflowdestination.cpp:43:8:43:10 | fgets output argument | overflowdestination.cpp:46:15:46:17 | *src | provenance | | +| overflowdestination.cpp:50:52:50:54 | *src | overflowdestination.cpp:50:52:50:54 | *src | provenance | | | overflowdestination.cpp:50:52:50:54 | *src | overflowdestination.cpp:53:15:53:17 | *src | provenance | | | overflowdestination.cpp:57:52:57:54 | *src | overflowdestination.cpp:64:16:64:19 | *src2 | provenance | | | overflowdestination.cpp:73:8:73:10 | fgets output argument | overflowdestination.cpp:75:30:75:32 | *src | provenance | | | overflowdestination.cpp:73:8:73:10 | fgets output argument | overflowdestination.cpp:76:30:76:32 | *src | provenance | | | overflowdestination.cpp:75:30:75:32 | *src | overflowdestination.cpp:50:52:50:54 | *src | provenance | | +| overflowdestination.cpp:75:30:75:32 | *src | overflowdestination.cpp:75:30:75:32 | overflowdest_test2 output argument | provenance | | +| overflowdestination.cpp:75:30:75:32 | overflowdest_test2 output argument | overflowdestination.cpp:76:30:76:32 | *src | provenance | | | overflowdestination.cpp:76:30:76:32 | *src | overflowdestination.cpp:57:52:57:54 | *src | provenance | | nodes | main.cpp:6:27:6:30 | **argv | semmle.label | **argv | @@ -17,13 +20,16 @@ nodes | overflowdestination.cpp:43:8:43:10 | fgets output argument | semmle.label | fgets output argument | | overflowdestination.cpp:46:15:46:17 | *src | semmle.label | *src | | overflowdestination.cpp:50:52:50:54 | *src | semmle.label | *src | +| overflowdestination.cpp:50:52:50:54 | *src | semmle.label | *src | | overflowdestination.cpp:53:15:53:17 | *src | semmle.label | *src | | overflowdestination.cpp:57:52:57:54 | *src | semmle.label | *src | | overflowdestination.cpp:64:16:64:19 | *src2 | semmle.label | *src2 | | overflowdestination.cpp:73:8:73:10 | fgets output argument | semmle.label | fgets output argument | | overflowdestination.cpp:75:30:75:32 | *src | semmle.label | *src | +| overflowdestination.cpp:75:30:75:32 | overflowdest_test2 output argument | semmle.label | overflowdest_test2 output argument | | overflowdestination.cpp:76:30:76:32 | *src | semmle.label | *src | subpaths +| overflowdestination.cpp:75:30:75:32 | *src | overflowdestination.cpp:50:52:50:54 | *src | overflowdestination.cpp:50:52:50:54 | *src | overflowdestination.cpp:75:30:75:32 | overflowdest_test2 output argument | #select | overflowdestination.cpp:30:2:30:8 | call to strncpy | main.cpp:6:27:6:30 | **argv | overflowdestination.cpp:30:17:30:20 | *arg1 | To avoid overflow, this operation should be bounded by destination-buffer size, not source-buffer size. | | overflowdestination.cpp:46:2:46:7 | call to memcpy | overflowdestination.cpp:43:8:43:10 | fgets output argument | overflowdestination.cpp:46:15:46:17 | *src | To avoid overflow, this operation should be bounded by destination-buffer size, not source-buffer size. | diff --git a/cpp/ql/test/query-tests/Security/CWE/CWE-119/semmle/tests/UnboundedWrite.expected b/cpp/ql/test/query-tests/Security/CWE/CWE-119/semmle/tests/UnboundedWrite.expected index c5cfefdbff07..cde0ba8bc754 100644 --- a/cpp/ql/test/query-tests/Security/CWE/CWE-119/semmle/tests/UnboundedWrite.expected +++ b/cpp/ql/test/query-tests/Security/CWE/CWE-119/semmle/tests/UnboundedWrite.expected @@ -1,6 +1,44 @@ edges +| main.cpp:6:27:6:30 | **argv | main.cpp:7:33:7:36 | **argv | provenance | | +| main.cpp:6:27:6:30 | **argv | main.cpp:8:34:8:37 | **argv | provenance | | +| main.cpp:6:27:6:30 | **argv | main.cpp:9:29:9:32 | **argv | provenance | | | main.cpp:6:27:6:30 | **argv | main.cpp:10:20:10:23 | **argv | provenance | | +| main.cpp:7:33:7:36 | **argv | main.cpp:7:33:7:36 | overflowdesination_main output argument | provenance | | +| main.cpp:7:33:7:36 | **argv | main.cpp:7:33:7:36 | overflowdesination_main output argument | provenance | | +| main.cpp:7:33:7:36 | **argv | overflowdestination.cpp:23:45:23:48 | **argv | provenance | | +| main.cpp:7:33:7:36 | overflowdesination_main output argument | main.cpp:8:34:8:37 | **argv | provenance | | +| main.cpp:7:33:7:36 | overflowdesination_main output argument | main.cpp:8:34:8:37 | *argv | provenance | | +| main.cpp:7:33:7:36 | overflowdesination_main output argument | main.cpp:9:29:9:32 | **argv | provenance | | +| main.cpp:7:33:7:36 | overflowdesination_main output argument | main.cpp:9:29:9:32 | *argv | provenance | | +| main.cpp:7:33:7:36 | overflowdesination_main output argument | main.cpp:10:20:10:23 | **argv | provenance | | +| main.cpp:7:33:7:36 | overflowdesination_main output argument | main.cpp:10:20:10:23 | *argv | provenance | | +| main.cpp:8:34:8:37 | **argv | main.cpp:8:34:8:37 | test_buffer_overrun_main output argument | provenance | | +| main.cpp:8:34:8:37 | **argv | main.cpp:8:34:8:37 | test_buffer_overrun_main output argument | provenance | | +| main.cpp:8:34:8:37 | **argv | test_buffer_overrun.cpp:32:46:32:49 | **argv | provenance | | +| main.cpp:8:34:8:37 | *argv | main.cpp:8:34:8:37 | test_buffer_overrun_main output argument | provenance | | +| main.cpp:8:34:8:37 | *argv | main.cpp:8:34:8:37 | test_buffer_overrun_main output argument | provenance | | +| main.cpp:8:34:8:37 | *argv | test_buffer_overrun.cpp:32:46:32:49 | **argv | provenance | | +| main.cpp:8:34:8:37 | *argv | test_buffer_overrun.cpp:32:46:32:49 | *argv | provenance | | +| main.cpp:8:34:8:37 | test_buffer_overrun_main output argument | main.cpp:9:29:9:32 | **argv | provenance | | +| main.cpp:8:34:8:37 | test_buffer_overrun_main output argument | main.cpp:9:29:9:32 | *argv | provenance | | +| main.cpp:8:34:8:37 | test_buffer_overrun_main output argument | main.cpp:10:20:10:23 | **argv | provenance | | +| main.cpp:8:34:8:37 | test_buffer_overrun_main output argument | main.cpp:10:20:10:23 | *argv | provenance | | +| main.cpp:9:29:9:32 | **argv | main.cpp:9:29:9:32 | tests_restrict_main output argument | provenance | | +| main.cpp:9:29:9:32 | **argv | tests_restrict.c:15:41:15:44 | **argv | provenance | | +| main.cpp:9:29:9:32 | *argv | main.cpp:9:29:9:32 | tests_restrict_main output argument | provenance | | +| main.cpp:9:29:9:32 | *argv | main.cpp:9:29:9:32 | tests_restrict_main output argument | provenance | | +| main.cpp:9:29:9:32 | *argv | tests_restrict.c:15:41:15:44 | **argv | provenance | | +| main.cpp:9:29:9:32 | *argv | tests_restrict.c:15:41:15:44 | *argv | provenance | | +| main.cpp:9:29:9:32 | tests_restrict_main output argument | main.cpp:10:20:10:23 | **argv | provenance | | +| main.cpp:9:29:9:32 | tests_restrict_main output argument | main.cpp:10:20:10:23 | *argv | provenance | | | main.cpp:10:20:10:23 | **argv | tests.cpp:657:32:657:35 | **argv | provenance | | +| main.cpp:10:20:10:23 | *argv | tests.cpp:657:32:657:35 | **argv | provenance | | +| main.cpp:10:20:10:23 | *argv | tests.cpp:657:32:657:35 | *argv | provenance | | +| overflowdestination.cpp:23:45:23:48 | **argv | overflowdestination.cpp:23:45:23:48 | **argv | provenance | | +| overflowdestination.cpp:23:45:23:48 | **argv | overflowdestination.cpp:23:45:23:48 | *argv | provenance | | +| test_buffer_overrun.cpp:32:46:32:49 | **argv | test_buffer_overrun.cpp:32:46:32:49 | **argv | provenance | | +| test_buffer_overrun.cpp:32:46:32:49 | **argv | test_buffer_overrun.cpp:32:46:32:49 | *argv | provenance | | +| test_buffer_overrun.cpp:32:46:32:49 | *argv | test_buffer_overrun.cpp:32:46:32:49 | *argv | provenance | | | tests.cpp:613:19:613:24 | *source | tests.cpp:615:17:615:22 | *source | provenance | | | tests.cpp:622:19:622:24 | *source | tests.cpp:625:2:625:16 | *... = ... | provenance | | | tests.cpp:625:2:625:2 | *s [post update] [*home] | tests.cpp:628:14:628:14 | *s [*home] | provenance | | @@ -10,11 +48,35 @@ edges | tests.cpp:628:16:628:19 | *home | tests.cpp:628:14:628:19 | *home | provenance | | | tests.cpp:657:32:657:35 | **argv | tests.cpp:682:9:682:15 | *access to array | provenance | | | tests.cpp:657:32:657:35 | **argv | tests.cpp:683:9:683:15 | *access to array | provenance | | +| tests.cpp:657:32:657:35 | *argv | tests.cpp:682:9:682:15 | *access to array | provenance | | +| tests.cpp:657:32:657:35 | *argv | tests.cpp:683:9:683:15 | *access to array | provenance | | | tests.cpp:682:9:682:15 | *access to array | tests.cpp:613:19:613:24 | *source | provenance | | | tests.cpp:683:9:683:15 | *access to array | tests.cpp:622:19:622:24 | *source | provenance | | +| tests_restrict.c:15:41:15:44 | **argv | tests_restrict.c:15:41:15:44 | **argv | provenance | | +| tests_restrict.c:15:41:15:44 | *argv | tests_restrict.c:15:41:15:44 | *argv | provenance | | nodes | main.cpp:6:27:6:30 | **argv | semmle.label | **argv | +| main.cpp:7:33:7:36 | **argv | semmle.label | **argv | +| main.cpp:7:33:7:36 | overflowdesination_main output argument | semmle.label | overflowdesination_main output argument | +| main.cpp:7:33:7:36 | overflowdesination_main output argument | semmle.label | overflowdesination_main output argument | +| main.cpp:8:34:8:37 | **argv | semmle.label | **argv | +| main.cpp:8:34:8:37 | *argv | semmle.label | *argv | +| main.cpp:8:34:8:37 | test_buffer_overrun_main output argument | semmle.label | test_buffer_overrun_main output argument | +| main.cpp:8:34:8:37 | test_buffer_overrun_main output argument | semmle.label | test_buffer_overrun_main output argument | +| main.cpp:9:29:9:32 | **argv | semmle.label | **argv | +| main.cpp:9:29:9:32 | *argv | semmle.label | *argv | +| main.cpp:9:29:9:32 | tests_restrict_main output argument | semmle.label | tests_restrict_main output argument | +| main.cpp:9:29:9:32 | tests_restrict_main output argument | semmle.label | tests_restrict_main output argument | | main.cpp:10:20:10:23 | **argv | semmle.label | **argv | +| main.cpp:10:20:10:23 | *argv | semmle.label | *argv | +| overflowdestination.cpp:23:45:23:48 | **argv | semmle.label | **argv | +| overflowdestination.cpp:23:45:23:48 | **argv | semmle.label | **argv | +| overflowdestination.cpp:23:45:23:48 | *argv | semmle.label | *argv | +| test_buffer_overrun.cpp:32:46:32:49 | **argv | semmle.label | **argv | +| test_buffer_overrun.cpp:32:46:32:49 | **argv | semmle.label | **argv | +| test_buffer_overrun.cpp:32:46:32:49 | *argv | semmle.label | *argv | +| test_buffer_overrun.cpp:32:46:32:49 | *argv | semmle.label | *argv | +| test_buffer_overrun.cpp:32:46:32:49 | *argv | semmle.label | *argv | | tests.cpp:613:19:613:24 | *source | semmle.label | *source | | tests.cpp:615:17:615:22 | *source | semmle.label | *source | | tests.cpp:622:19:622:24 | *source | semmle.label | *source | @@ -24,9 +86,24 @@ nodes | tests.cpp:628:14:628:19 | *home | semmle.label | *home | | tests.cpp:628:16:628:19 | *home | semmle.label | *home | | tests.cpp:657:32:657:35 | **argv | semmle.label | **argv | +| tests.cpp:657:32:657:35 | *argv | semmle.label | *argv | | tests.cpp:682:9:682:15 | *access to array | semmle.label | *access to array | | tests.cpp:683:9:683:15 | *access to array | semmle.label | *access to array | +| tests_restrict.c:15:41:15:44 | **argv | semmle.label | **argv | +| tests_restrict.c:15:41:15:44 | **argv | semmle.label | **argv | +| tests_restrict.c:15:41:15:44 | *argv | semmle.label | *argv | +| tests_restrict.c:15:41:15:44 | *argv | semmle.label | *argv | subpaths +| main.cpp:7:33:7:36 | **argv | overflowdestination.cpp:23:45:23:48 | **argv | overflowdestination.cpp:23:45:23:48 | **argv | main.cpp:7:33:7:36 | overflowdesination_main output argument | +| main.cpp:7:33:7:36 | **argv | overflowdestination.cpp:23:45:23:48 | **argv | overflowdestination.cpp:23:45:23:48 | *argv | main.cpp:7:33:7:36 | overflowdesination_main output argument | +| main.cpp:8:34:8:37 | **argv | test_buffer_overrun.cpp:32:46:32:49 | **argv | test_buffer_overrun.cpp:32:46:32:49 | **argv | main.cpp:8:34:8:37 | test_buffer_overrun_main output argument | +| main.cpp:8:34:8:37 | **argv | test_buffer_overrun.cpp:32:46:32:49 | **argv | test_buffer_overrun.cpp:32:46:32:49 | *argv | main.cpp:8:34:8:37 | test_buffer_overrun_main output argument | +| main.cpp:8:34:8:37 | *argv | test_buffer_overrun.cpp:32:46:32:49 | **argv | test_buffer_overrun.cpp:32:46:32:49 | **argv | main.cpp:8:34:8:37 | test_buffer_overrun_main output argument | +| main.cpp:8:34:8:37 | *argv | test_buffer_overrun.cpp:32:46:32:49 | **argv | test_buffer_overrun.cpp:32:46:32:49 | *argv | main.cpp:8:34:8:37 | test_buffer_overrun_main output argument | +| main.cpp:8:34:8:37 | *argv | test_buffer_overrun.cpp:32:46:32:49 | *argv | test_buffer_overrun.cpp:32:46:32:49 | *argv | main.cpp:8:34:8:37 | test_buffer_overrun_main output argument | +| main.cpp:9:29:9:32 | **argv | tests_restrict.c:15:41:15:44 | **argv | tests_restrict.c:15:41:15:44 | **argv | main.cpp:9:29:9:32 | tests_restrict_main output argument | +| main.cpp:9:29:9:32 | *argv | tests_restrict.c:15:41:15:44 | **argv | tests_restrict.c:15:41:15:44 | **argv | main.cpp:9:29:9:32 | tests_restrict_main output argument | +| main.cpp:9:29:9:32 | *argv | tests_restrict.c:15:41:15:44 | *argv | tests_restrict.c:15:41:15:44 | *argv | main.cpp:9:29:9:32 | tests_restrict_main output argument | #select | tests.cpp:615:2:615:7 | call to strcpy | main.cpp:6:27:6:30 | **argv | tests.cpp:615:17:615:22 | *source | This 'call to strcpy' with input from $@ may overflow the destination. | main.cpp:6:27:6:30 | **argv | a command-line argument | | tests.cpp:628:2:628:7 | call to strcpy | main.cpp:6:27:6:30 | **argv | tests.cpp:628:14:628:19 | *home | This 'call to strcpy' with input from $@ may overflow the destination. | main.cpp:6:27:6:30 | **argv | a command-line argument | diff --git a/cpp/ql/test/query-tests/Security/CWE/CWE-134/semmle/argv/argvLocal.expected b/cpp/ql/test/query-tests/Security/CWE/CWE-134/semmle/argv/argvLocal.expected index 8f09b2ee7f5c..6b0a955e7b1b 100644 --- a/cpp/ql/test/query-tests/Security/CWE/CWE-134/semmle/argv/argvLocal.expected +++ b/cpp/ql/test/query-tests/Security/CWE/CWE-134/semmle/argv/argvLocal.expected @@ -1,20 +1,28 @@ edges +| argvLocal.c:9:25:9:31 | *correct | argvLocal.c:9:25:9:31 | *correct | provenance | | | argvLocal.c:13:27:13:30 | **argv | argvLocal.c:95:9:95:15 | *access to array | provenance | | | argvLocal.c:13:27:13:30 | **argv | argvLocal.c:96:15:96:21 | *access to array | provenance | | +| argvLocal.c:13:27:13:30 | **argv | argvLocal.c:96:15:96:21 | *access to array | provenance | | | argvLocal.c:13:27:13:30 | **argv | argvLocal.c:101:9:101:10 | *i1 | provenance | | | argvLocal.c:13:27:13:30 | **argv | argvLocal.c:102:15:102:16 | *i1 | provenance | | +| argvLocal.c:13:27:13:30 | **argv | argvLocal.c:102:15:102:16 | *i1 | provenance | | | argvLocal.c:13:27:13:30 | **argv | argvLocal.c:106:9:106:13 | *access to array | provenance | | | argvLocal.c:13:27:13:30 | **argv | argvLocal.c:107:15:107:19 | *access to array | provenance | | +| argvLocal.c:13:27:13:30 | **argv | argvLocal.c:107:15:107:19 | *access to array | provenance | | | argvLocal.c:13:27:13:30 | **argv | argvLocal.c:110:9:110:11 | ** ... | provenance | | | argvLocal.c:13:27:13:30 | **argv | argvLocal.c:111:15:111:17 | ** ... | provenance | | | argvLocal.c:13:27:13:30 | **argv | argvLocal.c:116:9:116:10 | *i3 | provenance | | | argvLocal.c:13:27:13:30 | **argv | argvLocal.c:117:15:117:16 | *i3 | provenance | | +| argvLocal.c:13:27:13:30 | **argv | argvLocal.c:117:15:117:16 | *i3 | provenance | | | argvLocal.c:13:27:13:30 | **argv | argvLocal.c:121:9:121:10 | *i4 | provenance | | | argvLocal.c:13:27:13:30 | **argv | argvLocal.c:122:15:122:16 | *i4 | provenance | | +| argvLocal.c:13:27:13:30 | **argv | argvLocal.c:122:15:122:16 | *i4 | provenance | | | argvLocal.c:13:27:13:30 | **argv | argvLocal.c:127:9:127:10 | *i5 | provenance | | | argvLocal.c:13:27:13:30 | **argv | argvLocal.c:128:15:128:16 | *i5 | provenance | | +| argvLocal.c:13:27:13:30 | **argv | argvLocal.c:128:15:128:16 | *i5 | provenance | | | argvLocal.c:13:27:13:30 | **argv | argvLocal.c:131:9:131:14 | *... + ... | provenance | | | argvLocal.c:13:27:13:30 | **argv | argvLocal.c:132:15:132:20 | *... + ... | provenance | | +| argvLocal.c:13:27:13:30 | **argv | argvLocal.c:132:15:132:20 | *... + ... | provenance | | | argvLocal.c:13:27:13:30 | **argv | argvLocal.c:135:9:135:12 | *... ++ | provenance | | | argvLocal.c:13:27:13:30 | **argv | argvLocal.c:136:15:136:18 | *-- ... | provenance | | | argvLocal.c:13:27:13:30 | **argv | argvLocal.c:139:9:139:26 | *... ? ... : ... | provenance | | @@ -23,24 +31,100 @@ edges | argvLocal.c:13:27:13:30 | **argv | argvLocal.c:145:15:145:16 | *i7 | provenance | | | argvLocal.c:13:27:13:30 | **argv | argvLocal.c:150:9:150:10 | *i8 | provenance | | | argvLocal.c:13:27:13:30 | **argv | argvLocal.c:151:15:151:16 | *i8 | provenance | | +| argvLocal.c:96:15:96:21 | *access to array | argvLocal.c:9:25:9:31 | *correct | provenance | | +| argvLocal.c:96:15:96:21 | *access to array | argvLocal.c:96:15:96:21 | printWrapper output argument | provenance | | +| argvLocal.c:96:15:96:21 | printWrapper output argument | argvLocal.c:101:9:101:10 | *i1 | provenance | | +| argvLocal.c:96:15:96:21 | printWrapper output argument | argvLocal.c:102:15:102:16 | *i1 | provenance | | +| argvLocal.c:96:15:96:21 | printWrapper output argument | argvLocal.c:102:15:102:16 | *i1 | provenance | | +| argvLocal.c:96:15:96:21 | printWrapper output argument | argvLocal.c:106:9:106:13 | *access to array | provenance | | +| argvLocal.c:96:15:96:21 | printWrapper output argument | argvLocal.c:107:15:107:19 | *access to array | provenance | | +| argvLocal.c:96:15:96:21 | printWrapper output argument | argvLocal.c:107:15:107:19 | *access to array | provenance | | +| argvLocal.c:96:15:96:21 | printWrapper output argument | argvLocal.c:110:9:110:11 | ** ... | provenance | | +| argvLocal.c:96:15:96:21 | printWrapper output argument | argvLocal.c:111:15:111:17 | ** ... | provenance | | +| argvLocal.c:96:15:96:21 | printWrapper output argument | argvLocal.c:116:9:116:10 | *i3 | provenance | | +| argvLocal.c:96:15:96:21 | printWrapper output argument | argvLocal.c:117:15:117:16 | *i3 | provenance | | +| argvLocal.c:96:15:96:21 | printWrapper output argument | argvLocal.c:117:15:117:16 | *i3 | provenance | | +| argvLocal.c:96:15:96:21 | printWrapper output argument | argvLocal.c:121:9:121:10 | *i4 | provenance | | +| argvLocal.c:96:15:96:21 | printWrapper output argument | argvLocal.c:122:15:122:16 | *i4 | provenance | | +| argvLocal.c:96:15:96:21 | printWrapper output argument | argvLocal.c:122:15:122:16 | *i4 | provenance | | +| argvLocal.c:96:15:96:21 | printWrapper output argument | argvLocal.c:127:9:127:10 | *i5 | provenance | | +| argvLocal.c:96:15:96:21 | printWrapper output argument | argvLocal.c:128:15:128:16 | *i5 | provenance | | +| argvLocal.c:96:15:96:21 | printWrapper output argument | argvLocal.c:128:15:128:16 | *i5 | provenance | | +| argvLocal.c:96:15:96:21 | printWrapper output argument | argvLocal.c:131:9:131:14 | *... + ... | provenance | | +| argvLocal.c:96:15:96:21 | printWrapper output argument | argvLocal.c:132:15:132:20 | *... + ... | provenance | | +| argvLocal.c:96:15:96:21 | printWrapper output argument | argvLocal.c:132:15:132:20 | *... + ... | provenance | | +| argvLocal.c:96:15:96:21 | printWrapper output argument | argvLocal.c:135:9:135:12 | *... ++ | provenance | | +| argvLocal.c:96:15:96:21 | printWrapper output argument | argvLocal.c:136:15:136:18 | *-- ... | provenance | | +| argvLocal.c:96:15:96:21 | printWrapper output argument | argvLocal.c:139:9:139:26 | *... ? ... : ... | provenance | | +| argvLocal.c:96:15:96:21 | printWrapper output argument | argvLocal.c:140:15:140:32 | *... ? ... : ... | provenance | | +| argvLocal.c:96:15:96:21 | printWrapper output argument | argvLocal.c:144:9:144:10 | *i7 | provenance | | +| argvLocal.c:96:15:96:21 | printWrapper output argument | argvLocal.c:145:15:145:16 | *i7 | provenance | | +| argvLocal.c:96:15:96:21 | printWrapper output argument | argvLocal.c:150:9:150:10 | *i8 | provenance | | +| argvLocal.c:96:15:96:21 | printWrapper output argument | argvLocal.c:151:15:151:16 | *i8 | provenance | | +| argvLocal.c:102:15:102:16 | *i1 | argvLocal.c:9:25:9:31 | *correct | provenance | | +| argvLocal.c:102:15:102:16 | *i1 | argvLocal.c:102:15:102:16 | printWrapper output argument | provenance | | +| argvLocal.c:102:15:102:16 | printWrapper output argument | argvLocal.c:144:9:144:10 | *i7 | provenance | | +| argvLocal.c:102:15:102:16 | printWrapper output argument | argvLocal.c:145:15:145:16 | *i7 | provenance | | +| argvLocal.c:107:15:107:19 | *access to array | argvLocal.c:9:25:9:31 | *correct | provenance | | +| argvLocal.c:107:15:107:19 | *access to array | argvLocal.c:107:15:107:19 | printWrapper output argument | provenance | | +| argvLocal.c:107:15:107:19 | printWrapper output argument | argvLocal.c:110:9:110:11 | ** ... | provenance | | +| argvLocal.c:107:15:107:19 | printWrapper output argument | argvLocal.c:111:15:111:17 | ** ... | provenance | | +| argvLocal.c:117:15:117:16 | *i3 | argvLocal.c:9:25:9:31 | *correct | provenance | | +| argvLocal.c:117:15:117:16 | *i3 | argvLocal.c:117:15:117:16 | printWrapper output argument | provenance | | +| argvLocal.c:117:15:117:16 | printWrapper output argument | argvLocal.c:121:9:121:10 | *i4 | provenance | | +| argvLocal.c:117:15:117:16 | printWrapper output argument | argvLocal.c:122:15:122:16 | *i4 | provenance | | +| argvLocal.c:117:15:117:16 | printWrapper output argument | argvLocal.c:122:15:122:16 | *i4 | provenance | | +| argvLocal.c:117:15:117:16 | printWrapper output argument | argvLocal.c:135:9:135:12 | *... ++ | provenance | | +| argvLocal.c:117:15:117:16 | printWrapper output argument | argvLocal.c:136:15:136:18 | *-- ... | provenance | | +| argvLocal.c:122:15:122:16 | *i4 | argvLocal.c:9:25:9:31 | *correct | provenance | | +| argvLocal.c:122:15:122:16 | *i4 | argvLocal.c:122:15:122:16 | printWrapper output argument | provenance | | +| argvLocal.c:122:15:122:16 | printWrapper output argument | argvLocal.c:135:9:135:12 | *... ++ | provenance | | +| argvLocal.c:122:15:122:16 | printWrapper output argument | argvLocal.c:136:15:136:18 | *-- ... | provenance | | +| argvLocal.c:128:15:128:16 | *i5 | argvLocal.c:9:25:9:31 | *correct | provenance | | +| argvLocal.c:128:15:128:16 | *i5 | argvLocal.c:128:15:128:16 | printWrapper output argument | provenance | | +| argvLocal.c:128:15:128:16 | printWrapper output argument | argvLocal.c:131:9:131:14 | *... + ... | provenance | | +| argvLocal.c:128:15:128:16 | printWrapper output argument | argvLocal.c:132:15:132:20 | *... + ... | provenance | | +| argvLocal.c:128:15:128:16 | printWrapper output argument | argvLocal.c:132:15:132:20 | *... + ... | provenance | | +| argvLocal.c:128:15:128:16 | printWrapper output argument | argvLocal.c:139:9:139:26 | *... ? ... : ... | provenance | | +| argvLocal.c:128:15:128:16 | printWrapper output argument | argvLocal.c:140:15:140:32 | *... ? ... : ... | provenance | | +| argvLocal.c:132:15:132:20 | *... + ... | argvLocal.c:9:25:9:31 | *correct | provenance | | +| argvLocal.c:132:15:132:20 | *... + ... | argvLocal.c:132:15:132:20 | printWrapper output argument | provenance | | +| argvLocal.c:132:15:132:20 | printWrapper output argument | argvLocal.c:139:9:139:26 | *... ? ... : ... | provenance | | +| argvLocal.c:132:15:132:20 | printWrapper output argument | argvLocal.c:140:15:140:32 | *... ? ... : ... | provenance | | nodes +| argvLocal.c:9:25:9:31 | *correct | semmle.label | *correct | +| argvLocal.c:9:25:9:31 | *correct | semmle.label | *correct | | argvLocal.c:13:27:13:30 | **argv | semmle.label | **argv | | argvLocal.c:95:9:95:15 | *access to array | semmle.label | *access to array | | argvLocal.c:96:15:96:21 | *access to array | semmle.label | *access to array | +| argvLocal.c:96:15:96:21 | *access to array | semmle.label | *access to array | +| argvLocal.c:96:15:96:21 | printWrapper output argument | semmle.label | printWrapper output argument | | argvLocal.c:101:9:101:10 | *i1 | semmle.label | *i1 | | argvLocal.c:102:15:102:16 | *i1 | semmle.label | *i1 | +| argvLocal.c:102:15:102:16 | *i1 | semmle.label | *i1 | +| argvLocal.c:102:15:102:16 | printWrapper output argument | semmle.label | printWrapper output argument | | argvLocal.c:106:9:106:13 | *access to array | semmle.label | *access to array | | argvLocal.c:107:15:107:19 | *access to array | semmle.label | *access to array | +| argvLocal.c:107:15:107:19 | *access to array | semmle.label | *access to array | +| argvLocal.c:107:15:107:19 | printWrapper output argument | semmle.label | printWrapper output argument | | argvLocal.c:110:9:110:11 | ** ... | semmle.label | ** ... | | argvLocal.c:111:15:111:17 | ** ... | semmle.label | ** ... | | argvLocal.c:116:9:116:10 | *i3 | semmle.label | *i3 | | argvLocal.c:117:15:117:16 | *i3 | semmle.label | *i3 | +| argvLocal.c:117:15:117:16 | *i3 | semmle.label | *i3 | +| argvLocal.c:117:15:117:16 | printWrapper output argument | semmle.label | printWrapper output argument | | argvLocal.c:121:9:121:10 | *i4 | semmle.label | *i4 | | argvLocal.c:122:15:122:16 | *i4 | semmle.label | *i4 | +| argvLocal.c:122:15:122:16 | *i4 | semmle.label | *i4 | +| argvLocal.c:122:15:122:16 | printWrapper output argument | semmle.label | printWrapper output argument | | argvLocal.c:127:9:127:10 | *i5 | semmle.label | *i5 | | argvLocal.c:128:15:128:16 | *i5 | semmle.label | *i5 | +| argvLocal.c:128:15:128:16 | *i5 | semmle.label | *i5 | +| argvLocal.c:128:15:128:16 | printWrapper output argument | semmle.label | printWrapper output argument | | argvLocal.c:131:9:131:14 | *... + ... | semmle.label | *... + ... | | argvLocal.c:132:15:132:20 | *... + ... | semmle.label | *... + ... | +| argvLocal.c:132:15:132:20 | *... + ... | semmle.label | *... + ... | +| argvLocal.c:132:15:132:20 | printWrapper output argument | semmle.label | printWrapper output argument | | argvLocal.c:135:9:135:12 | *... ++ | semmle.label | *... ++ | | argvLocal.c:136:15:136:18 | *-- ... | semmle.label | *-- ... | | argvLocal.c:139:9:139:26 | *... ? ... : ... | semmle.label | *... ? ... : ... | @@ -50,6 +134,13 @@ nodes | argvLocal.c:150:9:150:10 | *i8 | semmle.label | *i8 | | argvLocal.c:151:15:151:16 | *i8 | semmle.label | *i8 | subpaths +| argvLocal.c:96:15:96:21 | *access to array | argvLocal.c:9:25:9:31 | *correct | argvLocal.c:9:25:9:31 | *correct | argvLocal.c:96:15:96:21 | printWrapper output argument | +| argvLocal.c:102:15:102:16 | *i1 | argvLocal.c:9:25:9:31 | *correct | argvLocal.c:9:25:9:31 | *correct | argvLocal.c:102:15:102:16 | printWrapper output argument | +| argvLocal.c:107:15:107:19 | *access to array | argvLocal.c:9:25:9:31 | *correct | argvLocal.c:9:25:9:31 | *correct | argvLocal.c:107:15:107:19 | printWrapper output argument | +| argvLocal.c:117:15:117:16 | *i3 | argvLocal.c:9:25:9:31 | *correct | argvLocal.c:9:25:9:31 | *correct | argvLocal.c:117:15:117:16 | printWrapper output argument | +| argvLocal.c:122:15:122:16 | *i4 | argvLocal.c:9:25:9:31 | *correct | argvLocal.c:9:25:9:31 | *correct | argvLocal.c:122:15:122:16 | printWrapper output argument | +| argvLocal.c:128:15:128:16 | *i5 | argvLocal.c:9:25:9:31 | *correct | argvLocal.c:9:25:9:31 | *correct | argvLocal.c:128:15:128:16 | printWrapper output argument | +| argvLocal.c:132:15:132:20 | *... + ... | argvLocal.c:9:25:9:31 | *correct | argvLocal.c:9:25:9:31 | *correct | argvLocal.c:132:15:132:20 | printWrapper output argument | #select | argvLocal.c:95:9:95:15 | *access to array | argvLocal.c:13:27:13:30 | **argv | argvLocal.c:95:9:95:15 | *access to array | The value of this argument may come from $@ and is being used as a formatting argument to printf(format). | argvLocal.c:13:27:13:30 | **argv | a command-line argument | | argvLocal.c:96:15:96:21 | *access to array | argvLocal.c:13:27:13:30 | **argv | argvLocal.c:96:15:96:21 | *access to array | The value of this argument may come from $@ and is being used as a formatting argument to printWrapper(correct), which calls printf(format). | argvLocal.c:13:27:13:30 | **argv | a command-line argument | 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 087a0a88662f..20b69b653c90 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,29 +1,46 @@ edges | globalVars.c:8:7:8:10 | **copy | globalVars.c:27:9:27:12 | *copy | provenance | | | globalVars.c:8:7:8:10 | **copy | globalVars.c:30:15:30:18 | *copy | provenance | | +| globalVars.c:8:7:8:10 | **copy | globalVars.c:30:15:30:18 | *copy | provenance | | | globalVars.c:8:7:8:10 | **copy | globalVars.c:35:11:35:14 | *copy | provenance | | | globalVars.c:9:7:9:11 | **copy2 | globalVars.c:38:9:38:13 | *copy2 | provenance | | | globalVars.c:9:7:9:11 | **copy2 | globalVars.c:41:15:41:19 | *copy2 | provenance | | +| globalVars.c:9:7:9:11 | **copy2 | globalVars.c:41:15:41:19 | *copy2 | provenance | | | globalVars.c:9:7:9:11 | **copy2 | globalVars.c:50:9:50:13 | *copy2 | provenance | | | globalVars.c:11:22:11:25 | **argv | globalVars.c:8:7:8:10 | **copy | provenance | | | globalVars.c:15:21:15:23 | *val | globalVars.c:9:7:9:11 | **copy2 | provenance | | +| globalVars.c:19:25:19:27 | *str | globalVars.c:19:25:19:27 | *str | provenance | | | globalVars.c:23:27:23:30 | **argv | globalVars.c:24:11:24:14 | **argv | provenance | | | globalVars.c:24:11:24:14 | **argv | globalVars.c:11:22:11:25 | **argv | provenance | | +| globalVars.c:30:15:30:18 | *copy | globalVars.c:19:25:19:27 | *str | provenance | | +| globalVars.c:30:15:30:18 | *copy | globalVars.c:30:15:30:18 | printWrapper output argument | provenance | | +| globalVars.c:30:15:30:18 | printWrapper output argument | globalVars.c:35:11:35:14 | *copy | provenance | | | globalVars.c:35:11:35:14 | *copy | globalVars.c:15:21:15:23 | *val | provenance | | +| globalVars.c:41:15:41:19 | *copy2 | globalVars.c:19:25:19:27 | *str | provenance | | +| globalVars.c:41:15:41:19 | *copy2 | globalVars.c:41:15:41:19 | printWrapper output argument | provenance | | +| globalVars.c:41:15:41:19 | printWrapper output argument | globalVars.c:50:9:50:13 | *copy2 | provenance | | nodes | globalVars.c:8:7:8:10 | **copy | semmle.label | **copy | | globalVars.c:9:7:9:11 | **copy2 | semmle.label | **copy2 | | globalVars.c:11:22:11:25 | **argv | semmle.label | **argv | | globalVars.c:15:21:15:23 | *val | semmle.label | *val | +| globalVars.c:19:25:19:27 | *str | semmle.label | *str | +| globalVars.c:19:25:19:27 | *str | semmle.label | *str | | globalVars.c:23:27:23:30 | **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:30:15:30:18 | *copy | semmle.label | *copy | +| globalVars.c:30:15:30:18 | *copy | semmle.label | *copy | +| globalVars.c:30:15:30:18 | printWrapper output argument | semmle.label | printWrapper output argument | | globalVars.c:35:11:35:14 | *copy | semmle.label | *copy | | 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 | printWrapper output argument | semmle.label | printWrapper output argument | | globalVars.c:50:9:50:13 | *copy2 | semmle.label | *copy2 | subpaths +| globalVars.c:30:15:30:18 | *copy | globalVars.c:19:25:19:27 | *str | globalVars.c:19:25:19:27 | *str | globalVars.c:30:15:30:18 | printWrapper output argument | +| globalVars.c:41:15:41:19 | *copy2 | globalVars.c:19:25:19:27 | *str | globalVars.c:19:25:19:27 | *str | globalVars.c:41:15:41:19 | printWrapper output argument | #select | globalVars.c:27:9:27:12 | *copy | globalVars.c:23:27:23:30 | **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:23:27:23:30 | **argv | a command-line argument | | globalVars.c:30:15:30:18 | *copy | globalVars.c:23:27:23:30 | **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:23:27:23:30 | **argv | a command-line argument | diff --git a/cpp/ql/test/query-tests/Security/CWE/CWE-311/semmle/tests/CleartextFileWrite.expected b/cpp/ql/test/query-tests/Security/CWE/CWE-311/semmle/tests/CleartextFileWrite.expected index ddeb3fed32f9..42992d988bac 100644 --- a/cpp/ql/test/query-tests/Security/CWE/CWE-311/semmle/tests/CleartextFileWrite.expected +++ b/cpp/ql/test/query-tests/Security/CWE/CWE-311/semmle/tests/CleartextFileWrite.expected @@ -1,7 +1,6 @@ edges | test2.cpp:62:18:62:25 | password | test2.cpp:65:31:65:34 | cpy1 | provenance | | | test2.cpp:72:15:72:24 | password | test2.cpp:73:30:73:32 | *buf | provenance | | -| test2.cpp:72:15:72:24 | password | test2.cpp:76:30:76:32 | *buf | provenance | | | test2.cpp:98:45:98:52 | password | test2.cpp:99:27:99:32 | *buffer | provenance | | | test.cpp:70:38:70:48 | thePassword | test.cpp:73:43:73:53 | thePassword | provenance | | | test.cpp:73:63:73:73 | thePassword | test.cpp:73:43:73:53 | thePassword | provenance | | @@ -17,7 +16,6 @@ nodes | test2.cpp:65:31:65:34 | cpy1 | semmle.label | cpy1 | | test2.cpp:72:15:72:24 | password | semmle.label | password | | test2.cpp:73:30:73:32 | *buf | semmle.label | *buf | -| test2.cpp:76:30:76:32 | *buf | semmle.label | *buf | | test2.cpp:98:45:98:52 | password | semmle.label | password | | test2.cpp:99:27:99:32 | *buffer | semmle.label | *buffer | | test.cpp:45:9:45:19 | thePassword | semmle.label | thePassword | @@ -36,7 +34,6 @@ subpaths | test2.cpp:57:2:57:8 | call to fprintf | test2.cpp:57:39:57:49 | call to getPassword | test2.cpp:57:39:57:49 | call to getPassword | This write into file 'log' may contain unencrypted data from $@. | test2.cpp:57:39:57:49 | call to getPassword | this source. | | test2.cpp:65:3:65:9 | call to fprintf | test2.cpp:62:18:62:25 | password | test2.cpp:65:31:65:34 | cpy1 | This write into file 'log' may contain unencrypted data from $@. | test2.cpp:62:18:62:25 | password | this source. | | test2.cpp:73:3:73:9 | call to fprintf | test2.cpp:72:15:72:24 | password | test2.cpp:73:30:73:32 | *buf | This write into file 'log' may contain unencrypted data from $@. | test2.cpp:72:17:72:24 | password | this source. | -| test2.cpp:76:3:76:9 | call to fprintf | test2.cpp:72:15:72:24 | password | test2.cpp:76:30:76:32 | *buf | This write into file 'log' may contain unencrypted data from $@. | test2.cpp:72:17:72:24 | password | this source. | | test2.cpp:99:3:99:9 | call to fprintf | test2.cpp:98:45:98:52 | password | test2.cpp:99:27:99:32 | *buffer | This write into file 'log' may contain unencrypted data from $@. | test2.cpp:98:45:98:52 | password | this source. | | test.cpp:45:3:45:7 | call to fputs | test.cpp:45:9:45:19 | thePassword | test.cpp:45:9:45:19 | thePassword | This write into file 'file' may contain unencrypted data from $@. | test.cpp:45:9:45:19 | thePassword | this source. | | test.cpp:70:35:70:35 | call to operator<< | test.cpp:70:38:70:48 | thePassword | test.cpp:70:38:70:48 | thePassword | This write into file 'mystream' may contain unencrypted data from $@. | test.cpp:70:38:70:48 | thePassword | this source. | diff --git a/cpp/ql/test/query-tests/Security/CWE/CWE-311/semmle/tests/test2.cpp b/cpp/ql/test/query-tests/Security/CWE/CWE-311/semmle/tests/test2.cpp index 0220b8d09eb3..ff10fba761b3 100644 --- a/cpp/ql/test/query-tests/Security/CWE/CWE-311/semmle/tests/test2.cpp +++ b/cpp/ql/test/query-tests/Security/CWE/CWE-311/semmle/tests/test2.cpp @@ -73,7 +73,7 @@ void tests(FILE *log, myStruct &s) fprintf(log, "buf = %s\n", buf); // BAD strcpy(buf, s.password_hash); - fprintf(log, "buf = %s\n", buf); // GOOD [FALSE POSITIVE] + fprintf(log, "buf = %s\n", buf); // GOOD } { 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 70386662fe88..44a83a752d6e 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 @@ -41,11 +41,14 @@ edges | tests.cpp:73:23:73:43 | call to XercesDOMParser | tests.cpp:80:2:80:2 | *p | provenance | | | tests.cpp:85:24:85:44 | call to XercesDOMParser | tests.cpp:88:3:88:3 | *q | provenance | | | tests.cpp:100:24:100:44 | call to XercesDOMParser | tests.cpp:104:3:104:3 | *q | provenance | | +| tests.cpp:112:39:112:39 | *p | tests.cpp:112:39:112:39 | *p | provenance | | | tests.cpp:112:39:112:39 | *p | tests.cpp:113:2:113:2 | *p | provenance | | | tests.cpp:116:39:116:39 | *p | tests.cpp:117:2:117:2 | *p | provenance | | | tests.cpp:122:23:122:43 | call to XercesDOMParser | tests.cpp:126:18:126:18 | *q | provenance | | | tests.cpp:122:23:122:43 | call to XercesDOMParser | tests.cpp:128:18:128:18 | *q | provenance | | | tests.cpp:126:18:126:18 | *q | tests.cpp:112:39:112:39 | *p | provenance | | +| tests.cpp:126:18:126:18 | *q | tests.cpp:126:18:126:18 | test10_doParseB output argument | provenance | | +| tests.cpp:126:18:126:18 | test10_doParseB output argument | tests.cpp:128:18:128:18 | *q | provenance | | | tests.cpp:128:18:128:18 | *q | tests.cpp:116:39:116:39 | *p | provenance | | nodes | tests2.cpp:20:17:20:31 | call to SAXParser | semmle.label | call to SAXParser | @@ -117,13 +120,16 @@ nodes | tests.cpp:100:24:100:44 | call to XercesDOMParser | semmle.label | call to XercesDOMParser | | tests.cpp:104:3:104:3 | *q | semmle.label | *q | | tests.cpp:112:39:112:39 | *p | semmle.label | *p | +| tests.cpp:112:39:112:39 | *p | semmle.label | *p | | tests.cpp:113:2:113:2 | *p | semmle.label | *p | | tests.cpp:116:39:116:39 | *p | semmle.label | *p | | tests.cpp:117:2:117:2 | *p | semmle.label | *p | | tests.cpp:122:23:122:43 | call to XercesDOMParser | semmle.label | call to XercesDOMParser | | tests.cpp:126:18:126:18 | *q | semmle.label | *q | +| tests.cpp:126:18:126:18 | test10_doParseB output argument | semmle.label | test10_doParseB output argument | | tests.cpp:128:18:128:18 | *q | semmle.label | *q | subpaths +| tests.cpp:126:18:126:18 | *q | tests.cpp:112:39:112:39 | *p | tests.cpp:112:39:112:39 | *p | tests.cpp:126:18:126:18 | test10_doParseB output argument | #select | tests2.cpp:22:2:22:2 | *p | tests2.cpp:20:17:20:31 | call to SAXParser | tests2.cpp:22:2:22:2 | *p | This $@ is not configured to prevent an XML external entity (XXE) attack. | tests2.cpp:20:17:20:31 | call to SAXParser | XML parser | | tests2.cpp:37:2:37:2 | *p | tests2.cpp:33:17:33:31 | call to SAXParser | tests2.cpp:37:2:37:2 | *p | This $@ is not configured to prevent an XML external entity (XXE) attack. | tests2.cpp:33:17:33:31 | call to SAXParser | XML parser |