2
2
* @name Use of expired stack-address
3
3
* @description Accessing the stack-allocated memory of a function
4
4
* after it has returned can lead to memory corruption.
5
- * @kind problem
5
+ * @kind path- problem
6
6
* @problem.severity error
7
7
* @security-severity 9.3
8
8
* @precision high
@@ -238,14 +238,86 @@ predicate step(
238
238
)
239
239
}
240
240
241
+ newtype TPathElement =
242
+ TStore ( StoreInstruction store ) { globalAddressPointsToStack ( store , _, _, _, _, _, _) } or
243
+ TCall ( CallInstruction call , IRBlock block ) {
244
+ globalAddressPointsToStack ( _, _, call , block , _, _, _)
245
+ } or
246
+ TMid ( IRBlock block ) { step ( _, _, _, _, _, block ) } or
247
+ TSink ( LoadInstruction load , IRBlock block ) {
248
+ exists ( TGlobalAddress address |
249
+ globalAddressPointsToStack ( _, _, _, block , address , _, _) and
250
+ block .getAnInstruction ( ) = load and
251
+ globalAddress ( load .getSourceAddress ( ) ) = address
252
+ )
253
+ }
254
+
255
+ class PathElement extends TPathElement {
256
+ StoreInstruction asStore ( ) { this = TStore ( result ) }
257
+
258
+ CallInstruction asCall ( IRBlock block ) { this = TCall ( result , block ) }
259
+
260
+ predicate isCall ( IRBlock block ) { exists ( this .asCall ( block ) ) }
261
+
262
+ IRBlock asMid ( ) { this = TMid ( result ) }
263
+
264
+ LoadInstruction asSink ( IRBlock block ) { this = TSink ( result , block ) }
265
+
266
+ predicate isSink ( IRBlock block ) { exists ( this .asSink ( block ) ) }
267
+
268
+ string toString ( ) {
269
+ result = [ asStore ( ) .toString ( ) , asCall ( _) .toString ( ) , asMid ( ) .toString ( ) , asSink ( _) .toString ( ) ]
270
+ }
271
+
272
+ predicate hasLocationInfo (
273
+ string filepath , int startline , int startcolumn , int endline , int endcolumn
274
+ ) {
275
+ this .asStore ( )
276
+ .getLocation ( )
277
+ .hasLocationInfo ( filepath , startline , startcolumn , endline , endcolumn )
278
+ or
279
+ this .asCall ( _)
280
+ .getLocation ( )
281
+ .hasLocationInfo ( filepath , startline , startcolumn , endline , endcolumn )
282
+ or
283
+ this .asMid ( ) .getLocation ( ) .hasLocationInfo ( filepath , startline , startcolumn , endline , endcolumn )
284
+ or
285
+ this .asSink ( _)
286
+ .getLocation ( )
287
+ .hasLocationInfo ( filepath , startline , startcolumn , endline , endcolumn )
288
+ }
289
+ }
290
+
241
291
predicate isSink ( LoadInstruction load , IRBlock block , int index , TGlobalAddress globalAddress ) {
242
292
block .getInstruction ( index ) = load and
243
293
globalAddress ( load .getSourceAddress ( ) ) = globalAddress
244
294
}
245
295
296
+ query predicate edges ( PathElement pred , PathElement succ ) {
297
+ // Store -> caller
298
+ globalAddressPointsToStack ( pred .asStore ( ) , _, succ .asCall ( _) , _, _, _, _)
299
+ or
300
+ // Call -> basic block
301
+ pred .isCall ( succ .asMid ( ) )
302
+ or
303
+ // Special case for when the caller goes directly to the load with no steps
304
+ // across basic blocks (i.e., caller -> sink)
305
+ exists ( IRBlock block |
306
+ pred .isCall ( block ) and
307
+ succ .isSink ( block )
308
+ )
309
+ or
310
+ // Basic block -> basic block
311
+ step ( _, _, _, _, pred .asMid ( ) , succ .asMid ( ) )
312
+ or
313
+ // Basic block -> load
314
+ succ .isSink ( pred .asMid ( ) )
315
+ }
316
+
246
317
from
247
318
StoreInstruction store , StackVariable var , LoadInstruction load , CallInstruction call ,
248
- IRBlock block , boolean isCallBlock , TGlobalAddress address , boolean isStoreBlock , int loadIndex
319
+ IRBlock block , boolean isCallBlock , TGlobalAddress address , boolean isStoreBlock ,
320
+ PathElement source , PathElement sink , int loadIndex
249
321
where
250
322
globalAddressPointsToStack ( store , var , call , block , address , isCallBlock , isStoreBlock ) and
251
323
isSink ( load , block , loadIndex , address ) and
@@ -269,6 +341,8 @@ where
269
341
loadIndex < storeIndex
270
342
)
271
343
else any ( )
272
- )
273
- select load , "Stack variable $@ escapes $@ and is used after it has expired." , var , var .toString ( ) ,
274
- store , "here"
344
+ ) and
345
+ source .asStore ( ) = store and
346
+ sink .asSink ( _) = load
347
+ select sink , source , sink , "Stack variable $@ escapes $@ and is used after it has expired." , var ,
348
+ var .toString ( ) , store , "here"
0 commit comments