通过 Python 为 TensorFlow 编写模糊测试

发布人:Laura Pak,TensorFlow 团队

 

模糊测试是通过生成的数据测试 API 的过程。模糊测试可确保代码在负向路径中不会中断,从而生成尽量覆盖每条代码分支的随机输入。常见选择是将模糊测试工具与排错程序配对使用,排错程序是用于检查非法情况的工具,因此会标记模糊测试工具输入所触发的错误。

由此,模糊测试可以查找:

  • 缓冲区溢出
  • 内存泄漏
  • 死锁
  • 无限递归
  • 往返一致性错误
  • 未捕获到的异常
  • 等等

最好的模糊测试方式便是持续运行模糊测试。测试运行次数越多,生成及测试的输入也越多。在本文中,您将了解如何向 TensorFlow 添加 Python 模糊测试工具。

 

技术实现方法

TensorFlow Python 模糊测试工具通过 OSS-Fuzz 运行,这是面向开源项目的持续模糊测试服务。

  • OSS-Fuzz

    https://google.github.io/oss-fuzz/

对于 Python 模糊测试工具,OSS-Fuzz 会使用 Atheris,这是一个覆盖率引导 Python 模糊测试引擎。Atheris 基于模糊测试引擎 libFuzzer,可结合动态内存错误检测器 Address Sanitizer 或快速未定义行为检测器 Undefined Behavior Sanitizer 一起使用。Atheris 依赖项将预安装在 OSS-Fuzz 基本 Docker 映像中。

  • libFuzzer

    https://llvm.org/docs/LibFuzzer.html

  • Address Sanitizer

    https://clang.llvm.org/docs/AddressSanitizer.html

  • Undefined Behavior Sanitizer

    https://clang.llvm.org/docs/UndefinedBehaviorSanitizer.html

以下是面向 TF 的 Python 模糊测试工具的一个准示例。该运行时将调用带有不同随机数据的 TestCode

import sys
import atheris_no_libfuzzer as atheris

def TestCode(data):
  DoSomethingWith(data)

def main():
  atheris.Setup(sys.argv, TestCode, enable_python_coverage=True)
  atheris.Fuzz()

在 TensorFlow 存储库的包含其他模糊测试工具的目录中,按以上方式添加自己的 Python 模糊测试工具。在 TestCode 中,选出要进行模糊测试的 TensorFlow API。在 constant_fuzz.py 中,该 API 为 tf.constant。该模糊测试工具会直接将数据传递至所选的 API,查看其是否会中断。无需添加用于捕获中断的代码,OSS-Fuzz 会检测和报告错误。

  • TensorFlow 存储库

    https://github.com/tensorflow/tensorflow

  • 目录

    https://github.com/tensorflow/tensorflow/tree/master/tensorflow/security/fuzzing

  • constant_fuzz.py

    https://clang.llvm.org/docs/UndefinedBehaviorSanitizer.html

有时,API 需要更多结构化数据,而不只是一个输入。TensorFlow 有一个名为FuzzingHelper 的 Python 类,该类支持生成随机 int 列表、随机 bool 值等。您可以在 sparseCountSparseOutput_fuzz.py 中查看其用途的示例,这是一个用于检查 API tf.raw_ops.SparseCountSparseOutput 中未捕获异常的模糊测试工具。

  • FuzzingHelper

    https://github.com/tensorflow/tensorflow/blob/master/tensorflow/security/fuzzing/python_fuzzing.py

  • sparseCountSparseOutput_fuzz.py

    https://github.com/tensorflow/tensorflow/blob/master/tensorflow/security/fuzzing/sparseCountSparseOutput_fuzz.py

要构建并运行模糊测试工具,您需要为模糊测试工具在 tf_fuzzing.bzl 中定义类型为 tf_py_fuzz_target 的模糊测试目标。以下是一个模糊目标示例,更多示例见此处。

  • tf_fuzzing.bzl

    https://github.com/tensorflow/tensorflow/blob/master/tensorflow/security/fuzzing/tf_fuzzing.bzl

  • 更多示例见此处

    https://github.com/tensorflow/tensorflow/blob/master/tensorflow/security/fuzzing/BUILD

tf_py_fuzz_target(
    name = "fuzz_target_name",
    srcs = ["your_fuzzer.py"],
    tags = ["notap"],  # Important: include to run in OSS.
)

 

使用 Docker 测试您的模糊测试工具

请确保使用 Docker 在 OSS-Fuzz 中构建您的模糊测试工具。

首先安装 Docker。在终端中,运行命令 docker image prune 以移除任何不稳定映像。

  • 安装 Docker

    https://docs.docker.com/get-docker/

从 GitHub 中克隆 oss-fuzz。针对 Python TF 模糊测试工具 tensorflow-py的项目包含一个在 Dockerfile 中定义的 build.sh 文件,该文件将在 Docker 容器中执行。Build.sh 定义了如何在 tensorflow-py 中为模糊目标构建二进制文件。具体来说,它会构建在 $SRC/tensorflow/tensorflow 中找到的所有 Python 模糊测试工具,包括您的新模糊测试工具!

  • oss-fuzz

    https://github.com/google/oss-fuzz

  • tensorflow-py

    https://github.com/google/oss-fuzz/tree/master/projects/tensorflow-py

在 oss-fuzz 中运行以下命令:

python infra/helper.py shell tensorflow
export FUZZING_LANGUAGE=python
compile

命令 compile 将运行 build.sh,以构建您的新模糊测试工具。

 

结果

模糊测试工具启动并运行后,您便可以在该信息中心中搜索您的模糊测试工具,查看模糊测试工具发现了哪些漏洞。

  • 信息中心

    https://bugs.chromium.org/p/oss-fuzz/issues/list

 

结论

模糊测试是从未知路径中测试软件的绝佳方式。不论您是想涉足安全领域,还是想更深入地了解 TensorFlow 的内部构造,我们都希望这篇博文能让您有一个良好的开端。

后续我们仍然会持续更新关于 TensorFlow 的发展进程,如果您想现在上手,将本文理论付诸实践,请点击下方链接,访问 TensorFlow 中国官网。

https://tensorflow.google.cn/?hl=zh_cn

你可能感兴趣的:(tensorflow)