模糊测试 Arrow C++#

为了使处理无效输入更加健壮,我们在 Arrow C++ 功能集的几个部分启用了模糊测试,目前包括

  • IPC 流格式

  • IPC 文件格式

  • Parquet 文件格式

我们欢迎任何贡献,以扩展模糊测试的范围,并涵盖摄取潜在无效或恶意数据的区域。

模糊测试目标和实用程序#

通过传递 -DARROW_FUZZING=ON CMake 选项(或等效地使用 fuzzing 预设),您将构建与上述 Arrow 功能相对应的模糊测试目标,以及其他相关的实用程序。

生成种子语料库#

模糊测试本质上是通过随机变异先前测试过的输入来探索域空间,而无需对被模糊测试的区域有任何高层理解。然而,域空间非常巨大,以至于仅凭这种策略可能无法实际产生任何“有趣的”输入。

因此,为了指导该过程,提供一个有效的(或无效但值得注意的)种子语料库非常重要,模糊测试基础设施可以从中派生新的输入以进行测试。 提供了一个脚本来自动化该任务。 假设可以在 build/debug 中找到模糊测试可执行文件,则可以按以下方式生成种子语料库

$ ./build-support/fuzzing/generate_corpuses.sh build/debug

持续模糊测试基础设施#

模糊测试过程计算量大,因此受益于专用计算设施。 Arrow C++ 由 Google 运营的 OSS-Fuzz 持续模糊测试基础设施进行测试。

OSS-Fuzz 发现的问题会通知并提供给有限的 核心开发人员集合。 如果您是 Arrow 核心开发人员并希望添加到该列表中,您可以在 邮件列表 中提出请求。

本地重现#

当模糊测试发现崩溃时,通常需要下载用于产生崩溃的数据,并使用它来重现崩溃,以便进行调试和调查。

假设您位于 cpp 内的子目录中,则以下命令允许您构建启用了调试信息和各种 Sanitizer 检查的模糊测试目标。

$ cmake .. --preset=fuzzing

然后,假设您已下载了崩溃的数据文件(我们将其称为 testcase-arrow-ipc-file-fuzz-123465),您可以通过在该文件上运行受影响的模糊测试目标来重现崩溃

$ build/debug/arrow-ipc-file-fuzz testcase-arrow-ipc-file-fuzz-123465

(您可能希望在调试器下运行该命令,以便更仔细地检查程序状态)

使用 conda#

模糊测试可执行文件必须使用 clang 编译,并链接到提供模糊测试运行时的库。 如果您使用 conda 来提供您的依赖项,您可能需要在构建模糊测试目标之前安装这些

$ conda install clang clangxx compiler-rt
$ cmake .. --preset=fuzzing