栈安全分析

简介

栈安全分析确定栈分配的变量是否可以被认为在内存访问错误方面是“安全的”。

该分析的主要目的是供消毒器使用,以避免对“安全”变量进行不必要的插桩。SafeStack 将是第一个用户。

“安全”变量可以定义为无法在作用域外使用(例如,返回后使用)或超出边界访问的变量。将来可以扩展它以跟踪其他变量属性。例如,我们计划扩展实现,通过检查确保变量在每次读取之前都已初始化,以优化未初始化内存使用检查。

工作原理

该分析分两个阶段实现

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

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

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

测试

该分析包含 lit 测试。

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

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