Blender试用

centipede是谷歌的新的分布式模式测试工具,不过现在合并到了https://github.com/google/fuzztest,

没合并之前,有个人搞了个Blender,据说是Automatic whole-program fuzzing,就是不需要编写模糊目标函数,而是直接接受要测试的二进制文件(最好是使用了内存检测和覆盖率的编译结果,但不需要修改源代码)。

https://github.com/dvyukov/centipede/tree/dvyukov-blender/blender

根据README的描述,此工具是拦截系统调用,忽略程序的所有输出(写入磁盘/网络的数据),并向输入提供随机数据(从磁盘/网络读取的数据)。

此外,运行一个随机的未知二进制文件是不安全的(它可能会格式化磁盘、删除文件等)。系统调用拦截的第二个重要作用是隔离。在 Blender 下,二进制文件完全被隔离,并且不会对真实世界产生任何影响。这使得可以安全地运行带有随机输入的随机二进制文件。

使用

Blender 有2种使用模式:
1、独立使用:在这种模式下,二进制文件以随机方式执行一次。
2、结合Centipede使用,Centipede 其实类似于libfuzzer,二进制文件将使用Centipede进行循环测试。

独立使用

构建Blender

1
bazel build -c opt blender:all

以bash为例

1
2
3
4
git clone https://git.savannah.gnu.org/git/bash.git
cd bash
CC=clang CFLAGS="-fsanitize=address,undefined -g" ./configure --with-bash-malloc=no
make -j

运行二进制文件并使用 Blender 进行模糊测试(在运行时进行模糊测试)

1
LD_PRELOAD=/XXX/XXX/bazel-bin/blender/blender.so ./bash

但是会报错:

1
blender.cc:238: FAIL: close_range (errno: Function not implemented)

后来发现close_range() 是一个 Linux 特定的系统调用,它在内核版本 5.9 中被引入。而ubuntu 20.04的默认内核是5.4,所以使用下面命令升级内核

1
2
3
apt update
apt install linux-image-5.15.0-76-generic linux-headers-5.15.0-76-generic
reboot

上面使用了LD_PRELOAD,如果你可以将一个额外的库链接到二进制文件中,那么你可以链接 bazel-bin/blender/libblender.pic.lo 代替。

如果没有检测到错误,它将不会打印任何内容并以0状态退出(没有正常输出和状态)。如果检测到错误,将打印错误报告并以非0状态退出。

作者说可以与压力工具一起用作一种简易的模糊测试工具

1
2
go get golang.org/x/tools/cmd/stress
LD_PRELOAD=bazel-bin/blender/blender.so stress ./bash

结合Centipede使用

build Centipede 和 Blender

1
bazel build -c opt :all blender:all

使用一些额外的标志构建目标二进制文件

1
2
3
4
5
CC=clang CFLAGS="-fsanitize=address,undefined -g -fno-builtin -fsanitize-coverage=trace-pc-guard,pc-table,trace-cmp" \
LDFLAGS="-lstdc++ -Wl,--whole-archive /XXX/centipede/bazel-bin/blender/libblender.pic.lo -Wl,--no-whole-archive \
/XXX/centipede/bazel-bin/blender/liblib.a /XXX/centipede/bazel-bin/libcentipede_runner_no_main.a" \
./configure --with-bash-malloc=no
BLENDER_DISABLE=1 make -j10

使用Centipede运行

1
2
mkdir /tmp/workdir
bazel-bin/centipede --workdir /tmp/workdir --batch_size=10 --max_len=65536 --timeout=60 --timeout_per_batch=600 --shmem_size_mb=4096 --binary ./bash
打赏专区