22 * @name Use of expired stack-address
33 * @description Accessing the stack-allocated memory of a function
44 * after it has returned can lead to memory corruption.
5- * @kind problem
5+ * @kind path- problem
66 * @problem.severity error
77 * @security-severity 9.3
88 * @precision high
@@ -238,14 +238,86 @@ predicate step(
238238 )
239239}
240240
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+
241291predicate isSink ( LoadInstruction load , IRBlock block , int index , TGlobalAddress globalAddress ) {
242292 block .getInstruction ( index ) = load and
243293 globalAddress ( load .getSourceAddress ( ) ) = globalAddress
244294}
245295
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+
246317from
247318 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
249321where
250322 globalAddressPointsToStack ( store , var , call , block , address , isCallBlock , isStoreBlock ) and
251323 isSink ( load , block , loadIndex , address ) and
@@ -269,6 +341,8 @@ where
269341 loadIndex < storeIndex
270342 )
271343 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