模糊模块

通过libfuzzer-sys crate 支持 Rust 模糊测试,它提供与 LLVM 的 libFuzzer 模糊测试引擎的绑定。有关更多信息,请参阅libfuzzer-sys存储库以及LLVM libFuzzer 项目页面

rust_fuzz模块生成一个模糊器二进制文件,它在运行时开始模糊测试(类似于cc_fuzz模块)。由于 fuzzer 利用libFuzzer引擎,它可以使用许多参数来控制 fuzzing。这些都在libFuzzer 文档中列出。

rust_fuzz模块是rust_binary模块的扩展,因此具有相同的属性和注意事项。此外,它们实现了许多与cc_fuzz模块相同的属性和功能。

编写一个基本的 Rust fuzzer

您可以使用以下代码在Android.bp构建文件中定义模糊模块:

rust_fuzz {
    name: "example_rust_fuzzer",
    srcs: ["fuzzer.rs"],

    // Config for running the target on fuzzing infrastructure can be set under
    // fuzz_config. This shares the same properties as cc_fuzz's fuzz_config.
    fuzz_config: {
        fuzz_on_haiku_device: true,
        fuzz_on_haiku_host: false,
    },

    // Path to a corpus of sample inputs, optional. See https://llvm.org/docs/LibFuzzer.html#corpus
    corpus: ["testdata/*"],

    // Path to a dictionary of sample byte sequences, optional. See https://llvm.org/docs/LibFuzzer.html#dictionaries
    dictionary: "example_rust_fuzzer.dict",
}

fuzzer.rs文件包含一个简单的 fuzzer:

fn heap_oob() {
    let xs = vec![0, 1, 2, 3];
    let val = unsafe { *xs.as_ptr().offset(4) };
    println!("Out-of-bounds heap value: {}", val);
}

fuzz_target!(|data: &[u8]| {
    let magic_number = 327;
    if data.len() == magic_number {
        heap_oob();
    }
});

Here fuzz_target!(|data: &[u8]| { /* fuzz using data here */ });定义libFuzzer引擎调用的 fuzz-target 入口点。 data参数是libFuzzer引擎提供的字节序列,可作为输入来对目标函数进行模糊测试。

在此示例模糊器中,仅检查数据的长度以确定是否调用heap_oob函数,调用该函数会导致越界读取。 libFuzzer是一个覆盖引导的模糊器,因此它可以快速收敛到有问题的长度,因为它确定前 326 B 的数据不会导致新的执行路径。

tools/security/fuzzing/example_rust_fuzzer/找到这个示例,在树中。要查看树中另一个模糊器( rustlib依赖项)的稍微复杂的示例,请参阅legacy_blob_fuzzer

有关如何编写结构感知 Rust fuzzer 的指导,请参阅Rust Fuzz 书,这是 Rust Fuzz 项目的官方文档。