0.2.7 |
|
---|---|
0.2.6 |
|
0.2.2 |
|
0.1.7 |
|
0.1.1 |
|
#16 in #corpus
在 aptos-fuzz 中使用
4MB
80K SLoC
Aptos 的模糊测试支持
此crate包含对Aptos目标的模糊测试支持。该支持包括
- 使用
proptest
生成语料库 - 使用
cargo test
自动运行失败的示例
先决条件
如果尚未安装,请安装 cargo-fuzz
: cargo install cargo-fuzz
。
模糊测试一个目标
首先,切换到本README所在的目录: cd testsuite/aptos-fuzzer
。
要列出已知的模糊测试目标,运行 cargo run --bin aptos-fuzzer list
。
为了有效进行模糊测试,需要一个现有的输入语料库。此crate包含使用 proptest
生成语料库的支持。使用 cargo run --bin aptos-fuzzer generate <target>
生成语料库。
一旦生成了语料库,模糊测试器就准备就绪,只需运行
RUSTC_BOOTSTRAP=1 cargo run --bin aptos-fuzzer --release fuzz <target>
要获取更多选项,请运行cargo run --bin aptos-fuzzer -- --help
。请注意,作为cargo fuzz
使用不稳定编译器标志的必要条件,必须设置RUSTC_BOOTSTRAP=1
。
添加新的目标
模糊测试目标存放在src/fuzz_targets/
中。添加新目标需要创建一个新的类型并为它实现FuzzTargetImpl
。
有关示例,请参阅src/fuzz_targets/
中现有的实现。
请记得将您的目标添加到src/fuzz_targets.rs
中的ALL_TARGETS
。完成此操作后,运行cargo run --bin aptos-fuzzer list
应列出您的新目标。
调试和测试工件
如果模糊测试器找到失败的工件,它将工件保存到fuzz
目录中的文件中,并打印其路径。要将此工件添加到测试套件中,将其复制到artifacts/<target>/
目录中的一个文件中。
现在,cargo test
将测试反序列化程序与新的工件。测试可能会在第一次使用时失败。
请注意,默认情况下,cargo test
将在单独的进程中运行每个测试以隔离失败和内存使用;如果您正在附加调试器并运行单个测试,请设置NO_FORK=1
以禁用分叉。
一旦反序列化程序已修复,请将工件检入artifacts/<target>/
目录。然后该工件将作为cargo test
运行时的回归测试。
有两种方法可以重现问题以进行调查
- 直接运行 Harness 测试(模糊测试器运行的代码)
- 运行模糊测试代码
以下命令(其中包含您的工件,位于类似路径)将使用您的输入运行 Harness 测试
cargo run --bin investigate -- -i artifacts/compiled_module/crash-5d7f403f
以下命令将在相关目标上运行 libfuzzer,使用您的输入
# build single fuzzer for target using instruction in the 'google oss-fuzz integration' section
./fuzzer input
请注意,对于崩溃,这应该可以正常工作,但对于超时可能需要 libfuzzer 的-timeout 25
参数,对于内存不足可能需要 libfuzzer 的-rss_limit_mb=2560
参数。
火焰图
要获取 Harness 测试的火焰图,请运行以下命令
FUZZ_TARGET=compiled_module cargo flamegraph -p aptos-fuzzer --bin flamegraph
最好先生成一些语料库并在上面运行模糊测试器一段时间(以找到新的语料库)。语料库越大,您获得的火焰图就越好。
模糊测试覆盖率
要测试模糊测试器的覆盖率,您可以使用grcov运行以下命令
RUSTFLAGS='--cfg feature="fuzzing"' CORPUS_PATH=fuzz/corpus cargo xtest --html-cov-dir <some path for html output> -p aptos-fuzzer -- --test-threads 1 --ignored coverage
构建单个模糊测试器
要将我们的模糊器集成到Google OSS-Fuzz项目中,我们需要为每个模糊器提供一个二进制文件。当您想使用Instruments等工具分析模糊器时,这也会很有用。为此,build.rs可以根据环境变量创建一个模糊器二进制文件。使用方法如下:
cd aptos-core/testsuite/aptos-fuzzer
fuzz/google-oss-fuzz/build_fuzzer.sh ConsensusProposal .
./ConsensusProposal
故障排除
我的堆栈跟踪不包含文件名和行号
您需要使用llvm-symbolizer
,请参阅https://github.com/rust-fuzz/cargo-fuzz/issues/160
macOS: 使用cc
链接失败
请确保Xcode已更新到最新版本。记住在重新构建之前,实际上使用xcode-select
更新新应用程序文件夹,并执行cargo clean
。
sudo xcode-select -s /Applications/Xcode_X.Y.Z.app
如果您遇到链接器错误,如
$ RUSTC_BOOTSTRAP=1 cargo run --bin aptos-fuzzer --release fuzz <target>
# ...
error: linking with `cc` failed: exit code: 1
|
= note: "cc" "-m64" "-L" "/Users/philiphayes/.rustup/toolchains/nightly-x86_64-apple-darwin/lib/rustlib/x86_64-apple-darwin/lib" # ...
= note: Undefined symbols for architecture x86_64:
"_CFMutableAttributedStringGetTypeID", referenced from:
_$LT$core_foundation..attributed_string..CFMutableAttributedString$u20$as$u20$core_foundation..base..TCFType$GT$::type_id::h9f6f71bdd347aca0 # ...
ld: symbol(s) not found for architecture x86_64
clang: error: linker command failed with exit code 1 (use -v to see invocation)
error: aborting due to previous error
这可能是由于core-foundation-rs(https://github.com/servo/core-foundation-rs/pull/357)中的问题造成的,该问题已在最新版本中修复,但我们的一个间接依赖项native-tls
仅在它的master
分支中更新。要修复此问题,请将以下内容添加到aptos-core/Cargo.toml
的末尾
[patch.crates-io]
native-tls = { git = "https://github.com/sfackler/rust-native-tls" }
依赖项
~117MB
~2.5M SLoC