栈安全分析

简介

栈安全分析确定堆栈分配的变量是否可以被认为是免受内存访问错误影响的“安全”变量。

该分析的主要目的是供 sanitizers 使用,以避免对“安全”变量进行不必要的检测。SafeStack 将成为首个用户。

“安全”变量可以定义为不能超出作用域(例如,返回后使用)或越界访问的变量。未来,它可以扩展到跟踪其他变量属性。例如,我们计划扩展实现,增加一项检查,以确保变量在每次读取之前始终被初始化,以优化未初始化内存使用检查。

工作原理

该分析分两个阶段实现

过程内或“本地”阶段在函数内部执行深度优先搜索,以收集每个 alloca 的所有用法,包括加载/存储以及用作函数参数的用法。在此阶段之后,我们知道 alloca 的哪些部分被函数本身使用,但我们不知道将其作为参数传递给另一个函数后会发生什么。

过程间或“全局”阶段解析在将 allocas 作为函数参数传递后会发生什么。此阶段对单个模块内的函数调用执行深度优先搜索,并通过函数调用传播 allocas 的用法。

当与 ThinLTO 一起使用时,全局阶段对模块摘要索引执行整个程序分析。

测试

该分析由 lit 测试覆盖。

我们预计,当变量实际上是“安全”的时,用户可以容忍将变量错误分类为“不安全”。这可能会导致代码效率低下。但是,我们不能接受错误的“安全”分类,这可能会导致 sanitizers 错过检测代码中的实际错误。为了避免这种情况,我们需要额外的验证工具。

AddressSanitizer 可能会帮助进行此验证。我们可以像往常一样检测所有变量,但另外将堆栈安全信息存储在 ASanStackVariableDescription 中。然后,如果 AddressSanitizer 在“安全”变量上检测到错误,我们可以生成一份额外的报告,让用户知道可能是堆栈安全分析失败,我们应该检查编译器中的错误。