Merge pull request #5035 from MathiasVP/implied-deref-flow

C++: Implied dataflow models
This commit is contained in:
Jonas Jensen
2021-01-28 09:35:58 +01:00
committed by GitHub
5 changed files with 58 additions and 27 deletions

View File

@@ -920,6 +920,27 @@ private predicate modelFlow(Operand opFrom, Instruction iTo) {
)
)
)
or
impliedModelFlow(opFrom, iTo)
}
/**
* When a `DataFlowFunction` specifies dataflow from a parameter `p` to the return value there should
* also be dataflow from the parameter dereference (i.e., `*p`) to the return value dereference.
*/
private predicate impliedModelFlow(Operand opFrom, Instruction iTo) {
exists(
CallInstruction call, DataFlowFunction func, FunctionInput modelIn, FunctionOutput modelOut,
int index
|
call.getStaticCallTarget() = func and
func.hasDataFlow(modelIn, modelOut)
|
modelIn.isParameterOrQualifierAddress(index) and
modelOut.isReturnValue() and
opFrom = getSideEffectFor(call, index).(ReadSideEffectInstruction).getSideEffectOperand() and
iTo = call // TODO: Add write side effects for return values
)
}
/**

View File

@@ -108,6 +108,16 @@ class FunctionInput extends TFunctionInput {
*/
predicate isQualifierAddress() { none() }
/**
* Holds if `i >= 0` and `isParameter(i)` holds for this value, or
* if `i = -1` and `isQualifierAddress()` holds for this value.
*/
final predicate isParameterOrQualifierAddress(ParameterIndex i) {
i >= 0 and this.isParameter(i)
or
i = -1 and this.isQualifierAddress()
}
/**
* Holds if this is the input value pointed to by the return value of a
* function, if the function returns a pointer, or the input value referred
@@ -134,7 +144,7 @@ class FunctionInput extends TFunctionInput {
predicate isReturnValueDeref() { none() }
/**
* Holds if `i >= 0` and `isParameterDeref(i)` holds for this is value, or
* Holds if `i >= 0` and `isParameterDeref(i)` holds for this value, or
* if `i = -1` and `isQualifierObject()` holds for this value.
*/
final predicate isParameterDerefOrQualifierObject(ParameterIndex i) {

View File

@@ -38,13 +38,13 @@ public:
void test_typedefs(int_iterator_by_typedefs source1) {
sink(*source1); // $ ast,ir
sink(*(source1++)); // $ ast MISSING: ir
sink(*(source1++)); // $ ast,ir
sink(*(++source1)); // $ ast MISSING: ir
}
void test_trait(int_iterator_by_trait source1) {
sink(*source1); // $ ast,ir
sink(*(source1++)); // $ ast MISSING: ir
sink(*(source1++)); // $ ast,ir
sink(*(++source1)); // $ ast MISSING: ir
}

View File

@@ -415,10 +415,10 @@ void test_string_iterators() {
sink(*i9); // $ ast,ir
i10 = i2;
sink(*(i10++)); // $ ast MISSING: ir
sink(*(i10++)); // $ ast,ir
sink(i10); // $ ast,ir
i11 = i2;
sink(*(i11--)); // $ ast MISSING: ir
sink(*(i11--)); // $ ast,ir
sink(i11); // $ ast,ir
}
}

View File

