퍼지 모듈

Rust 퍼징은 LLVM의 libFuzzer 퍼징 엔진에 대한 바인딩을 제공하는 libfuzzer-sys 크레이트를 통해 지원됩니다. 자세한 내용은 libfuzzer-sys 저장소 및 LLVM libFuzzer 프로젝트 페이지 를 참조하십시오.

rust_fuzz 모듈은 실행될 때 퍼지를 시작하는 fuzzer 바이너리를 생성합니다( cc_fuzz 모듈과 유사). fuzzer는 libFuzzer 퍼징 엔진을 활용하므로 퍼징을 제어하기 위해 여러 인수를 사용할 수 있습니다. 이것들은 libFuzzer 문서 에 열거되어 있습니다.

rust_fuzz 모듈은 rust_binary 모듈의 확장이며 동일한 속성과 고려 사항을 공유합니다. 또한 cc_fuzz 모듈과 동일한 속성과 기능을 많이 구현합니다.

기본적인 Rust fuzzer 작성하기

다음 코드를 사용하여 Android.bp 빌드 파일에서 fuzz 모듈을 정의할 수 있습니다.

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 엔진에서 제공하는 바이트 시퀀스로 대상 기능을 퍼지하기 위한 입력으로 조작됩니다.

이 예제 fuzzer에서는 heap_oob 함수를 호출할지 여부를 결정하기 위해 데이터 길이만 확인되며, 호출하면 범위를 벗어난 읽기가 발생합니다. libFuzzer 는 Coverage-guided fuzzer이므로 처음 326B 데이터가 새로운 실행 경로를 생성하지 않는다고 판단하므로 문제가 있는 길이로 빠르게 수렴합니다.

트리 내 tools/security/fuzzing/example_rust_fuzzer/ 에서 이 예제를 찾습니다. 트리 내에서 다른 fuzzer( rustlib 종속성을 퍼지하는)의 약간 더 복잡한 예를 보려면 legacy_blob_fuzzer 를 참조하세요.

구조 인식 Rust fuzzers를 작성하는 방법에 대한 지침은 Rust Fuzz 프로젝트의 공식 문서인 Rust Fuzz 책 을 참조하세요.