C++: Block flow by default.

This commit is contained in:
Mathias Vorreiter Pedersen
2024-02-15 10:17:20 +01:00
parent 625c47fa9c
commit 24a63ae94d
9 changed files with 97 additions and 59 deletions

View File

@@ -4,7 +4,10 @@ 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.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
@@ -796,10 +799,47 @@ 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` (or a conversion that
* flows to `n`).
*/
private predicate modeledFlowBarrier(Node n) {
exists(FIO::FunctionInput input, FIO::FunctionOutput output, CallInstruction call |
n = callInput(call, input) and
inOut(input, output) and
exists(callOutput(call, 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
)