mirror of
https://github.com/github/codeql.git
synced 2025-12-16 16:53:25 +01:00
C#: Add more copies of the data flow library
This commit is contained in:
@@ -1,5 +1,5 @@
|
||||
{
|
||||
"DataFlow Java/C++": [
|
||||
"DataFlow Java/C++/C#": [
|
||||
"java/ql/src/semmle/code/java/dataflow/internal/DataFlowImpl.qll",
|
||||
"java/ql/src/semmle/code/java/dataflow/internal/DataFlowImpl2.qll",
|
||||
"java/ql/src/semmle/code/java/dataflow/internal/DataFlowImpl3.qll",
|
||||
@@ -13,9 +13,13 @@
|
||||
"cpp/ql/src/semmle/code/cpp/ir/dataflow/internal/DataFlowImpl2.qll",
|
||||
"cpp/ql/src/semmle/code/cpp/ir/dataflow/internal/DataFlowImpl3.qll",
|
||||
"cpp/ql/src/semmle/code/cpp/ir/dataflow/internal/DataFlowImpl4.qll",
|
||||
"csharp/ql/src/semmle/code/csharp/dataflow/internal/DataFlowImpl.qll"
|
||||
"csharp/ql/src/semmle/code/csharp/dataflow/internal/DataFlowImpl.qll",
|
||||
"csharp/ql/src/semmle/code/csharp/dataflow/internal/DataFlowImpl2.qll",
|
||||
"csharp/ql/src/semmle/code/csharp/dataflow/internal/DataFlowImpl3.qll",
|
||||
"csharp/ql/src/semmle/code/csharp/dataflow/internal/DataFlowImpl4.qll",
|
||||
"csharp/ql/src/semmle/code/csharp/dataflow/internal/DataFlowImpl5.qll"
|
||||
],
|
||||
"DataFlow Java/C++ Common": [
|
||||
"DataFlow Java/C++/C# Common": [
|
||||
"java/ql/src/semmle/code/java/dataflow/internal/DataFlowImplCommon.qll",
|
||||
"cpp/ql/src/semmle/code/cpp/dataflow/internal/DataFlowImplCommon.qll",
|
||||
"cpp/ql/src/semmle/code/cpp/ir/dataflow/internal/DataFlowImplCommon.qll",
|
||||
|
||||
@@ -7,4 +7,23 @@ import csharp
|
||||
|
||||
module DataFlow {
|
||||
import semmle.code.csharp.dataflow.internal.DataFlowImpl
|
||||
|
||||
/**
|
||||
* This class exists to prevent mutual recursion between the user-overridden
|
||||
* member predicates of `Configuration` and the rest of the data-flow library.
|
||||
* Good performance cannot be guaranteed in the presence of such recursion, so
|
||||
* it should be replaced by using more than one copy of the data flow library.
|
||||
* Four copies are available: `DataFlow` through `DataFlow4`.
|
||||
*/
|
||||
abstract private class ConfigurationRecursionPrevention extends Configuration {
|
||||
bindingset[this]
|
||||
ConfigurationRecursionPrevention() { any() }
|
||||
|
||||
override predicate hasFlow(Node source, Node sink) {
|
||||
strictcount(Node n | this.isSource(n)) < 0 or
|
||||
strictcount(Node n | this.isSink(n)) < 0 or
|
||||
strictcount(Node n1, Node n2 | this.isAdditionalFlowStep(n1, n2)) < 0 or
|
||||
super.hasFlow(source, sink)
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
29
csharp/ql/src/semmle/code/csharp/dataflow/DataFlow2.qll
Normal file
29
csharp/ql/src/semmle/code/csharp/dataflow/DataFlow2.qll
Normal file
@@ -0,0 +1,29 @@
|
||||
/**
|
||||
* Provides classes for performing local (intra-procedural) and
|
||||
* global (inter-procedural) data flow analyses.
|
||||
*/
|
||||
|
||||
import csharp
|
||||
|
||||
module DataFlow2 {
|
||||
import semmle.code.csharp.dataflow.internal.DataFlowImpl2
|
||||
|
||||
/**
|
||||
* This class exists to prevent mutual recursion between the user-overridden
|
||||
* member predicates of `Configuration` and the rest of the data-flow library.
|
||||
* Good performance cannot be guaranteed in the presence of such recursion, so
|
||||
* it should be replaced by using more than one copy of the data flow library.
|
||||
* Four copies are available: `DataFlow` through `DataFlow4`.
|
||||
*/
|
||||
abstract private class ConfigurationRecursionPrevention extends Configuration {
|
||||
bindingset[this]
|
||||
ConfigurationRecursionPrevention() { any() }
|
||||
|
||||
override predicate hasFlow(Node source, Node sink) {
|
||||
strictcount(Node n | this.isSource(n)) < 0 or
|
||||
strictcount(Node n | this.isSink(n)) < 0 or
|
||||
strictcount(Node n1, Node n2 | this.isAdditionalFlowStep(n1, n2)) < 0 or
|
||||
super.hasFlow(source, sink)
|
||||
}
|
||||
}
|
||||
}
|
||||
29
csharp/ql/src/semmle/code/csharp/dataflow/DataFlow3.qll
Normal file
29
csharp/ql/src/semmle/code/csharp/dataflow/DataFlow3.qll
Normal file
@@ -0,0 +1,29 @@
|
||||
/**
|
||||
* Provides classes for performing local (intra-procedural) and
|
||||
* global (inter-procedural) data flow analyses.
|
||||
*/
|
||||
|
||||
import csharp
|
||||
|
||||
module DataFlow3 {
|
||||
import semmle.code.csharp.dataflow.internal.DataFlowImpl3
|
||||
|
||||
/**
|
||||
* This class exists to prevent mutual recursion between the user-overridden
|
||||
* member predicates of `Configuration` and the rest of the data-flow library.
|
||||
* Good performance cannot be guaranteed in the presence of such recursion, so
|
||||
* it should be replaced by using more than one copy of the data flow library.
|
||||
* Four copies are available: `DataFlow` through `DataFlow4`.
|
||||
*/
|
||||
abstract private class ConfigurationRecursionPrevention extends Configuration {
|
||||
bindingset[this]
|
||||
ConfigurationRecursionPrevention() { any() }
|
||||
|
||||
override predicate hasFlow(Node source, Node sink) {
|
||||
strictcount(Node n | this.isSource(n)) < 0 or
|
||||
strictcount(Node n | this.isSink(n)) < 0 or
|
||||
strictcount(Node n1, Node n2 | this.isAdditionalFlowStep(n1, n2)) < 0 or
|
||||
super.hasFlow(source, sink)
|
||||
}
|
||||
}
|
||||
}
|
||||
29
csharp/ql/src/semmle/code/csharp/dataflow/DataFlow4.qll
Normal file
29
csharp/ql/src/semmle/code/csharp/dataflow/DataFlow4.qll
Normal file
@@ -0,0 +1,29 @@
|
||||
/**
|
||||
* Provides classes for performing local (intra-procedural) and
|
||||
* global (inter-procedural) data flow analyses.
|
||||
*/
|
||||
|
||||
import csharp
|
||||
|
||||
module DataFlow4 {
|
||||
import semmle.code.csharp.dataflow.internal.DataFlowImpl4
|
||||
|
||||
/**
|
||||
* This class exists to prevent mutual recursion between the user-overridden
|
||||
* member predicates of `Configuration` and the rest of the data-flow library.
|
||||
* Good performance cannot be guaranteed in the presence of such recursion, so
|
||||
* it should be replaced by using more than one copy of the data flow library.
|
||||
* Four copies are available: `DataFlow` through `DataFlow4`.
|
||||
*/
|
||||
abstract private class ConfigurationRecursionPrevention extends Configuration {
|
||||
bindingset[this]
|
||||
ConfigurationRecursionPrevention() { any() }
|
||||
|
||||
override predicate hasFlow(Node source, Node sink) {
|
||||
strictcount(Node n | this.isSource(n)) < 0 or
|
||||
strictcount(Node n | this.isSink(n)) < 0 or
|
||||
strictcount(Node n1, Node n2 | this.isAdditionalFlowStep(n1, n2)) < 0 or
|
||||
super.hasFlow(source, sink)
|
||||
}
|
||||
}
|
||||
}
|
||||
29
csharp/ql/src/semmle/code/csharp/dataflow/DataFlow5.qll
Normal file
29
csharp/ql/src/semmle/code/csharp/dataflow/DataFlow5.qll
Normal file
@@ -0,0 +1,29 @@
|
||||
/**
|
||||
* Provides classes for performing local (intra-procedural) and
|
||||
* global (inter-procedural) data flow analyses.
|
||||
*/
|
||||
|
||||
import csharp
|
||||
|
||||
module DataFlow5 {
|
||||
import semmle.code.csharp.dataflow.internal.DataFlowImpl5
|
||||
|
||||
/**
|
||||
* This class exists to prevent mutual recursion between the user-overridden
|
||||
* member predicates of `Configuration` and the rest of the data-flow library.
|
||||
* Good performance cannot be guaranteed in the presence of such recursion, so
|
||||
* it should be replaced by using more than one copy of the data flow library.
|
||||
* Four copies are available: `DataFlow` through `DataFlow4`.
|
||||
*/
|
||||
abstract private class ConfigurationRecursionPrevention extends Configuration {
|
||||
bindingset[this]
|
||||
ConfigurationRecursionPrevention() { any() }
|
||||
|
||||
override predicate hasFlow(Node source, Node sink) {
|
||||
strictcount(Node n | this.isSource(n)) < 0 or
|
||||
strictcount(Node n | this.isSink(n)) < 0 or
|
||||
strictcount(Node n1, Node n2 | this.isAdditionalFlowStep(n1, n2)) < 0 or
|
||||
super.hasFlow(source, sink)
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -6,6 +6,11 @@
|
||||
import csharp
|
||||
|
||||
module TaintTracking {
|
||||
private import semmle.code.csharp.dataflow.DataFlow
|
||||
private import semmle.code.csharp.dataflow.DataFlow2
|
||||
private import semmle.code.csharp.dataflow.DataFlow3
|
||||
private import semmle.code.csharp.dataflow.DataFlow4
|
||||
private import semmle.code.csharp.dataflow.DataFlow5
|
||||
private import semmle.code.csharp.dataflow.internal.DataFlowImplCommon
|
||||
private import semmle.code.csharp.dataflow.internal.DataFlowPrivate
|
||||
private import semmle.code.csharp.dataflow.internal.ControlFlowReachability
|
||||
@@ -99,6 +104,258 @@ module TaintTracking {
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* A taint tracking configuration.
|
||||
*
|
||||
* A taint tracking configuration is a special dataflow 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.)
|
||||
*
|
||||
* Each use of the taint tracking library must define its own unique extension
|
||||
* of this abstract class. A configuration defines a set of relevant sources
|
||||
* (`isSource`) and sinks (`isSink`), and may additionally treat intermediate
|
||||
* nodes as "sanitizers" (`isSanitizer`) as well as add custom taint flow steps
|
||||
* (`isAdditionalTaintStep()`).
|
||||
*/
|
||||
abstract class Configuration2 extends DataFlow2::Configuration {
|
||||
bindingset[this]
|
||||
Configuration2() { 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 intermediate node `node` is a taint sanitizer. */
|
||||
predicate isSanitizer(DataFlow::Node node) { none() }
|
||||
|
||||
final override predicate isBarrier(DataFlow::Node node) { isSanitizer(node) }
|
||||
|
||||
/**
|
||||
* Holds if the additional taint propagation step from `pred` to `succ`
|
||||
* must be taken into account in the analysis.
|
||||
*/
|
||||
predicate isAdditionalTaintStep(DataFlow::Node pred, DataFlow::Node succ) { none() }
|
||||
|
||||
final override predicate isAdditionalFlowStep(DataFlow::Node pred, DataFlow::Node succ) {
|
||||
isAdditionalTaintStep(pred, succ)
|
||||
or
|
||||
localAdditionalTaintStep(pred, succ)
|
||||
or
|
||||
succ = pred.(DataFlow::NonLocalJumpNode).getAJumpSuccessor(false)
|
||||
}
|
||||
|
||||
/**
|
||||
* 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)
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* A taint tracking configuration.
|
||||
*
|
||||
* A taint tracking configuration is a special dataflow 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.)
|
||||
*
|
||||
* Each use of the taint tracking library must define its own unique extension
|
||||
* of this abstract class. A configuration defines a set of relevant sources
|
||||
* (`isSource`) and sinks (`isSink`), and may additionally treat intermediate
|
||||
* nodes as "sanitizers" (`isSanitizer`) as well as add custom taint flow steps
|
||||
* (`isAdditionalTaintStep()`).
|
||||
*/
|
||||
abstract class Configuration3 extends DataFlow3::Configuration {
|
||||
bindingset[this]
|
||||
Configuration3() { 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 intermediate node `node` is a taint sanitizer. */
|
||||
predicate isSanitizer(DataFlow::Node node) { none() }
|
||||
|
||||
final override predicate isBarrier(DataFlow::Node node) { isSanitizer(node) }
|
||||
|
||||
/**
|
||||
* Holds if the additional taint propagation step from `pred` to `succ`
|
||||
* must be taken into account in the analysis.
|
||||
*/
|
||||
predicate isAdditionalTaintStep(DataFlow::Node pred, DataFlow::Node succ) { none() }
|
||||
|
||||
final override predicate isAdditionalFlowStep(DataFlow::Node pred, DataFlow::Node succ) {
|
||||
isAdditionalTaintStep(pred, succ)
|
||||
or
|
||||
localAdditionalTaintStep(pred, succ)
|
||||
or
|
||||
succ = pred.(DataFlow::NonLocalJumpNode).getAJumpSuccessor(false)
|
||||
}
|
||||
|
||||
/**
|
||||
* 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)
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* A taint tracking configuration.
|
||||
*
|
||||
* A taint tracking configuration is a special dataflow 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.)
|
||||
*
|
||||
* Each use of the taint tracking library must define its own unique extension
|
||||
* of this abstract class. A configuration defines a set of relevant sources
|
||||
* (`isSource`) and sinks (`isSink`), and may additionally treat intermediate
|
||||
* nodes as "sanitizers" (`isSanitizer`) as well as add custom taint flow steps
|
||||
* (`isAdditionalTaintStep()`).
|
||||
*/
|
||||
abstract class Configuration4 extends DataFlow4::Configuration {
|
||||
bindingset[this]
|
||||
Configuration4() { 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 intermediate node `node` is a taint sanitizer. */
|
||||
predicate isSanitizer(DataFlow::Node node) { none() }
|
||||
|
||||
final override predicate isBarrier(DataFlow::Node node) { isSanitizer(node) }
|
||||
|
||||
/**
|
||||
* Holds if the additional taint propagation step from `pred` to `succ`
|
||||
* must be taken into account in the analysis.
|
||||
*/
|
||||
predicate isAdditionalTaintStep(DataFlow::Node pred, DataFlow::Node succ) { none() }
|
||||
|
||||
final override predicate isAdditionalFlowStep(DataFlow::Node pred, DataFlow::Node succ) {
|
||||
isAdditionalTaintStep(pred, succ)
|
||||
or
|
||||
localAdditionalTaintStep(pred, succ)
|
||||
or
|
||||
succ = pred.(DataFlow::NonLocalJumpNode).getAJumpSuccessor(false)
|
||||
}
|
||||
|
||||
/**
|
||||
* 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)
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* A taint tracking configuration.
|
||||
*
|
||||
* A taint tracking configuration is a special dataflow 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.)
|
||||
*
|
||||
* Each use of the taint tracking library must define its own unique extension
|
||||
* of this abstract class. A configuration defines a set of relevant sources
|
||||
* (`isSource`) and sinks (`isSink`), and may additionally treat intermediate
|
||||
* nodes as "sanitizers" (`isSanitizer`) as well as add custom taint flow steps
|
||||
* (`isAdditionalTaintStep()`).
|
||||
*/
|
||||
abstract class Configuration5 extends DataFlow5::Configuration {
|
||||
bindingset[this]
|
||||
Configuration5() { 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 intermediate node `node` is a taint sanitizer. */
|
||||
predicate isSanitizer(DataFlow::Node node) { none() }
|
||||
|
||||
final override predicate isBarrier(DataFlow::Node node) { isSanitizer(node) }
|
||||
|
||||
/**
|
||||
* Holds if the additional taint propagation step from `pred` to `succ`
|
||||
* must be taken into account in the analysis.
|
||||
*/
|
||||
predicate isAdditionalTaintStep(DataFlow::Node pred, DataFlow::Node succ) { none() }
|
||||
|
||||
final override predicate isAdditionalFlowStep(DataFlow::Node pred, DataFlow::Node succ) {
|
||||
isAdditionalTaintStep(pred, succ)
|
||||
or
|
||||
localAdditionalTaintStep(pred, succ)
|
||||
or
|
||||
succ = pred.(DataFlow::NonLocalJumpNode).getAJumpSuccessor(false)
|
||||
}
|
||||
|
||||
/**
|
||||
* 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)
|
||||
}
|
||||
}
|
||||
|
||||
/** INTERNAL: Do not use. */
|
||||
module Internal {
|
||||
private CIL::DataFlowNode asCilDataFlowNode(DataFlow::Node node) {
|
||||
|
||||
1829
csharp/ql/src/semmle/code/csharp/dataflow/internal/DataFlowImpl2.qll
Normal file
1829
csharp/ql/src/semmle/code/csharp/dataflow/internal/DataFlowImpl2.qll
Normal file
File diff suppressed because it is too large
Load Diff
1829
csharp/ql/src/semmle/code/csharp/dataflow/internal/DataFlowImpl3.qll
Normal file
1829
csharp/ql/src/semmle/code/csharp/dataflow/internal/DataFlowImpl3.qll
Normal file
File diff suppressed because it is too large
Load Diff
1829
csharp/ql/src/semmle/code/csharp/dataflow/internal/DataFlowImpl4.qll
Normal file
1829
csharp/ql/src/semmle/code/csharp/dataflow/internal/DataFlowImpl4.qll
Normal file
File diff suppressed because it is too large
Load Diff
1829
csharp/ql/src/semmle/code/csharp/dataflow/internal/DataFlowImpl5.qll
Normal file
1829
csharp/ql/src/semmle/code/csharp/dataflow/internal/DataFlowImpl5.qll
Normal file
File diff suppressed because it is too large
Load Diff
Reference in New Issue
Block a user