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
3
3
4
4
module ProductFlow {
5
5
abstract class Configuration extends string {
@@ -11,14 +11,31 @@ module ProductFlow {
11
11
*
12
12
* `source1` and `source2` must belong to the same callable.
13
13
*/
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
+ }
15
23
16
24
/**
17
25
* Holds if `(sink1, sink2)` is a relevant data flow sink.
18
26
*
19
27
* `sink1` and `sink2` must belong to the same callable.
20
28
*/
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
+ }
22
39
23
40
predicate hasFlowPath (
24
41
DataFlow:: PathNode source1 , DataFlow2:: PathNode source2 , DataFlow:: PathNode sink1 ,
@@ -34,28 +51,28 @@ module ProductFlow {
34
51
class Conf1 extends DataFlow:: Configuration {
35
52
Conf1 ( ) { this = "Conf1" }
36
53
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 , _ , _) )
39
56
}
40
57
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 , _ , _) )
43
60
}
44
61
}
45
62
46
63
class Conf2 extends DataFlow2:: Configuration {
47
64
Conf2 ( ) { this = "Conf2" }
48
65
49
- override predicate isSource ( DataFlow:: Node source ) {
66
+ override predicate isSource ( DataFlow:: Node source , string state ) {
50
67
exists ( Configuration conf , DataFlow:: Node source1 |
51
- conf .isSourcePair ( source1 , source ) and
68
+ conf .isSourcePair ( source1 , _ , source , state ) and
52
69
any ( Conf1 c ) .hasFlow ( source1 , _)
53
70
)
54
71
}
55
72
56
- override predicate isSink ( DataFlow:: Node sink ) {
73
+ override predicate isSink ( DataFlow:: Node sink , string state ) {
57
74
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 )
59
76
)
60
77
}
61
78
}
@@ -65,7 +82,7 @@ module ProductFlow {
65
82
Configuration conf , DataFlow:: PathNode source1 , DataFlow2:: PathNode source2 ,
66
83
DataFlow:: PathNode node1 , DataFlow2:: PathNode node2
67
84
) {
68
- conf .isSourcePair ( node1 .getNode ( ) , node2 .getNode ( ) ) and
85
+ conf .isSourcePair ( node1 .getNode ( ) , _ , node2 .getNode ( ) , _ ) and
69
86
node1 = source1 and
70
87
node2 = source2
71
88
or
@@ -128,7 +145,7 @@ module ProductFlow {
128
145
) {
129
146
exists ( DataFlow:: PathNode mid1 , DataFlow2:: PathNode mid2 |
130
147
reachableInterprocEntry ( conf , source1 , source2 , mid1 , mid2 ) and
131
- conf .isSinkPair ( sink1 .getNode ( ) , sink2 .getNode ( ) ) and
148
+ conf .isSinkPair ( sink1 .getNode ( ) , _ , sink2 .getNode ( ) , _ ) and
132
149
localPathStep1 * ( mid1 , sink1 ) and
133
150
localPathStep2 * ( mid2 , sink2 )
134
151
)
0 commit comments