diff --git a/config/identical-files.json b/config/identical-files.json index 63f4945680b4..6a216ac256d4 100644 --- a/config/identical-files.json +++ b/config/identical-files.json @@ -29,6 +29,8 @@ "TaintTracking::Configuration Java/C++/C#": [ "cpp/ql/src/semmle/code/cpp/dataflow/internal/tainttracking1/TaintTrackingImpl.qll", "cpp/ql/src/semmle/code/cpp/dataflow/internal/tainttracking2/TaintTrackingImpl.qll", + "cpp/ql/src/semmle/code/cpp/ir/dataflow/internal/tainttracking1/TaintTrackingImpl.qll", + "cpp/ql/src/semmle/code/cpp/ir/dataflow/internal/tainttracking2/TaintTrackingImpl.qll", "csharp/ql/src/semmle/code/csharp/dataflow/internal/tainttracking1/TaintTrackingImpl.qll", "csharp/ql/src/semmle/code/csharp/dataflow/internal/tainttracking2/TaintTrackingImpl.qll", "csharp/ql/src/semmle/code/csharp/dataflow/internal/tainttracking3/TaintTrackingImpl.qll", diff --git a/cpp/ql/src/semmle/code/cpp/ir/dataflow/DataFlow.qll b/cpp/ql/src/semmle/code/cpp/ir/dataflow/DataFlow.qll index 9315830fc49f..2aaa10e03319 100644 --- a/cpp/ql/src/semmle/code/cpp/ir/dataflow/DataFlow.qll +++ b/cpp/ql/src/semmle/code/cpp/ir/dataflow/DataFlow.qll @@ -13,8 +13,10 @@ * * To use global (interprocedural) data flow, extend the class * `DataFlow::Configuration` as documented on that class. To use local - * (intraprocedural) data flow, invoke `DataFlow::localFlow` or - * `DataFlow::LocalFlowStep` with arguments of type `DataFlow::Node`. + * (intraprocedural) data flow between expressions, call + * `DataFlow::localExprFlow`. For more general cases of local data flow, call + * `DataFlow::localFlow` or `DataFlow::localFlowStep` with arguments of type + * `DataFlow::Node`. */ import cpp diff --git a/cpp/ql/src/semmle/code/cpp/ir/dataflow/DataFlow2.qll b/cpp/ql/src/semmle/code/cpp/ir/dataflow/DataFlow2.qll index 11caa9631820..95eb979192d3 100644 --- a/cpp/ql/src/semmle/code/cpp/ir/dataflow/DataFlow2.qll +++ b/cpp/ql/src/semmle/code/cpp/ir/dataflow/DataFlow2.qll @@ -6,7 +6,7 @@ * `DataFlow2::Configuration`, a `DataFlow3::Configuration`, or a * `DataFlow4::Configuration`. * - * See `semmle.code.cpp.dataflow.DataFlow` for the full documentation. + * See `semmle.code.cpp.ir.dataflow.DataFlow` for the full documentation. */ import cpp diff --git a/cpp/ql/src/semmle/code/cpp/ir/dataflow/DataFlow3.qll b/cpp/ql/src/semmle/code/cpp/ir/dataflow/DataFlow3.qll index 479971baaddf..42529f78e5be 100644 --- a/cpp/ql/src/semmle/code/cpp/ir/dataflow/DataFlow3.qll +++ b/cpp/ql/src/semmle/code/cpp/ir/dataflow/DataFlow3.qll @@ -6,7 +6,7 @@ * `DataFlow2::Configuration`, a `DataFlow3::Configuration`, or a * `DataFlow4::Configuration`. * - * See `semmle.code.cpp.dataflow.DataFlow` for the full documentation. + * See `semmle.code.cpp.ir.dataflow.DataFlow` for the full documentation. */ import cpp diff --git a/cpp/ql/src/semmle/code/cpp/ir/dataflow/DataFlow4.qll b/cpp/ql/src/semmle/code/cpp/ir/dataflow/DataFlow4.qll index 8264178b6b39..6cd49e39e710 100644 --- a/cpp/ql/src/semmle/code/cpp/ir/dataflow/DataFlow4.qll +++ b/cpp/ql/src/semmle/code/cpp/ir/dataflow/DataFlow4.qll @@ -6,7 +6,7 @@ * `DataFlow2::Configuration`, a `DataFlow3::Configuration`, or a * `DataFlow4::Configuration`. * - * See `semmle.code.cpp.dataflow.DataFlow` for the full documentation. + * See `semmle.code.cpp.ir.dataflow.DataFlow` for the full documentation. */ import cpp diff --git a/cpp/ql/src/semmle/code/cpp/ir/dataflow/TaintTracking.qll b/cpp/ql/src/semmle/code/cpp/ir/dataflow/TaintTracking.qll index 19fec3e6ee1a..c95fcd3f5749 100644 --- a/cpp/ql/src/semmle/code/cpp/ir/dataflow/TaintTracking.qll +++ b/cpp/ql/src/semmle/code/cpp/ir/dataflow/TaintTracking.qll @@ -6,166 +6,24 @@ * the information from the source is preserved at the sink. For example, taint * propagates from `x` to `x + 100`, but it does not propagate from `x` to `x > * 100` since we consider a single bit of information to be too little. + * + * To use global (interprocedural) taint tracking, extend the class + * `TaintTracking::Configuration` as documented on that class. To use local + * (intraprocedural) taint tracking between expressions, call + * `TaintTracking::localExprTaint`. For more general cases of local taint + * tracking, call `TaintTracking::localTaint` or + * `TaintTracking::localTaintStep` with arguments of type `DataFlow::Node`. */ import semmle.code.cpp.ir.dataflow.DataFlow import semmle.code.cpp.ir.dataflow.DataFlow2 -private import semmle.code.cpp.ir.IR module TaintTracking { - /** - * A configuration of interprocedural taint tracking analysis. This defines - * sources, sinks, and any other configurable aspect of the analysis. Each - * use of the taint tracking library must define its own unique extension of - * this abstract class. - * - * A taint-tracking configuration is a special data flow configuration - * (`DataFlow::Configuration`) that allows for flow through nodes that do not - * necessarily preserve values but are still relevant from a taint-tracking - * perspective. (For example, string concatenation, where one of the operands - * is tainted.) - * - * To create a configuration, extend this class with a subclass whose - * characteristic predicate is a unique singleton string. For example, write - * - * ``` - * class MyAnalysisConfiguration extends TaintTracking::Configuration { - * MyAnalysisConfiguration() { this = "MyAnalysisConfiguration" } - * // Override `isSource` and `isSink`. - * // Optionally override `isSanitizer`. - * // Optionally override `isAdditionalTaintStep`. - * } - * ``` - * - * Then, to query whether there is flow between some `source` and `sink`, - * write - * - * ``` - * exists(MyAnalysisConfiguration cfg | cfg.hasFlow(source, sink)) - * ``` - * - * Multiple configurations can coexist, but it is unsupported to depend on a - * `TaintTracking::Configuration` or a `DataFlow::Configuration` in the - * overridden predicates that define sources, sinks, or additional steps. - * Instead, the dependency should go to a `TaintTracking::Configuration2` or - * a `DataFlow{2,3,4}::Configuration`. - */ - abstract class Configuration extends DataFlow::Configuration { - bindingset[this] - Configuration() { any() } - - /** Holds if `source` is a taint source. */ - // overridden to provide taint-tracking specific qldoc - abstract override predicate isSource(DataFlow::Node source); - - /** Holds if `sink` is a taint sink. */ - // overridden to provide taint-tracking specific qldoc - abstract override predicate isSink(DataFlow::Node sink); - - /** - * Holds if taint should not flow into `node`. - */ - predicate isSanitizer(DataFlow::Node node) { none() } - - /** - * Holds if the additional taint propagation step - * from `source` to `target` must be taken into account in the analysis. - * This step will only be followed if `target` is not in the `isSanitizer` - * predicate. - */ - predicate isAdditionalTaintStep(DataFlow::Node source, DataFlow::Node target) { none() } - - final override predicate isBarrier(DataFlow::Node node) { isSanitizer(node) } - - final override predicate isAdditionalFlowStep(DataFlow::Node source, DataFlow::Node target) { - this.isAdditionalTaintStep(source, target) - or - localTaintStep(source, target) - } - } - - /** - * A taint-tracking configuration that is backed by the `DataFlow2` library - * instead of `DataFlow`. Use this class when taint-tracking configurations - * or data-flow configurations must depend on each other. - * - * See `TaintTracking::Configuration` for the full documentation. - */ - abstract class Configuration2 extends DataFlow2::Configuration { - bindingset[this] - Configuration2() { any() } - - /** Holds if `source` is a taint source. */ - // overridden to provide taint-tracking specific qldoc - abstract override predicate isSource(DataFlow::Node source); - - /** Holds if `sink` is a taint sink. */ - // overridden to provide taint-tracking specific qldoc - abstract override predicate isSink(DataFlow::Node sink); - - /** - * Holds if taint should not flow into `node`. - */ - predicate isSanitizer(DataFlow::Node node) { none() } - - /** - * Holds if the additional taint propagation step - * from `source` to `target` must be taken into account in the analysis. - * This step will only be followed if `target` is not in the `isSanitizer` - * predicate. - */ - predicate isAdditionalTaintStep(DataFlow::Node source, DataFlow::Node target) { none() } - - final override predicate isBarrier(DataFlow::Node node) { isSanitizer(node) } - - final override predicate isAdditionalFlowStep(DataFlow::Node source, DataFlow::Node target) { - this.isAdditionalTaintStep(source, target) - or - localTaintStep(source, target) - } - } - - /** - * Holds if taint propagates from `nodeFrom` to `nodeTo` in exactly one local - * (intra-procedural) step. - */ - predicate localTaintStep(DataFlow::Node nodeFrom, DataFlow::Node nodeTo) { - // Taint can flow into using ordinary data flow. - DataFlow::localFlowStep(nodeFrom, nodeTo) - or - localInstructionTaintStep(nodeFrom.asInstruction(), nodeTo.asInstruction()) - } - - /** - * Holds if taint propagates from `nodeFrom` to `nodeTo` in exactly one local - * (intra-procedural) step. - */ - private predicate localInstructionTaintStep(Instruction nodeFrom, Instruction nodeTo) { - // Taint can flow through expressions that alter the value but preserve - // more than one bit of it _or_ expressions that follow data through - // pointer indirections. - nodeTo.getAnOperand().getAnyDef() = nodeFrom and - ( - nodeTo instanceof ArithmeticInstruction - or - nodeTo instanceof BitwiseInstruction - or - nodeTo instanceof PointerArithmeticInstruction - or - nodeTo instanceof FieldAddressInstruction - or - // The `CopyInstruction` case is also present in non-taint data flow, but - // that uses `getDef` rather than `getAnyDef`. For taint, we want flow - // from a definition of `myStruct` to a `myStruct.myField` expression. - nodeTo instanceof CopyInstruction - ) - or - nodeTo.(LoadInstruction).getSourceAddress() = nodeFrom - } + import semmle.code.cpp.ir.dataflow.internal.tainttracking1.TaintTrackingImpl + private import semmle.code.cpp.ir.dataflow.TaintTracking2 /** - * Holds if taint may propagate from `source` to `sink` in zero or more local - * (intra-procedural) steps. + * DEPRECATED: Use TaintTracking2::Configuration instead. */ - predicate localTaint(DataFlow::Node source, DataFlow::Node sink) { localTaintStep*(source, sink) } + deprecated class Configuration2 = TaintTracking2::Configuration; } diff --git a/cpp/ql/src/semmle/code/cpp/ir/dataflow/TaintTracking2.qll b/cpp/ql/src/semmle/code/cpp/ir/dataflow/TaintTracking2.qll new file mode 100644 index 000000000000..3ef03a3bd2cb --- /dev/null +++ b/cpp/ql/src/semmle/code/cpp/ir/dataflow/TaintTracking2.qll @@ -0,0 +1,15 @@ +/** + * Provides a `TaintTracking2` module, which is a copy of the `TaintTracking` + * module. Use this class when data-flow configurations or taint-tracking + * configurations must depend on each other. Two classes extending + * `DataFlow::Configuration` should never depend on each other, but one of them + * should instead depend on a `DataFlow2::Configuration`, a + * `DataFlow3::Configuration`, or a `DataFlow4::Configuration`. The + * `TaintTracking::Configuration` class extends `DataFlow::Configuration`, and + * `TaintTracking2::Configuration` extends `DataFlow2::Configuration`. + * + * See `semmle.code.cpp.ir.dataflow.TaintTracking` for the full documentation. + */ +module TaintTracking2 { + import semmle.code.cpp.ir.dataflow.internal.tainttracking2.TaintTrackingImpl +} diff --git a/cpp/ql/src/semmle/code/cpp/ir/dataflow/internal/TaintTrackingUtil.qll b/cpp/ql/src/semmle/code/cpp/ir/dataflow/internal/TaintTrackingUtil.qll new file mode 100644 index 000000000000..e34709e94ec1 --- /dev/null +++ b/cpp/ql/src/semmle/code/cpp/ir/dataflow/internal/TaintTrackingUtil.qll @@ -0,0 +1,76 @@ +private import semmle.code.cpp.ir.IR +private import semmle.code.cpp.ir.dataflow.DataFlow + +/** + * Holds if taint propagates from `nodeFrom` to `nodeTo` in exactly one local + * (intra-procedural) step. + */ +predicate localTaintStep(DataFlow::Node nodeFrom, DataFlow::Node nodeTo) { + DataFlow::localFlowStep(nodeFrom, nodeTo) + or + localAdditionalTaintStep(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. + */ +predicate localAdditionalTaintStep(DataFlow::Node nodeFrom, DataFlow::Node nodeTo) { + localInstructionTaintStep(nodeFrom.asInstruction(), nodeTo.asInstruction()) +} + +/** + * Holds if taint propagates from `nodeFrom` to `nodeTo` in exactly one local + * (intra-procedural) step. + */ +private predicate localInstructionTaintStep(Instruction nodeFrom, Instruction nodeTo) { + // Taint can flow through expressions that alter the value but preserve + // more than one bit of it _or_ expressions that follow data through + // pointer indirections. + nodeTo.getAnOperand().getAnyDef() = nodeFrom and + ( + nodeTo instanceof ArithmeticInstruction + or + nodeTo instanceof BitwiseInstruction + or + nodeTo instanceof PointerArithmeticInstruction + or + nodeTo instanceof FieldAddressInstruction + or + // The `CopyInstruction` case is also present in non-taint data flow, but + // that uses `getDef` rather than `getAnyDef`. For taint, we want flow + // from a definition of `myStruct` to a `myStruct.myField` expression. + nodeTo instanceof CopyInstruction + ) + or + nodeTo.(LoadInstruction).getSourceAddress() = nodeFrom +} + +/** + * Holds if taint may propagate from `source` to `sink` in zero or more local + * (intra-procedural) steps. + */ +predicate localTaint(DataFlow::Node source, DataFlow::Node sink) { localTaintStep*(source, sink) } + +/** + * Holds if taint can flow from `e1` to `e2` in zero or more + * local (intra-procedural) steps. + */ +predicate localExprTaint(Expr e1, Expr e2) { + localTaint(DataFlow::exprNode(e1), DataFlow::exprNode(e2)) +} + +/** + * Holds if the additional step from `src` to `sink` should be included in all + * global taint flow configurations. + */ +predicate defaultAdditionalTaintStep(DataFlow::Node src, DataFlow::Node sink) { + localAdditionalTaintStep(src, sink) +} + +/** + * Holds if `node` should be a barrier in all global taint flow configurations + * but not in local taint. + */ +predicate defaultTaintBarrier(DataFlow::Node node) { none() } diff --git a/cpp/ql/src/semmle/code/cpp/ir/dataflow/internal/tainttracking1/TaintTrackingImpl.qll b/cpp/ql/src/semmle/code/cpp/ir/dataflow/internal/tainttracking1/TaintTrackingImpl.qll new file mode 100644 index 000000000000..c05de75bfab0 --- /dev/null +++ b/cpp/ql/src/semmle/code/cpp/ir/dataflow/internal/tainttracking1/TaintTrackingImpl.qll @@ -0,0 +1,112 @@ +import TaintTrackingParameter::Public +private import TaintTrackingParameter::Private + +/** + * A configuration of interprocedural taint tracking analysis. This defines + * sources, sinks, and any other configurable aspect of the analysis. Each + * use of the taint tracking library must define its own unique extension of + * this abstract class. + * + * A taint-tracking configuration is a special data flow configuration + * (`DataFlow::Configuration`) that allows for flow through nodes that do not + * necessarily preserve values but are still relevant from a taint tracking + * perspective. (For example, string concatenation, where one of the operands + * is tainted.) + * + * To create a configuration, extend this class with a subclass whose + * characteristic predicate is a unique singleton string. For example, write + * + * ``` + * class MyAnalysisConfiguration extends TaintTracking::Configuration { + * MyAnalysisConfiguration() { this = "MyAnalysisConfiguration" } + * // Override `isSource` and `isSink`. + * // Optionally override `isSanitizer`. + * // Optionally override `isSanitizerIn`. + * // Optionally override `isSanitizerOut`. + * // Optionally override `isSanitizerGuard`. + * // Optionally override `isAdditionalTaintStep`. + * } + * ``` + * + * Then, to query whether there is flow between some `source` and `sink`, + * write + * + * ``` + * exists(MyAnalysisConfiguration cfg | cfg.hasFlow(source, sink)) + * ``` + * + * Multiple configurations can coexist, but it is unsupported to depend on + * another `TaintTracking::Configuration` or a `DataFlow::Configuration` in the + * overridden predicates that define sources, sinks, or additional steps. + * Instead, the dependency should go to a `TaintTracking2::Configuration` or a + * `DataFlow2::Configuration`, `DataFlow3::Configuration`, etc. + */ +abstract class Configuration extends DataFlow::Configuration { + bindingset[this] + Configuration() { any() } + + /** + * Holds if `source` is a relevant taint source. + * + * The smaller this predicate is, the faster `hasFlow()` will converge. + */ + // overridden to provide taint-tracking specific qldoc + abstract override predicate isSource(DataFlow::Node source); + + /** + * Holds if `sink` is a relevant taint sink. + * + * The smaller this predicate is, the faster `hasFlow()` will converge. + */ + // overridden to provide taint-tracking specific qldoc + abstract override predicate isSink(DataFlow::Node sink); + + /** Holds if the node `node` is a taint sanitizer. */ + predicate isSanitizer(DataFlow::Node node) { none() } + + final override predicate isBarrier(DataFlow::Node node) { + isSanitizer(node) or + defaultTaintBarrier(node) + } + + /** DEPRECATED: override `isSanitizerIn` and `isSanitizerOut` instead. */ + deprecated predicate isSanitizerEdge(DataFlow::Node node1, DataFlow::Node node2) { none() } + + deprecated final override predicate isBarrierEdge(DataFlow::Node node1, DataFlow::Node node2) { + isSanitizerEdge(node1, node2) + } + + /** Holds if data flow into `node` is prohibited. */ + predicate isSanitizerIn(DataFlow::Node node) { none() } + + final override predicate isBarrierIn(DataFlow::Node node) { isSanitizerIn(node) } + + /** Holds if data flow out of `node` is prohibited. */ + predicate isSanitizerOut(DataFlow::Node node) { none() } + + final override predicate isBarrierOut(DataFlow::Node node) { isSanitizerOut(node) } + + /** Holds if data flow through nodes guarded by `guard` is prohibited. */ + predicate isSanitizerGuard(DataFlow::BarrierGuard guard) { none() } + + final override predicate isBarrierGuard(DataFlow::BarrierGuard guard) { isSanitizerGuard(guard) } + + /** + * Holds if the additional taint propagation step from `node1` to `node2` + * must be taken into account in the analysis. + */ + predicate isAdditionalTaintStep(DataFlow::Node node1, DataFlow::Node node2) { none() } + + final override predicate isAdditionalFlowStep(DataFlow::Node node1, DataFlow::Node node2) { + isAdditionalTaintStep(node1, node2) or + defaultAdditionalTaintStep(node1, node2) + } + + /** + * Holds if taint may flow from `source` to `sink` for this configuration. + */ + // overridden to provide taint-tracking specific qldoc + override predicate hasFlow(DataFlow::Node source, DataFlow::Node sink) { + super.hasFlow(source, sink) + } +} diff --git a/cpp/ql/src/semmle/code/cpp/ir/dataflow/internal/tainttracking1/TaintTrackingParameter.qll b/cpp/ql/src/semmle/code/cpp/ir/dataflow/internal/tainttracking1/TaintTrackingParameter.qll new file mode 100644 index 000000000000..1a1d605bc74c --- /dev/null +++ b/cpp/ql/src/semmle/code/cpp/ir/dataflow/internal/tainttracking1/TaintTrackingParameter.qll @@ -0,0 +1,5 @@ +import semmle.code.cpp.ir.dataflow.internal.TaintTrackingUtil as Public + +module Private { + import semmle.code.cpp.ir.dataflow.DataFlow::DataFlow as DataFlow +} diff --git a/cpp/ql/src/semmle/code/cpp/ir/dataflow/internal/tainttracking2/TaintTrackingImpl.qll b/cpp/ql/src/semmle/code/cpp/ir/dataflow/internal/tainttracking2/TaintTrackingImpl.qll new file mode 100644 index 000000000000..c05de75bfab0 --- /dev/null +++ b/cpp/ql/src/semmle/code/cpp/ir/dataflow/internal/tainttracking2/TaintTrackingImpl.qll @@ -0,0 +1,112 @@ +import TaintTrackingParameter::Public +private import TaintTrackingParameter::Private + +/** + * A configuration of interprocedural taint tracking analysis. This defines + * sources, sinks, and any other configurable aspect of the analysis. Each + * use of the taint tracking library must define its own unique extension of + * this abstract class. + * + * A taint-tracking configuration is a special data flow configuration + * (`DataFlow::Configuration`) that allows for flow through nodes that do not + * necessarily preserve values but are still relevant from a taint tracking + * perspective. (For example, string concatenation, where one of the operands + * is tainted.) + * + * To create a configuration, extend this class with a subclass whose + * characteristic predicate is a unique singleton string. For example, write + * + * ``` + * class MyAnalysisConfiguration extends TaintTracking::Configuration { + * MyAnalysisConfiguration() { this = "MyAnalysisConfiguration" } + * // Override `isSource` and `isSink`. + * // Optionally override `isSanitizer`. + * // Optionally override `isSanitizerIn`. + * // Optionally override `isSanitizerOut`. + * // Optionally override `isSanitizerGuard`. + * // Optionally override `isAdditionalTaintStep`. + * } + * ``` + * + * Then, to query whether there is flow between some `source` and `sink`, + * write + * + * ``` + * exists(MyAnalysisConfiguration cfg | cfg.hasFlow(source, sink)) + * ``` + * + * Multiple configurations can coexist, but it is unsupported to depend on + * another `TaintTracking::Configuration` or a `DataFlow::Configuration` in the + * overridden predicates that define sources, sinks, or additional steps. + * Instead, the dependency should go to a `TaintTracking2::Configuration` or a + * `DataFlow2::Configuration`, `DataFlow3::Configuration`, etc. + */ +abstract class Configuration extends DataFlow::Configuration { + bindingset[this] + Configuration() { any() } + + /** + * Holds if `source` is a relevant taint source. + * + * The smaller this predicate is, the faster `hasFlow()` will converge. + */ + // overridden to provide taint-tracking specific qldoc + abstract override predicate isSource(DataFlow::Node source); + + /** + * Holds if `sink` is a relevant taint sink. + * + * The smaller this predicate is, the faster `hasFlow()` will converge. + */ + // overridden to provide taint-tracking specific qldoc + abstract override predicate isSink(DataFlow::Node sink); + + /** Holds if the node `node` is a taint sanitizer. */ + predicate isSanitizer(DataFlow::Node node) { none() } + + final override predicate isBarrier(DataFlow::Node node) { + isSanitizer(node) or + defaultTaintBarrier(node) + } + + /** DEPRECATED: override `isSanitizerIn` and `isSanitizerOut` instead. */ + deprecated predicate isSanitizerEdge(DataFlow::Node node1, DataFlow::Node node2) { none() } + + deprecated final override predicate isBarrierEdge(DataFlow::Node node1, DataFlow::Node node2) { + isSanitizerEdge(node1, node2) + } + + /** Holds if data flow into `node` is prohibited. */ + predicate isSanitizerIn(DataFlow::Node node) { none() } + + final override predicate isBarrierIn(DataFlow::Node node) { isSanitizerIn(node) } + + /** Holds if data flow out of `node` is prohibited. */ + predicate isSanitizerOut(DataFlow::Node node) { none() } + + final override predicate isBarrierOut(DataFlow::Node node) { isSanitizerOut(node) } + + /** Holds if data flow through nodes guarded by `guard` is prohibited. */ + predicate isSanitizerGuard(DataFlow::BarrierGuard guard) { none() } + + final override predicate isBarrierGuard(DataFlow::BarrierGuard guard) { isSanitizerGuard(guard) } + + /** + * Holds if the additional taint propagation step from `node1` to `node2` + * must be taken into account in the analysis. + */ + predicate isAdditionalTaintStep(DataFlow::Node node1, DataFlow::Node node2) { none() } + + final override predicate isAdditionalFlowStep(DataFlow::Node node1, DataFlow::Node node2) { + isAdditionalTaintStep(node1, node2) or + defaultAdditionalTaintStep(node1, node2) + } + + /** + * Holds if taint may flow from `source` to `sink` for this configuration. + */ + // overridden to provide taint-tracking specific qldoc + override predicate hasFlow(DataFlow::Node source, DataFlow::Node sink) { + super.hasFlow(source, sink) + } +} diff --git a/cpp/ql/src/semmle/code/cpp/ir/dataflow/internal/tainttracking2/TaintTrackingParameter.qll b/cpp/ql/src/semmle/code/cpp/ir/dataflow/internal/tainttracking2/TaintTrackingParameter.qll new file mode 100644 index 000000000000..ac0b79d067e6 --- /dev/null +++ b/cpp/ql/src/semmle/code/cpp/ir/dataflow/internal/tainttracking2/TaintTrackingParameter.qll @@ -0,0 +1,5 @@ +import semmle.code.cpp.ir.dataflow.internal.TaintTrackingUtil as Public + +module Private { + import semmle.code.cpp.ir.dataflow.DataFlow2::DataFlow2 as DataFlow +}