mirror of
https://github.com/github/codeql.git
synced 2026-05-04 05:05:12 +02:00
C++: Add a cache module to taint-tracking and ensure they happen in the same stage as the dataflow stage.
This commit is contained in:
@@ -124,6 +124,7 @@ private module Cached {
|
|||||||
cached
|
cached
|
||||||
predicate simpleLocalFlowStep(Node nodeFrom, Node nodeTo, string model) {
|
predicate simpleLocalFlowStep(Node nodeFrom, Node nodeTo, string model) {
|
||||||
(
|
(
|
||||||
|
TaintTrackingUtil::forceCachingInSameStage() and
|
||||||
// Def-use/Use-use flow
|
// Def-use/Use-use flow
|
||||||
SsaImpl::ssaFlow(nodeFrom, nodeTo)
|
SsaImpl::ssaFlow(nodeFrom, nodeTo)
|
||||||
or
|
or
|
||||||
|
|||||||
@@ -9,60 +9,71 @@ private import SsaImpl as Ssa
|
|||||||
private import semmle.code.cpp.dataflow.internal.FlowSummaryImpl as FlowSummaryImpl
|
private import semmle.code.cpp.dataflow.internal.FlowSummaryImpl as FlowSummaryImpl
|
||||||
private import semmle.code.cpp.ir.dataflow.FlowSteps
|
private import semmle.code.cpp.ir.dataflow.FlowSteps
|
||||||
|
|
||||||
/**
|
cached
|
||||||
* Holds if taint propagates from `nodeFrom` to `nodeTo` in exactly one local
|
private module Cached {
|
||||||
* (intra-procedural) step. This relation is only used for local taint flow
|
private import DataFlowImplCommon as DataFlowImplCommon
|
||||||
* (for example `TaintTracking::localTaint(source, sink)`) so it may contain
|
|
||||||
* special cases that should only apply to local taint flow.
|
cached
|
||||||
*/
|
predicate forceCachingInSameStage() { DataFlowImplCommon::forceCachingInSameStage() }
|
||||||
predicate localTaintStep(DataFlow::Node nodeFrom, DataFlow::Node nodeTo) {
|
|
||||||
// dataflow step
|
/**
|
||||||
DataFlow::localFlowStep(nodeFrom, nodeTo)
|
* Holds if taint propagates from `nodeFrom` to `nodeTo` in exactly one local
|
||||||
or
|
* (intra-procedural) step. This relation is only used for local taint flow
|
||||||
// taint flow step
|
* (for example `TaintTracking::localTaint(source, sink)`) so it may contain
|
||||||
localAdditionalTaintStep(nodeFrom, nodeTo, _)
|
* special cases that should only apply to local taint flow.
|
||||||
or
|
*/
|
||||||
// models-as-data summarized flow for local data flow (i.e. special case for flow
|
cached
|
||||||
// through calls to modeled functions, without relying on global dataflow to join
|
predicate localTaintStep(DataFlow::Node nodeFrom, DataFlow::Node nodeTo) {
|
||||||
// the dots).
|
// dataflow step
|
||||||
FlowSummaryImpl::Private::Steps::summaryThroughStepTaint(nodeFrom, nodeTo, _)
|
DataFlow::localFlowStep(nodeFrom, nodeTo)
|
||||||
|
or
|
||||||
|
// taint flow step
|
||||||
|
localAdditionalTaintStep(nodeFrom, nodeTo, _)
|
||||||
|
or
|
||||||
|
// models-as-data summarized flow for local data flow (i.e. special case for flow
|
||||||
|
// through calls to modeled functions, without relying on global dataflow to join
|
||||||
|
// the dots).
|
||||||
|
FlowSummaryImpl::Private::Steps::summaryThroughStepTaint(nodeFrom, nodeTo, _)
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Holds if taint can flow in one local step from `nodeFrom` to `nodeTo` excluding
|
||||||
|
* local data flow steps. That is, `nodeFrom` and `nodeTo` are likely to represent
|
||||||
|
* different objects.
|
||||||
|
*/
|
||||||
|
cached
|
||||||
|
predicate localAdditionalTaintStep(DataFlow::Node nodeFrom, DataFlow::Node nodeTo, string model) {
|
||||||
|
operandToInstructionTaintStep(nodeFrom.asOperand(), nodeTo.asInstruction()) and
|
||||||
|
model = ""
|
||||||
|
or
|
||||||
|
modeledTaintStep(nodeFrom, nodeTo, model)
|
||||||
|
or
|
||||||
|
// Flow from (the indirection of) an operand of a pointer arithmetic instruction to the
|
||||||
|
// indirection of the pointer arithmetic instruction. This provides flow from `source`
|
||||||
|
// in `x[source]` to the result of the associated load instruction.
|
||||||
|
exists(PointerArithmeticInstruction pai, int indirectionIndex |
|
||||||
|
nodeHasOperand(nodeFrom, pai.getAnOperand(), pragma[only_bind_into](indirectionIndex)) and
|
||||||
|
hasInstructionAndIndex(nodeTo, pai, indirectionIndex + 1)
|
||||||
|
) and
|
||||||
|
model = ""
|
||||||
|
or
|
||||||
|
any(Ssa::Indirection ind).isAdditionalTaintStep(nodeFrom, nodeTo) and
|
||||||
|
model = ""
|
||||||
|
or
|
||||||
|
// models-as-data summarized flow
|
||||||
|
FlowSummaryImpl::Private::Steps::summaryLocalStep(nodeFrom.(FlowSummaryNode).getSummaryNode(),
|
||||||
|
nodeTo.(FlowSummaryNode).getSummaryNode(), false, model)
|
||||||
|
or
|
||||||
|
// object->field conflation for content that is a `TaintInheritingContent`.
|
||||||
|
exists(DataFlow::ContentSet f |
|
||||||
|
readStep(nodeFrom, f, nodeTo) and
|
||||||
|
f.getAReadContent() instanceof TaintInheritingContent
|
||||||
|
) and
|
||||||
|
model = ""
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
import Cached
|
||||||
* Holds if taint can flow in one local step from `nodeFrom` to `nodeTo` excluding
|
|
||||||
* local data flow steps. That is, `nodeFrom` and `nodeTo` are likely to represent
|
|
||||||
* different objects.
|
|
||||||
*/
|
|
||||||
cached
|
|
||||||
predicate localAdditionalTaintStep(DataFlow::Node nodeFrom, DataFlow::Node nodeTo, string model) {
|
|
||||||
operandToInstructionTaintStep(nodeFrom.asOperand(), nodeTo.asInstruction()) and
|
|
||||||
model = ""
|
|
||||||
or
|
|
||||||
modeledTaintStep(nodeFrom, nodeTo, model)
|
|
||||||
or
|
|
||||||
// Flow from (the indirection of) an operand of a pointer arithmetic instruction to the
|
|
||||||
// indirection of the pointer arithmetic instruction. This provides flow from `source`
|
|
||||||
// in `x[source]` to the result of the associated load instruction.
|
|
||||||
exists(PointerArithmeticInstruction pai, int indirectionIndex |
|
|
||||||
nodeHasOperand(nodeFrom, pai.getAnOperand(), pragma[only_bind_into](indirectionIndex)) and
|
|
||||||
hasInstructionAndIndex(nodeTo, pai, indirectionIndex + 1)
|
|
||||||
) and
|
|
||||||
model = ""
|
|
||||||
or
|
|
||||||
any(Ssa::Indirection ind).isAdditionalTaintStep(nodeFrom, nodeTo) and
|
|
||||||
model = ""
|
|
||||||
or
|
|
||||||
// models-as-data summarized flow
|
|
||||||
FlowSummaryImpl::Private::Steps::summaryLocalStep(nodeFrom.(FlowSummaryNode).getSummaryNode(),
|
|
||||||
nodeTo.(FlowSummaryNode).getSummaryNode(), false, model)
|
|
||||||
or
|
|
||||||
// object->field conflation for content that is a `TaintInheritingContent`.
|
|
||||||
exists(DataFlow::ContentSet f |
|
|
||||||
readStep(nodeFrom, f, nodeTo) and
|
|
||||||
f.getAReadContent() instanceof TaintInheritingContent
|
|
||||||
) and
|
|
||||||
model = ""
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Holds if taint propagates from `nodeFrom` to `nodeTo` in exactly one local
|
* Holds if taint propagates from `nodeFrom` to `nodeTo` in exactly one local
|
||||||
|
|||||||
Reference in New Issue
Block a user