分享自:

基于数据流图的生命周期感知库API模糊测试

期刊:44th International Conference on Software Engineering (ICSE '22)DOI:https://doi.org/10.1145/3510003.3510228

研究报告:GraphFuzz: Library API Fuzzing with Lifetime-Aware Dataflow Graphs

一、研究作者与论文发表信息

本文的主要作者为 Harrison Green 和 Thanassis Avgerinos,二人隶属于 ForAllSecure 公司,研究成果发表在 *44th International Conference on Software Engineering (ICSE ‘22)*,发表时间为 2022 年 5 月 21 日至 29 日。论文标题为《GraphFuzz: Library API Fuzzing with Lifetime-Aware Dataflow Graphs》。论文还附有开源工具 GraphFuzz,提供了相关代码和结果复现方法,公开于 GitHub。


二、研究背景和目的

研究背景
Fuzzing(模糊测试)作为一种动态分析技术,已成为软件漏洞发现和可靠性保障的标准。行业内,如从常见的开源库到浏览器组件测试、安全关键系统到汽车与航空航天标准的实现,模糊测试的需求逐渐增长,发现了成千上万的关键问题。近年来,众多基于覆盖率引导(coverage-guided,灰盒)的模糊测试工具例如 libFuzzer 在业界应用广泛,同时也有基于模型的模糊测试工具旨在支持高效和结构化输入生成,比如 libprotobuf-mutator 和 *Nautilus*。

研究问题
尽管模糊测试技术取得了很大进展,低级别的 C/C++ 库 API 测试依然面临挑战。传统的灰盒模糊测试工具如 libFuzzer 更适合针对单个或少量端点(endpoint)进行测试,而当需要对多个端点进行大规模测试时仍需要大量人工干预。与此同时,现有针对 API 测试的工具大多缺乏自动化或开放性,诸如 Google 内部的 Fudge 依赖于私有基础设施,其他工具如 Csmith 在编译库 API 时效率较低。

研究目标
为了填补以上空白,本文提出了一种新的模糊测试方法:基于数据流图的模糊测试(dataflow graph-based fuzzing)。研究目标是设计和实现一个名为 GraphFuzz 的工具,旨在通过建模低级别库的 API 为数据流图,达到覆盖率引导和对象生命周期感知的自动化测试。研究验证了 GraphFuzz 的有效性,通过其在实际库中发现的缺陷以及与当前技术的对比来评估性能。


三、研究的详细工作流程

总体流程
GraphFuzz 的核心由两个部分组成:
1. 用 C++ 实现的 libGraphFuzz 核心框架,用于数据流图的构建和变异。
2. Python 命令行工具 gfuzz,通过自动生成测试文件和推导 API 规范来完成辅助任务。

流程涵盖了数据流图生成与变异、API 测试用例的执行、反馈测量以及对实际目标程序的覆盖率分析。

(1)数据流图的建模与使用
数据流图是一种有向无环图(DAG),顶点(vertices)表示 API 的端点(endpoint),边(edges)表示对象依赖关系,即一个端点生成的数据对象被另一个端点消费。每个顶点都与一段上下文字节串(context byte string)相关联,用于存储短期对象的原始数据。测试流程中,GraphFuzz 动态生成数据流图并按依赖顺序执行端点,以触发缺陷。

(2)数据流图生成与变异算法
GraphFuzz 通过多种变异操作对已有数据流图进行调整,包括插入新端点(splice-in)、删除端点(splice-out)、交叉连接顶点(crosslink)、调整执行顺序(priority)等,还可以通过交叉操作(crossover)将两个图合并。每次变异生成的图需通过图完成算法验证合法性,以避免无意义或错误的输入。

(3)目标库 API 的模式归纳与测试流程
GraphFuzz 借助 YAML 配置文件,以人类可读的方式定义库 API 的模式信息(schema),其中描述了目标库的对象、函数以及方法参数。用户可通过自动提取(schema inference)功能生成初始模式,并在必要时手动修订。完成模式归纳后,gfuzz 自动生成两个变异引擎形式的测试框架:执行版本(fuzzExec)和代码生成版本(fuzzWrite)。

(4)数据驱动测试与反馈机制
执行过程中,GraphFuzz 使用 libFuzzer 提供的覆盖率引导机制进行输入选择,以实现高效的语义探索。覆盖率以代码行覆盖为衡量标准,并与其他工具进行对比分析。


四、研究的主要结果

(1)目标库分析及缺陷发现
研究通过 GraphFuzz 对五个实际开源 C/C++ 库进行模糊测试:
- Skia:在此图形库中,GraphFuzz 发现了多个安全漏洞,包括内存越界和 use-after-free 缺陷。
- RDKit:在化学信息学库中发现了 10 余个错误,包括安全相关问题,尤其是涉及 Python API 的内存操作问题。
- SQLite:在数据库库中,GraphFuzz 生成了多个多端点缺陷案例,其中涉及 SQL 配置选项与备份功能的错误交互。
- EigenIowow:发现了覆盖率测试中的断言错误及两个关键崩溃缺陷。

(2)性能比较与定量评估
在 Skia 的 10 个现有 libFuzzer 模糊测试方案基础上,研究分别构建了等效的 GraphFuzz 测试方案以对比两者性能。实验表明,GraphFuzz 平均获得 2 至 3 倍测试线覆盖率提升,尤其在大型库中生成了更多有效的 API 交互模式。

(3)实用性分析
研究表明,GraphFuzz 在 90% 的情况下可直接从函数签名推导出有效的测试模式,无需额外定义,显著降低了开发者的工作量和门槛。


五、研究结论与价值

科学价值
本研究首次提出基于数据流图的模糊测试方法,为跨多端点直接交互的复杂对象生命周期管理提供了解决方案。测试范围覆盖 API 限制性语义的角落情况,并发现了一些常规方法无法触发的隐蔽缺陷。

应用价值
GraphFuzz 降低了 C/C++ 库模糊测试的开发门槛,填补了现有灰盒模糊测试工具在支持多端点 fuzzing 时的空白。通过模型自动化生成和统一的反馈系统,GraphFuzz 减少了对人工调试和修改的依赖。


六、研究亮点

  1. 全新方法:提出了首个支持基于数据流图生成和动态调整的模糊测试方案。
  2. 覆盖率显著提升:相比传统工具,对于复杂目标,GraphFuzz 显著提升了有效覆盖率。
  3. 开源工具:GraphFuzz 提供友好的文档和易用框架,支持快速部署与大规模模糊测试。

研究的创新方法和开源实用性为未来模糊测试研究及工具开发提供了重要参考。

上述解读依据用户上传的学术文献,如有不准确或可能侵权之处请联系本站站长:admin@fmread.com