@@ -75,7 +75,7 @@ void test_stringstream_int(int source)
sink(ss1 << 1234);
sink(ss2 << source); // $ ast MISSING: ir
sink(ss1 >> v1);
sink(ss2 >> v2); // $ ast MISSING: ir
sink(ss2 >> v2); // $ ast,ir
sink(ss1);
sink(ss2); // $ ast,ir
@@ -143,27 +143,27 @@ void test_stringstream_in()
sink(ss2 << source()); // $ ast,ir
sink(ss1 >> s1);
sink(ss2 >> s2); // $ ast MISSING: ir
sink(ss2 >> s3 >> s4); // $ ast MISSING: ir
sink(ss2 >> s2); // $ ast,ir
sink(ss2 >> s3 >> s4); // $ ast,ir
sink(s1);
sink(s2); // $ ast,ir
sink(s3); // $ ast,ir
sink(s4); // $ ast MISSING: ir
sink(s4); // $ ast,ir
sink(ss1 >> b1);
sink(ss2 >> b2); // $ ast MISSING: ir
sink(ss2 >> b3 >> b4); // $ ast MISSING: ir
sink(ss2 >> b2); // $ ast,ir
sink(ss2 >> b3 >> b4); // $ ast,ir
sink(b1);
sink(b2); // $ ast,ir
sink(b3); // $ ast,ir
sink(b4); // $ ast MISSING: ir
sink(b4); // $ ast,ir
sink(ss1.read(b5, 100));
sink(ss2.read(b6, 100)); // $ ast MISSING: ir
sink(ss2.read(b6, 100)); // $ ast,ir
sink(ss1.readsome(b7, 100));
sink(ss2.readsome(b8, 100)); // (returns a length, not significantly tainted)
sink(ss1.get(b9, 100));
sink(ss2.get(b10, 100)); // $ ast MISSING: ir
sink(ss2.get(b10, 100)); // $ ast,ir
sink(b5);
sink(b6); // $ ast,ir
sink(b7);
@@ -176,7 +176,7 @@ void test_stringstream_in()
sink(c3 = ss1.peek());
sink(c4 = ss2.peek()); // $ ast,ir
sink(ss1.get(c5));
sink(ss2.get(c6)); // $ ast MISSING: ir
sink(ss2.get(c6)); // $ ast,ir
sink(c1);
sink(c2); // $ ast,ir
sink(c3);
@@ -212,44 +212,44 @@ void test_getline()
std::string s1, s2, s3, s4, s5, s6, s7, s8;
sink(ss1.getline(b1, 1000));
sink(ss2.getline(b2, 1000)); // $ ast MISSING: ir
sink(ss2.getline(b3, 1000)); // $ ast MISSING: ir
sink(ss2.getline(b2, 1000)); // $ ast,ir
sink(ss2.getline(b3, 1000)); // $ ast,ir
sink(ss1.getline(b3, 1000));
sink(b1);
sink(b2); // $ ast,ir
sink(b3); // $ SPURIOUS: ast,ir
sink(ss1.getline(b4, 1000, ' '));
sink(ss2.getline(b5, 1000, ' ')); // $ ast MISSING: ir
sink(ss2.getline(b6, 1000, ' ')); // $ ast MISSING: ir
sink(ss2.getline(b5, 1000, ' ')); // $ ast,ir
sink(ss2.getline(b6, 1000, ' ')); // $ ast,ir
sink(ss1.getline(b6, 1000, ' '));
sink(b4);
sink(b5); // $ ast,ir
sink(b6); // $ SPURIOUS: ast,ir
sink(ss2.getline(b7, 1000).getline(b8, 1000)); // $ ast MISSING: ir
sink(ss2.getline(b7, 1000).getline(b8, 1000)); // $ ast,ir
sink(b7); // $ ast,ir
sink(b8); // $ ast MISSING: ir
sink(getline(ss1, s1));
sink(getline(ss2, s2)); // $ ast MISSING: ir
sink(getline(ss2, s3)); // $ ast MISSING: ir
sink(getline(ss2, s2)); // $ ast,ir
sink(getline(ss2, s3)); // $ ast,ir
sink(getline(ss1, s3));
sink(s1);
sink(s2); // $ ast,ir
sink(s3); // $ SPURIOUS: ast,ir
sink(getline(ss1, s4, ' '));
sink(getline(ss2, s5, ' ')); // $ ast MISSING: ir
sink(getline(ss2, s6, ' ')); // $ ast MISSING: ir
sink(getline(ss2, s5, ' ')); // $ ast,ir
sink(getline(ss2, s6, ' ')); // $ ast,ir
sink(getline(ss1, s6, ' '));
sink(s4);
sink(s5); // $ ast,ir
sink(s6); // $ SPURIOUS: ast,ir
sink(getline(getline(ss2, s7), s8)); // $ ast MISSING: ir
sink(getline(getline(ss2, s7), s8)); // $ ast,ir
sink(s7); // $ ast,ir
sink(s8); // $ ast MISSING: ir
sink(s8); // $ ast,ir
}
void test_chaining()
@@ -259,7 +259,7 @@ void test_chaining()
char b1[1000] = {0};
char b2[1000] = {0};
sink(ss1.get(b1, 100).unget().get(b2, 100)); // $ ast MISSING: ir
sink(ss1.get(b1, 100).unget().get(b2, 100)); // $ ast,ir
sink(b1); // $ ast,ir
sink(b2); // $ ast MISSING: ir