【论文速读 | USENIX Security‘2022】Debloating Address Sanitizer

2024-06-09 13:04:58 浏览数 (2)

研究背景

  • 内存错误的重要性:内存错误是导致软件安全问题的主要原因之一,尤其是在使用 C 和 C 等低级语言开发的程序中。
  • ASan 的优势与局限ASan 能够有效检测多种内存错误,包括空间和时间错误,但同时也因其运行时开销较大而受到限制。
  • 现有解决方案的不足:以往的研究和工具在尝试减少 ASan 检查的缺点时可能会损害其检测能力、可扩展性或可用性。

研究问题

论文主要研究的问题是如何解决地址消毒器(Address Sanitizer,ASan)(翻译比较抽象,不如直接用 ASan 表示)在检测内存错误时所面临的高运行时开销问题。ASan 是一种广泛使用的内存错误检测工具,但因其开销较大,限制了其在更多场景下的应用。

研究内容/创新方法

系统性分析:对 ASan 的运行时活动、状态进行了详细的分类和测量,识别出 sanitizer 检查是导致高开销的主要原因。


sanitizer 检查即 ASan 在运行时进行的一系列内存访问检查。

"sanitizer 检查" 通常包括以下步骤:

  1. 影子内存分配:ASan 分配一块影子内存区域,用于记录应用程序使用的内存状态。
  2. 内存访问插桩:在程序的内存访问点(如加载和存储指令)插入额外的检查代码,这些代码会在运行时检查影子内存,以确定对应的内存访问是否有效。
  3. 错误检测:如果在影子内存中发现异常(例如,访问了未初始化或已释放的内存),ASan 将报告错误并可能终止程序执行。

本文提出了 ASan- 工具:它集成了多种优化措施,旨在减少 sanitizer 检查,从而降低开销。

开发了四种静态优化技术,包括:

  • 去除不满足条件的检查(Removing Unsatisfiable Checks):移除那些在任何执行路径上都不会越界的检查。
  • 去除重复的检查(Removing Recurring Checks):识别并移除那些已经被其他检查覆盖的冗余检查。
  • 合并邻近的检查(Merging Neighbor Checks):将空间上相邻的内存访问的检查合并为一个。
  • 优化循环中的检查(Optimizing Checks in Loops):将循环中不变的内存访问检查移出循环,以及合并循环中单调递增或递减的内存访问检查。

将这些优化措施集成到 LLVM 编译器中,使得 ASan- 可以与现有的编译流程无缝集成。


有必要介绍一下上述四种优化技术:

  1. 去除不满足条件的检查(Removing Unsatisfiable Checks)
    • 目的:移除那些在任何情况下都不会导致越界的检查,因为这些检查是不必要的。
    • 方法通过控制流遍历和基本常量传播,识别出可以证明是界限内的堆或全局变量访问,然后移除它们的 sanitizer 检查
    • 分析:这项技术利用了编译时的分析来确保某些访问在运行时总是安全的,从而避免了运行时的检查开销。
  2. 去除重复的检查(Removing Recurring Checks)
    • 目的:消除对同一内存位置的冗余检查,特别是当一个检查的结果可以保证后续相同位置访问的安全性时。
    • 方法使用支配分析(domination analysis)和流不敏感别名分析(flow-insensitive alias analysis)来识别并移除被其他检查所覆盖的冗余检查
    • 分析:这项技术通过分析程序的控制流图来确定哪些检查是多余的,从而减少运行时的检查次数。
  3. 合并邻近的检查(Merging Neighbor Checks)
    • 目的:对于在内存中相邻的访问,将它们的 sanitizer 检查合并为一个,以减少内存访问次数。
    • 方法识别在内存中相邻的访问,并将它们的检查合并。这包括将多个检查合并为对影子内存(shadow memory)的一个检查
    • 分析:这项技术通过减少对影子内存的访问次数来降低开销,同时保持对内存错误的检测。
  4. 优化循环中的检查(Optimizing Checks in Loops)
    • 目的:循环中的检查通常会导致开销累积,因此需要特别优化。
    • 方法:包括两种优化:
      • 不变检查的重定位(Relocating Invariant Checks):将循环中不变的内存访问检查移出循环,因为这些检查可以在循环之外执行一次
      • 单调检查的分组(Grouping Monotonic Checks):对于循环中单调递增或递减的内存访问,将连续迭代中的检查合并为一个
    • 分析:通过减少循环内部的检查次数,可以显著降低循环的开销,同时通过在循环外部进行一次性检查来保持检测能力。

评估

  1. 错误检测能力(Capability):
    • 使用 Juliet Test Suite 和 Linux Flaw Project 中的漏洞进行测试,以确保 ASan- 与 ASan 具有相同的错误检测能力。
    • 通过比较 ASan- 和 ASan 在这些测试套件上的结果,验证 ASan- 是否能够检测到相同的内存错误。
  2. 可扩展性(Scalability):
    • 在 SPEC CPU2006 和 Chromium 上构建和运行 ASan- ,以测试其在大型和复杂程序上的表现。
    • 测量编译时间和二进制大小,评估 ASan- 对编译过程和生成的可执行文件大小的影响。
  3. 可用性(Usability):
    • 通过在 Chromium 浏览器中部署 ASan- 并进行为期四周的日常工作使用,评估 ASan- 在实际应用中的表现和可用性。
    • 测量运行时开销,评估 ASan- 对用户体验的影响。
  4. 运行时开销(Runtime Overhead):
    • 在 SPEC CPU2006 和 Chromium 上比较 ASan 和 ASan- 的性能开销。
    • 分析不同优化技术对减少运行时开销的贡献。
  5. fuzzing 应用(Applications in Fuzzing):
    • 评估 ASan- 在 fuzzing(模糊测试)中的性能,特别是在与 AFL(American Fuzzy Lop)结合使用时。
    • 测量执行速度和分支覆盖率的提高,评估 ASan- 对 fuzzing 效率的影响。
  6. 与其他工具的比较:
    • 将 ASan- 与现有的其他工具(如 SANRAZOR 和 FuZZan)进行比较,以评估其性能和效率。

该分析借助了部分 AI 。

0 人点赞