研究背景
- 内存错误的重要性:内存错误是导致软件安全问题的主要原因之一,尤其是在使用 C 和 C 等低级语言开发的程序中。
- ASan 的优势与局限:ASan 能够有效检测多种内存错误,包括空间和时间错误,但同时也因其运行时开销较大而受到限制。
- 现有解决方案的不足:以往的研究和工具在尝试减少 ASan 检查的缺点时可能会损害其检测能力、可扩展性或可用性。
研究问题
论文主要研究的问题是如何解决地址消毒器(Address Sanitizer,ASan)(翻译比较抽象,不如直接用 ASan 表示)在检测内存错误时所面临的高运行时开销问题。ASan 是一种广泛使用的内存错误检测工具,但因其开销较大,限制了其在更多场景下的应用。
研究内容/创新方法
系统性分析:对 ASan 的运行时活动、状态进行了详细的分类和测量,识别出 sanitizer 检查是导致高开销的主要原因。
sanitizer 检查即 ASan 在运行时进行的一系列内存访问检查。
"sanitizer 检查" 通常包括以下步骤:
- 影子内存分配:ASan 分配一块影子内存区域,用于记录应用程序使用的内存状态。
- 内存访问插桩:在程序的内存访问点(如加载和存储指令)插入额外的检查代码,这些代码会在运行时检查影子内存,以确定对应的内存访问是否有效。
- 错误检测:如果在影子内存中发现异常(例如,访问了未初始化或已释放的内存),ASan 将报告错误并可能终止程序执行。
本文提出了 ASan- 工具:它集成了多种优化措施,旨在减少 sanitizer 检查,从而降低开销。
开发了四种静态优化技术,包括:
- 去除不满足条件的检查(Removing Unsatisfiable Checks):移除那些在任何执行路径上都不会越界的检查。
- 去除重复的检查(Removing Recurring Checks):识别并移除那些已经被其他检查覆盖的冗余检查。
- 合并邻近的检查(Merging Neighbor Checks):将空间上相邻的内存访问的检查合并为一个。
- 优化循环中的检查(Optimizing Checks in Loops):将循环中不变的内存访问检查移出循环,以及合并循环中单调递增或递减的内存访问检查。
将这些优化措施集成到 LLVM 编译器中,使得 ASan- 可以与现有的编译流程无缝集成。
有必要介绍一下上述四种优化技术:
- 去除不满足条件的检查(Removing Unsatisfiable Checks)
- 目的:移除那些在任何情况下都不会导致越界的检查,因为这些检查是不必要的。
- 方法:通过控制流遍历和基本常量传播,识别出可以证明是界限内的堆或全局变量访问,然后移除它们的 sanitizer 检查。
- 分析:这项技术利用了编译时的分析来确保某些访问在运行时总是安全的,从而避免了运行时的检查开销。
- 去除重复的检查(Removing Recurring Checks)
- 目的:消除对同一内存位置的冗余检查,特别是当一个检查的结果可以保证后续相同位置访问的安全性时。
- 方法:使用支配分析(domination analysis)和流不敏感别名分析(flow-insensitive alias analysis)来识别并移除被其他检查所覆盖的冗余检查。
- 分析:这项技术通过分析程序的控制流图来确定哪些检查是多余的,从而减少运行时的检查次数。
- 合并邻近的检查(Merging Neighbor Checks)
- 目的:对于在内存中相邻的访问,将它们的 sanitizer 检查合并为一个,以减少内存访问次数。
- 方法:识别在内存中相邻的访问,并将它们的检查合并。这包括将多个检查合并为对影子内存(shadow memory)的一个检查。
- 分析:这项技术通过减少对影子内存的访问次数来降低开销,同时保持对内存错误的检测。
- 优化循环中的检查(Optimizing Checks in Loops)
- 目的:循环中的检查通常会导致开销累积,因此需要特别优化。
- 方法:包括两种优化:
- 不变检查的重定位(Relocating Invariant Checks):将循环中不变的内存访问检查移出循环,因为这些检查可以在循环之外执行一次。
- 单调检查的分组(Grouping Monotonic Checks):对于循环中单调递增或递减的内存访问,将连续迭代中的检查合并为一个。
- 分析:通过减少循环内部的检查次数,可以显著降低循环的开销,同时通过在循环外部进行一次性检查来保持检测能力。
评估
- 错误检测能力(Capability):
- 使用 Juliet Test Suite 和 Linux Flaw Project 中的漏洞进行测试,以确保 ASan- 与 ASan 具有相同的错误检测能力。
- 通过比较 ASan- 和 ASan 在这些测试套件上的结果,验证 ASan- 是否能够检测到相同的内存错误。
- 可扩展性(Scalability):
- 在 SPEC CPU2006 和 Chromium 上构建和运行 ASan- ,以测试其在大型和复杂程序上的表现。
- 测量编译时间和二进制大小,评估 ASan- 对编译过程和生成的可执行文件大小的影响。
- 可用性(Usability):
- 通过在 Chromium 浏览器中部署 ASan- 并进行为期四周的日常工作使用,评估 ASan- 在实际应用中的表现和可用性。
- 测量运行时开销,评估 ASan- 对用户体验的影响。
- 运行时开销(Runtime Overhead):
- 在 SPEC CPU2006 和 Chromium 上比较 ASan 和 ASan- 的性能开销。
- 分析不同优化技术对减少运行时开销的贡献。
- fuzzing 应用(Applications in Fuzzing):
- 评估 ASan- 在 fuzzing(模糊测试)中的性能,特别是在与 AFL(American Fuzzy Lop)结合使用时。
- 测量执行速度和分支覆盖率的提高,评估 ASan- 对 fuzzing 效率的影响。
- 与其他工具的比较:
- 将 ASan- 与现有的其他工具(如 SANRAZOR 和 FuZZan)进行比较,以评估其性能和效率。
该分析借助了部分 AI 。