@@ -78,28 +78,39 @@ predicate isInvalidPointerDerefSink2(DataFlow::Node sink, Instruction i, string
78
78
)
79
79
}
80
80
81
+ predicate arrayTypeCand ( ArrayType arrayType ) { any ( Variable v ) .getUnspecifiedType ( ) = arrayType }
82
+
81
83
pragma [ nomagic]
82
84
predicate arrayTypeHasSizes ( ArrayType arr , int baseTypeSize , int arraySize ) {
85
+ arrayTypeCand ( arr ) and
83
86
arr .getBaseType ( ) .getSize ( ) = baseTypeSize and
84
87
arr .getArraySize ( ) = arraySize
85
88
}
86
89
87
- predicate pointerArithOverflow0 (
88
- PointerArithmeticInstruction pai , Variable v , int size , int bound , int delta
89
- ) {
90
- not v .getNamespace ( ) instanceof StdNamespace and
91
- arrayTypeHasSizes ( v .getUnspecifiedType ( ) , pai .getElementSize ( ) , size ) and
92
- semBounded ( getSemanticExpr ( pai .getRight ( ) ) , any ( SemZeroBound b ) , bound , true , _) and
90
+ bindingset [ pai]
91
+ pragma [ inline_late]
92
+ predicate constantUpperBounded ( PointerArithmeticInstruction pai , int delta ) {
93
+ semBounded ( getSemanticExpr ( pai .getRight ( ) ) , any ( SemZeroBound b ) , delta , true , _)
94
+ }
95
+
96
+ bindingset [ pai, size]
97
+ predicate pointerArithOverflow0Impl ( PointerArithmeticInstruction pai , int size , int bound , int delta ) {
98
+ constantUpperBounded ( pai , bound ) and
93
99
delta = bound - size and
94
100
delta >= 0 and
95
101
size != 0 and
96
102
size != 1
97
103
}
98
104
105
+ predicate pointerArithOverflow0 ( PointerArithmeticInstruction pai , int delta ) {
106
+ exists ( int size , int bound |
107
+ arrayTypeHasSizes ( _, pai .getElementSize ( ) , size ) and
108
+ pointerArithOverflow0Impl ( pai , size , bound , delta )
109
+ )
110
+ }
111
+
99
112
module PointerArithmeticToDerefConfig implements DataFlow:: ConfigSig {
100
- predicate isSource ( DataFlow:: Node source ) {
101
- pointerArithOverflow0 ( source .asInstruction ( ) , _, _, _, _)
102
- }
113
+ predicate isSource ( DataFlow:: Node source ) { pointerArithOverflow0 ( source .asInstruction ( ) , _) }
103
114
104
115
predicate isBarrierIn ( DataFlow:: Node node ) { isSource ( node ) }
105
116
@@ -110,30 +121,38 @@ module PointerArithmeticToDerefConfig implements DataFlow::ConfigSig {
110
121
111
122
module PointerArithmeticToDerefFlow = DataFlow:: Global< PointerArithmeticToDerefConfig > ;
112
123
113
- predicate pointerArithOverflow (
114
- PointerArithmeticInstruction pai , Variable v , int size , int bound , int delta
115
- ) {
116
- pointerArithOverflow0 ( pai , v , size , bound , delta ) and
124
+ predicate pointerArithOverflow ( PointerArithmeticInstruction pai , int delta ) {
125
+ pointerArithOverflow0 ( pai , delta ) and
117
126
PointerArithmeticToDerefFlow:: flow ( DataFlow:: instructionNode ( pai ) , _)
118
127
}
119
128
129
+ bindingset [ v]
130
+ predicate finalPointerArithOverflow ( Variable v , PointerArithmeticInstruction pai , int delta ) {
131
+ exists ( int size |
132
+ arrayTypeHasSizes ( pragma [ only_bind_out ] ( v .getUnspecifiedType ( ) ) , pai .getElementSize ( ) , size ) and
133
+ pointerArithOverflow0Impl ( pai , size , _, delta )
134
+ )
135
+ }
136
+
137
+ predicate isSourceImpl ( DataFlow:: Node source , Variable v ) {
138
+ (
139
+ source .asInstruction ( ) .( FieldAddressInstruction ) .getField ( ) = v
140
+ or
141
+ source .asInstruction ( ) .( VariableAddressInstruction ) .getAstVariable ( ) = v
142
+ ) and
143
+ exists ( v .getUnspecifiedType ( ) .( ArrayType ) .getArraySize ( ) )
144
+ }
145
+
120
146
module ArrayAddressToDerefConfig implements DataFlow:: StateConfigSig {
121
147
newtype FlowState =
122
- additional TArray ( Variable v ) { pointerArithOverflow ( _ , v , _ , _ , _ ) } or
148
+ additional TArray ( ) or
123
149
additional TOverflowArithmetic ( PointerArithmeticInstruction pai ) {
124
- pointerArithOverflow ( pai , _, _ , _ , _ )
150
+ pointerArithOverflow ( pai , _)
125
151
}
126
152
127
153
predicate isSource ( DataFlow:: Node source , FlowState state ) {
128
- exists ( Variable v |
129
- (
130
- source .asInstruction ( ) .( FieldAddressInstruction ) .getField ( ) = v
131
- or
132
- source .asInstruction ( ) .( VariableAddressInstruction ) .getAstVariable ( ) = v
133
- ) and
134
- exists ( v .getUnspecifiedType ( ) .( ArrayType ) .getArraySize ( ) ) and
135
- state = TArray ( v )
136
- )
154
+ isSourceImpl ( source , _) and
155
+ state = TArray ( )
137
156
}
138
157
139
158
predicate isSink ( DataFlow:: Node sink , FlowState state ) {
@@ -152,12 +171,12 @@ module ArrayAddressToDerefConfig implements DataFlow::StateConfigSig {
152
171
predicate isAdditionalFlowStep (
153
172
DataFlow:: Node node1 , FlowState state1 , DataFlow:: Node node2 , FlowState state2
154
173
) {
155
- exists ( PointerArithmeticInstruction pai , Variable v |
156
- state1 = TArray ( v ) and
174
+ exists ( PointerArithmeticInstruction pai |
175
+ state1 = TArray ( ) and
157
176
state2 = TOverflowArithmetic ( pai ) and
158
177
pai .getLeft ( ) = node1 .asInstruction ( ) and
159
178
node2 .asInstruction ( ) = pai and
160
- pointerArithOverflow ( pai , v , _ , _ , _)
179
+ pointerArithOverflow ( pai , _)
161
180
)
162
181
}
163
182
}
@@ -168,11 +187,11 @@ from
168
187
Variable v , ArrayAddressToDerefFlow:: PathNode source , PointerArithmeticInstruction pai ,
169
188
ArrayAddressToDerefFlow:: PathNode sink , Instruction deref , string operation , int delta
170
189
where
171
- ArrayAddressToDerefFlow:: flowPath ( source , sink ) and
190
+ ArrayAddressToDerefFlow:: flowPath ( pragma [ only_bind_into ] ( source ) , pragma [ only_bind_into ] ( sink ) ) and
172
191
isInvalidPointerDerefSink2 ( sink .getNode ( ) , deref , operation ) and
173
- source .getState ( ) = ArrayAddressToDerefConfig:: TArray ( v ) and
174
- sink . getState ( ) = ArrayAddressToDerefConfig :: TOverflowArithmetic ( pai ) and
175
- pointerArithOverflow ( pai , v , _ , _ , delta )
192
+ pragma [ only_bind_out ] ( sink .getState ( ) ) = ArrayAddressToDerefConfig:: TOverflowArithmetic ( pai ) and
193
+ isSourceImpl ( source . getNode ( ) , v ) and
194
+ finalPointerArithOverflow ( v , pai , delta )
176
195
select pai , source , sink ,
177
196
"This pointer arithmetic may have an off-by-" + ( delta + 1 ) +
178
197
" error allowing it to overrun $@ at this $@." , v , v .getName ( ) , deref , operation
0 commit comments