@@ -20,6 +20,7 @@ import semmle.code.cpp.models.interfaces.ArrayFunction
20
20
import semmle.code.cpp.rangeanalysis.new.internal.semantic.analysis.RangeAnalysis
21
21
import semmle.code.cpp.rangeanalysis.new.internal.semantic.SemanticExprSpecific
22
22
import StringSizeFlow:: PathGraph1
23
+ import codeql.util.Unit
23
24
24
25
pragma [ nomagic]
25
26
Instruction getABoundIn ( SemBound b , IRFunction func ) {
@@ -46,7 +47,7 @@ VariableAccess getAVariableAccess(Expr e) { e.getAChild*() = result }
46
47
* Holds if `(n, state)` pair represents the source of flow for the size
47
48
* expression associated with `alloc`.
48
49
*/
49
- predicate hasSize ( AllocationExpr alloc , DataFlow:: Node n , string state ) {
50
+ predicate hasSize ( AllocationExpr alloc , DataFlow:: Node n , int state ) {
50
51
exists ( VariableAccess va , Expr size , int delta |
51
52
size = alloc .getSizeExpr ( ) and
52
53
// 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) {
55
56
bounded ( any ( Instruction instr | instr .getUnconvertedResultExpression ( ) = size ) ,
56
57
any ( LoadInstruction load | load .getUnconvertedResultExpression ( ) = va ) , delta ) and
57
58
n .asConvertedExpr ( ) = va .getFullyConverted ( ) and
58
- state = delta . toString ( )
59
+ state = delta
59
60
)
60
61
}
61
62
@@ -78,9 +79,9 @@ predicate isSinkPairImpl(
78
79
}
79
80
80
81
module StringSizeConfig implements ProductFlow:: StateConfigSig {
81
- class FlowState1 = string ;
82
+ class FlowState1 = Unit ;
82
83
83
- class FlowState2 = string ;
84
+ class FlowState2 = int ;
84
85
85
86
predicate isSourcePair (
86
87
DataFlow:: Node bufSource , FlowState1 state1 , DataFlow:: Node sizeSource , FlowState2 state2
@@ -91,18 +92,18 @@ module StringSizeConfig implements ProductFlow::StateConfigSig {
91
92
// ```
92
93
// we use `state2` to remember that there was an offset (in this case an offset of `1`) added
93
94
// to the size of the allocation. This state is then checked in `isSinkPair`.
94
- state1 instanceof DataFlow :: FlowStateEmpty and
95
+ exists ( state1 ) and
95
96
hasSize ( bufSource .asConvertedExpr ( ) , sizeSource , state2 )
96
97
}
97
98
98
99
predicate isSinkPair (
99
100
DataFlow:: Node bufSink , FlowState1 state1 , DataFlow:: Node sizeSink , FlowState2 state2
100
101
) {
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`
103
104
exists ( int delta |
104
105
isSinkPairImpl ( _, bufSink , sizeSink , delta , _) and
105
- delta > state2 . toInt ( )
106
+ delta > state2
106
107
)
107
108
}
108
109
@@ -111,18 +112,18 @@ module StringSizeConfig implements ProductFlow::StateConfigSig {
111
112
predicate isBarrier2 ( DataFlow:: Node node , FlowState2 state ) { none ( ) }
112
113
113
114
predicate isAdditionalFlowStep1 (
114
- DataFlow:: Node node1 , FlowState1 state1 , DataFlow:: Node node2 , FlowState2 state2
115
+ DataFlow:: Node node1 , FlowState1 state1 , DataFlow:: Node node2 , FlowState1 state2
115
116
) {
116
117
none ( )
117
118
}
118
119
119
120
predicate isAdditionalFlowStep2 (
120
- DataFlow:: Node node1 , FlowState1 state1 , DataFlow:: Node node2 , FlowState2 state2
121
+ DataFlow:: Node node1 , FlowState2 state1 , DataFlow:: Node node2 , FlowState2 state2
121
122
) {
122
123
exists ( AddInstruction add , Operand op , int delta , int s1 , int s2 |
123
124
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
126
127
add .hasOperands ( node1 .asOperand ( ) , op ) and
127
128
semBounded ( getSemanticExpr ( op .getDef ( ) ) , any ( SemZeroBound zero ) , delta , true , _) and
128
129
node2 .asInstruction ( ) = add and
139
140
CallInstruction c , DataFlow:: Node sourceNode , Expr buffer , string element
140
141
where
141
142
StringSizeFlow:: hasFlowPath ( source1 , source2 , sink1 , sink2 ) and
142
- sinkState = sink2 .getState ( ) . toInt ( ) and
143
+ sinkState = sink2 .getState ( ) and
143
144
isSinkPairImpl ( c , sink1 .getNode ( ) , sink2 .getNode ( ) , overflow + sinkState , buffer ) and
144
145
overflow > 0 and
145
146
sourceNode = source1 .getNode ( ) and
0 commit comments