打造爵士樂

本指南假設您已建立目前要建構的模糊處理工具。該段落使用與指南中相同的程式碼範例

Fuchsia 使用中繼建構系統 GN 產生 .ninja 檔案,明確說明如何建構系統。GN 目標是建構圖中的節點,代表特定輸出內容 (例如程式庫或執行檔)。GN 範本是會產生額外目標的規則。

為了盡可能輕鬆新增模糊漏洞,Fussia 提供經過模糊化處理的 GN 範本。

定義建構規則後,您就可以使用 fx 建構模糊化工具

Fuchsia 程式庫模糊 GN 範本

每種語言都有特定的模糊 GN 範本:

C/C++

fuchsia_library_fuzzer GN 範本會產生 executable 目標,該目標會編譯模糊目標函式,並連結至測試中的程式碼和模糊引擎。

如要為 C 或 C++ 模糊工具建立建構規則,請將 fuchsia_library_fuzzer GN 目標新增至適當的 BUILD.gn (例如具有對應單元測試規則的目標)。

例如:

import("//build/fuzz.gni")

fuchsia_library_fuzzer("parser-fuzzer") {
  sources = [ "parser_fuzzer.cc" ]
  deps = [ ":parser-lib" ]
}

Rust

rustc_fuzzer GN 範本會產生 GN 目標,用於將 Rust 模糊目標函式編譯成 C 物件檔案,再與模糊化引擎建立連結。

如要為 Rust 模糊工具建立建構規則,請將 rustc_fuzzer GN 目標新增至 Crate 的 BUILD.gn。

選擇新增目標的位置和方式時,請考量下列事項:

  • 建議您將模糊目標名稱與模糊目標函式名稱相符,並在 Rust 程式庫中加入模糊目標函式,例如在 src/lib.rs 中。按照這些建議操作時,您可以將範本內文留空。舉例來說,您可以使用 toy_example_arbitrary 範例,將以下內容新增至 BUILD.gn
import("//build/rust/rustc_fuzzer.gni")

rustc_fuzzer("toy_example_arbitrary") {
}
  • 如果模糊目標函式名稱與模糊工具名稱不同,您必須提供 rustfunction 參數。舉例來說,您可以使用 toy_example_u8 範例,將以下內容新增至 BUILD.gn
import("//build/rust/rustc_fuzzer.gni")

rustc_fuzzer("toy_example_raw_bytes") {
    rustfunction = "toy_example_u8"
}
  • 如果要測試的程式碼無法輕易歸入程式庫,您可以搭配兩個額外步驟來使用 Rust 二進位檔:

  • 您必須將 main 函式從編譯作業中排除,以及模糊時未使用的任何項目,例如僅在 main 中使用的匯入項目。例如:

    #[cfg(not(fuzz))]
    use only::used::in::main;
    
    #[cfg(not(fuzz))]
    fn main() { ... }
    
  • 您必須使用 source_root 參數向 rustc_fuzzer 明確提供模糊目標函式。例如,在您的 BUILD.gn 中:

    import("//build/rust/rustc_fuzzer.gni")
    
    rustc_fuzzer("toy_example_with_main") {
        source_root = "src/main.rs"
    }
    

當您選取模糊化變數時,這些範本會使用所提供的 sources 和/或 deps 連結 [libFuzzer] 編譯器執行階段,藉此建立模糊測試二進位檔。此程式碼必須提供模糊目標函式。

否則,系統會使用提供的程式碼連結「測試控管工具」,進行模糊測試單元測試。這項測試控管工具會使用固定輸入內容 (例如長度為零) 呼叫模糊目標函式。即使未建構用於模糊測試,這項測試也可以確保模糊測試可以編譯及連結。

主機程式庫模糊化 GN 範本

您也可以使用 Fuchsia 建構系統,在開發主機上執行模糊軟體。如要建構主機模糊效果,請使用 host_library_fuzzer GN 範本。

例如:

