Skip to content

Commit 1401e7d

Browse files
authored
Merge pull request github#8855 from michaelnebel/csharp/singlereadstore
C#: Only allow two read and two store steps in model capturing.
2 parents c21849b + 83aa65f commit 1401e7d

File tree

2 files changed

+50
-14
lines changed

2 files changed

+50
-14
lines changed

csharp/ql/src/utils/model-generator/internal/CaptureModels.qll

Lines changed: 25 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -90,18 +90,34 @@ string captureQualifierFlow(TargetApi api) {
9090
result = asValueModel(api, qualifierString(), "ReturnValue")
9191
}
9292

93+
private int accessPathLimit() { result = 2 }
94+
9395
/**
9496
* A FlowState representing a tainted read.
9597
*/
9698
private class TaintRead extends DataFlow::FlowState {
97-
TaintRead() { this = "TaintRead" }
99+
private int step;
100+
101+
TaintRead() { this = "TaintRead(" + step + ")" and step in [0 .. accessPathLimit()] }
102+
103+
/**
104+
* Gets the flow state step number.
105+
*/
106+
int getStep() { result = step }
98107
}
99108

100109
/**
101110
* A FlowState representing a tainted write.
102111
*/
103112
private class TaintStore extends DataFlow::FlowState {
104-
TaintStore() { this = "TaintStore" }
113+
private int step;
114+
115+
TaintStore() { this = "TaintStore(" + step + ")" and step in [1 .. accessPathLimit()] }
116+
117+
/**
118+
* Gets the flow state step number.
119+
*/
120+
int getStep() { result = step }
105121
}
106122

107123
/**
@@ -116,7 +132,7 @@ private class ThroughFlowConfig extends TaintTracking::Configuration {
116132
override predicate isSource(DataFlow::Node source, DataFlow::FlowState state) {
117133
source instanceof DataFlow::ParameterNode and
118134
source.getEnclosingCallable() instanceof TargetApi and
119-
state instanceof TaintRead
135+
state.(TaintRead).getStep() = 0
120136
}
121137

122138
override predicate isSink(DataFlow::Node sink, DataFlow::FlowState state) {
@@ -133,15 +149,17 @@ private class ThroughFlowConfig extends TaintTracking::Configuration {
133149
exists(DataFlowImplCommon::TypedContent tc |
134150
DataFlowImplCommon::store(node1, tc, node2, _) and
135151
isRelevantContent(tc.getContent()) and
136-
(state1 instanceof TaintRead or state1 instanceof TaintStore) and
137-
state2 instanceof TaintStore
152+
(
153+
state1 instanceof TaintRead and state2.(TaintStore).getStep() = 1
154+
or
155+
state1.(TaintStore).getStep() + 1 = state2.(TaintStore).getStep()
156+
)
138157
)
139158
or
140159
exists(DataFlow::Content c |
141160
DataFlowPrivate::readStep(node1, c, node2) and
142161
isRelevantContent(c) and
143-
state1 instanceof TaintRead and
144-
state2 instanceof TaintRead
162+
state1.(TaintRead).getStep() + 1 = state2.(TaintRead).getStep()
145163
)
146164
}
147165

java/ql/src/utils/model-generator/internal/CaptureModels.qll

Lines changed: 25 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -90,18 +90,34 @@ string captureQualifierFlow(TargetApi api) {
9090
result = asValueModel(api, qualifierString(), "ReturnValue")
9191
}
9292

93+
private int accessPathLimit() { result = 2 }
94+
9395
/**
9496
* A FlowState representing a tainted read.
9597
*/
9698
private class TaintRead extends DataFlow::FlowState {
97-
TaintRead() { this = "TaintRead" }
99+
private int step;
100+
101+
TaintRead() { this = "TaintRead(" + step + ")" and step in [0 .. accessPathLimit()] }
102+
103+
/**
104+
* Gets the flow state step number.
105+
*/
106+
int getStep() { result = step }
98107
}
99108

100109
/**
101110
* A FlowState representing a tainted write.
102111
*/
103112
private class TaintStore extends DataFlow::FlowState {
104-
TaintStore() { this = "TaintStore" }
113+
private int step;
114+
115+
TaintStore() { this = "TaintStore(" + step + ")" and step in [1 .. accessPathLimit()] }
116+
117+
/**
118+
* Gets the flow state step number.
119+
*/
120+
int getStep() { result = step }
105121
}
106122

107123
/**
@@ -116,7 +132,7 @@ private class ThroughFlowConfig extends TaintTracking::Configuration {
116132
override predicate isSource(DataFlow::Node source, DataFlow::FlowState state) {
117133
source instanceof DataFlow::ParameterNode and
118134
source.getEnclosingCallable() instanceof TargetApi and
119-
state instanceof TaintRead
135+
state.(TaintRead).getStep() = 0
120136
}
121137

122138
override predicate isSink(DataFlow::Node sink, DataFlow::FlowState state) {
@@ -133,15 +149,17 @@ private class ThroughFlowConfig extends TaintTracking::Configuration {
133149
exists(DataFlowImplCommon::TypedContent tc |
134150
DataFlowImplCommon::store(node1, tc, node2, _) and
135151
isRelevantContent(tc.getContent()) and
136-
(state1 instanceof TaintRead or state1 instanceof TaintStore) and
137-
state2 instanceof TaintStore
152+
(
153+
state1 instanceof TaintRead and state2.(TaintStore).getStep() = 1
154+
or
155+
state1.(TaintStore).getStep() + 1 = state2.(TaintStore).getStep()
156+
)
138157
)
139158
or
140159
exists(DataFlow::Content c |
141160
DataFlowPrivate::readStep(node1, c, node2) and
142161
isRelevantContent(c) and
143-
state1 instanceof TaintRead and
144-
state2 instanceof TaintRead
162+
state1.(TaintRead).getStep() + 1 = state2.(TaintRead).getStep()
145163
)
146164
}
147165

0 commit comments

Comments
 (0)