Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
19 changes: 10 additions & 9 deletions java/ql/lib/semmle/code/java/dataflow/TaintTrackingStack.qll
Original file line number Diff line number Diff line change
Expand Up @@ -7,10 +7,11 @@ private import semmle.code.java.dataflow.TaintTracking
private import semmle.code.java.dataflow.internal.DataFlowImplSpecific
private import semmle.code.java.dataflow.internal.TaintTrackingImplSpecific
private import codeql.dataflowstack.TaintTrackingStack as TTS
private import TTS::TaintTrackingStackMake<Location, JavaDataFlow, JavaTaintTracking> as TaintTrackingStackFactory

private module TaintTrackingStackInput<TaintTrackingStackFactory::DataFlow::ConfigSig Config>
implements TTS::TaintTrackingStackSig<Location, JavaDataFlow, JavaTaintTracking, Config>
module LanguageTaintTrackingStack = TTS::LanguageTaintTracking<Location, JavaDataFlow, JavaTaintTracking>;

private module TaintTrackingStackInput<DataFlow::ConfigSig Config>
implements LanguageTaintTrackingStack::DataFlowGroup<Config>::TaintTrackingStackSig<TaintTracking::Global<Config>>
{
private module Flow = TaintTracking::Global<Config>;

Expand All @@ -29,13 +30,13 @@ private module TaintTrackingStackInput<TaintTrackingStackFactory::DataFlow::Conf
}
}

