@@ -1157,14 +1157,50 @@ private module Cached {
11571157 cached
11581158 predicate sinkNode ( Node n , string kind ) { n .( FlowSummaryNode ) .isSink ( kind , _) }
11591159
1160- /** Holds if `n` is a flow barrier of kind `kind`. */
1160+ private newtype TKindModelPair =
1161+ TMkPair ( string kind , string model ) {
1162+ FlowSummaryImpl:: Private:: barrierGuardSpec ( _, _, _, kind , model )
1163+ }
1164+
1165+ private boolean convertAcceptingValue ( FlowSummaryImpl:: Public:: AcceptingValue av ) {
1166+ av .isTrue ( ) and result = true
1167+ or
1168+ av .isFalse ( ) and result = false
1169+ // Remaining cases are not supported yet, they depend on the shared Guards library.
1170+ // or
1171+ // av.isNoException() and result.getDualValue().isThrowsException()
1172+ // or
1173+ // av.isZero() and result.asIntValue() = 0
1174+ // or
1175+ // av.isNotZero() and result.getDualValue().asIntValue() = 0
1176+ // or
1177+ // av.isNull() and result.isNullValue()
1178+ // or
1179+ // av.isNotNull() and result.isNonNullValue()
1180+ }
1181+
1182+ private predicate barrierGuardChecks ( AstNode g , Expr e , boolean gv , TKindModelPair kmp ) {
1183+ exists (
1184+ FlowSummaryImpl:: Public:: BarrierGuardElement b ,
1185+ FlowSummaryImpl:: Private:: SummaryComponentStack stack ,
1186+ FlowSummaryImpl:: Public:: AcceptingValue acceptingvalue , string kind , string model
1187+ |
1188+ FlowSummaryImpl:: Private:: barrierGuardSpec ( b , stack , acceptingvalue , kind , model ) and
1189+ e = FlowSummaryImpl:: StepsInput:: getSinkNode ( b , stack .headOfSingleton ( ) ) .asExpr ( ) and
1190+ kmp = TMkPair ( kind , model ) and
1191+ gv = convertAcceptingValue ( acceptingvalue ) and
1192+ g = b .getCall ( )
1193+ )
1194+ }
1195+
1196+ /** Holds if `n` is a flow barrier of kind `kind` and model `model`. */
11611197 cached
1162- predicate barrierNode ( Node n , string kind ) {
1198+ predicate barrierNode ( Node n , string kind , string model ) {
11631199 exists (
11641200 FlowSummaryImpl:: Public:: BarrierElement b ,
11651201 FlowSummaryImpl:: Private:: SummaryComponentStack stack
11661202 |
1167- FlowSummaryImpl:: Private:: barrierSpec ( b , stack , kind , _ )
1203+ FlowSummaryImpl:: Private:: barrierSpec ( b , stack , kind , model )
11681204 |
11691205 n = FlowSummaryImpl:: StepsInput:: getSourceNode ( b , stack , false )
11701206 or
@@ -1174,6 +1210,9 @@ private module Cached {
11741210 .( PostUpdateNode )
11751211 .getPreUpdateNode ( )
11761212 )
1213+ or
1214+ ParameterizedBarrierGuard< TKindModelPair , barrierGuardChecks / 4 > :: getABarrierNode ( TMkPair ( kind ,
1215+ model ) ) = n
11771216 }
11781217
11791218 /**
@@ -1199,3 +1238,34 @@ private module Cached {
11991238}
12001239
12011240import Cached
1241+
1242+ /** Holds if `n` is a flow barrier of kind `kind`. */
1243+ predicate barrierNode ( Node n , string kind ) { barrierNode ( n , kind , _) }
1244+
1245+ bindingset [ this ]
1246+ private signature class ParamSig ;
1247+
1248+ private module WithParam< ParamSig P> {
1249+ /**
1250+ * Holds if the guard `g` validates the expression `e` upon evaluating to `gv`.
1251+ *
1252+ * The expression `e` is expected to be a syntactic part of the guard `g`.
1253+ * For example, the guard `g` might be a call `isSafe(x)` and the expression `e`
1254+ * the argument `x`.
1255+ */
1256+ signature predicate guardChecksSig ( AstNode g , Expr e , boolean branch , P param ) ;
1257+ }
1258+
1259+ /**
1260+ * Provides a set of barrier nodes for a guard that validates an expression.
1261+ *
1262+ * This is expected to be used in `isBarrier`/`isSanitizer` definitions
1263+ * in data flow and taint tracking.
1264+ */
1265+ module ParameterizedBarrierGuard< ParamSig P, WithParam< P > :: guardChecksSig / 4 guardChecks> {
1266+ /** Gets a node that is safely guarded by the given guard check. */
1267+ Node getABarrierNode ( P param ) {
1268+ SsaFlow:: asNode ( result ) =
1269+ SsaImpl:: DataFlowIntegration:: ParameterizedBarrierGuard< P , guardChecks / 4 > :: getABarrierNode ( param )
1270+ }
1271+ }
0 commit comments