Java: Add support for boolean MaD barrier guards.

This commit is contained in:
Anders Schack-Mulligen
2025-12-09 12:35:27 +01:00
parent d24b0ff596
commit 8da65ec6d0
6 changed files with 227 additions and 6 deletions

View File

@@ -420,3 +420,31 @@ module BarrierGuard<guardChecksSig/3 guardChecks> {
/** Gets a node that is safely guarded by the given guard check. */
Node getABarrierNode() { result = BarrierGuardValue<guardChecks0/3>::getABarrierNode() }
}
bindingset[this]
private signature class ParamSig;
private module WithParam<ParamSig P> {
/**
* Holds if the guard `g` validates the expression `e` upon evaluating to `gv`.
*
* The expression `e` is expected to be a syntactic part of the guard `g`.
* For example, the guard `g` might be a call `isSafe(x)` and the expression `e`
* the argument `x`.
*/
signature predicate guardChecksSig(Guard g, Expr e, GuardValue gv, P param);
}
/**
* Provides a set of barrier nodes for a guard that validates an expression.
*
* This is expected to be used in `isBarrier`/`isSanitizer` definitions
* in data flow and taint tracking.
*/
module ParameterizedBarrierGuard<ParamSig P, WithParam<P>::guardChecksSig/4 guardChecks> {
/** Gets a node that is safely guarded by the given guard check. */
Node getABarrierNode(P param) {
SsaFlow::asNode(result) =
SsaImpl::DataFlowIntegration::ParameterizedBarrierGuard<P, guardChecks/4>::getABarrierNode(param)
}
}

View File

@@ -28,6 +28,14 @@ extensible predicate barrierModel(
string output, string kind, string provenance, QlBuiltins::ExtensionId madId
);
/**
* Holds if a barrier guard model exists for the given parameters.
*/
extensible predicate barrierGuardModel(
string package, string type, boolean subtypes, string name, string signature, string ext,
string input, string acceptingvalue, string kind, string provenance, QlBuiltins::ExtensionId madId
);
/**
* Holds if a summary model exists for the given parameters.
*/

View File

@@ -159,7 +159,8 @@ private predicate relatedArgSpec(Callable c, string spec) {
summaryModel(namespace, type, subtypes, name, signature, ext, _, spec, _, _, _) or
sourceModel(namespace, type, subtypes, name, signature, ext, spec, _, _, _) or
sinkModel(namespace, type, subtypes, name, signature, ext, spec, _, _, _) or
barrierModel(namespace, type, subtypes, name, signature, ext, spec, _, _, _)
barrierModel(namespace, type, subtypes, name, signature, ext, spec, _, _, _) or
barrierGuardModel(namespace, type, subtypes, name, signature, ext, spec, _, _, _, _)
|
c = interpretElement(namespace, type, subtypes, name, signature, ext, _)
)
@@ -267,8 +268,28 @@ module SourceSinkInterpretationInput implements
string namespace, string type, boolean subtypes, string name, string signature, string ext,
SourceOrSinkElement baseBarrier, string originalOutput, QlBuiltins::ExtensionId madId
|
barrierModel(namespace, type, subtypes, name, signature, ext, originalOutput, kind, provenance,
madId) and
barrierModel(namespace, type, subtypes, name, signature, ext, originalOutput, kind,
provenance, madId) and
model = "MaD:" + madId.toString() and
baseBarrier = interpretElement(namespace, type, subtypes, name, signature, ext, _) and
(
e = baseBarrier and output = originalOutput
or
correspondingKotlinParameterDefaultsArgSpec(baseBarrier, e, originalOutput, output)
)
)
}
predicate barrierGuardElement(
Element e, string output, Public::AcceptingValue acceptingvalue, string kind,
Public::Provenance provenance, string model
) {
exists(
string namespace, string type, boolean subtypes, string name, string signature, string ext,
SourceOrSinkElement baseBarrier, string originalOutput, QlBuiltins::ExtensionId madId
|
barrierGuardModel(namespace, type, subtypes, name, signature, ext, originalOutput,
acceptingvalue, kind, provenance, madId) and
model = "MaD:" + madId.toString() and
baseBarrier = interpretElement(namespace, type, subtypes, name, signature, ext, _) and
(

View File

@@ -588,6 +588,36 @@ private module Cached {
predicate getABarrierNode = getABarrierNodeImpl/0;
}
bindingset[this]
private signature class ParamSig;
private module WithParam<ParamSig P> {
signature predicate guardChecksSig(Guards::Guard g, Expr e, Guards::GuardValue gv, P param);
}
cached // nothing is actually cached
module ParameterizedBarrierGuard<ParamSig P, WithParam<P>::guardChecksSig/4 guardChecks> {
private predicate guardChecksAdjTypes(
Guards::Guards_v3::Guard g, Expr e, Guards::GuardValue gv, P param
) {
guardChecks(g, e, gv, param)
}
private predicate guardChecksWithWrappers(
DataFlowIntegrationInput::Guard g, Definition def, Guards::GuardValue val, P param
) {
Guards::Guards_v3::ParameterizedValidationWrapper<P, guardChecksAdjTypes/4>::guardChecksDef(g,
def, val, param)
}
private Node getABarrierNodeImpl(P param) {
result =
DataFlowIntegrationImpl::BarrierGuardDefWithState<P, guardChecksWithWrappers/4>::getABarrierNode(param)
}
predicate getABarrierNode = getABarrierNodeImpl/1;
}
}
cached