模糊测试 Arrow C++ IPC 实现
已发布 2020 年 3 月 31 日
作者 Antoine Pitrou (apitrou)
Apache Arrow 旨在允许在异构运行时和环境之间进行快速无缝的数据交换。无论是使用列式 IPC 流协议、Flight RPC 层、Feather 文件格式、Plasma 共享对象存储,还是任何特定于应用程序的数据分发机制,Arrow IPC 实现都可能尝试解码来自不受信任的输入的数据。在这种情况下,报告错误是可以接受的,但 Arrow 不应在读取此类数据时崩溃或从事有风险的行为。
为了验证 Arrow C++ IPC 读取器的健壮性(这也是 Python、C/GLib、R 和 Ruby 绑定的基础),我们已成功提交 Arrow 项目到 OSS-Fuzz,这是一个由 Google 提供的关键开源项目的持续模糊测试计划。
正在进行模糊测试的内容
在撰写本文时,RecordBatchStreamReader
和 RecordBatchFileReader
C++ 类正在通过将模糊测试器生成的数据馈送给它们来进行模糊测试。
当其中一个类成功读取记录批次时,模糊测试设置然后使用 RecordBatch::ValidateFull
验证它。此方法可以成功或失败,但不应崩溃。
通过确保从 IPC 读取记录批次然后验证它始终显示确定性行为,我们希望使其相对安全地摄取来自不受信任源的 Arrow IPC 数据。
(当然,仍然建议安全关键型应用程序使用加密方式进行身份验证和完整性控制 - 例如,使用 Flight RPC 协议启用 TLS)
我们如何帮助模糊测试器发现问题
模糊测试是一个暴力过程,它试图设计无效数据来练习实现的响应。默认情况下,模糊测试器对被测程序预期的数据表示一无所知。因此,模糊测试可能非常低效,测试大量不相关的变体,同时错过关键的变体。
为了帮助指导模糊测试过程,我们添加了一个包含各种数据类型的有效 Arrow IPC 文件的种子语料库。通过从此数据开始并对其进行变异以查找无效变体,OSS-Fuzz 能够发现数据验证方面的数十个问题。所有这些问题都已得到修复。在撰写本文时,自 2020 年 3 月 4 日以来,在 IPC 层中没有发现任何新问题。
接下来是什么
当然,我们仍然会监控 OSS-Fuzz 中可能在 C++ IPC 实现中发现的任何新问题。例如,当向 Arrow IPC 格式添加功能时,可能会出现此类问题。
我们已经开始模糊测试 Parquet C++ 实现。已经发现并修复了几个问题,但还有更多问题即将出现。我们希望在未来一两个月内稳定局势。
tensor 和稀疏 tensor IPC 读取路径尚未被执行。一旦有积极的核心开发人员想要拥有该主题,它们将被执行。