mirror of
https://github.com/github/codeql.git
synced 2026-04-30 19:26:02 +02:00
C++: Remove cartesian product in 'ExecTainted'.
This commit is contained in:
@@ -19,6 +19,7 @@ import semmle.code.cpp.security.Security
|
||||
import semmle.code.cpp.valuenumbering.GlobalValueNumbering
|
||||
import semmle.code.cpp.ir.IR
|
||||
import semmle.code.cpp.ir.dataflow.TaintTracking
|
||||
import semmle.code.cpp.ir.dataflow.TaintTracking2
|
||||
import semmle.code.cpp.security.FlowSources
|
||||
import semmle.code.cpp.models.implementations.Strcat
|
||||
import DataFlow::PathGraph
|
||||
@@ -83,6 +84,32 @@ class ExecState extends DataFlow::FlowState {
|
||||
DataFlow::Node getFstNode() { result = fst }
|
||||
|
||||
DataFlow::Node getSndNode() { result = snd }
|
||||
|
||||
/** Holds if this is a possible `ExecState` for `sink`. */
|
||||
predicate isFeasibleForSink(DataFlow::Node sink) {
|
||||
any(ExecStateConfiguration conf).hasFlow(snd, sink)
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* A `TaintTracking` configuration that's used to find the relevant `ExecState`s for a
|
||||
* given sink. This avoids a cartesian product between all sinks and all `ExecState`s in
|
||||
* `ExecTaintConfiguration::isSink`.
|
||||
*/
|
||||
class ExecStateConfiguration extends TaintTracking2::Configuration {
|
||||
ExecStateConfiguration() { this = "ExecStateConfiguration" }
|
||||
|
||||
override predicate isSource(DataFlow::Node source) {
|
||||
exists(ExecState state | state.getSndNode() = source)
|
||||
}
|
||||
|
||||
override predicate isSink(DataFlow::Node sink) {
|
||||
shellCommand(sinkAsArgumentIndirection(sink), _)
|
||||
}
|
||||
|
||||
override predicate isSanitizerOut(DataFlow::Node node) {
|
||||
isSink(node, _) // Prevent duplicates along a call chain, since `shellCommand` will include wrappers
|
||||
}
|
||||
}
|
||||
|
||||
class ExecTaintConfiguration extends TaintTracking::Configuration {
|
||||
@@ -94,8 +121,8 @@ class ExecTaintConfiguration extends TaintTracking::Configuration {
|
||||
}
|
||||
|
||||
override predicate isSink(DataFlow::Node sink, DataFlow::FlowState state) {
|
||||
shellCommand(sinkAsArgumentIndirection(sink), _) and
|
||||
state instanceof ExecState
|
||||
any(ExecStateConfiguration conf).isSink(sink) and
|
||||
state.(ExecState).isFeasibleForSink(sink)
|
||||
}
|
||||
|
||||
override predicate isAdditionalTaintStep(
|
||||
|
||||
Reference in New Issue
Block a user