1- import semmle.code.cpp.ir.dataflow.DataFlow
2- import semmle.code.cpp.ir.dataflow.DataFlow2
1+ import experimental. semmle.code.cpp.ir.dataflow.DataFlow
2+ import experimental. semmle.code.cpp.ir.dataflow.DataFlow2
33
44module ProductFlow {
55 abstract class Configuration extends string {
@@ -11,14 +11,31 @@ module ProductFlow {
1111 *
1212 * `source1` and `source2` must belong to the same callable.
1313 */
14- abstract predicate isSourcePair ( DataFlow:: Node source1 , DataFlow:: Node source2 ) ;
14+ predicate isSourcePair ( DataFlow:: Node source1 , DataFlow:: Node source2 ) { none ( ) }
15+
16+ predicate isSourcePair (
17+ DataFlow:: Node source1 , string state1 , DataFlow:: Node source2 , string state2
18+ ) {
19+ state1 = "" and
20+ state2 = "" and
21+ this .isSourcePair ( source1 , source2 )
22+ }
1523
1624 /**
1725 * Holds if `(sink1, sink2)` is a relevant data flow sink.
1826 *
1927 * `sink1` and `sink2` must belong to the same callable.
2028 */
21- abstract predicate isSinkPair ( DataFlow:: Node sink1 , DataFlow:: Node sink2 ) ;
29+ predicate isSinkPair ( DataFlow:: Node sink1 , DataFlow:: Node sink2 ) { none ( ) }
30+
31+ predicate isSinkPair (
32+ DataFlow:: Node sink1 , DataFlow:: FlowState state1 , DataFlow:: Node sink2 ,
33+ DataFlow:: FlowState state2
34+ ) {
35+ state1 = "" and
36+ state2 = "" and
37+ this .isSinkPair ( sink1 , sink2 )
38+ }
2239
2340 predicate hasFlowPath (
2441 DataFlow:: PathNode source1 , DataFlow2:: PathNode source2 , DataFlow:: PathNode sink1 ,
@@ -34,28 +51,28 @@ module ProductFlow {
3451 class Conf1 extends DataFlow:: Configuration {
3552 Conf1 ( ) { this = "Conf1" }
3653
37- override predicate isSource ( DataFlow:: Node source ) {
38- exists ( Configuration conf | conf .isSourcePair ( source , _) )
54+ override predicate isSource ( DataFlow:: Node source , string state ) {
55+ exists ( Configuration conf | conf .isSourcePair ( source , state , _ , _) )
3956 }
4057
41- override predicate isSink ( DataFlow:: Node sink ) {
42- exists ( Configuration conf | conf .isSinkPair ( sink , _) )
58+ override predicate isSink ( DataFlow:: Node sink , string state ) {
59+ exists ( Configuration conf | conf .isSinkPair ( sink , state , _ , _) )
4360 }
4461 }
4562
4663 class Conf2 extends DataFlow2:: Configuration {
4764 Conf2 ( ) { this = "Conf2" }
4865
49- override predicate isSource ( DataFlow:: Node source ) {
66+ override predicate isSource ( DataFlow:: Node source , string state ) {
5067 exists ( Configuration conf , DataFlow:: Node source1 |
51- conf .isSourcePair ( source1 , source ) and
68+ conf .isSourcePair ( source1 , _ , source , state ) and
5269 any ( Conf1 c ) .hasFlow ( source1 , _)
5370 )
5471 }
5572
56- override predicate isSink ( DataFlow:: Node sink ) {
73+ override predicate isSink ( DataFlow:: Node sink , string state ) {
5774 exists ( Configuration conf , DataFlow:: Node sink1 |
58- conf .isSinkPair ( sink1 , sink ) and any ( Conf1 c ) .hasFlow ( _, sink1 )
75+ conf .isSinkPair ( sink1 , _ , sink , state ) and any ( Conf1 c ) .hasFlow ( _, sink1 )
5976 )
6077 }
6178 }
@@ -65,7 +82,7 @@ module ProductFlow {
6582 Configuration conf , DataFlow:: PathNode source1 , DataFlow2:: PathNode source2 ,
6683 DataFlow:: PathNode node1 , DataFlow2:: PathNode node2
6784 ) {
68- conf .isSourcePair ( node1 .getNode ( ) , node2 .getNode ( ) ) and
85+ conf .isSourcePair ( node1 .getNode ( ) , _ , node2 .getNode ( ) , _ ) and
6986 node1 = source1 and
7087 node2 = source2
7188 or
@@ -128,7 +145,7 @@ module ProductFlow {
128145 ) {
129146 exists ( DataFlow:: PathNode mid1 , DataFlow2:: PathNode mid2 |
130147 reachableInterprocEntry ( conf , source1 , source2 , mid1 , mid2 ) and
131- conf .isSinkPair ( sink1 .getNode ( ) , sink2 .getNode ( ) ) and
148+ conf .isSinkPair ( sink1 .getNode ( ) , _ , sink2 .getNode ( ) , _ ) and
132149 localPathStep1 * ( mid1 , sink1 ) and
133150 localPathStep2 * ( mid2 , sink2 )
134151 )
0 commit comments