@@ -1157,14 +1157,48 @@ 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 ) { FlowSummaryImpl:: Private:: barrierSpec ( _, _, kind , model ) }
1162+
1163+ private boolean convertAcceptingValue ( FlowSummaryImpl:: Public:: AcceptingValue av ) {
1164+ av .isTrue ( ) and result = true
1165+ or
1166+ av .isFalse ( ) and result = false
1167+ // Remaining cases are not supported yet, they depend on the shared Guards library.
1168+ // or
1169+ // av.isNoException() and result.getDualValue().isThrowsException()
1170+ // or
1171+ // av.isZero() and result.asIntValue() = 0
1172+ // or
1173+ // av.isNotZero() and result.getDualValue().asIntValue() = 0
1174+ // or
1175+ // av.isNull() and result.isNullValue()
1176+ // or
1177+ // av.isNotNull() and result.isNonNullValue()
1178+ }
1179+
1180+ private predicate barrierGuardChecks ( Node g , Expr e , boolean gv , TKindModelPair kmp ) {
1181+ exists (
1182+ FlowSummaryImpl:: Public:: BarrierElement n ,
1183+ FlowSummaryImpl:: Public:: AcceptingValue acceptingvalue , string kind , string model
1184+ |
1185+ FlowSummaryImpl:: Private:: barrierSpec ( n , acceptingvalue , kind , model ) and
1186+ n .asNode ( ) .asExpr ( ) = e and
1187+ kmp = TMkPair ( kind , model ) and
1188+ gv = convertAcceptingValue ( acceptingvalue )
1189+ |
1190+ g .asExpr ( ) .( CallExpr ) .getAnArgument ( ) = e // TODO: qualifier?
1191+ )
1192+ }
1193+
1194+ /** Holds if `n` is a flow barrier of kind `kind` and model `model`. */
11611195 cached
1162- predicate barrierNode ( Node n , string kind ) {
1196+ predicate barrierNode ( Node n , string kind , string model ) {
11631197 exists (
11641198 FlowSummaryImpl:: Public:: BarrierElement b ,
11651199 FlowSummaryImpl:: Private:: SummaryComponentStack stack
11661200 |
1167- FlowSummaryImpl:: Private:: barrierSpec ( b , stack , kind , _ )
1201+ FlowSummaryImpl:: Private:: barrierSpec ( b , stack , kind , model )
11681202 |
11691203 n = FlowSummaryImpl:: StepsInput:: getSourceNode ( b , stack , false )
11701204 or
@@ -1174,6 +1208,9 @@ private module Cached {
11741208 .( PostUpdateNode )
11751209 .getPreUpdateNode ( )
11761210 )
1211+ or
1212+ ParameterizedBarrierGuard< TKindModelPair , barrierGuardChecks / 4 > :: getABarrierNode ( TMkPair ( kind ,
1213+ model ) ) = n
11771214 }
11781215
11791216 /**
@@ -1199,3 +1236,34 @@ private module Cached {
11991236}
12001237
12011238import Cached
1239+
1240+ /** Holds if `n` is a flow barrier of kind `kind`. */
1241+ predicate barrierNode ( Node n , string kind ) { barrierNode ( n , kind , _) }
1242+
1243+ bindingset [ this ]
1244+ private signature class ParamSig ;
1245+
1246+ private module WithParam< ParamSig P> {
1247+ /**
1248+ * Holds if the guard `g` validates the expression `e` upon evaluating to `gv`.
1249+ *
1250+ * The expression `e` is expected to be a syntactic part of the guard `g`.
1251+ * For example, the guard `g` might be a call `isSafe(x)` and the expression `e`
1252+ * the argument `x`.
1253+ */
1254+ signature predicate guardChecksSig ( AstNode g , Expr e , boolean branch , P param ) ;
1255+ }
1256+
1257+ /**
1258+ * Provides a set of barrier nodes for a guard that validates an expression.
1259+ *
1260+ * This is expected to be used in `isBarrier`/`isSanitizer` definitions
1261+ * in data flow and taint tracking.
1262+ */
1263+ module ParameterizedBarrierGuard< ParamSig P, WithParam< P > :: guardChecksSig / 4 guardChecks> {
1264+ /** Gets a node that is safely guarded by the given guard check. */
1265+ Node getABarrierNode ( P param ) {
1266+ SsaFlow:: asNode ( result ) =
1267+ SsaImpl:: DataFlowIntegration:: ParameterizedBarrierGuard< P , guardChecks / 4 > :: getABarrierNode ( param )
1268+ }
1269+ }
0 commit comments