@@ -103,6 +103,22 @@ abstract class Configuration extends string {
103103 deprecated predicate hasFlowBackward ( Node source , Node sink ) { hasFlow ( source , sink ) }
104104}
105105
106+ private predicate inBarrier ( Node node , Configuration config ) {
107+ config .isBarrier ( node ) and
108+ config .isSource ( node )
109+ }
110+
111+ private predicate outBarrier ( Node node , Configuration config ) {
112+ config .isBarrier ( node ) and
113+ config .isSink ( node )
114+ }
115+
116+ private predicate fullBarrier ( Node node , Configuration config ) {
117+ config .isBarrier ( node ) and
118+ not config .isSource ( node ) and
119+ not config .isSink ( node )
120+ }
121+
106122private class AdditionalFlowStepSource extends Node {
107123 AdditionalFlowStepSource ( ) { any ( Configuration c ) .isAdditionalFlowStep ( this , _) }
108124}
@@ -119,22 +135,47 @@ private predicate isAdditionalFlowStep(
119135 * Holds if data can flow in one local step from `node1` to `node2`.
120136 */
121137private predicate localFlowStep ( Node node1 , Node node2 , Configuration config ) {
122- localFlowStep ( node1 , node2 ) and not config .isBarrierEdge ( node1 , node2 )
138+ localFlowStep ( node1 , node2 ) and
139+ not config .isBarrierEdge ( node1 , node2 ) and
140+ not outBarrier ( node1 , config ) and
141+ not inBarrier ( node2 , config ) and
142+ not fullBarrier ( node1 , config ) and
143+ not fullBarrier ( node2 , config )
123144}
124145
125146/**
126147 * Holds if the additional step from `node1` to `node2` does not jump between callables.
127148 */
128149private predicate additionalLocalFlowStep ( Node node1 , Node node2 , Configuration config ) {
129- isAdditionalFlowStep ( node1 , node2 , node2 .getEnclosingCallable ( ) , config )
150+ isAdditionalFlowStep ( node1 , node2 , node2 .getEnclosingCallable ( ) , config ) and
151+ not outBarrier ( node1 , config ) and
152+ not inBarrier ( node2 , config ) and
153+ not fullBarrier ( node1 , config ) and
154+ not fullBarrier ( node2 , config )
155+ }
156+
157+ /**
158+ * Holds if data can flow from `node1` to `node2` in a way that discards call contexts.
159+ */
160+ private predicate jumpStep ( Node node1 , Node node2 , Configuration config ) {
161+ jumpStep ( node1 , node2 ) and
162+ not outBarrier ( node1 , config ) and
163+ not inBarrier ( node2 , config ) and
164+ not fullBarrier ( node1 , config ) and
165+ not fullBarrier ( node2 , config )
130166}
131167
132168/**
133169 * Holds if the additional step from `node1` to `node2` jumps between callables.
134170 */
135171private predicate additionalJumpStep ( Node node1 , Node node2 , Configuration config ) {
136- exists ( DataFlowCallable callable1 | isAdditionalFlowStep ( node1 , node2 , callable1 , config ) |
137- node2 .getEnclosingCallable ( ) != callable1
172+ exists ( DataFlowCallable callable1 |
173+ isAdditionalFlowStep ( node1 , node2 , callable1 , config ) and
174+ node2 .getEnclosingCallable ( ) != callable1 and
175+ not outBarrier ( node1 , config ) and
176+ not inBarrier ( node2 , config ) and
177+ not fullBarrier ( node1 , config ) and
178+ not fullBarrier ( node2 , config )
138179 )
139180}
140181
@@ -154,7 +195,7 @@ private ReturnPosition viableReturnPos(DataFlowCall call, ReturnKind kind) {
154195 * ignoring call contexts.
155196 */
156197private predicate nodeCandFwd1 ( Node node , boolean stored , Configuration config ) {
157- not config . isBarrier ( node ) and
198+ not fullBarrier ( node , config ) and
158199 (
159200 config .isSource ( node ) and stored = false
160201 or
@@ -171,7 +212,7 @@ private predicate nodeCandFwd1(Node node, boolean stored, Configuration config)
171212 or
172213 exists ( Node mid |
173214 nodeCandFwd1 ( mid , stored , config ) and
174- jumpStep ( mid , node )
215+ jumpStep ( mid , node , config )
175216 )
176217 or
177218 exists ( Node mid |
@@ -185,15 +226,17 @@ private predicate nodeCandFwd1(Node node, boolean stored, Configuration config)
185226 useFieldFlow ( config ) and
186227 nodeCandFwd1 ( mid , _, config ) and
187228 store ( mid , _, node ) and
188- stored = true
229+ stored = true and
230+ not outBarrier ( mid , config )
189231 )
190232 or
191233 // read
192234 exists ( Node mid , Content f |
193235 nodeCandFwd1 ( mid , true , config ) and
194236 read ( mid , f , node ) and
195237 storeCandFwd1 ( f , unbind ( config ) ) and
196- ( stored = false or stored = true )
238+ ( stored = false or stored = true ) and
239+ not inBarrier ( node , config )
197240 )
198241 or
199242 // flow into a callable
@@ -223,7 +266,7 @@ private predicate nodeCandFwd1(Node node, boolean stored, Configuration config)
223266 */
224267private predicate storeCandFwd1 ( Content f , Configuration config ) {
225268 exists ( Node mid , Node node |
226- not config . isBarrier ( node ) and
269+ not fullBarrier ( node , config ) and
227270 useFieldFlow ( config ) and
228271 nodeCandFwd1 ( mid , _, config ) and
229272 store ( mid , f , node )
@@ -257,7 +300,7 @@ private predicate nodeCand1(Node node, boolean stored, Configuration config) {
257300 )
258301 or
259302 exists ( Node mid |
260- jumpStep ( node , mid ) and
303+ jumpStep ( node , mid , config ) and
261304 nodeCand1 ( mid , stored , config )
262305 )
263306 or
@@ -318,6 +361,11 @@ private predicate readCand1(Content f, Configuration config) {
318361 )
319362}
320363
364+ private predicate throughFlowNodeCand ( Node node , Configuration config ) {
365+ nodeCand1 ( node , false , config ) and
366+ not config .isBarrier ( node )
367+ }
368+
321369/**
322370 * Holds if there is a path from `p` to `node` in the same callable that is
323371 * part of a path from a source to a sink taking simple call contexts into
@@ -329,7 +377,7 @@ pragma[nomagic]
329377private predicate simpleParameterFlow (
330378 ParameterNode p , Node node , DataFlowType t , Configuration config
331379) {
332- nodeCand1 ( node , false , config ) and
380+ throughFlowNodeCand ( node , config ) and
333381 p = node and
334382 t = getErasedRepr ( node .getType ( ) ) and
335383 exists ( ReturnNode ret , ReturnKind kind |
@@ -338,37 +386,37 @@ private predicate simpleParameterFlow(
338386 not parameterValueFlowsThrough ( p , kind , _)
339387 )
340388 or
341- nodeCand1 ( node , false , unbind ( config ) ) and
389+ throughFlowNodeCand ( node , unbind ( config ) ) and
342390 exists ( Node mid |
343391 simpleParameterFlow ( p , mid , t , config ) and
344392 localFlowStep ( mid , node , config ) and
345393 compatibleTypes ( t , node .getType ( ) )
346394 )
347395 or
348- nodeCand1 ( node , false , unbind ( config ) ) and
396+ throughFlowNodeCand ( node , unbind ( config ) ) and
349397 exists ( Node mid |
350398 simpleParameterFlow ( p , mid , _, config ) and
351399 additionalLocalFlowStep ( mid , node , config ) and
352400 t = getErasedRepr ( node .getType ( ) )
353401 )
354402 or
355- nodeCand1 ( node , false , unbind ( config ) ) and
403+ throughFlowNodeCand ( node , unbind ( config ) ) and
356404 exists ( Node mid |
357405 simpleParameterFlow ( p , mid , t , config ) and
358406 localStoreReadStep ( mid , node ) and
359407 compatibleTypes ( t , node .getType ( ) )
360408 )
361409 or
362410 // value flow through a callable
363- nodeCand1 ( node , false , unbind ( config ) ) and
411+ throughFlowNodeCand ( node , unbind ( config ) ) and
364412 exists ( Node arg |
365413 simpleParameterFlow ( p , arg , t , config ) and
366414 argumentValueFlowsThrough ( arg , node , _) and
367415 compatibleTypes ( t , node .getType ( ) )
368416 )
369417 or
370418 // flow through a callable
371- nodeCand1 ( node , false , unbind ( config ) ) and
419+ throughFlowNodeCand ( node , unbind ( config ) ) and
372420 exists ( Node arg |
373421 simpleParameterFlow ( p , arg , _, config ) and
374422 simpleArgumentFlowsThrough ( arg , node , t , config )
@@ -380,6 +428,7 @@ private predicate simpleArgumentFlowsThrough0(
380428 DataFlowCall call , ArgumentNode arg , ReturnKind kind , DataFlowType t , Configuration config
381429) {
382430 nodeCand1 ( arg , false , unbind ( config ) ) and
431+ not outBarrier ( arg , config ) and
383432 exists ( ParameterNode p , ReturnNode ret |
384433 simpleParameterFlow ( p , ret , t , config ) and
385434 kind = ret .getKind ( ) and
@@ -399,6 +448,7 @@ private predicate simpleArgumentFlowsThrough(
399448) {
400449 exists ( DataFlowCall call , ReturnKind kind |
401450 nodeCand1 ( out , false , unbind ( config ) ) and
451+ not inBarrier ( out , config ) and
402452 simpleArgumentFlowsThrough0 ( call , arg , kind , t , config ) and
403453 out = getAnOutNode ( call , kind )
404454 )
@@ -440,6 +490,8 @@ private predicate additionalLocalFlowStepOrFlowThroughCallable(
440490private predicate flowOutOfCallable ( Node node1 , Node node2 , Configuration config ) {
441491 nodeCand1 ( node1 , _, unbind ( config ) ) and
442492 nodeCand1 ( node2 , _, config ) and
493+ not outBarrier ( node1 , config ) and
494+ not inBarrier ( node2 , config ) and
443495 (
444496 // flow out of an argument
445497 exists ( ParameterNode p |
@@ -462,7 +514,9 @@ private predicate flowOutOfCallable(Node node1, Node node2, Configuration config
462514private predicate flowIntoCallable ( Node node1 , Node node2 , Configuration config ) {
463515 viableParamArg ( _, node2 , node1 ) and
464516 nodeCand1 ( node1 , _, unbind ( config ) ) and
465- nodeCand1 ( node2 , _, config )
517+ nodeCand1 ( node2 , _, config ) and
518+ not outBarrier ( node1 , config ) and
519+ not inBarrier ( node2 , config )
466520}
467521
468522/**
@@ -546,7 +600,7 @@ private predicate nodeCandFwd2(Node node, boolean fromArg, boolean stored, Confi
546600 or
547601 exists ( Node mid |
548602 nodeCandFwd2 ( mid , _, stored , config ) and
549- jumpStep ( mid , node ) and
603+ jumpStep ( mid , node , config ) and
550604 fromArg = false
551605 )
552606 or
@@ -626,7 +680,7 @@ private predicate nodeCand2(Node node, boolean toReturn, boolean stored, Configu
626680 )
627681 or
628682 exists ( Node mid |
629- jumpStep ( node , mid ) and
683+ jumpStep ( node , mid , config ) and
630684 nodeCand2 ( mid , _, stored , config ) and
631685 toReturn = false
632686 )
@@ -714,7 +768,7 @@ private predicate localFlowEntry(Node node, Configuration config) {
714768 nodeCand ( node , config ) and
715769 (
716770 config .isSource ( node ) or
717- jumpStep ( _, node ) or
771+ jumpStep ( _, node , config ) or
718772 additionalJumpStep ( _, node , config ) or
719773 node instanceof ParameterNode or
720774 node instanceof OutNode or
@@ -730,7 +784,7 @@ private predicate localFlowEntry(Node node, Configuration config) {
730784 */
731785private predicate localFlowExit ( Node node , Configuration config ) {
732786 exists ( Node next | nodeCand ( next , config ) |
733- jumpStep ( node , next ) or
787+ jumpStep ( node , next , config ) or
734788 additionalJumpStep ( node , next , config ) or
735789 flowIntoCallable ( node , next , config ) or
736790 flowOutOfCallable ( node , next , config ) or
@@ -882,7 +936,7 @@ private predicate flowCandFwd0(Node node, boolean fromArg, AccessPathFront apf,
882936 or
883937 exists ( Node mid |
884938 flowCandFwd ( mid , _, apf , config ) and
885- jumpStep ( mid , node ) and
939+ jumpStep ( mid , node , config ) and
886940 fromArg = false
887941 )
888942 or
@@ -973,7 +1027,7 @@ private predicate flowCand0(Node node, boolean toReturn, AccessPathFront apf, Co
9731027 )
9741028 or
9751029 exists ( Node mid |
976- jumpStep ( node , mid ) and
1030+ jumpStep ( node , mid , config ) and
9771031 flowCand ( mid , _, apf , config ) and
9781032 toReturn = false
9791033 )
@@ -1154,7 +1208,7 @@ private predicate flowFwd0(
11541208 or
11551209 exists ( Node mid |
11561210 flowFwd ( mid , _, apf , ap , config ) and
1157- jumpStep ( mid , node ) and
1211+ jumpStep ( mid , node , config ) and
11581212 fromArg = false
11591213 )
11601214 or
@@ -1263,7 +1317,7 @@ private predicate flow0(Node node, boolean toReturn, AccessPath ap, Configuratio
12631317 )
12641318 or
12651319 exists ( Node mid |
1266- jumpStep ( node , mid ) and
1320+ jumpStep ( node , mid , config ) and
12671321 flow ( mid , _, ap , config ) and
12681322 toReturn = false
12691323 )
@@ -1518,7 +1572,7 @@ private predicate pathStep(PathNodeMid mid, Node node, CallContext cc, AccessPat
15181572 mid .getAp ( ) instanceof AccessPathNil and
15191573 ap = node .( AccessPathNilNode ) .getAp ( )
15201574 or
1521- jumpStep ( mid .getNode ( ) , node ) and
1575+ jumpStep ( mid .getNode ( ) , node , mid . getConfiguration ( ) ) and
15221576 cc instanceof CallContextAny and
15231577 ap = mid .getAp ( )
15241578 or
0 commit comments