Skip to content

Commit 4c2081b

Browse files
authored
Merge pull request #8401 from jketema/taint-flow
Extend taint tracking interface with flow states
2 parents 2f4a22c + c832b21 commit 4c2081b

File tree

28 files changed

+825
-25
lines changed

28 files changed

+825
-25
lines changed
Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,4 @@
1+
---
2+
category: breaking
3+
---
4+
* The flow state variants of `isBarrier` and `isAdditionalFlowStep` are no longer exposed in the taint tracking library. The `isSanitizer` and `isAdditionalTaintStep` predicates should be used instead.

cpp/ql/lib/semmle/code/cpp/dataflow/TaintTracking.qll

Lines changed: 0 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -20,5 +20,4 @@ import semmle.code.cpp.dataflow.DataFlow2
2020

2121
module TaintTracking {
2222
import semmle.code.cpp.dataflow.internal.tainttracking1.TaintTrackingImpl
23-
private import semmle.code.cpp.dataflow.TaintTracking2
2423
}

cpp/ql/lib/semmle/code/cpp/dataflow/internal/tainttracking1/TaintTrackingImpl.qll

Lines changed: 47 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -64,13 +64,30 @@ abstract class Configuration extends DataFlow::Configuration {
6464
override predicate isSource(DataFlow::Node source) { none() }
6565

6666
/**
67-
* Holds if `sink` is a relevant taint sink.
67+
* Holds if `source` is a relevant taint source with the given initial
68+
* `state`.
69+
*
70+
* The smaller this predicate is, the faster `hasFlow()` will converge.
71+
*/
72+
// overridden to provide taint-tracking specific qldoc
73+
override predicate isSource(DataFlow::Node source, DataFlow::FlowState state) { none() }
74+
75+
/**
76+
* Holds if `sink` is a relevant taint sink
6877
*
6978
* The smaller this predicate is, the faster `hasFlow()` will converge.
7079
*/
7180
// overridden to provide taint-tracking specific qldoc
7281
override predicate isSink(DataFlow::Node sink) { none() }
7382

83+
/**
84+
* Holds if `sink` is a relevant taint sink accepting `state`.
85+
*
86+
* The smaller this predicate is, the faster `hasFlow()` will converge.
87+
*/
88+
// overridden to provide taint-tracking specific qldoc
89+
override predicate isSink(DataFlow::Node sink, DataFlow::FlowState state) { none() }
90+
7491
/** Holds if the node `node` is a taint sanitizer. */
7592
predicate isSanitizer(DataFlow::Node node) { none() }
7693

@@ -79,6 +96,16 @@ abstract class Configuration extends DataFlow::Configuration {
7996
defaultTaintSanitizer(node)
8097
}
8198

99+
/**
100+
* Holds if the node `node` is a taint sanitizer when the flow state is
101+
* `state`.
102+
*/
103+
predicate isSanitizer(DataFlow::Node node, DataFlow::FlowState state) { none() }
104+
105+
final override predicate isBarrier(DataFlow::Node node, DataFlow::FlowState state) {
106+
this.isSanitizer(node, state)
107+
}
108+
82109
/** Holds if taint propagation into `node` is prohibited. */
83110
predicate isSanitizerIn(DataFlow::Node node) { none() }
84111

@@ -107,6 +134,25 @@ abstract class Configuration extends DataFlow::Configuration {
107134
defaultAdditionalTaintStep(node1, node2)
108135
}
109136

137+
/**
138+
* Holds if the additional taint propagation step from `node1` to `node2`
139+
* must be taken into account in the analysis. This step is only applicable
140+
* in `state1` and updates the flow state to `state2`.
141+
*/
142+
predicate isAdditionalTaintStep(
143+
DataFlow::Node node1, DataFlow::FlowState state1, DataFlow::Node node2,
144+
DataFlow::FlowState state2
145+
) {
146+
none()
147+
}
148+
149+
final override predicate isAdditionalFlowStep(
150+
DataFlow::Node node1, DataFlow::FlowState state1, DataFlow::Node node2,
151+
DataFlow::FlowState state2
152+
) {
153+
this.isAdditionalTaintStep(node1, state1, node2, state2)
154+
}
155+
110156
override predicate allowImplicitRead(DataFlow::Node node, DataFlow::Content c) {
111157
(this.isSink(node) or this.isAdditionalTaintStep(node, _)) and
112158
defaultImplicitTaintRead(node, c)

cpp/ql/lib/semmle/code/cpp/dataflow/internal/tainttracking2/TaintTrackingImpl.qll

Lines changed: 47 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -64,13 +64,30 @@ abstract class Configuration extends DataFlow::Configuration {
6464
override predicate isSource(DataFlow::Node source) { none() }
6565

6666
/**
67-
* Holds if `sink` is a relevant taint sink.
67+
* Holds if `source` is a relevant taint source with the given initial
68+
* `state`.
69+
*
70+
* The smaller this predicate is, the faster `hasFlow()` will converge.
71+
*/
72+
// overridden to provide taint-tracking specific qldoc
73+
override predicate isSource(DataFlow::Node source, DataFlow::FlowState state) { none() }
74+
75+
/**
76+
* Holds if `sink` is a relevant taint sink
6877
*
6978
* The smaller this predicate is, the faster `hasFlow()` will converge.
7079
*/
7180
// overridden to provide taint-tracking specific qldoc
7281
override predicate isSink(DataFlow::Node sink) { none() }
7382

83+
/**
84+
* Holds if `sink` is a relevant taint sink accepting `state`.
85+
*
86+
* The smaller this predicate is, the faster `hasFlow()` will converge.
87+
*/
88+
// overridden to provide taint-tracking specific qldoc
89+
override predicate isSink(DataFlow::Node sink, DataFlow::FlowState state) { none() }
90+
7491
/** Holds if the node `node` is a taint sanitizer. */
7592
predicate isSanitizer(DataFlow::Node node) { none() }
7693

@@ -79,6 +96,16 @@ abstract class Configuration extends DataFlow::Configuration {
7996
defaultTaintSanitizer(node)
8097
}
8198

99+
/**
100+
* Holds if the node `node` is a taint sanitizer when the flow state is
101+
* `state`.
102+
*/
103+
predicate isSanitizer(DataFlow::Node node, DataFlow::FlowState state) { none() }
104+
105+
final override predicate isBarrier(DataFlow::Node node, DataFlow::FlowState state) {
106+
this.isSanitizer(node, state)
107+
}
108+
82109
/** Holds if taint propagation into `node` is prohibited. */
83110
predicate isSanitizerIn(DataFlow::Node node) { none() }
84111

@@ -107,6 +134,25 @@ abstract class Configuration extends DataFlow::Configuration {
107134
defaultAdditionalTaintStep(node1, node2)
108135
}
109136

137+
/**
138+
* Holds if the additional taint propagation step from `node1` to `node2`
139+
* must be taken into account in the analysis. This step is only applicable
140+
* in `state1` and updates the flow state to `state2`.
141+
*/
142+
predicate isAdditionalTaintStep(
143+
DataFlow::Node node1, DataFlow::FlowState state1, DataFlow::Node node2,
144+
DataFlow::FlowState state2
145+
) {
146+
none()
147+
}
148+
149+
final override predicate isAdditionalFlowStep(
150+
DataFlow::Node node1, DataFlow::FlowState state1, DataFlow::Node node2,
151+
DataFlow::FlowState state2
152+
) {
153+
this.isAdditionalTaintStep(node1, state1, node2, state2)
154+
}
155+
110156
override predicate allowImplicitRead(DataFlow::Node node, DataFlow::Content c) {
111157
(this.isSink(node) or this.isAdditionalTaintStep(node, _)) and
112158
defaultImplicitTaintRead(node, c)

cpp/ql/lib/semmle/code/cpp/ir/dataflow/TaintTracking.qll

Lines changed: 0 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -20,5 +20,4 @@ import semmle.code.cpp.ir.dataflow.DataFlow2
2020

2121
module TaintTracking {
2222
import semmle.code.cpp.ir.dataflow.internal.tainttracking1.TaintTrackingImpl
23-
private import semmle.code.cpp.ir.dataflow.TaintTracking2
2423
}

cpp/ql/lib/semmle/code/cpp/ir/dataflow/internal/tainttracking1/TaintTrackingImpl.qll

Lines changed: 47 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -64,13 +64,30 @@ abstract class Configuration extends DataFlow::Configuration {
6464
override predicate isSource(DataFlow::Node source) { none() }
6565

6666
/**
67-
* Holds if `sink` is a relevant taint sink.
67+
* Holds if `source` is a relevant taint source with the given initial
68+
* `state`.
69+
*
70+
* The smaller this predicate is, the faster `hasFlow()` will converge.
71+
*/
72+
// overridden to provide taint-tracking specific qldoc
73+
override predicate isSource(DataFlow::Node source, DataFlow::FlowState state) { none() }
74+
75+
/**
76+
* Holds if `sink` is a relevant taint sink
6877
*
6978
* The smaller this predicate is, the faster `hasFlow()` will converge.
7079
*/
7180
// overridden to provide taint-tracking specific qldoc
7281
override predicate isSink(DataFlow::Node sink) { none() }
7382

83+
/**
84+
* Holds if `sink` is a relevant taint sink accepting `state`.
85+
*
86+
* The smaller this predicate is, the faster `hasFlow()` will converge.
87+
*/
88+
// overridden to provide taint-tracking specific qldoc
89+
override predicate isSink(DataFlow::Node sink, DataFlow::FlowState state) { none() }
90+
7491
/** Holds if the node `node` is a taint sanitizer. */
7592
predicate isSanitizer(DataFlow::Node node) { none() }
7693

@@ -79,6 +96,16 @@ abstract class Configuration extends DataFlow::Configuration {
7996
defaultTaintSanitizer(node)
8097
}
8198

99+
/**
100+
* Holds if the node `node` is a taint sanitizer when the flow state is
101+
* `state`.
102+
*/
103+
predicate isSanitizer(DataFlow::Node node, DataFlow::FlowState state) { none() }
104+
105+
final override predicate isBarrier(DataFlow::Node node, DataFlow::FlowState state) {
106+
this.isSanitizer(node, state)
107+
}
108+
82109
/** Holds if taint propagation into `node` is prohibited. */
83110
predicate isSanitizerIn(DataFlow::Node node) { none() }
84111

@@ -107,6 +134,25 @@ abstract class Configuration extends DataFlow::Configuration {
107134
defaultAdditionalTaintStep(node1, node2)
108135
}
109136

137+
/**
138+
* Holds if the additional taint propagation step from `node1` to `node2`
139+
* must be taken into account in the analysis. This step is only applicable
140+
* in `state1` and updates the flow state to `state2`.
141+
*/
142+
predicate isAdditionalTaintStep(
143+
DataFlow::Node node1, DataFlow::FlowState state1, DataFlow::Node node2,
144+
DataFlow::FlowState state2
145+
) {
146+
none()
147+
}
148+
149+
final override predicate isAdditionalFlowStep(
150+
DataFlow::Node node1, DataFlow::FlowState state1, DataFlow::Node node2,
151+
DataFlow::FlowState state2
152+
) {
153+
this.isAdditionalTaintStep(node1, state1, node2, state2)
154+
}
155+
110156
override predicate allowImplicitRead(DataFlow::Node node, DataFlow::Content c) {
111157
(this.isSink(node) or this.isAdditionalTaintStep(node, _)) and
112158
defaultImplicitTaintRead(node, c)

cpp/ql/lib/semmle/code/cpp/ir/dataflow/internal/tainttracking2/TaintTrackingImpl.qll

Lines changed: 47 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -64,13 +64,30 @@ abstract class Configuration extends DataFlow::Configuration {
6464
override predicate isSource(DataFlow::Node source) { none() }
6565

6666
/**
67-
* Holds if `sink` is a relevant taint sink.
67+
* Holds if `source` is a relevant taint source with the given initial
68+
* `state`.
69+
*
70+
* The smaller this predicate is, the faster `hasFlow()` will converge.
71+
*/
72+
// overridden to provide taint-tracking specific qldoc
73+
override predicate isSource(DataFlow::Node source, DataFlow::FlowState state) { none() }
74+
75+
/**
76+
* Holds if `sink` is a relevant taint sink
6877
*
6978
* The smaller this predicate is, the faster `hasFlow()` will converge.
7079
*/
7180
// overridden to provide taint-tracking specific qldoc
7281
override predicate isSink(DataFlow::Node sink) { none() }
7382

83+
/**
84+
* Holds if `sink` is a relevant taint sink accepting `state`.
85+
*
86+
* The smaller this predicate is, the faster `hasFlow()` will converge.
87+
*/
88+
// overridden to provide taint-tracking specific qldoc
89+
override predicate isSink(DataFlow::Node sink, DataFlow::FlowState state) { none() }
90+
7491
/** Holds if the node `node` is a taint sanitizer. */
7592
predicate isSanitizer(DataFlow::Node node) { none() }
7693

@@ -79,6 +96,16 @@ abstract class Configuration extends DataFlow::Configuration {
7996
defaultTaintSanitizer(node)
8097
}
8198

99+
/**
100+
* Holds if the node `node` is a taint sanitizer when the flow state is
101+
* `state`.
102+
*/
103+
predicate isSanitizer(DataFlow::Node node, DataFlow::FlowState state) { none() }
104+
105+
final override predicate isBarrier(DataFlow::Node node, DataFlow::FlowState state) {
106+
this.isSanitizer(node, state)
107+
}
108+
82109
/** Holds if taint propagation into `node` is prohibited. */
83110
predicate isSanitizerIn(DataFlow::Node node) { none() }
84111

@@ -107,6 +134,25 @@ abstract class Configuration extends DataFlow::Configuration {
107134
defaultAdditionalTaintStep(node1, node2)
108135
}
109136

137+
/**
138+
* Holds if the additional taint propagation step from `node1` to `node2`
139+
* must be taken into account in the analysis. This step is only applicable
140+
* in `state1` and updates the flow state to `state2`.
141+
*/
142+
predicate isAdditionalTaintStep(
143+
DataFlow::Node node1, DataFlow::FlowState state1, DataFlow::Node node2,
144+
DataFlow::FlowState state2
145+
) {
146+
none()
147+
}
148+
149+
final override predicate isAdditionalFlowStep(
150+
DataFlow::Node node1, DataFlow::FlowState state1, DataFlow::Node node2,
151+
DataFlow::FlowState state2
152+
) {
153+
this.isAdditionalTaintStep(node1, state1, node2, state2)
154+
}
155+
110156
override predicate allowImplicitRead(DataFlow::Node node, DataFlow::Content c) {
111157
(this.isSink(node) or this.isAdditionalTaintStep(node, _)) and
112158
defaultImplicitTaintRead(node, c)

cpp/ql/lib/semmle/code/cpp/ir/dataflow/internal/tainttracking3/TaintTrackingImpl.qll

Lines changed: 47 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -64,13 +64,30 @@ abstract class Configuration extends DataFlow::Configuration {
6464
override predicate isSource(DataFlow::Node source) { none() }
6565

6666
/**
67-
* Holds if `sink` is a relevant taint sink.
67+
* Holds if `source` is a relevant taint source with the given initial
68+
* `state`.
69+
*
70+
* The smaller this predicate is, the faster `hasFlow()` will converge.
71+
*/
72+
// overridden to provide taint-tracking specific qldoc
73+
override predicate isSource(DataFlow::Node source, DataFlow::FlowState state) { none() }
74+
75+
/**
76+
* Holds if `sink` is a relevant taint sink
6877
*
6978
* The smaller this predicate is, the faster `hasFlow()` will converge.
7079
*/
7180
// overridden to provide taint-tracking specific qldoc
7281
override predicate isSink(DataFlow::Node sink) { none() }
7382

83+
/**
84+
* Holds if `sink` is a relevant taint sink accepting `state`.
85+
*
86+
* The smaller this predicate is, the faster `hasFlow()` will converge.
87+
*/
88+
// overridden to provide taint-tracking specific qldoc
89+
override predicate isSink(DataFlow::Node sink, DataFlow::FlowState state) { none() }
90+
7491
/** Holds if the node `node` is a taint sanitizer. */
7592
predicate isSanitizer(DataFlow::Node node) { none() }
7693

@@ -79,6 +96,16 @@ abstract class Configuration extends DataFlow::Configuration {
7996
defaultTaintSanitizer(node)
8097
}
8198

99+
/**
100+
* Holds if the node `node` is a taint sanitizer when the flow state is
101+
* `state`.
102+
*/
103+
predicate isSanitizer(DataFlow::Node node, DataFlow::FlowState state) { none() }
104+
105+
final override predicate isBarrier(DataFlow::Node node, DataFlow::FlowState state) {
106+
this.isSanitizer(node, state)
107+
}
108+
82109
/** Holds if taint propagation into `node` is prohibited. */
83110
predicate isSanitizerIn(DataFlow::Node node) { none() }
84111

@@ -107,6 +134,25 @@ abstract class Configuration extends DataFlow::Configuration {
107134
defaultAdditionalTaintStep(node1, node2)
108135
}
109136

137+
/**
138+
* Holds if the additional taint propagation step from `node1` to `node2`
139+
* must be taken into account in the analysis. This step is only applicable
140+
* in `state1` and updates the flow state to `state2`.
141+
*/
142+
predicate isAdditionalTaintStep(
143+
DataFlow::Node node1, DataFlow::FlowState state1, DataFlow::Node node2,
144+
DataFlow::FlowState state2
145+
) {
146+
none()
147+
}
148+
149+
final override predicate isAdditionalFlowStep(
150+
DataFlow::Node node1, DataFlow::FlowState state1, DataFlow::Node node2,
151+
DataFlow::FlowState state2
152+
) {
153+
this.isAdditionalTaintStep(node1, state1, node2, state2)
154+
}
155+
110156
override predicate allowImplicitRead(DataFlow::Node node, DataFlow::Content c) {
111157
(this.isSink(node) or this.isAdditionalTaintStep(node, _)) and
112158
defaultImplicitTaintRead(node, c)
Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,4 @@
1+
---
2+
category: breaking
3+
---
4+
* The flow state variants of `isBarrier` and `isAdditionalFlowStep` are no longer exposed in the taint tracking library. The `isSanitizer` and `isAdditionalTaintStep` predicates should be used instead.

0 commit comments

Comments
 (0)