diff --git a/cpp/ql/lib/semmle/code/cpp/models/implementations/Allocation.qll b/cpp/ql/lib/semmle/code/cpp/models/implementations/Allocation.qll index df6d94917299..bb7b5432af11 100644 --- a/cpp/ql/lib/semmle/code/cpp/models/implementations/Allocation.qll +++ b/cpp/ql/lib/semmle/code/cpp/models/implementations/Allocation.qll @@ -45,7 +45,10 @@ private class ReallocAllocationFunction extends AllocationFunction, DataFlowFunc override int getReallocPtrArg() { result = reallocArg } override predicate hasDataFlow(FunctionInput input, FunctionOutput output) { - input.isParameterDeref(this.getReallocPtrArg()) and output.isReturnValueDeref() + exists(int indirectionIndex | + input.isParameterDeref(this.getReallocPtrArg(), indirectionIndex) and + output.isReturnValueDeref(indirectionIndex) + ) } } 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 9689c2f8a3b3..b925ee34e82a 100644 --- a/cpp/ql/lib/semmle/code/cpp/models/implementations/GetDelim.qll +++ b/cpp/ql/lib/semmle/code/cpp/models/implementations/GetDelim.qll @@ -12,10 +12,10 @@ private class GetDelimFunction extends TaintFunction, AliasFunction, SideEffectF GetDelimFunction() { this.hasGlobalName(["getdelim", "getwdelim", "__getdelim"]) } override predicate hasTaintFlow(FunctionInput i, FunctionOutput o) { - i.isParameter(3) and o.isParameterDeref(0) + i.isParameter(3) and o.isParameterDeref(0, 2) } - override predicate isPartialWrite(FunctionOutput o) { o.isParameterDeref(3) } + override predicate isPartialWrite(FunctionOutput o) { o.isParameterDeref(0, 2) } override predicate parameterNeverEscapes(int index) { index = [0, 1, 3] } @@ -38,7 +38,7 @@ private class GetDelimFunction extends TaintFunction, AliasFunction, SideEffectF } override predicate hasRemoteFlowSource(FunctionOutput output, string description) { - output.isParameterDeref(0) and + output.isParameterDeref(0, 2) and description = "string read by " + this.getName() } } 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 c0e2c0c45381..b142a708752b 100644 --- a/cpp/ql/lib/semmle/code/cpp/models/implementations/Gets.qll +++ b/cpp/ql/lib/semmle/code/cpp/models/implementations/Gets.qll @@ -30,7 +30,7 @@ private class FgetsFunction extends DataFlowFunction, TaintFunction, ArrayFuncti override predicate isPartialWrite(FunctionOutput output) { output.isParameterDeref(2) } override predicate hasTaintFlow(FunctionInput input, FunctionOutput output) { - input.isParameter(2) and + input.isParameterDeref(2) and output.isParameterDeref(0) } diff --git a/cpp/ql/lib/semmle/code/cpp/models/implementations/IdentityFunction.qll b/cpp/ql/lib/semmle/code/cpp/models/implementations/IdentityFunction.qll index f07e990dc16b..41ded42d74db 100644 --- a/cpp/ql/lib/semmle/code/cpp/models/implementations/IdentityFunction.qll +++ b/cpp/ql/lib/semmle/code/cpp/models/implementations/IdentityFunction.qll @@ -31,6 +31,8 @@ private class IdentityFunction extends DataFlowFunction, SideEffectFunction, Ali // These functions simply return the argument value. input.isParameter(0) and output.isReturnValue() or - input.isParameterDeref(0) and output.isReturnValueDeref() + exists(int indirectionIndex | + input.isParameterDeref(0, indirectionIndex) and output.isReturnValueDeref(indirectionIndex) + ) } } 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 f61b13dc5680..4c6bbb8b1a4e 100644 --- a/cpp/ql/lib/semmle/code/cpp/models/implementations/Inet.qll +++ b/cpp/ql/lib/semmle/code/cpp/models/implementations/Inet.qll @@ -151,7 +151,7 @@ private class Getaddrinfo extends TaintFunction, ArrayFunction, RemoteFlowSource override predicate hasTaintFlow(FunctionInput input, FunctionOutput output) { input.isParameterDeref([0 .. 2]) and - output.isParameterDeref(3) + output.isParameterDeref(3, 2) } override predicate hasArrayInput(int bufParam) { bufParam in [0, 1] } diff --git a/cpp/ql/lib/semmle/code/cpp/models/implementations/Iterator.qll b/cpp/ql/lib/semmle/code/cpp/models/implementations/Iterator.qll index 3a93188e9ca6..e8db7b2423fc 100644 --- a/cpp/ql/lib/semmle/code/cpp/models/implementations/Iterator.qll +++ b/cpp/ql/lib/semmle/code/cpp/models/implementations/Iterator.qll @@ -164,7 +164,9 @@ private class IteratorCrementNonMemberOperatorModel extends IteratorCrementNonMe input = getIteratorArgumentInput(this, 0) and output.isReturnValue() or - input.isParameterDeref(0) and output.isReturnValueDeref() + exists(int indirectionIndex | + input.isParameterDeref(0, indirectionIndex) and output.isReturnValueDeref(indirectionIndex) + ) } override predicate hasOnlySpecificReadSideEffects() { any() } @@ -205,16 +207,21 @@ private class IteratorCrementMemberOperatorModel extends IteratorCrementMemberOp input.isQualifierAddress() and output.isReturnValue() or - input.isReturnValueDeref() and - output.isQualifierObject() - or - input.isQualifierObject() and - output.isReturnValueDeref() + exists(int indirectionIndex | + // reverse flow + input.isReturnValueDeref(indirectionIndex) and + output.isQualifierObject(indirectionIndex) + or + input.isQualifierObject(indirectionIndex) and + output.isReturnValueDeref(indirectionIndex) + ) } override predicate hasTaintFlow(FunctionInput input, FunctionOutput output) { - input.isQualifierObject() and - output.isReturnValueDeref() + exists(int indirectionIndex | + input.isQualifierObject(indirectionIndex) and + output.isReturnValueDeref(indirectionIndex) + ) } override predicate hasOnlySpecificReadSideEffects() { any() } @@ -286,8 +293,11 @@ private class IteratorBinaryArithmeticMemberOperatorModel extends IteratorBinary TaintFunction { override predicate hasTaintFlow(FunctionInput input, FunctionOutput output) { - input.isQualifierObject() and - output.isReturnValue() + exists(int indirectionIndex | input.isQualifierObject(indirectionIndex) | + output.isReturnValueDeref(indirectionIndex) + or + output.isReturnValue() + ) } } @@ -346,15 +356,23 @@ private class IteratorAssignArithmeticNonMemberOperatorModel extends IteratorAss } override predicate hasTaintFlow(FunctionInput input, FunctionOutput output) { - input.isParameterDeref(0) and output.isReturnValueDeref() - or - // reverse flow from returned reference to the object referenced by the first parameter - input.isReturnValueDeref() and - output.isParameterDeref(0) - or - (input.isParameter(1) or input.isParameterDeref(1)) and - output.isParameterDeref(0) + exists(int indirectionIndex | + input.isParameterDeref(0, indirectionIndex) and output.isReturnValueDeref(indirectionIndex) + or + // reverse flow from returned reference to the object referenced by the first parameter + input.isReturnValueDeref(indirectionIndex) and + output.isParameterDeref(0, indirectionIndex) + or + ( + input.isParameter(1) and indirectionIndex = 0 + or + input.isParameterDeref(1, indirectionIndex) + ) and + output.isParameterDeref(0, indirectionIndex + 1) + ) } + + override predicate isPartialWrite(FunctionOutput output) { output.isParameterDeref(0, _) } } /** @@ -378,16 +396,25 @@ private class IteratorAssignArithmeticMemberOperatorModel extends IteratorAssign } override predicate hasTaintFlow(FunctionInput input, FunctionOutput output) { - input.isQualifierObject() and - output.isReturnValueDeref() - or - // reverse flow from returned reference to the qualifier - input.isReturnValueDeref() and - output.isQualifierObject() - or - (input.isParameter(0) or input.isParameterDeref(0)) and - output.isQualifierObject() + exists(int indirectionIndex | + input.isParameterDeref(0, indirectionIndex) and output.isReturnValueDeref(indirectionIndex) + or + input.isQualifierObject(indirectionIndex) and output.isReturnValueDeref(indirectionIndex) + or + // reverse flow from returned reference to the object referenced by the first parameter + input.isReturnValueDeref(indirectionIndex) and + output.isQualifierObject(indirectionIndex) + or + ( + input.isParameter(0) and indirectionIndex = 0 + or + input.isParameterDeref(0, indirectionIndex) + ) and + output.isQualifierObject(indirectionIndex + 1) + ) } + + override predicate isPartialWrite(FunctionOutput output) { output.isQualifierObject(_) } } /** @@ -414,11 +441,14 @@ class IteratorPointerDereferenceMemberOperator extends MemberFunction, TaintFunc } override predicate hasTaintFlow(FunctionInput input, FunctionOutput output) { - input.isQualifierObject() and - output.isReturnValue() - or - input.isReturnValueDeref() and - output.isQualifierObject() + exists(int indirectionIndex | + input.isQualifierObject(indirectionIndex) and + (output.isReturnValueDeref(indirectionIndex) or output.isReturnValue()) + or + // reverse flow + input.isReturnValueDeref(indirectionIndex) and + output.isQualifierObject(indirectionIndex) + ) } override predicate parameterNeverEscapes(int index) { index = -1 } @@ -454,8 +484,10 @@ private class IteratorPointerDereferenceNonMemberOperatorModel extends IteratorP input = getIteratorArgumentInput(this, 0) and output.isReturnValue() or - input.isReturnValueDeref() and - output.isParameterDeref(0) + exists(int indirectionIndex | + input.isReturnValueDeref(indirectionIndex) and + output.isParameterDeref(0, indirectionIndex) + ) } override predicate parameterNeverEscapes(int index) { index = 0 } @@ -488,8 +520,10 @@ private class IteratorFieldMemberOperator extends Operator, TaintFunction { IteratorFieldMemberOperator() { this.getClassAndName("operator->") instanceof Iterator } override predicate hasTaintFlow(FunctionInput input, FunctionOutput output) { - input.isQualifierObject() and - output.isReturnValue() + exists(int indirectionIndex | + input.isQualifierObject(indirectionIndex) and + output.isReturnValueDeref(indirectionIndex) // TODO + ) } } @@ -502,8 +536,10 @@ private class IteratorArrayMemberOperator extends MemberFunction, TaintFunction, IteratorArrayMemberOperator() { this.getClassAndName("operator[]") instanceof Iterator } override predicate hasTaintFlow(FunctionInput input, FunctionOutput output) { - input.isQualifierObject() and - output.isReturnValue() + exists(int indirectionIndex | + input.isQualifierObject(indirectionIndex) and + output.isReturnValueDeref(indirectionIndex) // TODO + ) } } @@ -595,8 +631,11 @@ private class IteratorAssignmentMemberOperatorModel extends IteratorAssignmentMe TaintFunction, SideEffectFunction, AliasFunction { override predicate hasTaintFlow(FunctionInput input, FunctionOutput output) { - (input.isParameterDeref(0) or input.isParameter(0)) and - output.isQualifierObject() + exists(int indirectionIndex | output.isQualifierObject(indirectionIndex + 1) | + input.isParameterDeref(0, indirectionIndex) + or + input.isParameter(0) and indirectionIndex = 0 + ) } override predicate hasOnlySpecificReadSideEffects() { any() } @@ -669,8 +708,11 @@ private class BeginOrEndFunctionModels extends BeginOrEndFunction, TaintFunction GetIteratorFunction, AliasFunction, SideEffectFunction { override predicate hasTaintFlow(FunctionInput input, FunctionOutput output) { - input.isQualifierObject() and - output.isReturnValue() + exists(int indirectionIndex | input.isQualifierObject(indirectionIndex) | + // output.isReturnValue() + // or + output.isReturnValueDeref(indirectionIndex) // TODO + ) } override predicate getsIterator(FunctionInput input, FunctionOutput output) { diff --git a/cpp/ql/lib/semmle/code/cpp/models/implementations/MemberFunction.qll b/cpp/ql/lib/semmle/code/cpp/models/implementations/MemberFunction.qll index 70fd04859daa..0935123fc131 100644 --- a/cpp/ql/lib/semmle/code/cpp/models/implementations/MemberFunction.qll +++ b/cpp/ql/lib/semmle/code/cpp/models/implementations/MemberFunction.qll @@ -65,12 +65,14 @@ private class MoveConstructorModel extends MoveConstructor, DataFlowFunction { private class CopyAssignmentOperatorModel extends CopyAssignmentOperator, TaintFunction { override predicate hasTaintFlow(FunctionInput input, FunctionOutput output) { // taint flow from argument to self - input.isParameterDeref(0) and - output.isQualifierObject() - or - // taint flow from argument to return value - input.isParameterDeref(0) and - output.isReturnValueDeref() + exists(int indirectionIndex | + input.isParameterDeref(0, indirectionIndex) and + output.isQualifierObject(indirectionIndex) + or + // taint flow from argument to return value + input.isParameterDeref(0, indirectionIndex) and + output.isReturnValueDeref(indirectionIndex) + ) // TODO: it would be more accurate to model copy assignment as data flow } } @@ -81,12 +83,14 @@ private class CopyAssignmentOperatorModel extends CopyAssignmentOperator, TaintF private class MoveAssignmentOperatorModel extends MoveAssignmentOperator, TaintFunction { override predicate hasTaintFlow(FunctionInput input, FunctionOutput output) { // taint flow from argument to self - input.isParameterDeref(0) and - output.isQualifierObject() - or - // taint flow from argument to return value - input.isParameterDeref(0) and - output.isReturnValueDeref() + exists(int indirectionIndex | + input.isParameterDeref(0, indirectionIndex) and + output.isQualifierObject(indirectionIndex) + or + // taint flow from argument to return value + input.isParameterDeref(0, indirectionIndex) and + output.isReturnValueDeref(indirectionIndex) + ) // TODO: it would be more accurate to model move assignment as data flow } } diff --git a/cpp/ql/lib/semmle/code/cpp/models/implementations/Memcpy.qll b/cpp/ql/lib/semmle/code/cpp/models/implementations/Memcpy.qll index dc1302d3b8fc..b3777ecbb2e4 100644 --- a/cpp/ql/lib/semmle/code/cpp/models/implementations/Memcpy.qll +++ b/cpp/ql/lib/semmle/code/cpp/models/implementations/Memcpy.qll @@ -53,11 +53,13 @@ private class MemcpyFunction extends ArrayFunction, DataFlowFunction, SideEffect override predicate hasArrayOutput(int bufParam) { bufParam = this.getParamDest() } override predicate hasDataFlow(FunctionInput input, FunctionOutput output) { - input.isParameterDeref(this.getParamSrc()) and - output.isParameterDeref(this.getParamDest()) - or - input.isParameterDeref(this.getParamSrc()) and - output.isReturnValueDeref() + exists(int indirectionIndex | + input.isParameterDeref(this.getParamSrc(), indirectionIndex) and + output.isParameterDeref(this.getParamDest(), indirectionIndex) + or + input.isParameterDeref(this.getParamSrc(), indirectionIndex) and + output.isReturnValueDeref(indirectionIndex) + ) or input.isParameter(this.getParamDest()) and output.isReturnValue() diff --git a/cpp/ql/lib/semmle/code/cpp/models/implementations/Scanf.qll b/cpp/ql/lib/semmle/code/cpp/models/implementations/Scanf.qll index 2c82e5423239..ea56a0b6e991 100644 --- a/cpp/ql/lib/semmle/code/cpp/models/implementations/Scanf.qll +++ b/cpp/ql/lib/semmle/code/cpp/models/implementations/Scanf.qll @@ -40,8 +40,10 @@ abstract private class ScanfFunctionModel extends ArrayFunction, TaintFunction, int getArgsStartPosition() { result = this.getNumberOfParameters() } override predicate hasTaintFlow(FunctionInput input, FunctionOutput output) { - input.isParameterDeref(this.(ScanfFunction).getInputParameterIndex()) and - output.isParameterDeref(any(int i | i >= this.getArgsStartPosition())) + exists(int indirectionIndex | + input.isParameterDeref(this.(ScanfFunction).getInputParameterIndex(), indirectionIndex) and + output.isParameterDeref(any(int i | i >= this.getArgsStartPosition()), indirectionIndex) + ) } override predicate parameterNeverEscapes(int index) { diff --git a/cpp/ql/lib/semmle/code/cpp/models/implementations/SmartPointer.qll b/cpp/ql/lib/semmle/code/cpp/models/implementations/SmartPointer.qll index fe5448812fd2..c36ebecbec5b 100644 --- a/cpp/ql/lib/semmle/code/cpp/models/implementations/SmartPointer.qll +++ b/cpp/ql/lib/semmle/code/cpp/models/implementations/SmartPointer.qll @@ -38,12 +38,17 @@ private class PointerUnwrapperFunction extends MemberFunction, TaintFunction, Da } override predicate hasTaintFlow(FunctionInput input, FunctionOutput output) { - input.isReturnValueDeref() and - output.isQualifierObject() + exists(int indirectionIndex | + input.isReturnValueDeref(indirectionIndex) and + output.isQualifierObject(indirectionIndex) + ) } override predicate hasDataFlow(FunctionInput input, FunctionOutput output) { - input.isQualifierObject() and output.isReturnValue() + exists(int indirectionIndex | + input.isQualifierObject(indirectionIndex + 1) and + output.isReturnValueDeref(indirectionIndex) + ) } override predicate hasOnlySpecificReadSideEffects() { any() } @@ -75,11 +80,16 @@ private class MakeUniqueOrShared extends TaintFunction { // since these just take a size argument, which we don't want to propagate taint through. not this.isArray() and ( - input.isParameter([0 .. this.getNumberOfParameters() - 1]) + input.isParameter([0 .. this.getNumberOfParameters() - 1]) and + output.isReturnValue() or - input.isParameterDeref([0 .. this.getNumberOfParameters() - 1]) - ) and - output.isReturnValue() + exists(int indirectionIndex | output.isReturnValueDeref(indirectionIndex) | + input.isParameterDeref([0 .. this.getNumberOfParameters() - 1], indirectionIndex - 1) + or + input.isParameter([0 .. this.getNumberOfParameters() - 1]) and + indirectionIndex = 1 + ) + ) } /** @@ -96,7 +106,9 @@ private class MakeUniqueOrShared extends TaintFunction { * * This could be a constructor, an assignment operator, or a named member function like `reset()`. */ -private class SmartPtrSetterFunction extends MemberFunction, AliasFunction, SideEffectFunction { +private class SmartPtrSetterFunction extends MemberFunction, AliasFunction, SideEffectFunction, + TaintFunction +{ SmartPtrSetterFunction() { this.getDeclaringType() instanceof SmartPtr and not this.isStatic() and @@ -148,6 +160,16 @@ private class SmartPtrSetterFunction extends MemberFunction, AliasFunction, Side output.isReturnValue() } + override predicate hasTaintFlow(FunctionInput input, FunctionOutput output) { + exists(Parameter param0, Type t, int indirectionIndex | + param0 = this.getParameter(0) and + param0.getUnspecifiedType().(PointerType).getBaseType() = t and + this.getTemplateArgument(0) = t and + input.isParameterDeref(0, indirectionIndex) and + output.isQualifierObject(indirectionIndex + 1) + ) + } + private FunctionInput getPointerInput() { exists(Parameter param0 | param0 = this.getParameter(0) | ( 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 5d2133b6f450..d62dc6e7f87c 100644 --- a/cpp/ql/lib/semmle/code/cpp/models/implementations/StdMap.qll +++ b/cpp/ql/lib/semmle/code/cpp/models/implementations/StdMap.qll @@ -32,11 +32,12 @@ private class StdMapConstructor extends Constructor, TaintFunction, AliasFunctio override predicate hasTaintFlow(FunctionInput input, FunctionOutput output) { // taint flow from any parameter of an iterator type to the qualifier - input.isParameterDeref(this.getAnIteratorParameterIndex()) and - ( + exists(int indirectionIndex | + input.isParameterDeref(this.getAnIteratorParameterIndex(), indirectionIndex) + | output.isReturnValue() // TODO: this is only needed for AST data flow, which treats constructors as returning the new object or - output.isQualifierObject() + output.isQualifierObject(indirectionIndex) ) } @@ -69,14 +70,15 @@ private class StdMapInsert extends TaintFunction { override predicate hasTaintFlow(FunctionInput input, FunctionOutput output) { // flow from last parameter to qualifier and return value // (where the return value is a pair, this should really flow just to the first part of it) - input.isParameterDeref(this.getNumberOfParameters() - 1) and - ( - output.isQualifierObject() or + exists(int indirectionIndex | + input.isParameterDeref(this.getNumberOfParameters() - 1, indirectionIndex) + | + output.isQualifierObject(indirectionIndex) or output.isReturnValue() ) } - override predicate isPartialWrite(FunctionOutput output) { output.isQualifierObject() } + override predicate isPartialWrite(FunctionOutput output) { output.isQualifierObject(_) } } /** @@ -90,17 +92,19 @@ private class StdMapEmplace extends TaintFunction { // construct a pair, or a pair to be copied / moved) to the qualifier and // return value. // (where the return value is a pair, this should really flow just to the first part of it) - input.isParameterDeref(this.getNumberOfParameters() - 1) and - ( - output.isQualifierObject() or + exists(int indirectionIndex | + input.isParameterDeref(this.getNumberOfParameters() - 1, indirectionIndex) and + ( + output.isQualifierObject(indirectionIndex) or + output.isReturnValue() + ) + or + input.isQualifierObject(indirectionIndex) and output.isReturnValue() ) - or - input.isQualifierObject() and - output.isReturnValue() } - override predicate isPartialWrite(FunctionOutput output) { output.isQualifierObject() } + override predicate isPartialWrite(FunctionOutput output) { output.isQualifierObject(_) } } /** @@ -113,23 +117,25 @@ private class StdMapTryEmplace extends TaintFunction { // flow from any parameter apart from the key to qualifier and return value // (here we assume taint flow from any constructor parameter to the constructed object) // (where the return value is a pair, this should really flow just to the first part of it) - exists(int arg | arg = [1 .. this.getNumberOfParameters() - 1] | - ( - not this.getUnspecifiedType() instanceof Iterator or - arg != 1 + exists(int indirectionIndex | + exists(int arg | arg = [1 .. this.getNumberOfParameters() - 1] | + ( + not this.getUnspecifiedType() instanceof Iterator or + arg != 1 + ) and + input.isParameterDeref(arg, indirectionIndex) ) and - input.isParameterDeref(arg) - ) and - ( - output.isQualifierObject() or + ( + output.isQualifierObject(indirectionIndex) or + output.isReturnValue() + ) + or + input.isQualifierObject(indirectionIndex) and output.isReturnValue() ) - or - input.isQualifierObject() and - output.isReturnValue() } - override predicate isPartialWrite(FunctionOutput output) { output.isQualifierObject() } + override predicate isPartialWrite(FunctionOutput output) { output.isQualifierObject(_) } } /** @@ -140,11 +146,13 @@ private class StdMapMerge extends TaintFunction { override predicate hasTaintFlow(FunctionInput input, FunctionOutput output) { // container1.merge(container2) - input.isParameterDeref(0) and - output.isQualifierObject() + exists(int indirectionIndex | + input.isParameterDeref(0, indirectionIndex) and + output.isQualifierObject(indirectionIndex) + ) } - override predicate isPartialWrite(FunctionOutput output) { output.isQualifierObject() } + override predicate isPartialWrite(FunctionOutput output) { output.isQualifierObject(_) } } /** @@ -157,12 +165,14 @@ class StdMapAt extends MemberFunction { private class StdMapAtModels extends StdMapAt, TaintFunction, AliasFunction, SideEffectFunction { override predicate hasTaintFlow(FunctionInput input, FunctionOutput output) { // flow from qualifier to referenced return value - input.isQualifierObject() and - output.isReturnValueDeref() - or - // reverse flow from returned reference to the qualifier - input.isReturnValueDeref() and - output.isQualifierObject() + exists(int indirectionIndex | + input.isQualifierObject(indirectionIndex) and + output.isReturnValueDeref(indirectionIndex) + or + // reverse flow from returned reference to the qualifier + input.isReturnValueDeref(indirectionIndex) and + output.isQualifierObject(indirectionIndex) + ) } override predicate hasOnlySpecificReadSideEffects() { any() } @@ -177,7 +187,7 @@ private class StdMapAtModels extends StdMapAt, TaintFunction, AliasFunction, Sid i = -1 and buffer = false } - override predicate isPartialWrite(FunctionOutput output) { output.isQualifierObject() } + override predicate isPartialWrite(FunctionOutput output) { output.isQualifierObject(_) } } /** @@ -187,8 +197,11 @@ private class StdMapFind extends TaintFunction { StdMapFind() { this.getClassAndName("find") instanceof MapOrUnorderedMap } override predicate hasTaintFlow(FunctionInput input, FunctionOutput output) { - input.isQualifierObject() and - output.isReturnValue() + exists(int indirectionIndex | input.isQualifierObject(indirectionIndex) | + output.isReturnValue() + or + output.isReturnValueDeref(indirectionIndex) + ) } } @@ -201,8 +214,11 @@ private class StdMapErase extends TaintFunction { override predicate hasTaintFlow(FunctionInput input, FunctionOutput output) { // flow from qualifier to iterator return value this.getType().getUnderlyingType() instanceof Iterator and - input.isQualifierObject() and - output.isReturnValue() + exists(int indirectionIndex | input.isQualifierObject(indirectionIndex) | + output.isReturnValue() + or + output.isReturnValueDeref(indirectionIndex) + ) } } @@ -216,8 +232,11 @@ private class StdMapEqualRange extends TaintFunction { override predicate hasTaintFlow(FunctionInput input, FunctionOutput output) { // flow from qualifier to return value - input.isQualifierObject() and - output.isReturnValue() + exists(int indirectionIndex | input.isQualifierObject(indirectionIndex) | + output.isReturnValue() + or + output.isReturnValueDeref(indirectionIndex) + ) } } diff --git a/cpp/ql/lib/semmle/code/cpp/models/implementations/StdPair.qll b/cpp/ql/lib/semmle/code/cpp/models/implementations/StdPair.qll index 54b6719e289f..ea6c9a835499 100644 --- a/cpp/ql/lib/semmle/code/cpp/models/implementations/StdPair.qll +++ b/cpp/ql/lib/semmle/code/cpp/models/implementations/StdPair.qll @@ -26,12 +26,13 @@ class StdPairCopyishConstructor extends Constructor, TaintFunction { } override predicate hasTaintFlow(FunctionInput input, FunctionOutput output) { - // taint flow from the source object to the constructed object - input.isParameterDeref(0) and - ( + exists(int indirectionIndex | + // taint flow from the source object to the constructed object + input.isParameterDeref(0, indirectionIndex) + | output.isReturnValue() or - output.isQualifierObject() + output.isQualifierObject(indirectionIndex) ) } } @@ -56,11 +57,10 @@ private class StdPairConstructor extends Constructor, TaintFunction, AliasFuncti override predicate hasTaintFlow(FunctionInput input, FunctionOutput output) { // taint flow from second parameter of a value type to the qualifier this.getAValueTypeParameterIndex() = 1 and - input.isParameterDeref(1) and - ( + exists(int indirectionIndex | input.isParameterDeref(1, indirectionIndex) | output.isReturnValue() // TODO: this is only needed for AST data flow, which treats constructors as returning the new object or - output.isQualifierObject() + output.isQualifierObject(indirectionIndex) ) } 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 8fe7fb930c2c..0386b45256e7 100644 --- a/cpp/ql/lib/semmle/code/cpp/models/implementations/StdSet.qll +++ b/cpp/ql/lib/semmle/code/cpp/models/implementations/StdSet.qll @@ -27,16 +27,17 @@ private class StdSetConstructor extends Constructor, TaintFunction { override predicate hasTaintFlow(FunctionInput input, FunctionOutput output) { // taint flow from any parameter of an iterator type to the qualifier - ( + exists(int indirectionIndex | // AST dataflow doesn't have indirection for iterators. // Once we deprecate AST dataflow we can delete this first disjunct. - input.isParameter(this.getAnIteratorParameterIndex()) or - input.isParameterDeref(this.getAnIteratorParameterIndex()) - ) and - ( + input.isParameter(this.getAnIteratorParameterIndex()) and + indirectionIndex = 1 + or + input.isParameterDeref(this.getAnIteratorParameterIndex(), indirectionIndex) + | output.isReturnValue() // TODO: this is only needed for AST data flow, which treats constructors as returning the new object or - output.isQualifierObject() + output.isQualifierObject(indirectionIndex) ) } } @@ -50,19 +51,19 @@ private class StdSetInsert extends TaintFunction { override predicate hasTaintFlow(FunctionInput input, FunctionOutput output) { // flow from last parameter to qualifier and return value // (where the return value is a pair, this should really flow just to the first part of it) - ( + exists(int indirectionIndex | // AST dataflow doesn't have indirection for iterators. // Once we deprecate AST dataflow we can delete this first disjunct. - input.isParameter(this.getNumberOfParameters() - 1) or - input.isParameterDeref(this.getNumberOfParameters() - 1) - ) and - ( - output.isQualifierObject() or + input.isParameter(this.getNumberOfParameters() - 1) and indirectionIndex = 1 + or + input.isParameterDeref(this.getNumberOfParameters() - 1, indirectionIndex) + | + output.isQualifierObject(indirectionIndex) or output.isReturnValue() ) } - override predicate isPartialWrite(FunctionOutput output) { output.isQualifierObject() } + override predicate isPartialWrite(FunctionOutput output) { output.isQualifierObject(_) } } /** @@ -75,17 +76,20 @@ private class StdSetEmplace extends TaintFunction { // flow from any parameter to qualifier and return value // (here we assume taint flow from any constructor parameter to the constructed object) // (where the return value is a pair, this should really flow just to the first part of it) - input.isParameterDeref([0 .. this.getNumberOfParameters() - 1]) and - ( - output.isQualifierObject() or + exists(int indirectionIndex | + input.isParameterDeref([0 .. this.getNumberOfParameters() - 1], indirectionIndex) + | + output.isQualifierObject(indirectionIndex) or output.isReturnValue() ) or - input.isQualifierObject() and - output.isReturnValue() + exists(int indirectionIndex | + input.isQualifierObject(indirectionIndex) and + output.isReturnValueDeref(indirectionIndex) + ) } - override predicate isPartialWrite(FunctionOutput output) { output.isQualifierObject() } + override predicate isPartialWrite(FunctionOutput output) { output.isQualifierObject(_) } } /** @@ -96,11 +100,13 @@ private class StdSetMerge extends TaintFunction { override predicate hasTaintFlow(FunctionInput input, FunctionOutput output) { // container1.merge(container2) - input.isParameterDeref(0) and - output.isQualifierObject() + exists(int indirectionIndex | + input.isParameterDeref(0, indirectionIndex) and + output.isQualifierObject(indirectionIndex) + ) } - override predicate isPartialWrite(FunctionOutput output) { output.isQualifierObject() } + override predicate isPartialWrite(FunctionOutput output) { output.isQualifierObject(_) } } /** @@ -110,8 +116,11 @@ private class StdSetFind extends TaintFunction { StdSetFind() { this.getClassAndName("find") instanceof StdSet } override predicate hasTaintFlow(FunctionInput input, FunctionOutput output) { - input.isQualifierObject() and - output.isReturnValue() + exists(int indirectionIndex | input.isQualifierObject(indirectionIndex) | + output.isReturnValueDeref(indirectionIndex) + or + output.isReturnValue() + ) } } @@ -124,8 +133,10 @@ private class StdSetErase extends TaintFunction { override predicate hasTaintFlow(FunctionInput input, FunctionOutput output) { // flow from qualifier to iterator return value this.getType().getUnderlyingType() instanceof Iterator and - input.isQualifierObject() and - output.isReturnValue() + exists(int indirectionIndex | + input.isQualifierObject(indirectionIndex) and + output.isReturnValueDeref(indirectionIndex) + ) } } @@ -139,7 +150,10 @@ private class StdSetEqualRange extends TaintFunction { override predicate hasTaintFlow(FunctionInput input, FunctionOutput output) { // flow from qualifier to return value - input.isQualifierObject() and - output.isReturnValue() + exists(int indirectionIndex | input.isQualifierObject(indirectionIndex) | + output.isReturnValueDeref(indirectionIndex) + or + output.isReturnValue() + ) } } 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 00dc8d26ad39..48463b0f4089 100644 --- a/cpp/ql/lib/semmle/code/cpp/models/implementations/StdString.qll +++ b/cpp/ql/lib/semmle/code/cpp/models/implementations/StdString.qll @@ -87,15 +87,18 @@ private class StdStringConstructor extends Constructor, StdStringTaintFunction, override predicate hasTaintFlow(FunctionInput input, FunctionOutput output) { // taint flow from any parameter of the value type to the returned object - ( - input.isParameterDeref(this.getAStringParameterIndex()) or - input.isParameter(this.getACharParameterIndex()) or + exists(int indirectionIndex | + input.isParameterDeref(this.getAStringParameterIndex(), indirectionIndex) + or + indirectionIndex = 1 and + input.isParameter(this.getACharParameterIndex()) + or + indirectionIndex = 1 and input.isParameter(this.getAnIteratorParameterIndex()) - ) and - ( + | output.isReturnValue() // TODO: this is only needed for AST data flow, which treats constructors as returning the new object or - output.isQualifierObject() + output.isQualifierObject(indirectionIndex) ) } diff --git a/cpp/ql/lib/semmle/code/cpp/models/implementations/Strcat.qll b/cpp/ql/lib/semmle/code/cpp/models/implementations/Strcat.qll index df16d220e02d..3e1c39004476 100644 --- a/cpp/ql/lib/semmle/code/cpp/models/implementations/Strcat.qll +++ b/cpp/ql/lib/semmle/code/cpp/models/implementations/Strcat.qll @@ -64,9 +64,7 @@ class StrcatFunction extends TaintFunction, DataFlowFunction, ArrayFunction, Sid this.getName() = ["_mbsncat_l", "_mbsnbcat_l"] and input.isParameter(3) or - input.isParameterDeref(0) - or - input.isParameterDeref(1) + input.isParameterDeref([0, 1], 1) ) and (output.isParameterDeref(0) or output.isReturnValueDeref()) } diff --git a/cpp/ql/lib/semmle/code/cpp/models/implementations/Strtok.qll b/cpp/ql/lib/semmle/code/cpp/models/implementations/Strtok.qll index 6ccc4eb2fbe1..53b8e03d7f2f 100644 --- a/cpp/ql/lib/semmle/code/cpp/models/implementations/Strtok.qll +++ b/cpp/ql/lib/semmle/code/cpp/models/implementations/Strtok.qll @@ -67,9 +67,7 @@ private class Strsep extends ArrayFunction, AliasFunction, TaintFunction, SideEf override predicate parameterIsAlwaysReturned(int index) { none() } override predicate hasTaintFlow(FunctionInput input, FunctionOutput output) { - // NOTE: What we really want here is: (input.isParameterDerefDeref(0) or input.isParameterDeref(1)) - // as the first conjunct. - input.isParameterDeref([0, 1]) and + (input.isParameterDeref(0, 2) or input.isParameterDeref(1)) and (output.isReturnValue() or output.isReturnValueDeref()) } diff --git a/cpp/ql/lib/semmle/code/cpp/models/implementations/Swap.qll b/cpp/ql/lib/semmle/code/cpp/models/implementations/Swap.qll index 2e8e7ef6e90f..46e96a234c50 100644 --- a/cpp/ql/lib/semmle/code/cpp/models/implementations/Swap.qll +++ b/cpp/ql/lib/semmle/code/cpp/models/implementations/Swap.qll @@ -12,11 +12,13 @@ private class Swap extends DataFlowFunction { Swap() { this.hasQualifiedName(["std", "bsl"], "swap") } override predicate hasDataFlow(FunctionInput input, FunctionOutput output) { - input.isParameterDeref(0) and - output.isParameterDeref(1) - or - input.isParameterDeref(1) and - output.isParameterDeref(0) + exists(int indirectionIndex | + input.isParameterDeref(0, indirectionIndex) and + output.isParameterDeref(1, indirectionIndex) + or + input.isParameterDeref(1, indirectionIndex) and + output.isParameterDeref(0, indirectionIndex) + ) } } @@ -35,11 +37,13 @@ private class MemberSwap extends DataFlowFunction, MemberFunction, AliasFunction } override predicate hasDataFlow(FunctionInput input, FunctionOutput output) { - input.isQualifierObject() and - output.isParameterDeref(0) - or - input.isParameterDeref(0) and - output.isQualifierObject() + exists(int indirectionIndex | + input.isQualifierObject(indirectionIndex) and + output.isParameterDeref(0, indirectionIndex) + or + input.isParameterDeref(0, indirectionIndex) and + output.isQualifierObject(indirectionIndex) + ) } override predicate parameterNeverEscapes(int index) { none() } diff --git a/cpp/ql/lib/semmle/code/cpp/models/interfaces/FunctionInputsAndOutputs.qll b/cpp/ql/lib/semmle/code/cpp/models/interfaces/FunctionInputsAndOutputs.qll index d81bc960988c..78862f05882a 100644 --- a/cpp/ql/lib/semmle/code/cpp/models/interfaces/FunctionInputsAndOutputs.qll +++ b/cpp/ql/lib/semmle/code/cpp/models/interfaces/FunctionInputsAndOutputs.qll @@ -9,9 +9,9 @@ import semmle.code.cpp.Parameter private newtype TFunctionInput = TInParameter(ParameterIndex i) or TInParameterDeref(ParameterIndex i, int indirectionIndex) { indirectionIndex = [1, 2] } or - TInQualifierObject() or + TInQualifierObject(int indirectionIndex) { indirectionIndex = [1, 2] } or TInQualifierAddress() or - TInReturnValueDeref() + TInReturnValueDeref(int indirectionIndex) { indirectionIndex = [1, 2] } /** * An input to a function. This can be: @@ -84,7 +84,7 @@ class FunctionInput extends TFunctionInput { * - There is no `FunctionInput` for which `isParameterDeref(0)` holds, because `n` is neither a * pointer nor a reference. */ - predicate isParameterDeref(ParameterIndex index) { this.isParameterDeref(index, 1) } + final predicate isParameterDeref(ParameterIndex index) { this.isParameterDeref(index, 1) } /** * Holds if this is the input value pointed to by the `this` pointer of an instance member @@ -114,7 +114,7 @@ class FunctionInput extends TFunctionInput { * - `isQualifierObject()` holds for the `FunctionInput` that represents the value of `*this` * (with type `C const`) on entry to the function. */ - predicate isQualifierObject() { this.isQualifierObject(1) } + final predicate isQualifierObject() { this.isQualifierObject(1) } /** * Holds if this is the input value of the `this` pointer of an instance member function. @@ -163,7 +163,7 @@ class FunctionInput extends TFunctionInput { * rare, but they do occur when a function returns a reference to itself, * part of itself, or one of its other inputs. */ - predicate isReturnValueDeref() { this.isReturnValueDeref(1) } + final predicate isReturnValueDeref() { this.isReturnValueDeref(1) } /** * Holds if this is the input value pointed to by the return value of a @@ -176,9 +176,9 @@ class FunctionInput extends TFunctionInput { * float& getReference(); * int getInt(); * ``` - * - `isReturnValueDeref(1)` holds for the `FunctionInput` that represents the + * - `isReturnValueDeref()` holds for the `FunctionInput` that represents the * value of `*getPointer()` (with type `char`). - * - `isReturnValueDeref(1)` holds for the `FunctionInput` that represents the + * - `isReturnValueDeref()` holds for the `FunctionInput` that represents the * value of `getReference()` (with type `float`). * - There is no `FunctionInput` of `getInt()` for which * `isReturnValueDeref(_)` holds because the return type of `getInt()` is @@ -286,11 +286,17 @@ class InParameterDeref extends FunctionInput, TInParameterDeref { * function. */ class InQualifierObject extends FunctionInput, TInQualifierObject { + int indirectionIndex; + + InQualifierObject() { this = TInQualifierObject(indirectionIndex) } + override string toString() { result = "InQualifierObject" } - override predicate isQualifierObject() { any() } + override predicate isQualifierObject(int indirectionIndex_) { + indirectionIndex_ = indirectionIndex + } - override FunctionInput getIndirectionInput() { none() } + override FunctionInput getIndirectionInput() { result = TInQualifierObject(indirectionIndex + 1) } } /** @@ -310,7 +316,7 @@ class InQualifierAddress extends FunctionInput, TInQualifierAddress { override predicate isQualifierAddress() { any() } - override FunctionInput getIndirectionInput() { result = TInQualifierObject() } + override FunctionInput getIndirectionInput() { result = TInQualifierObject(1) } } /** @@ -336,16 +342,25 @@ class InQualifierAddress extends FunctionInput, TInQualifierAddress { * part of itself, or one of its other inputs. */ class InReturnValueDeref extends FunctionInput, TInReturnValueDeref { + int indirectionIndex; + + InReturnValueDeref() { this = TInReturnValueDeref(indirectionIndex) } + override string toString() { result = "InReturnValueDeref" } - override predicate isReturnValueDeref() { any() } + // override predicate isReturnValueDeref() { any() } + override predicate isReturnValueDeref(int indirectionIndex_) { + indirectionIndex_ = indirectionIndex + } - override FunctionInput getIndirectionInput() { none() } + override FunctionInput getIndirectionInput() { + result = TInReturnValueDeref(indirectionIndex + 1) + } } private newtype TFunctionOutput = TOutParameterDeref(ParameterIndex i, int indirectionIndex) { indirectionIndex = [1, 2] } or - TOutQualifierObject() or + TOutQualifierObject(int indirectionIndex) { indirectionIndex = [1, 2] } or TOutReturnValue() or TOutReturnValueDeref(int indirections) { indirections = [1, 2] } @@ -384,7 +399,7 @@ class FunctionOutput extends TFunctionOutput { * - There is no `FunctionOutput` for which `isParameterDeref(0)` holds, because `n` is neither a * pointer nor a reference. */ - predicate isParameterDeref(ParameterIndex i) { this.isParameterDeref(i, 1) } + final predicate isParameterDeref(ParameterIndex i) { this.isParameterDeref(i, 1) } /** * Holds if this is the output value pointed to by a pointer parameter (through `ind` number @@ -417,7 +432,7 @@ class FunctionOutput extends TFunctionOutput { * - `isQualifierObject()` holds for the `FunctionOutput` that represents the value of `*this` * (with type `C`) on return from the function. */ - predicate isQualifierObject() { this.isQualifierObject(1) } + final predicate isQualifierObject() { this.isQualifierObject(1) } /** * Holds if this is the output value pointed to by the `this` pointer of an instance member @@ -471,7 +486,7 @@ class FunctionOutput extends TFunctionOutput { * - There is no `FunctionOutput` of `getInt()` for which `isReturnValueDeref()` holds because the * return type of `getInt()` is neither a pointer nor a reference. */ - predicate isReturnValueDeref() { this.isReturnValueDeref(_) } + final predicate isReturnValueDeref() { this.isReturnValueDeref(1) } /** * Holds if this is the output value pointed to by the return value of a function, if the function @@ -484,9 +499,9 @@ class FunctionOutput extends TFunctionOutput { * float& getReference(); * int getInt(); * ``` - * - `isReturnValueDeref(1)` holds for the `FunctionOutput` that represents the value of + * - `isReturnValueDeref()` holds for the `FunctionOutput` that represents the value of * `*getPointer()` (with type `char`). - * - `isReturnValueDeref(1)` holds for the `FunctionOutput` that represents the value of + * - `isReturnValueDeref()` holds for the `FunctionOutput` that represents the value of * `getReference()` (with type `float`). * - There is no `FunctionOutput` of `getInt()` for which `isReturnValueDeref(_)` holds because the * return type of `getInt()` is neither a pointer nor a reference. @@ -559,11 +574,19 @@ class OutParameterDeref extends FunctionOutput, TOutParameterDeref { * function. */ class OutQualifierObject extends FunctionOutput, TOutQualifierObject { + int indirectionIndex; + + OutQualifierObject() { this = TOutQualifierObject(indirectionIndex) } + override string toString() { result = "OutQualifierObject" } - override predicate isQualifierObject() { any() } + override predicate isQualifierObject(int indirectionIndex_) { + indirectionIndex_ = indirectionIndex + } - override FunctionOutput getIndirectionOutput() { none() } + override FunctionOutput getIndirectionOutput() { + result = TOutQualifierObject(indirectionIndex + 1) + } } /** @@ -613,8 +636,6 @@ class OutReturnValueDeref extends FunctionOutput, TOutReturnValueDeref { override string toString() { result = "OutReturnValueDeref" } - override predicate isReturnValueDeref() { any() } - override predicate isReturnValueDeref(int indirectionIndex_) { indirectionIndex = indirectionIndex_ } diff --git a/cpp/ql/test/library-tests/dataflow/dataflow-tests/TestBase.qll b/cpp/ql/test/library-tests/dataflow/dataflow-tests/TestBase.qll index e28d19133c75..86933caa86b8 100644 --- a/cpp/ql/test/library-tests/dataflow/dataflow-tests/TestBase.qll +++ b/cpp/ql/test/library-tests/dataflow/dataflow-tests/TestBase.qll @@ -95,8 +95,8 @@ module IRTest { output.isReturnValue() or argIndToReturnInd = true and - input.isParameterDeref(0, 1) and - output.isReturnValueDeref(1) + input.isParameterDeref(0) and + output.isReturnValueDeref() or argIndInToReturnIndInd = true and input.isParameterDeref(0, 2) and diff --git a/cpp/ql/test/library-tests/dataflow/dataflow-tests/dataflow-ir-consistency.expected b/cpp/ql/test/library-tests/dataflow/dataflow-tests/dataflow-ir-consistency.expected index d0d49db4a21f..132a30e218d4 100644 --- a/cpp/ql/test/library-tests/dataflow/dataflow-tests/dataflow-ir-consistency.expected +++ b/cpp/ql/test/library-tests/dataflow/dataflow-tests/dataflow-ir-consistency.expected @@ -21,9 +21,14 @@ argHasPostUpdate postWithInFlow | flowOut.cpp:84:3:84:14 | *access to array | PostUpdateNode should not be the target of local flow. | | flowOut.cpp:111:28:111:31 | memcpy output argument | PostUpdateNode should not be the target of local flow. | +| flowOut.cpp:111:28:111:31 | memcpy output argument | PostUpdateNode should not be the target of local flow. | +| test.cpp:384:10:384:13 | memcpy output argument | PostUpdateNode should not be the target of local flow. | | test.cpp:384:10:384:13 | memcpy output argument | PostUpdateNode should not be the target of local flow. | | test.cpp:391:10:391:13 | memcpy output argument | PostUpdateNode should not be the target of local flow. | +| test.cpp:391:10:391:13 | memcpy output argument | PostUpdateNode should not be the target of local flow. | | test.cpp:400:10:400:13 | memcpy output argument | PostUpdateNode should not be the target of local flow. | +| test.cpp:400:10:400:13 | memcpy output argument | PostUpdateNode should not be the target of local flow. | +| test.cpp:407:10:407:13 | memcpy output argument | PostUpdateNode should not be the target of local flow. | | test.cpp:407:10:407:13 | memcpy output argument | PostUpdateNode should not be the target of local flow. | | test.cpp:1045:9:1045:11 | memset output argument | PostUpdateNode should not be the target of local flow. | | test.cpp:1076:2:1076:3 | swap output argument | PostUpdateNode should not be the target of local flow. | diff --git a/cpp/ql/test/library-tests/dataflow/dataflow-tests/localFlow-ir.expected b/cpp/ql/test/library-tests/dataflow/dataflow-tests/localFlow-ir.expected index 3aa5b3c30e02..ad1756c7b111 100644 --- a/cpp/ql/test/library-tests/dataflow/dataflow-tests/localFlow-ir.expected +++ b/cpp/ql/test/library-tests/dataflow/dataflow-tests/localFlow-ir.expected @@ -124,12 +124,12 @@ | test.cpp:384:10:384:13 | pointer to memcpy output argument | test.cpp:385:8:385:10 | tmp | | test.cpp:384:11:384:13 | tmp | test.cpp:384:10:384:13 | & ... | | test.cpp:384:16:384:23 | & ... | test.cpp:384:16:384:23 | & ... | -| test.cpp:384:16:384:23 | *& ... | test.cpp:384:3:384:8 | **call to memcpy | | test.cpp:384:16:384:23 | *& ... | test.cpp:384:3:384:8 | *call to memcpy | | test.cpp:384:16:384:23 | *& ... | test.cpp:384:10:384:13 | memcpy output argument | | test.cpp:384:16:384:23 | *& ... | test.cpp:384:16:384:23 | *& ... | | test.cpp:384:16:384:23 | **& ... | test.cpp:384:3:384:8 | **call to memcpy | | test.cpp:384:16:384:23 | **& ... | test.cpp:384:10:384:13 | memcpy output argument | +| test.cpp:384:16:384:23 | **& ... | test.cpp:384:10:384:13 | memcpy output argument | | test.cpp:384:17:384:23 | source1 | test.cpp:384:16:384:23 | & ... | | test.cpp:388:53:388:59 | source1 | test.cpp:391:16:391:23 | *& ... | | test.cpp:388:66:388:66 | b | test.cpp:393:7:393:7 | b | @@ -148,12 +148,12 @@ | test.cpp:391:10:391:13 | pointer to memcpy output argument | test.cpp:392:8:392:10 | tmp | | test.cpp:391:11:391:13 | tmp | test.cpp:391:10:391:13 | & ... | | test.cpp:391:16:391:23 | & ... | test.cpp:391:16:391:23 | & ... | -| test.cpp:391:16:391:23 | *& ... | test.cpp:391:3:391:8 | **call to memcpy | | test.cpp:391:16:391:23 | *& ... | test.cpp:391:3:391:8 | *call to memcpy | | test.cpp:391:16:391:23 | *& ... | test.cpp:391:10:391:13 | memcpy output argument | | test.cpp:391:16:391:23 | *& ... | test.cpp:391:16:391:23 | *& ... | | test.cpp:391:16:391:23 | **& ... | test.cpp:391:3:391:8 | **call to memcpy | | test.cpp:391:16:391:23 | **& ... | test.cpp:391:10:391:13 | memcpy output argument | +| test.cpp:391:16:391:23 | **& ... | test.cpp:391:10:391:13 | memcpy output argument | | test.cpp:391:17:391:23 | source1 | test.cpp:391:16:391:23 | & ... | | test.cpp:392:8:392:10 | tmp | test.cpp:394:10:394:12 | tmp | | test.cpp:392:8:392:10 | tmp | test.cpp:394:10:394:12 | tmp | diff --git a/cpp/ql/test/library-tests/dataflow/external-models/flow.expected b/cpp/ql/test/library-tests/dataflow/external-models/flow.expected index 4142b09473a9..7a956c1f60fd 100644 --- a/cpp/ql/test/library-tests/dataflow/external-models/flow.expected +++ b/cpp/ql/test/library-tests/dataflow/external-models/flow.expected @@ -98,7 +98,7 @@ edges | azure.cpp:277:45:277:47 | call to GetBody | azure.cpp:278:10:278:13 | body | provenance | | | azure.cpp:278:10:278:13 | body | azure.cpp:278:10:278:13 | body | provenance | | | azure.cpp:281:68:281:84 | *call to ExtractBodyStream | azure.cpp:281:68:281:84 | *call to ExtractBodyStream | provenance | Src:MaD:26 | -| azure.cpp:281:68:281:84 | *call to ExtractBodyStream | azure.cpp:282:21:282:23 | *call to get | provenance | | +| azure.cpp:281:68:281:84 | *call to ExtractBodyStream | azure.cpp:282:21:282:23 | *call to get | provenance | DataFlowFunction | | azure.cpp:282:21:282:23 | *call to get | azure.cpp:115:30:115:38 | [summary param] this in ReadToEnd | provenance | | | azure.cpp:282:21:282:23 | *call to get | azure.cpp:282:28:282:36 | call to ReadToEnd [element] | provenance | MaD:55 | | azure.cpp:282:28:282:36 | call to ReadToEnd [element] | azure.cpp:282:10:282:38 | call to ReadToEnd | provenance | | diff --git a/cpp/ql/test/library-tests/dataflow/fields/dataflow-ir-consistency.expected b/cpp/ql/test/library-tests/dataflow/fields/dataflow-ir-consistency.expected index 364c6549fe5e..718125a83bb8 100644 --- a/cpp/ql/test/library-tests/dataflow/fields/dataflow-ir-consistency.expected +++ b/cpp/ql/test/library-tests/dataflow/fields/dataflow-ir-consistency.expected @@ -19,6 +19,8 @@ reverseRead argHasPostUpdate postWithInFlow | realistic.cpp:54:16:54:47 | memcpy output argument | PostUpdateNode should not be the target of local flow. | +| realistic.cpp:54:16:54:47 | memcpy output argument | PostUpdateNode should not be the target of local flow. | +| realistic.cpp:60:16:60:18 | memcpy output argument | PostUpdateNode should not be the target of local flow. | | realistic.cpp:60:16:60:18 | memcpy output argument | PostUpdateNode should not be the target of local flow. | viableImplInCallContextTooLarge uniqueParameterNodeAtPosition diff --git a/cpp/ql/test/library-tests/dataflow/smart-pointers-taint/memory.h b/cpp/ql/test/library-tests/dataflow/smart-pointers-taint/memory.h index 79f39b831c60..7fd65b9ce6f5 100644 --- a/cpp/ql/test/library-tests/dataflow/smart-pointers-taint/memory.h +++ b/cpp/ql/test/library-tests/dataflow/smart-pointers-taint/memory.h @@ -108,7 +108,7 @@ namespace std { public: constexpr shared_ptr() noexcept = default; - shared_ptr(T* ptr) : ctrl(new ctrl_block_impl(ptr, default_delete())) {} + template shared_ptr(U* ptr) : ctrl(new ctrl_block_impl(ptr, default_delete())) {} shared_ptr(const shared_ptr& s) noexcept : ptr(s.ptr), ctrl(s.ctrl) { inc(); } diff --git a/cpp/ql/test/library-tests/dataflow/smart-pointers-taint/test.cpp b/cpp/ql/test/library-tests/dataflow/smart-pointers-taint/test.cpp index 8d0dd6b12200..c684c8b9fe31 100644 --- a/cpp/ql/test/library-tests/dataflow/smart-pointers-taint/test.cpp +++ b/cpp/ql/test/library-tests/dataflow/smart-pointers-taint/test.cpp @@ -31,7 +31,7 @@ void test_shared_ptr_int() { std::shared_ptr p1(new int(source())); std::shared_ptr p2 = std::make_shared(source()); - sink(*p1); // $ ast,ir + sink(*p1); // $ ast ir sink(*p2); // $ ast ir } diff --git a/cpp/ql/test/library-tests/dataflow/source-sink-tests/sources-and-sinks.cpp b/cpp/ql/test/library-tests/dataflow/source-sink-tests/sources-and-sinks.cpp index 7edd46344382..07b69332511e 100644 --- a/cpp/ql/test/library-tests/dataflow/source-sink-tests/sources-and-sinks.cpp +++ b/cpp/ql/test/library-tests/dataflow/source-sink-tests/sources-and-sinks.cpp @@ -3,9 +3,9 @@ char *secure_getenv(const char *name); wchar_t *_wgetenv(const wchar_t *name); void test_getenv() { - void *var1 = getenv("VAR"); // $ local_source=6:18 local_source=6:18 - void *var2 = secure_getenv("VAR"); // $ local_source=7:18 local_source=7:18 - void *var3 = _wgetenv(L"VAR"); // $ local_source=8:18 local_source=8:18 + void *var1 = getenv("VAR"); // $ local_source + void *var2 = secure_getenv("VAR"); // $ local_source + void *var3 = _wgetenv(L"VAR"); // $ local_source } int send(int, const void*, int, int); 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 d4d961a3a048..9794a343f333 100644 --- a/cpp/ql/test/library-tests/dataflow/taint-tests/localTaint.expected +++ b/cpp/ql/test/library-tests/dataflow/taint-tests/localTaint.expected @@ -4642,19 +4642,19 @@ WARNING: module 'TaintTracking' has been deprecated and may be removed in future | smart_pointer.cpp:47:11:47:11 | p | smart_pointer.cpp:47:10:47:10 | call to operator* | | | smart_pointer.cpp:51:30:51:50 | call to make_shared | smart_pointer.cpp:52:10:52:10 | p | | | smart_pointer.cpp:51:52:51:57 | call to source | smart_pointer.cpp:51:30:51:50 | call to make_shared | TAINT | -| smart_pointer.cpp:52:10:52:10 | p | smart_pointer.cpp:52:12:52:14 | call to get | | +| smart_pointer.cpp:52:10:52:10 | p | smart_pointer.cpp:52:12:52:14 | call to get | TAINT | | smart_pointer.cpp:52:12:52:14 | ref arg call to get | smart_pointer.cpp:52:10:52:10 | ref arg p | TAINT | | smart_pointer.cpp:56:30:56:50 | call to make_unique | smart_pointer.cpp:57:10:57:10 | p | | | smart_pointer.cpp:56:52:56:57 | call to source | smart_pointer.cpp:56:30:56:50 | call to make_unique | TAINT | -| smart_pointer.cpp:57:10:57:10 | p | smart_pointer.cpp:57:12:57:14 | call to get | | +| smart_pointer.cpp:57:10:57:10 | p | smart_pointer.cpp:57:12:57:14 | call to get | TAINT | | smart_pointer.cpp:57:12:57:14 | ref arg call to get | smart_pointer.cpp:57:10:57:10 | ref arg p | TAINT | | smart_pointer.cpp:65:28:65:46 | call to make_unique | smart_pointer.cpp:66:10:66:10 | p | | | smart_pointer.cpp:65:28:65:46 | call to make_unique | smart_pointer.cpp:67:10:67:10 | p | | | smart_pointer.cpp:65:48:65:53 | call to source | smart_pointer.cpp:65:28:65:46 | call to make_unique | TAINT | | smart_pointer.cpp:65:58:65:58 | 0 | smart_pointer.cpp:65:28:65:46 | call to make_unique | TAINT | -| smart_pointer.cpp:66:10:66:10 | p | smart_pointer.cpp:66:11:66:11 | call to operator-> | | +| smart_pointer.cpp:66:10:66:10 | p | smart_pointer.cpp:66:11:66:11 | call to operator-> | TAINT | | smart_pointer.cpp:66:10:66:10 | ref arg p | smart_pointer.cpp:67:10:67:10 | p | | -| smart_pointer.cpp:67:10:67:10 | p | smart_pointer.cpp:67:11:67:11 | call to operator-> | | +| smart_pointer.cpp:67:10:67:10 | p | smart_pointer.cpp:67:11:67:11 | call to operator-> | TAINT | | smart_pointer.cpp:70:37:70:39 | ptr | smart_pointer.cpp:70:37:70:39 | ptr | | | smart_pointer.cpp:70:37:70:39 | ptr | smart_pointer.cpp:71:4:71:6 | ptr | | | smart_pointer.cpp:71:3:71:3 | call to operator* [post update] | smart_pointer.cpp:70:37:70:39 | ptr | | @@ -4682,36 +4682,34 @@ WARNING: module 'TaintTracking' has been deprecated and may be removed in future | smart_pointer.cpp:86:67:86:67 | q | smart_pointer.cpp:92:8:92:8 | q | | | smart_pointer.cpp:86:67:86:67 | q | smart_pointer.cpp:93:8:93:8 | q | | | smart_pointer.cpp:86:67:86:67 | q | smart_pointer.cpp:94:8:94:8 | q | | -| smart_pointer.cpp:87:3:87:3 | p | smart_pointer.cpp:87:4:87:4 | call to operator-> | | +| smart_pointer.cpp:87:3:87:3 | p | smart_pointer.cpp:87:4:87:4 | call to operator-> | TAINT | | smart_pointer.cpp:87:3:87:3 | ref arg p | smart_pointer.cpp:86:45:86:45 | p | | | smart_pointer.cpp:87:3:87:3 | ref arg p | smart_pointer.cpp:88:8:88:8 | p | | | smart_pointer.cpp:87:3:87:3 | ref arg p | smart_pointer.cpp:89:8:89:8 | p | | | smart_pointer.cpp:87:3:87:17 | ... = ... | smart_pointer.cpp:87:6:87:6 | x [post update] | | -| smart_pointer.cpp:87:3:87:17 | ... = ... | smart_pointer.cpp:88:11:88:11 | x | | | smart_pointer.cpp:87:4:87:4 | call to operator-> [post update] | smart_pointer.cpp:87:3:87:3 | ref arg p | TAINT | | smart_pointer.cpp:87:10:87:15 | call to source | smart_pointer.cpp:87:3:87:17 | ... = ... | | -| smart_pointer.cpp:88:8:88:8 | p | smart_pointer.cpp:88:9:88:9 | call to operator-> | | +| smart_pointer.cpp:88:8:88:8 | p | smart_pointer.cpp:88:9:88:9 | call to operator-> | TAINT | | smart_pointer.cpp:88:8:88:8 | ref arg p | smart_pointer.cpp:86:45:86:45 | p | | | smart_pointer.cpp:88:8:88:8 | ref arg p | smart_pointer.cpp:89:8:89:8 | p | | -| smart_pointer.cpp:89:8:89:8 | p | smart_pointer.cpp:89:9:89:9 | call to operator-> | | +| smart_pointer.cpp:89:8:89:8 | p | smart_pointer.cpp:89:9:89:9 | call to operator-> | TAINT | | smart_pointer.cpp:89:8:89:8 | ref arg p | smart_pointer.cpp:86:45:86:45 | p | | -| smart_pointer.cpp:91:3:91:3 | q | smart_pointer.cpp:91:4:91:4 | call to operator-> | | +| smart_pointer.cpp:91:3:91:3 | q | smart_pointer.cpp:91:4:91:4 | call to operator-> | TAINT | | smart_pointer.cpp:91:3:91:3 | ref arg q | smart_pointer.cpp:86:67:86:67 | q | | | smart_pointer.cpp:91:3:91:3 | ref arg q | smart_pointer.cpp:92:8:92:8 | q | | | smart_pointer.cpp:91:3:91:3 | ref arg q | smart_pointer.cpp:93:8:93:8 | q | | | smart_pointer.cpp:91:3:91:3 | ref arg q | smart_pointer.cpp:94:8:94:8 | q | | | smart_pointer.cpp:91:3:91:20 | ... = ... | smart_pointer.cpp:91:9:91:9 | x [post update] | | -| smart_pointer.cpp:91:3:91:20 | ... = ... | smart_pointer.cpp:92:14:92:14 | x | | | smart_pointer.cpp:91:4:91:4 | call to operator-> [post update] | smart_pointer.cpp:91:3:91:3 | ref arg q | TAINT | | smart_pointer.cpp:91:13:91:18 | call to source | smart_pointer.cpp:91:3:91:20 | ... = ... | | -| smart_pointer.cpp:92:8:92:8 | q | smart_pointer.cpp:92:9:92:9 | call to operator-> | | +| smart_pointer.cpp:92:8:92:8 | q | smart_pointer.cpp:92:9:92:9 | call to operator-> | TAINT | | smart_pointer.cpp:92:8:92:8 | ref arg q | smart_pointer.cpp:86:67:86:67 | q | | | smart_pointer.cpp:92:8:92:8 | ref arg q | smart_pointer.cpp:93:8:93:8 | q | | | smart_pointer.cpp:92:8:92:8 | ref arg q | smart_pointer.cpp:94:8:94:8 | q | | -| smart_pointer.cpp:93:8:93:8 | q | smart_pointer.cpp:93:9:93:9 | call to operator-> | | +| smart_pointer.cpp:93:8:93:8 | q | smart_pointer.cpp:93:9:93:9 | call to operator-> | TAINT | | smart_pointer.cpp:93:8:93:8 | ref arg q | smart_pointer.cpp:86:67:86:67 | q | | | smart_pointer.cpp:93:8:93:8 | ref arg q | smart_pointer.cpp:94:8:94:8 | q | | -| smart_pointer.cpp:94:8:94:8 | q | smart_pointer.cpp:94:9:94:9 | call to operator-> | | +| smart_pointer.cpp:94:8:94:8 | q | smart_pointer.cpp:94:9:94:9 | call to operator-> | TAINT | | smart_pointer.cpp:94:8:94:8 | ref arg q | smart_pointer.cpp:86:67:86:67 | q | | | smart_pointer.cpp:97:17:97:18 | pa | smart_pointer.cpp:97:17:97:18 | pa | | | smart_pointer.cpp:97:17:97:18 | pa | smart_pointer.cpp:98:5:98:6 | pa | | @@ -4720,20 +4718,20 @@ WARNING: module 'TaintTracking' has been deprecated and may be removed in future | smart_pointer.cpp:98:13:98:18 | call to source | smart_pointer.cpp:98:5:98:20 | ... = ... | | | smart_pointer.cpp:102:25:102:50 | call to unique_ptr | smart_pointer.cpp:103:11:103:11 | p | | | smart_pointer.cpp:102:25:102:50 | call to unique_ptr | smart_pointer.cpp:104:8:104:8 | p | | -| smart_pointer.cpp:103:11:103:11 | p | smart_pointer.cpp:103:13:103:15 | call to get | | +| smart_pointer.cpp:103:11:103:11 | p | smart_pointer.cpp:103:13:103:15 | call to get | TAINT | | smart_pointer.cpp:103:11:103:11 | ref arg p | smart_pointer.cpp:104:8:104:8 | p | | | smart_pointer.cpp:103:13:103:15 | ref arg call to get | smart_pointer.cpp:103:11:103:11 | ref arg p | TAINT | -| smart_pointer.cpp:104:8:104:8 | p | smart_pointer.cpp:104:9:104:9 | call to operator-> | | +| smart_pointer.cpp:104:8:104:8 | p | smart_pointer.cpp:104:9:104:9 | call to operator-> | TAINT | | smart_pointer.cpp:112:40:112:42 | ptr | smart_pointer.cpp:112:40:112:42 | ptr | | | smart_pointer.cpp:112:40:112:42 | ptr | smart_pointer.cpp:113:2:113:4 | ptr | | -| smart_pointer.cpp:113:2:113:4 | ptr | smart_pointer.cpp:113:5:113:5 | call to operator-> | | +| smart_pointer.cpp:113:2:113:4 | ptr | smart_pointer.cpp:113:5:113:5 | call to operator-> | TAINT | | smart_pointer.cpp:113:2:113:4 | ref arg ptr | smart_pointer.cpp:112:40:112:42 | ptr | | | smart_pointer.cpp:113:2:113:18 | ... = ... | smart_pointer.cpp:113:7:113:7 | x [post update] | | | smart_pointer.cpp:113:5:113:5 | call to operator-> [post update] | smart_pointer.cpp:113:2:113:4 | ref arg ptr | TAINT | | smart_pointer.cpp:113:11:113:16 | call to source | smart_pointer.cpp:113:2:113:18 | ... = ... | | | smart_pointer.cpp:116:52:116:54 | ptr | smart_pointer.cpp:116:52:116:54 | ptr | | | smart_pointer.cpp:116:52:116:54 | ptr | smart_pointer.cpp:117:2:117:4 | ptr | | -| smart_pointer.cpp:117:2:117:4 | ptr | smart_pointer.cpp:117:5:117:5 | call to operator-> | | +| smart_pointer.cpp:117:2:117:4 | ptr | smart_pointer.cpp:117:5:117:5 | call to operator-> | TAINT | | smart_pointer.cpp:117:2:117:4 | ref arg ptr | smart_pointer.cpp:116:52:116:54 | ptr | | | smart_pointer.cpp:117:2:117:18 | ... = ... | smart_pointer.cpp:117:7:117:7 | x [post update] | | | smart_pointer.cpp:117:5:117:5 | call to operator-> [post update] | smart_pointer.cpp:117:2:117:4 | ref arg ptr | TAINT | @@ -4754,18 +4752,17 @@ WARNING: module 'TaintTracking' has been deprecated and may be removed in future | smart_pointer.cpp:124:90:124:91 | p2 | smart_pointer.cpp:124:90:124:91 | p2 | | | smart_pointer.cpp:124:90:124:91 | p2 | smart_pointer.cpp:128:14:128:15 | p2 | | | smart_pointer.cpp:124:90:124:91 | p2 | smart_pointer.cpp:129:10:129:11 | p2 | | -| smart_pointer.cpp:125:18:125:19 | p1 | smart_pointer.cpp:125:20:125:20 | call to operator-> | | +| smart_pointer.cpp:125:18:125:19 | p1 | smart_pointer.cpp:125:20:125:20 | call to operator-> | TAINT | | smart_pointer.cpp:125:18:125:19 | ref arg p1 | smart_pointer.cpp:124:48:124:49 | p1 | | | smart_pointer.cpp:125:18:125:19 | ref arg p1 | smart_pointer.cpp:126:8:126:9 | p1 | | | smart_pointer.cpp:125:18:125:22 | ref arg call to shared_ptr | smart_pointer.cpp:125:22:125:22 | q [inner post update] | | | smart_pointer.cpp:125:20:125:20 | call to operator-> [post update] | smart_pointer.cpp:125:18:125:19 | ref arg p1 | TAINT | | smart_pointer.cpp:125:22:125:22 | q | smart_pointer.cpp:125:18:125:22 | call to shared_ptr | | | smart_pointer.cpp:125:22:125:22 | ref arg q | smart_pointer.cpp:125:22:125:22 | q [inner post update] | | -| smart_pointer.cpp:125:22:125:22 | ref arg q | smart_pointer.cpp:126:12:126:12 | q | | -| smart_pointer.cpp:126:8:126:9 | p1 | smart_pointer.cpp:126:10:126:10 | call to operator-> | | +| smart_pointer.cpp:126:8:126:9 | p1 | smart_pointer.cpp:126:10:126:10 | call to operator-> | TAINT | | smart_pointer.cpp:126:8:126:9 | ref arg p1 | smart_pointer.cpp:124:48:124:49 | p1 | | | smart_pointer.cpp:126:10:126:10 | call to operator-> [post update] | smart_pointer.cpp:126:8:126:9 | ref arg p1 | TAINT | -| smart_pointer.cpp:126:12:126:12 | q | smart_pointer.cpp:126:13:126:13 | call to operator-> | | +| smart_pointer.cpp:126:12:126:12 | q | smart_pointer.cpp:126:13:126:13 | call to operator-> | TAINT | | smart_pointer.cpp:128:13:128:13 | call to operator* | smart_pointer.cpp:128:13:128:15 | call to shared_ptr | TAINT | | smart_pointer.cpp:128:13:128:13 | call to operator* [inner post update] | smart_pointer.cpp:128:14:128:15 | ref arg p2 | TAINT | | smart_pointer.cpp:128:13:128:13 | ref arg call to operator* | smart_pointer.cpp:124:90:124:91 | p2 | | @@ -4795,15 +4792,14 @@ WARNING: module 'TaintTracking' has been deprecated and may be removed in future | smart_pointer.cpp:132:95:132:96 | p2 | smart_pointer.cpp:132:95:132:96 | p2 | | | smart_pointer.cpp:132:95:132:96 | p2 | smart_pointer.cpp:136:18:136:19 | p2 | | | smart_pointer.cpp:132:95:132:96 | p2 | smart_pointer.cpp:137:10:137:11 | p2 | | -| smart_pointer.cpp:133:23:133:24 | p1 | smart_pointer.cpp:133:25:133:25 | call to operator-> | | +| smart_pointer.cpp:133:23:133:24 | p1 | smart_pointer.cpp:133:25:133:25 | call to operator-> | TAINT | | smart_pointer.cpp:133:23:133:24 | ref arg p1 | smart_pointer.cpp:132:53:132:54 | p1 | | | smart_pointer.cpp:133:23:133:24 | ref arg p1 | smart_pointer.cpp:134:8:134:9 | p1 | | | smart_pointer.cpp:133:25:133:25 | call to operator-> [post update] | smart_pointer.cpp:133:23:133:24 | ref arg p1 | TAINT | -| smart_pointer.cpp:133:27:133:27 | ref arg q | smart_pointer.cpp:134:12:134:12 | q | | -| smart_pointer.cpp:134:8:134:9 | p1 | smart_pointer.cpp:134:10:134:10 | call to operator-> | | +| smart_pointer.cpp:134:8:134:9 | p1 | smart_pointer.cpp:134:10:134:10 | call to operator-> | TAINT | | smart_pointer.cpp:134:8:134:9 | ref arg p1 | smart_pointer.cpp:132:53:132:54 | p1 | | | smart_pointer.cpp:134:10:134:10 | call to operator-> [post update] | smart_pointer.cpp:134:8:134:9 | ref arg p1 | TAINT | -| smart_pointer.cpp:134:12:134:12 | q | smart_pointer.cpp:134:13:134:13 | call to operator-> | | +| smart_pointer.cpp:134:12:134:12 | q | smart_pointer.cpp:134:13:134:13 | call to operator-> | TAINT | | smart_pointer.cpp:136:17:136:17 | ref arg call to operator* | smart_pointer.cpp:132:95:132:96 | p2 | | | smart_pointer.cpp:136:17:136:17 | ref arg call to operator* | smart_pointer.cpp:136:18:136:19 | p2 [inner post update] | | | smart_pointer.cpp:136:17:136:17 | ref arg call to operator* | smart_pointer.cpp:136:18:136:19 | ref arg p2 | TAINT | @@ -5583,12 +5579,14 @@ WARNING: module 'TaintTracking' has been deprecated and may be removed in future | string.cpp:409:12:409:12 | call to operator+= | string.cpp:409:8:409:8 | call to operator* | TAINT | | string.cpp:409:12:409:12 | ref arg call to operator+= | string.cpp:409:10:409:11 | ref arg i7 | TAINT | | string.cpp:409:14:409:14 | 1 | string.cpp:409:10:409:11 | ref arg i7 | TAINT | +| string.cpp:409:14:409:14 | 1 | string.cpp:409:12:409:12 | call to operator+= | TAINT | | string.cpp:410:8:410:9 | i2 | string.cpp:410:3:410:9 | ... = ... | | | string.cpp:410:8:410:9 | i2 | string.cpp:411:10:411:11 | i8 | | | string.cpp:411:10:411:11 | i8 | string.cpp:411:12:411:12 | call to operator-= | TAINT | | string.cpp:411:12:411:12 | call to operator-= | string.cpp:411:8:411:8 | call to operator* | TAINT | | string.cpp:411:12:411:12 | ref arg call to operator-= | string.cpp:411:10:411:11 | ref arg i8 | TAINT | | string.cpp:411:14:411:14 | 1 | string.cpp:411:10:411:11 | ref arg i8 | TAINT | +| string.cpp:411:14:411:14 | 1 | string.cpp:411:12:411:12 | call to operator-= | TAINT | | string.cpp:413:8:413:9 | s2 | string.cpp:413:11:413:13 | call to end | TAINT | | string.cpp:413:11:413:13 | call to end | string.cpp:413:3:413:15 | ... = ... | | | string.cpp:413:11:413:13 | call to end | string.cpp:414:5:414:6 | i9 | | @@ -7592,7 +7590,6 @@ WARNING: module 'TaintTracking' has been deprecated and may be removed in future | taint.cpp:505:18:505:19 | ref arg & ... | taint.cpp:505:19:505:19 | n [inner post update] | | | taint.cpp:505:19:505:19 | n | taint.cpp:505:18:505:19 | & ... | | | taint.cpp:505:28:505:34 | ref arg source1 | taint.cpp:502:26:502:32 | source1 | | -| taint.cpp:505:28:505:34 | source1 | taint.cpp:505:11:505:15 | ref arg & ... | TAINT | | taint.cpp:514:24:514:29 | source | taint.cpp:514:24:514:29 | source | | | taint.cpp:514:24:514:29 | source | taint.cpp:516:27:516:32 | source | | | taint.cpp:515:22:515:29 | ,.-;:_ | taint.cpp:516:35:516:39 | delim | | @@ -7728,11 +7725,9 @@ WARNING: module 'TaintTracking' has been deprecated and may be removed in future | taint.cpp:594:21:594:26 | call to strsep | taint.cpp:594:9:594:42 | ... = ... | | | taint.cpp:594:21:594:26 | call to strsep | taint.cpp:595:10:595:18 | tokenized | | | taint.cpp:594:21:594:26 | call to strsep | taint.cpp:596:11:596:19 | tokenized | | -| taint.cpp:594:28:594:34 | & ... | taint.cpp:594:21:594:26 | call to strsep | TAINT | | taint.cpp:594:28:594:34 | ref arg & ... | taint.cpp:591:24:591:29 | source | | | taint.cpp:594:28:594:34 | ref arg & ... | taint.cpp:594:29:594:34 | source | | | taint.cpp:594:28:594:34 | ref arg & ... | taint.cpp:594:29:594:34 | source [inner post update] | | -| taint.cpp:594:29:594:34 | source | taint.cpp:594:21:594:26 | call to strsep | TAINT | | taint.cpp:594:29:594:34 | source | taint.cpp:594:28:594:34 | & ... | | | taint.cpp:594:37:594:41 | delim | taint.cpp:594:21:594:26 | call to strsep | TAINT | | taint.cpp:595:10:595:18 | ref arg tokenized | taint.cpp:596:11:596:19 | tokenized | | @@ -9594,12 +9589,14 @@ WARNING: module 'TaintTracking' has been deprecated and may be removed in future | vector.cpp:528:3:528:4 | ref arg it | vector.cpp:530:3:530:4 | it | | | vector.cpp:528:3:528:4 | ref arg it | vector.cpp:531:9:531:10 | it | | | vector.cpp:528:9:528:9 | 1 | vector.cpp:528:3:528:4 | ref arg it | TAINT | +| vector.cpp:528:9:528:9 | 1 | vector.cpp:528:6:528:6 | call to operator+= | TAINT | | vector.cpp:529:9:529:10 | it | vector.cpp:529:8:529:8 | call to operator* | TAINT | | vector.cpp:529:9:529:10 | ref arg it | vector.cpp:530:3:530:4 | it | | | vector.cpp:529:9:529:10 | ref arg it | vector.cpp:531:9:531:10 | it | | | vector.cpp:530:3:530:4 | it | vector.cpp:530:6:530:6 | call to operator+= | TAINT | | vector.cpp:530:3:530:4 | ref arg it | vector.cpp:531:9:531:10 | it | | | vector.cpp:530:9:530:14 | call to source | vector.cpp:530:3:530:4 | ref arg it | TAINT | +| vector.cpp:530:9:530:14 | call to source | vector.cpp:530:6:530:6 | call to operator+= | TAINT | | vector.cpp:531:9:531:10 | it | vector.cpp:531:8:531:8 | call to operator* | TAINT | | vector.cpp:532:8:532:9 | ref arg vs | vector.cpp:533:2:533:2 | vs | | | zmq.cpp:17:21:17:26 | socket | zmq.cpp:17:21:17:26 | socket | | diff --git a/cpp/ql/test/library-tests/dataflow/taint-tests/taint.expected b/cpp/ql/test/library-tests/dataflow/taint-tests/taint.expected index 444be2565167..cb27f0de7407 100644 --- a/cpp/ql/test/library-tests/dataflow/taint-tests/taint.expected +++ b/cpp/ql/test/library-tests/dataflow/taint-tests/taint.expected @@ -3,3 +3,11 @@ WARNING: module 'DataFlow' has been deprecated and may be removed in future (tai WARNING: module 'DataFlow' has been deprecated and may be removed in future (taint.ql:61,22-30) WARNING: module 'DataFlow' has been deprecated and may be removed in future (taint.ql:68,25-33) WARNING: module 'TaintTracking' has been deprecated and may be removed in future (taint.ql:73,20-33) +| smart_pointer.cpp:88:15:88:25 | // $ ast,ir | Missing result: ast | +| smart_pointer.cpp:92:18:92:28 | // $ ast,ir | Missing result: ast | +| smart_pointer.cpp:104:15:104:25 | // $ ast,ir | Missing result: ast | +| smart_pointer.cpp:126:19:126:38 | // $ ast MISSING: ir | Missing result: ast | +| smart_pointer.cpp:134:19:134:29 | // $ ast,ir | Missing result: ast | +| taint.cpp:507:14:507:24 | // $ ir,ast | Missing result: ast | +| taint.cpp:595:22:595:32 | // $ ast,ir | Missing result: ast | +| taint.cpp:596:23:596:33 | // $ ast,ir | Missing result: ast | diff --git a/cpp/ql/test/library-tests/dataflow/taint-tests/taint.ql b/cpp/ql/test/library-tests/dataflow/taint-tests/taint.ql index 3bde6ca03f06..733c54ba5ce0 100644 --- a/cpp/ql/test/library-tests/dataflow/taint-tests/taint.ql +++ b/cpp/ql/test/library-tests/dataflow/taint-tests/taint.ql @@ -104,7 +104,7 @@ module IRTest { or source.asIndirectExpr().(FunctionCall).getTarget().getName() = "indirect_source" or - source.asParameter().getName().matches("source%") + source.asParameter(_).getName().matches("source%") or exists(FunctionCall fc | fc.getAnArgument() = source.asDefiningArgument() and