模糊测试 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++ 实现。已经发现并修复了几个问题,但更多问题仍在出现。我们希望在未来一两个月内稳定这种情况。
张量和稀疏张量 IPC 读取路径尚未得到测试。一旦有积极的核心开发人员愿意负责此主题,它们就会得到测试。