module DataFlowStackMake<TaintTrackingStackFactory::DataFlow::ConfigSig Config> {
import TaintTrackingStackFactory::FlowStack<Config, TaintTrackingStackInput<Config>>
module DataFlowStackMake<DataFlow::ConfigSig Config> {
import LanguageTaintTrackingStack::FlowStack<TaintTracking::Global<Config>, Config, TaintTrackingStackInput<Config>>
}

module BiStackAnalysisMake<
TaintTrackingStackFactory::DataFlow::ConfigSig ConfigA,
TaintTrackingStackFactory::DataFlow::ConfigSig ConfigB>
{
import TaintTrackingStackFactory::BiStackAnalysis<ConfigA, TaintTrackingStackInput<ConfigA>, ConfigB, TaintTrackingStackInput<ConfigB>>
DataFlow::ConfigSig ConfigA,
DataFlow::ConfigSig ConfigB
>{
import LanguageTaintTrackingStack::BiStackAnalysis<ConfigA, TaintTracking::Global<ConfigA>, TaintTrackingStackInput<ConfigA>, ConfigB, TaintTracking::Global<ConfigB>, TaintTrackingStackInput<ConfigB>>
}
101 changes: 60 additions & 41 deletions shared/dataflowstack/codeql/dataflowstack/TaintTrackingStack.qll
Original file line number Diff line number Diff line change
Expand Up @@ -5,43 +5,58 @@ private import codeql.dataflow.DataFlow as DF
private import codeql.dataflow.TaintTracking as TT
private import codeql.util.Location

signature module TaintTrackingStackSig<
LocationSig Location, DF::InputSig<Location> Lang, TT::InputSig<Location, Lang> TTLang,
DF::Configs<Location, Lang>::ConfigSig Config>
{
Lang::Node getNode(TT::TaintFlowMake<Location, Lang, TTLang>::Global<Config>::PathNode n);
/**
* A Language-initialized grouping of DataFlow types and primitives.
*/
module LanguageTaintTracking<LocationSig Location, DF::InputSig<Location> Lang, TT::InputSig<Location, Lang> TTLang>{
module AbstractDF = DF::Configs<Location, Lang>;
module AbstractDataFlow = DF::DataFlowMake<Location, Lang>;
module AbstractTaintFlow = TT::TaintFlowMake<Location, Lang, TTLang>;
module AbstractTaintFlowOverlay = TT::TaintFlowMakeOverlay<Location, Lang, TTLang>;

/**
* A collection of modules that are scoped to a specific DataFlow config implementation
*/
module DataFlowGroup<AbstractDF::ConfigSig Config>{

module MyConfig = Config;
module TaintFlowGlobal = AbstractTaintFlow::Global<Config>;
module TaintFlowOverlayGlobal = AbstractTaintFlowOverlay::Global<Config>;

predicate isSource(TT::TaintFlowMake<Location, Lang, TTLang>::Global<Config>::PathNode n);
/**
* A Taint tracking implementation, paramaterized over a DataFlow type
*/
signature module TaintTrackingStackSig<AbstractDataFlow::GlobalFlowSig GlobalFlow>{

TT::TaintFlowMake<Location, Lang, TTLang>::Global<Config>::PathNode getASuccessor(
TT::TaintFlowMake<Location, Lang, TTLang>::Global<Config>::PathNode n
);
Lang::Node getNode(GlobalFlow::PathNode n);

Lang::DataFlowCallable getARuntimeTarget(Lang::DataFlowCall call);
predicate isSource(GlobalFlow::PathNode n);

Lang::Node getAnArgumentNode(Lang::DataFlowCall call);
}
GlobalFlow::PathNode getASuccessor(
GlobalFlow::PathNode n
);

module TaintTrackingStackMake<
LocationSig Location, DF::InputSig<Location> Lang, TT::InputSig<Location, Lang> TTLang>
{
module DataFlow = DF::DataFlowMake<Location, Lang>;
Lang::DataFlowCallable getARuntimeTarget(Lang::DataFlowCall call);

module TaintTracking = TT::TaintFlowMake<Location, Lang, TTLang>;
Lang::Node getAnArgumentNode(Lang::DataFlowCall call);
}
}

module BiStackAnalysis<
DF::Configs<Location, Lang>::ConfigSig ConfigA,
TaintTrackingStackSig<Location, Lang, TTLang, ConfigA> TaintTrackingStackA,
DF::Configs<Location, Lang>::ConfigSig ConfigB,
TaintTrackingStackSig<Location, Lang, TTLang, ConfigB> TaintTrackingStackB>
AbstractDF::ConfigSig ConfigA,
AbstractDataFlow::GlobalFlowSig GlobalFlowA,
DataFlowGroup<ConfigA>::TaintTrackingStackSig<GlobalFlowA> TaintTrackingStackA,
AbstractDF::ConfigSig ConfigB,
AbstractDataFlow::GlobalFlowSig GlobalFlowB,
DataFlowGroup<ConfigB>::TaintTrackingStackSig<GlobalFlowB> TaintTrackingStackB>
{
module FlowA = TaintTracking::Global<ConfigA>;
module FlowA = GlobalFlowA;

module FlowStackA = FlowStack<ConfigA, TaintTrackingStackA>;
module FlowStackA = FlowStack<GlobalFlowA, ConfigA, TaintTrackingStackA>;

module FlowB = TaintTracking::Global<ConfigB>;
module FlowB = GlobalFlowB;

module FlowStackB = FlowStack<ConfigB, TaintTrackingStackB>;
module FlowStackB = FlowStack<GlobalFlowB, ConfigB, TaintTrackingStackB>;

/**
* Holds if either the Stack associated with `sourceNodeA` is a subset of the stack associated with `sourceNodeB`
Expand All @@ -59,10 +74,10 @@ module TaintTrackingStackMake<
flowStackA = FlowStackA::createFlowStack(sourceNodeA, sinkNodeA) and
flowStackB = FlowStackB::createFlowStack(sourceNodeB, sinkNodeB) and
(
BiStackAnalysisImpl<ConfigA, TaintTrackingStackA, ConfigB, TaintTrackingStackB>::flowStackIsSubsetOf(flowStackA,
BiStackAnalysisImpl<GlobalFlowA, ConfigA, TaintTrackingStackA, GlobalFlowB, ConfigB, TaintTrackingStackB>::flowStackIsSubsetOf(flowStackA,
flowStackB)
or
BiStackAnalysisImpl<ConfigB, TaintTrackingStackB, ConfigA, TaintTrackingStackA>::flowStackIsSubsetOf(flowStackB,
BiStackAnalysisImpl<GlobalFlowB, ConfigB, TaintTrackingStackB, GlobalFlowA, ConfigA, TaintTrackingStackA>::flowStackIsSubsetOf(flowStackB,
flowStackA)
)
)
Expand All @@ -87,10 +102,10 @@ module TaintTrackingStackMake<
flowStackA = FlowStackA::createFlowStack(sourceNodeA, sinkNodeA) and
flowStackB = FlowStackB::createFlowStack(sourceNodeB, sinkNodeB) and
(
BiStackAnalysisImpl<ConfigA, TaintTrackingStackA, ConfigB, TaintTrackingStackB>::flowStackIsConvergingTerminatingSubsetOf(flowStackA,
BiStackAnalysisImpl<GlobalFlowA, ConfigA, TaintTrackingStackA, GlobalFlowB, ConfigB, TaintTrackingStackB>::flowStackIsConvergingTerminatingSubsetOf(flowStackA,
flowStackB)
or
BiStackAnalysisImpl<ConfigB, TaintTrackingStackB, ConfigA, TaintTrackingStackA>::flowStackIsConvergingTerminatingSubsetOf(flowStackB,
BiStackAnalysisImpl<GlobalFlowB, ConfigB, TaintTrackingStackB, GlobalFlowA, ConfigA, TaintTrackingStackA>::flowStackIsConvergingTerminatingSubsetOf(flowStackB,
flowStackA)
)
)
Expand All @@ -103,7 +118,7 @@ module TaintTrackingStackMake<
* The top of stackA is in stackB and the bottom of stackA is then some successor further down stackB.
*/
predicate flowStackIsSubsetOf(FlowStackA::FlowStack flowStackA, FlowStackB::FlowStack flowStackB) {
BiStackAnalysisImpl<ConfigA, TaintTrackingStackA, ConfigB, TaintTrackingStackB>::flowStackIsSubsetOf(flowStackA,
BiStackAnalysisImpl<GlobalFlowA, ConfigA, TaintTrackingStackA, GlobalFlowB, ConfigB, TaintTrackingStackB>::flowStackIsSubsetOf(flowStackA,
flowStackB)
}

Expand All @@ -115,20 +130,23 @@ module TaintTrackingStackMake<
predicate flowStackIsConvergingTerminatingSubsetOf(
FlowStackA::FlowStack flowStackA, FlowStackB::FlowStack flowStackB
) {
BiStackAnalysisImpl<ConfigA, TaintTrackingStackA, ConfigB, TaintTrackingStackB>::flowStackIsConvergingTerminatingSubsetOf(flowStackA,
BiStackAnalysisImpl<GlobalFlowA, ConfigA, TaintTrackingStackA, GlobalFlowB, ConfigB, TaintTrackingStackB>::flowStackIsConvergingTerminatingSubsetOf(flowStackA,
flowStackB)
}
}

private module BiStackAnalysisImpl<
DF::Configs<Location, Lang>::ConfigSig ConfigA,
TaintTrackingStackSig<Location, Lang, TTLang, ConfigA> DataFlowStackA,
DF::Configs<Location, Lang>::ConfigSig ConfigB,
TaintTrackingStackSig<Location, Lang, TTLang, ConfigB> DataFlowStackB>
AbstractDataFlow::GlobalFlowSig GlobalFlowA,
AbstractDF::ConfigSig ConfigA,
DataFlowGroup<ConfigA>::TaintTrackingStackSig<GlobalFlowA> DataFlowStackA,
AbstractDataFlow::GlobalFlowSig GlobalFlowB,
AbstractDF::ConfigSig ConfigB,
DataFlowGroup<ConfigB>::TaintTrackingStackSig<GlobalFlowB> DataFlowStackB>
{
module FlowStackA = FlowStack<ConfigA, DataFlowStackA>;

module FlowStackB = FlowStack<ConfigB, DataFlowStackB>;
module FlowStackA = FlowStack<GlobalFlowA, ConfigA, DataFlowStackA>;

module FlowStackB = FlowStack<GlobalFlowB, ConfigB, DataFlowStackB>;

/**
* Holds if stackA is a subset of stackB,
Expand Down Expand Up @@ -173,10 +191,11 @@ module TaintTrackingStackMake<
}

module FlowStack<
DF::Configs<Location, Lang>::ConfigSig Config,
TaintTrackingStackSig<Location, Lang, TTLang, Config> TaintTrackingStack>
AbstractDataFlow::GlobalFlowSig GlobalFlow,
AbstractDF::ConfigSig Config,
DataFlowGroup<Config>::TaintTrackingStackSig<GlobalFlow> TaintTrackingStack>
{
private module Flow = TT::TaintFlowMake<Location, Lang, TTLang>::Global<Config>;
private module Flow = GlobalFlow;

/**
* Determines whether or not the given PathNode is a source
Expand Down Expand Up @@ -436,4 +455,4 @@ module TaintTrackingStackMake<
}
}
}
}
}