From 9cd2247b91d4fe55ca32283ff1e3dc1c3f44fed3 Mon Sep 17 00:00:00 2001 From: Anders Schack-Mulligen Date: Wed, 10 Dec 2025 11:21:01 +0100 Subject: [PATCH] Java: expose support for more general BarrierGuards. --- .../java/dataflow/internal/DataFlowUtil.qll | 32 ++++++++++++++++--- .../code/java/dataflow/internal/SsaImpl.qll | 4 +-- 2 files changed, 30 insertions(+), 6 deletions(-) diff --git a/java/ql/lib/semmle/code/java/dataflow/internal/DataFlowUtil.qll b/java/ql/lib/semmle/code/java/dataflow/internal/DataFlowUtil.qll index 00e7d15ee8b..d96834a5533 100644 --- a/java/ql/lib/semmle/code/java/dataflow/internal/DataFlowUtil.qll +++ b/java/ql/lib/semmle/code/java/dataflow/internal/DataFlowUtil.qll @@ -374,6 +374,29 @@ class ContentSet instanceof Content { } } +/** + * 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 valueGuardChecksSig(Guard g, Expr e, GuardValue gv); + +/** + * 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 BarrierGuardValue { + /** Gets a node that is safely guarded by the given guard check. */ + Node getABarrierNode() { + SsaFlow::asNode(result) = + SsaImpl::DataFlowIntegration::BarrierGuard::getABarrierNode() + } +} + /** * Holds if the guard `g` validates the expression `e` upon evaluating to `branch`. * @@ -390,9 +413,10 @@ signature predicate guardChecksSig(Guard g, Expr e, boolean branch); * in data flow and taint tracking. */ module BarrierGuard { - /** Gets a node that is safely guarded by the given guard check. */ - Node getABarrierNode() { - SsaFlow::asNode(result) = - SsaImpl::DataFlowIntegration::BarrierGuard::getABarrierNode() + private predicate guardChecks0(Guard g, Expr e, GuardValue gv) { + guardChecks(g, e, gv.asBooleanValue()) } + + /** Gets a node that is safely guarded by the given guard check. */ + Node getABarrierNode() { result = BarrierGuardValue::getABarrierNode() } } diff --git a/java/ql/lib/semmle/code/java/dataflow/internal/SsaImpl.qll b/java/ql/lib/semmle/code/java/dataflow/internal/SsaImpl.qll index 079fad797d8..323f14f550f 100644 --- a/java/ql/lib/semmle/code/java/dataflow/internal/SsaImpl.qll +++ b/java/ql/lib/semmle/code/java/dataflow/internal/SsaImpl.qll @@ -564,14 +564,14 @@ private module Cached { DataFlowIntegrationImpl::localMustFlowStep(v, nodeFrom, nodeTo) } - signature predicate guardChecksSig(Guards::Guard g, Expr e, boolean branch); + signature predicate guardChecksSig(Guards::Guard g, Expr e, Guards::GuardValue gv); cached // nothing is actually cached module BarrierGuard { private predicate guardChecksAdjTypes( Guards::Guards_v3::Guard g, Expr e, Guards::GuardValue gv ) { - guardChecks(g, e, gv.asBooleanValue()) + guardChecks(g, e, gv) } private predicate guardChecksWithWrappers(