Skip to content

Commit 39272de

Browse files
committed
C++: Clean up the ProductFlow FlowStates
1 parent 4e12924 commit 39272de

File tree

2 files changed

+25
-23
lines changed

2 files changed

+25
-23
lines changed

cpp/ql/src/experimental/Likely Bugs/OverrunWriteProductFlow.ql

Lines changed: 14 additions & 13 deletions
Original file line numberDiff line numberDiff line change
@@ -20,6 +20,7 @@ import semmle.code.cpp.models.interfaces.ArrayFunction
2020
import semmle.code.cpp.rangeanalysis.new.internal.semantic.analysis.RangeAnalysis
2121
import semmle.code.cpp.rangeanalysis.new.internal.semantic.SemanticExprSpecific
2222
import StringSizeFlow::PathGraph1
23+
import codeql.util.Unit
2324

2425
pragma[nomagic]
2526
Instruction getABoundIn(SemBound b, IRFunction func) {
@@ -46,7 +47,7 @@ VariableAccess getAVariableAccess(Expr e) { e.getAChild*() = result }
4647
* Holds if `(n, state)` pair represents the source of flow for the size
4748
* expression associated with `alloc`.
4849
*/
49-
predicate hasSize(AllocationExpr alloc, DataFlow::Node n, string state) {
50+
predicate hasSize(AllocationExpr alloc, DataFlow::Node n, int state) {
5051
exists(VariableAccess va, Expr size, int delta |
5152
size = alloc.getSizeExpr() and
5253
// Get the unique variable in a size expression like `x` in `malloc(x + 1)`.
@@ -55,7 +56,7 @@ predicate hasSize(AllocationExpr alloc, DataFlow::Node n, string state) {
5556
bounded(any(Instruction instr | instr.getUnconvertedResultExpression() = size),
5657
any(LoadInstruction load | load.getUnconvertedResultExpression() = va), delta) and
5758
n.asConvertedExpr() = va.getFullyConverted() and
58-
state = delta.toString()
59+
state = delta
5960
)
6061
}
6162

@@ -78,9 +79,9 @@ predicate isSinkPairImpl(
7879
}
7980

8081
module StringSizeConfig implements ProductFlow::StateConfigSig {
81-
class FlowState1 = string;
82+
class FlowState1 = Unit;
8283

83-
class FlowState2 = string;
84+
class FlowState2 = int;
8485

8586
predicate isSourcePair(
8687
DataFlow::Node bufSource, FlowState1 state1, DataFlow::Node sizeSource, FlowState2 state2
@@ -91,18 +92,18 @@ module StringSizeConfig implements ProductFlow::StateConfigSig {
9192
// ```
9293
// we use `state2` to remember that there was an offset (in this case an offset of `1`) added
9394
// to the size of the allocation. This state is then checked in `isSinkPair`.
94-
state1 instanceof DataFlow::FlowStateEmpty and
95+
exists(state1) and
9596
hasSize(bufSource.asConvertedExpr(), sizeSource, state2)
9697
}
9798

9899
predicate isSinkPair(
99100
DataFlow::Node bufSink, FlowState1 state1, DataFlow::Node sizeSink, FlowState2 state2
100101
) {
101-
state1 instanceof DataFlow::FlowStateEmpty and
102-
state2 = [-32 .. 32].toString() and // An arbitrary bound because we need to bound `state2`
102+
exists(state1) and
103+
state2 = [-32 .. 32] and // An arbitrary bound because we need to bound `state2`
103104
exists(int delta |
104105
isSinkPairImpl(_, bufSink, sizeSink, delta, _) and
105-
delta > state2.toInt()
106+
delta > state2
106107
)
107108
}
108109

@@ -111,18 +112,18 @@ module StringSizeConfig implements ProductFlow::StateConfigSig {
111112
predicate isBarrier2(DataFlow::Node node, FlowState2 state) { none() }
112113

113114
predicate isAdditionalFlowStep1(
114-
DataFlow::Node node1, FlowState1 state1, DataFlow::Node node2, FlowState2 state2
115+
DataFlow::Node node1, FlowState1 state1, DataFlow::Node node2, FlowState1 state2
115116
) {
116117
none()
117118
}
118119

119120
predicate isAdditionalFlowStep2(
120-
DataFlow::Node node1, FlowState1 state1, DataFlow::Node node2, FlowState2 state2
121+
DataFlow::Node node1, FlowState2 state1, DataFlow::Node node2, FlowState2 state2
121122
) {
122123
exists(AddInstruction add, Operand op, int delta, int s1, int s2 |
123124
s1 = [-32 .. 32] and // An arbitrary bound because we need to bound `state`
124-
state1 = s1.toString() and
125-
state2 = s2.toString() and
125+
state1 = s1 and
126+
state2 = s2 and
126127
add.hasOperands(node1.asOperand(), op) and
127128
semBounded(getSemanticExpr(op.getDef()), any(SemZeroBound zero), delta, true, _) and
128129
node2.asInstruction() = add and
@@ -139,7 +140,7 @@ from
139140
CallInstruction c, DataFlow::Node sourceNode, Expr buffer, string element
140141
where
141142
StringSizeFlow::hasFlowPath(source1, source2, sink1, sink2) and
142-
sinkState = sink2.getState().toInt() and
143+
sinkState = sink2.getState() and
143144
isSinkPairImpl(c, sink1.getNode(), sink2.getNode(), overflow + sinkState, buffer) and
144145
overflow > 0 and
145146
sourceNode = source1.getNode() and

cpp/ql/src/experimental/Security/CWE/CWE-193/InvalidPointerDeref.ql

Lines changed: 11 additions & 10 deletions
Original file line numberDiff line numberDiff line change
@@ -20,6 +20,7 @@ import experimental.semmle.code.cpp.dataflow.ProductFlow
2020
import semmle.code.cpp.rangeanalysis.new.internal.semantic.analysis.RangeAnalysis
2121
import semmle.code.cpp.rangeanalysis.new.internal.semantic.SemanticExprSpecific
2222
import semmle.code.cpp.ir.IR
23+
import codeql.util.Unit
2324

2425
pragma[nomagic]
2526
Instruction getABoundIn(SemBound b, IRFunction func) {
@@ -51,14 +52,14 @@ predicate bounded2(Instruction i, Instruction b, int delta) { boundedImpl(i, b,
5152
* Holds if the combination of `n` and `state` represents an appropriate
5253
* source for the expression `e` suitable for use-use flow.
5354
*/
54-
private predicate hasSizeImpl(Expr e, DataFlow::Node n, string state) {
55+
private predicate hasSizeImpl(Expr e, DataFlow::Node n, int state) {
5556
// The simple case: If the size is a variable access with no qualifier we can just use the
5657
// dataflow node for that expression and no state.
5758
exists(VariableAccess va |
5859
va = e and
5960
not va instanceof FieldAccess and
6061
n.asConvertedExpr() = va.getFullyConverted() and
61-
state = "0"
62+
state = 0
6263
)
6364
or
6465
// If the size is a choice between two expressions we allow both to be nodes representing the size.
@@ -68,13 +69,13 @@ private predicate hasSizeImpl(Expr e, DataFlow::Node n, string state) {
6869
// remember the constant in the state.
6970
exists(Expr const, Expr nonconst |
7071
e.(AddExpr).hasOperands(const, nonconst) and
71-
state = const.getValue() and
72+
state = const.getValue().toInt() and
7273
hasSizeImpl(nonconst, n, _)
7374
)
7475
or
7576
exists(Expr const, Expr nonconst |
7677
e.(SubExpr).hasOperands(const, nonconst) and
77-
state = "-" + const.getValue() and
78+
state = -const.getValue().toInt() and
7879
hasSizeImpl(nonconst, n, _)
7980
)
8081
}
@@ -83,7 +84,7 @@ private predicate hasSizeImpl(Expr e, DataFlow::Node n, string state) {
8384
* Holds if `(n, state)` pair represents the source of flow for the size
8485
* expression associated with `alloc`.
8586
*/
86-
predicate hasSize(HeuristicAllocationExpr alloc, DataFlow::Node n, string state) {
87+
predicate hasSize(HeuristicAllocationExpr alloc, DataFlow::Node n, int state) {
8788
hasSizeImpl(alloc.getSizeExpr(), n, state)
8889
}
8990

@@ -108,9 +109,9 @@ predicate hasSize(HeuristicAllocationExpr alloc, DataFlow::Node n, string state)
108109
* is non-strictly upper-bounded by `end` (which in this case is `*p`).
109110
*/
110111
module AllocToInvalidPointerConfig implements ProductFlow::StateConfigSig {
111-
class FlowState1 = string;
112+
class FlowState1 = Unit;
112113

113-
class FlowState2 = string;
114+
class FlowState2 = int;
114115

115116
predicate isSourcePair(
116117
DataFlow::Node source1, FlowState1 state1, DataFlow::Node source2, FlowState2 state2
@@ -121,19 +122,19 @@ module AllocToInvalidPointerConfig implements ProductFlow::StateConfigSig {
121122
// ```
122123
// we use `state2` to remember that there was an offset (in this case an offset of `1`) added
123124
// to the size of the allocation. This state is then checked in `isSinkPair`.
124-
state1 = "" and
125+
exists(state1) and
125126
hasSize(source1.asConvertedExpr(), source2, state2)
126127
}
127128

128129
predicate isSinkPair(
129130
DataFlow::Node sink1, FlowState1 state1, DataFlow::Node sink2, FlowState2 state2
130131
) {
131-
state1 = "" and
132+
exists(state1) and
132133
// We check that the delta computed by the range analysis matches the
133134
// state value that we set in `isSourcePair`.
134135
exists(int delta |
135136
isSinkImpl(_, sink1, sink2, delta) and
136-
state2 = delta.toString()
137+
state2 = delta
137138
)
138139
}
139140

0 commit comments

Comments
 (0)