@@ -91,6 +91,7 @@ module;
9191
9292import java
9393private import semmle.code.java.dataflow.DataFlow:: DataFlow
94+ private import semmle.code.java.controlflow.Guards
9495private import FlowSummary as FlowSummary
9596private import internal.DataFlowPrivate
9697private import internal.FlowSummaryImpl
@@ -174,6 +175,24 @@ predicate sinkModel(
174175 )
175176}
176177
178+ /** Holds if a barrier model exists for the given parameters. */
179+ predicate barrierModel (
180+ string package , string type , boolean subtypes , string name , string signature , string ext ,
181+ string output , string kind , string provenance , QlBuiltins:: ExtensionId madId
182+ ) {
183+ Extensions:: barrierModel ( package , type , subtypes , name , signature , ext , output , kind , provenance ,
184+ madId )
185+ }
186+
187+ /** Holds if a barrier guard model exists for the given parameters. */
188+ predicate barrierGuardModel (
189+ string package , string type , boolean subtypes , string name , string signature , string ext ,
190+ string input , string acceptingvalue , string kind , string provenance , QlBuiltins:: ExtensionId madId
191+ ) {
192+ Extensions:: barrierGuardModel ( package , type , subtypes , name , signature , ext , input ,
193+ acceptingvalue , kind , provenance , madId )
194+ }
195+
177196/** Holds if a summary model exists for the given parameters. */
178197predicate summaryModel (
179198 string package , string type , boolean subtypes , string name , string signature , string ext ,
@@ -234,6 +253,7 @@ predicate interpretModelForTest(QlBuiltins::ExtensionId madId, string model) {
234253 "Summary: " + package + "; " + type + "; " + subtypes + "; " + name + "; " + signature + "; " +
235254 ext + "; " + input + "; " + output + "; " + kind + "; " + provenance
236255 )
256+ //TODO: possibly barrier models?
237257}
238258
239259/** Holds if a neutral model exists for the given parameters. */
@@ -292,6 +312,7 @@ predicate modelCoverage(string package, int pkgs, string kind, string part, int
292312 summaryModel ( subpkg , type , subtypes , name , signature , ext , input , output , kind , provenance ,
293313 _)
294314 )
315+ // TODO: possibly barrier models?
295316 )
296317}
297318
@@ -303,7 +324,9 @@ module ModelValidation {
303324 summaryModel ( _, _, _, _, _, _, path , _, _, _, _) or
304325 summaryModel ( _, _, _, _, _, _, _, path , _, _, _) or
305326 sinkModel ( _, _, _, _, _, _, path , _, _, _) or
306- sourceModel ( _, _, _, _, _, _, path , _, _, _)
327+ sourceModel ( _, _, _, _, _, _, path , _, _, _) or
328+ barrierModel ( _, _, _, _, _, _, path , _, _, _) or
329+ barrierGuardModel ( _, _, _, _, _, _, path , _, _, _, _)
307330 }
308331
309332 private module MkAccessPath = AccessPathSyntax:: AccessPath< getRelevantAccessPath / 1 > ;
@@ -316,6 +339,8 @@ module ModelValidation {
316339 exists ( string pred , AccessPath input , AccessPathToken part |
317340 sinkModel ( _, _, _, _, _, _, input , _, _, _) and pred = "sink"
318341 or
342+ barrierGuardModel ( _, _, _, _, _, _, input , _, _, _, _) and pred = "barrier guard"
343+ or
319344 summaryModel ( _, _, _, _, _, _, input , _, _, _, _) and pred = "summary"
320345 |
321346 (
@@ -338,6 +363,8 @@ module ModelValidation {
338363 exists ( string pred , AccessPath output , AccessPathToken part |
339364 sourceModel ( _, _, _, _, _, _, output , _, _, _) and pred = "source"
340365 or
366+ barrierModel ( _, _, _, _, _, _, output , _, _, _) and pred = "barrier"
367+ or
341368 summaryModel ( _, _, _, _, _, _, _, output , _, _, _) and pred = "summary"
342369 |
343370 (
@@ -355,7 +382,13 @@ module ModelValidation {
355382 private module KindValConfig implements SharedModelVal:: KindValidationConfigSig {
356383 predicate summaryKind ( string kind ) { summaryModel ( _, _, _, _, _, _, _, _, kind , _, _) }
357384
358- predicate sinkKind ( string kind ) { sinkModel ( _, _, _, _, _, _, _, kind , _, _) }
385+ predicate sinkKind ( string kind ) {
386+ sinkModel ( _, _, _, _, _, _, _, kind , _, _)
387+ or
388+ barrierModel ( _, _, _, _, _, _, _, kind , _, _)
389+ or
390+ barrierGuardModel ( _, _, _, _, _, _, _, _, kind , _, _)
391+ }
359392
360393 predicate sourceKind ( string kind ) { sourceModel ( _, _, _, _, _, _, _, kind , _, _) }
361394
@@ -373,6 +406,11 @@ module ModelValidation {
373406 or
374407 sinkModel ( package , type , _, name , signature , ext , _, _, provenance , _) and pred = "sink"
375408 or
409+ barrierModel ( package , type , _, name , signature , ext , _, _, provenance , _) and pred = "barrier"
410+ or
411+ barrierGuardModel ( package , type , _, name , signature , ext , _, _, _, provenance , _) and
412+ pred = "barrier guard"
413+ or
376414 summaryModel ( package , type , _, name , signature , ext , _, _, _, provenance , _) and
377415 pred = "summary"
378416 or
@@ -398,6 +436,14 @@ module ModelValidation {
398436 invalidProvenance ( provenance ) and
399437 result = "Unrecognized provenance description \"" + provenance + "\" in " + pred + " model."
400438 )
439+ or
440+ exists ( string acceptingvalue |
441+ barrierGuardModel ( _, _, _, _, _, _, _, acceptingvalue , _, _, _) and
442+ invalidAcceptingValue ( acceptingvalue ) and
443+ result =
444+ "Unrecognized accepting value description \"" + acceptingvalue +
445+ "\" in barrier guard model."
446+ )
401447 }
402448
403449 /** Holds if some row in a MaD flow model appears to contain typos. */
@@ -418,6 +464,10 @@ private predicate elementSpec(
418464 or
419465 sinkModel ( package , type , subtypes , name , signature , ext , _, _, _, _)
420466 or
467+ barrierModel ( package , type , subtypes , name , signature , ext , _, _, _, _)
468+ or
469+ barrierGuardModel ( package , type , subtypes , name , signature , ext , _, _, _, _, _)
470+ or
421471 summaryModel ( package , type , subtypes , name , signature , ext , _, _, _, _, _)
422472 or
423473 neutralModel ( package , type , name , signature , _, _) and ext = "" and subtypes = true
@@ -578,6 +628,53 @@ private module Cached {
578628 isSinkNode ( n , kind , model ) and n .asNode ( ) = node
579629 )
580630 }
631+
632+ private newtype TKindModelPair =
633+ TMkPair ( string kind , string model ) { isBarrierGuardNode ( _, _, kind , model ) }
634+
635+ private GuardValue convertAcceptingValue ( AcceptingValue av ) {
636+ av .isTrue ( ) and result .asBooleanValue ( ) = true
637+ or
638+ av .isFalse ( ) and result .asBooleanValue ( ) = false
639+ or
640+ av .isNoException ( ) and result .getDualValue ( ) .isThrowsException ( )
641+ or
642+ av .isZero ( ) and result .asIntValue ( ) = 0
643+ or
644+ av .isNotZero ( ) and result .getDualValue ( ) .asIntValue ( ) = 0
645+ or
646+ av .isNull ( ) and result .isNullValue ( )
647+ or
648+ av .isNotNull ( ) and result .isNonNullValue ( )
649+ }
650+
651+ private predicate barrierGuardChecks ( Guard g , Expr e , GuardValue gv , TKindModelPair kmp ) {
652+ exists (
653+ SourceSinkInterpretationInput:: InterpretNode n , AcceptingValue acceptingvalue , string kind ,
654+ string model
655+ |
656+ isBarrierGuardNode ( n , acceptingvalue , kind , model ) and
657+ n .asNode ( ) .asExpr ( ) = e and
658+ kmp = TMkPair ( kind , model ) and
659+ gv = convertAcceptingValue ( acceptingvalue )
660+ |
661+ g .( Call ) .getAnArgument ( ) = e or g .( MethodCall ) .getQualifier ( ) = e
662+ )
663+ }
664+
665+ /**
666+ * Holds if `node` is specified as a barrier with the given kind in a MaD flow
667+ * model.
668+ */
669+ cached
670+ predicate barrierNode ( Node node , string kind , string model ) {
671+ exists ( SourceSinkInterpretationInput:: InterpretNode n |
672+ isBarrierNode ( n , kind , model ) and n .asNode ( ) = node
673+ )
674+ or
675+ ParameterizedBarrierGuard< TKindModelPair , barrierGuardChecks / 4 > :: getABarrierNode ( TMkPair ( kind ,
676+ model ) ) = node
677+ }
581678}
582679
583680import Cached
@@ -594,6 +691,12 @@ predicate sourceNode(Node node, string kind) { sourceNode(node, kind, _) }
594691 */
595692predicate sinkNode ( Node node , string kind ) { sinkNode ( node , kind , _) }
596693
694+ /**
695+ * Holds if `node` is specified as a barrier with the given kind in a MaD flow
696+ * model.
697+ */
698+ predicate barrierNode ( Node node , string kind ) { barrierNode ( node , kind , _) }
699+
597700// adapter class for converting Mad summaries to `SummarizedCallable`s
598701private class SummarizedCallableAdapter extends SummarizedCallable {
599702 SummarizedCallableAdapter ( ) { summaryElement ( this , _, _, _, _, _, _) }
0 commit comments