host_library_fuzzer("my_host_fuzzer") {
  sources = [ ... ]
  deps = [ ... ]
}

可以使用 fx 建構主機模糊化工具,而無需將其新增至 Fuchsia 元件或套件。

Fuchsia 模糊元件 GN 範本

fuchsia_fuzzer_component 範本會建立一個用來執行模糊測試的元件。可包含一般元件參數,例如 component_namedeps

例如:

fuchsia_fuzzer_component("my-fuzzer-component") {
  component_name = "my-fuzzer"
  manifest = "meta/my-fuzzer.cml"
  deps = [ ":my-corpus"]
}

模糊的輸出名稱必須提供做為第一個程式引數,做為套件相關路徑。其他引數可能包含 libFuzzer 選項,或稱為「種子語料」的種子輸入目錄的套件相關路徑。

例如:

{
    include: [
        "//sdk/lib/inspect/client.shard.cml",
        "//src/sys/fuzzing/libfuzzer/default.shard.cml",
        "//src/sys/test_runners/fuzz/default.shard.cml",
        "//src/sys/test_runners/tmp_storage.shard.cml",
        "syslog/client.shard.cml",
    ]
    program: {
        args: [
            "test/my-fuzzer",
            "-max_input_size=256",
            "data/my-corpus",
        ]
    }
}

種子語料庫應與元件 deps 中的 resource 目標相符。

例如:


import("//build/dist/resource.gni")

resource("my-corpus") {
  sources = [
    "input0",
    "input1",
    "input2",
  ]
  outputs = [ "data/my-corpus/{{source_file_part}}" ]
}

Fuchsia 模糊套件 GN 範本

fuchsia_fuzzer_packagefuchsia_test_packagefuchsia_fuzzer_package 範本的區別方式是新增特定建構規則,在透過模糊工具鍊 變化版本建構項目時為模糊處理工具加上註解。

範本中包含參數,即依語言整理的模糊元件清單。每種語言都有一組支援的清理器,由其工具鍊提供做為編譯器執行階段。如果所選工具鍊變化版本包含支援指定語言的消毒液,則對應的模糊工具元件清單能夠進行模糊檢查。

舉例來說,如果 C++ 工具鍊支援假想 examplesan,則 Rust 工具鍊並未選取且選取了 examplesan-fuzzer 變數,則下列套件定義會建構 my-cpp-fuzzer 進行模糊測試,my-rust-fuzzer 則僅供測試使用。

fuchsia_fuzzer_package("my-fuzzers") {
  cpp_fuzz_components = [ ":my-cpp-fuzzer" ]
  rust_fuzz_components = [ ":my-rust-fuzzer" ]
}

如果套件沒有以對應語言編寫的模糊字元,就不需要納入清單。

fuchsia_fuzzer_package 可以使用與 fuchsia_package 相同的所有參數。

例如:

fuchsia_fuzzer_package("my-fuzzers") {
  package_name = "the-fuzzers"
  cpp_fuzz_components = [ ":my-fuzzer" ]
}

定義後,您必須像其他測試套件一樣,將套件納入建構依附元件圖中。通常也就是將其加入一組測試。

例如:

group("tests") {
  deps = [
    ":my-test-package",
    ":my-fuzzers",
  ]
}

運用 fx 打造打毛衣

如前文所述,只有明確要求 Fuchsia 建構系統在使用適當的模糊變數進行模糊偵測時,才會建構模糊工具。這些是結尾為 -fuzzer已知變數。每個物件都是 Sanitizer 變化版本的擴充功能,包括:

如要使用模糊變數建構 fuzzer_package,最簡單的方法是使用 --fuzz-with <sanitizer> 旗標搭配 fx set

例如:

fx set core.x64 --fuzz-with asan --with //bundles/tests
fx build

執行 fx set 後,您可以使用 ffx fuzz list 查看目前設定的模糊工具。您還可以使用額外的 ffx fuzz 指令執行模糊測試