ossfuzz について
OSS-Fuzzは、継続的なファジングテスト向けのGoogleのオープンソースプロジェクトです。分散インフラとローカルでハーネスを構築・実行するCLIを備え、オープンソースの保守担当者や独自環境で非公開プロジェクトをテストする組織に向いています。
主な機能
- 01ファジングハーネスの構築と実行
- 02ローカルテストとカバレッジ分析
- 03ビルド状況とバグの追跡
- 04独自インスタンスのホスト
活用シーン
- 01オープンソースプロジェクトの継続的ファジング
- 02既存ハーネスのローカルテスト
- 03バグ報告のクラッシュ再現
インストール
コマンドをコピーしてターミナルで実行します。
npx skills add https:/ / github.com/ trailofbits/ skills --skill ossfuzzインストール後、Claude Code で/ossfuzzを入力して読み込まれたか確認します。
同梱ファイルagents/openai.yamlassets/trail-of-bits-mark.svg
詳細
OSS-Fuzz
OSS-Fuzz は、継続的なファジングテスト用の分散インフラストラクチャを無料で提供する、Google が開発したオープンソースプロジェクトです。ファジングのプロセスを効率化し、より簡単に変更できるようにします。OSS-Fuzz に受け入れられるプロジェクトは一部に限られますが、プロジェクトの中核はオープンソースであり、誰でも自分のプライベートプロジェクト用に独自のインスタンスをホストできます。
概要
OSS-Fuzz は、ハーネスのビルドと実行、またはカバレッジの計算に使えるシンプルな CLI フレームワークを提供します。また、カバレッジ情報など、ファジングの出力から生成した静的ウェブページをホストするサービスとしても利用できます。
主な概念
| 概念 | 説明 |
|---|---|
| helper.py | イメージのビルド、ファザーのビルド、ハーネスのローカル実行に使う CLI スクリプト |
| Base Images | ビルド依存関係とコンパイラーを提供する階層型 Docker イメージ |
| project.yaml | OSS-Fuzz への登録に必要なプロジェクトのメタデータを定義する設定ファイル |
| Dockerfile | ビルド依存関係を含む、プロジェクト固有のイメージ |
| build.sh | プロジェクトのファジングハーネスをビルドするスクリプト |
| Criticality Score | OSS-Fuzz チームがプロジェクトの受け入れを評価する際に使用する指標 |
適用する場面
次のような場合にこの手法を適用します:
- オープンソースプロジェクトで継続的なファジングを設定する場合
- サーバーを管理せずに分散ファジングインフラストラクチャを利用したい場合
- カバレッジレポートやバグ追跡をファジングと統合したい場合
- 既存の OSS-Fuzz ハーネスをローカルでテストする場合
- OSS-Fuzz のバグ報告にあるクラッシュを再現する場合
次のような場合はこの手法を使用しないでください:
- プロジェクトがクローズドソースである場合(独自の OSS-Fuzz インスタンスをホストする場合を除く)
- プロジェクトが OSS-Fuzz の Criticality Score のしきい値を満たさない場合
- プロプライエタリな、または特殊なファジングインフラストラクチャが必要な場合
- インフラストラクチャを必要としない単純なスクリプトをファジングする場合
クイックリファレンス
| タスク | コマンド |
|---|---|
| OSS-Fuzz をクローンする | git clone https://github.com/google/oss-fuzz |
| プロジェクトのイメージをビルドする | uv run --no-project python infra/helper.py build_image --pull <project> |
| ASan を使ってファザーをビルドする | uv run --no-project python infra/helper.py build_fuzzers --sanitizer=address <project> |
| 特定のハーネスを実行する | uv run --no-project python infra/helper.py run_fuzzer <project> <harness> |
| カバレッジレポートを生成する | uv run --no-project python infra/helper.py coverage <project> |
| helper.py のオプションを確認する | uv run --no-project python infra/helper.py --help |
OSS-Fuzz のプロジェクトコンポーネント
OSS-Fuzz は、一般公開されている複数のツールとウェブインターフェースを提供します。
バグトラッカー
バグトラッカーでは、次のことができます:
- 特定のプロジェクトのバグを確認する(当初はメンテナーのみが閲覧でき、その後公開されました)
- 新しい課題を作成し、既存の課題にコメントする
- すべてのプロジェクトを対象に類似のバグを検索し、問題を把握する
ビルドステータスシステム
ビルドステータスシステムでは、次の情報を確認できます:
- 対象となるすべてのプロジェクトのビルドステータス
- 最後にビルドが成功した日付
- ビルドの失敗とその継続時間
Fuzz Introspector
Fuzz Introspectorでは、次の情報を確認できます:
- OSS-Fuzz に登録されたプロジェクトのカバレッジデータ
- カバーされたコードのヒット頻度
- パフォーマンス分析とボトルネックの特定
例と解説については、こちらのケーススタディをお読みください。
手順:単一のハーネスを実行する
OSS-Fuzz プラットフォーム全体をホストしなくても利用できます。ヘルパースクリプトを使えば、個々のハーネスをローカルで簡単に実行できます。
ステップ 1:OSS-Fuzz をクローンする
git clone https://github.com/google/oss-fuzz
cd oss-fuzz
uv run --no-project python infra/helper.py --help
ステップ 2:プロジェクトのイメージをビルドする
uv run --no-project python infra/helper.py build_image --pull <project-name>
これにより、プロジェクトのベース Docker イメージがダウンロードされ、ビルドされます。
ステップ 3:サニタイザーを使ってファザーをビルドする
uv run --no-project python infra/helper.py build_fuzzers --sanitizer=address <project-name>
サニタイザーのオプション:
- AddressSanitizer と LeakSanitizer を使う場合は
--sanitizer=address - ほかのサニタイザーも利用できます(言語によって対応状況は異なります)
注: ファザーは /build/out/<project-name>/ にビルドされます。このディレクトリにはハーネスの実行ファイル、辞書、コーパス、クラッシュファイルが含まれます。
ステップ 4:ファザーを実行する
uv run --no-project python infra/helper.py run_fuzzer <project-name> <harness-name> [<fuzzer-args>]
ヘルパースクリプトは、スキップした手順があれば自動的に実行します。
ステップ 5:カバレッジを分析する(任意)
まず、gsutil をインストールします(gcloud の初期化はスキップしてください)。
uv run --no-project python infra/helper.py build_fuzzers --sanitizer=coverage <project-name>
uv run --no-project python infra/helper.py coverage <project-name>
ローカルのコーパスのみを使うには --no-corpus-download を使用します。このコマンドはカバレッジレポートを生成し、ローカルでホストします。
詳細については、OSS-Fuzz の公式ドキュメントを参照してください。
よくあるパターン
パターン:irssi の例を実行する
ユースケース: OSS-Fuzz のセットアップを、登録済みのシンプルなプロジェクトでテストする
# Clone and navigate to OSS-Fuzz
git clone https://github.com/google/oss-fuzz
cd oss-fuzz
# Build and run irssi fuzzer
uv run --no-project python infra/helper.py build_image --pull irssi
uv run --no-project python infra/helper.py build_fuzzers --sanitizer=address irssi
uv run --no-project python infra/helper.py run_fuzzer irssi irssi-fuzz
期待される出力:
INFO:__main__:Running: docker run --rm --privileged --shm-size=2g --platform linux/amd64 -i -e FUZZING_ENGINE=libfuzzer -e SANITIZER=address -e RUN_FUZZER_MODE=interactive -e HELPER=True -v /private/tmp/oss-fuzz/build/out/irssi:/out -t gcr.io/oss-fuzz-base/base-runner run_fuzzer irssi-fuzz.
Using seed corpus: irssi-fuzz_seed_corpus.zip
/out/irssi-fuzz -rss_limit_mb=2560 -timeout=25 /tmp/irssi-fuzz_corpus -max_len=2048 < /dev/null
INFO: Running with entropic power schedule (0xFF, 100).
INFO: Seed: 1531341664
INFO: Loaded 1 modules (95687 inline 8-bit counters): 95687 [0x1096c80, 0x10ae247),
INFO: Loaded 1 PC tables (95687 PCs): 95687 [0x10ae248,0x1223eb8),
INFO: 719 files found in /tmp/irssi-fuzz_corpus
INFO: seed corpus: files: 719 min: 1b max: 170106b total: 367969b rss: 48Mb
#720 INITED cov: 409 ft: 1738 corp: 640/163Kb exec/s: 0 rss: 62Mb
#762 REDUCE cov: 409 ft: 1738 corp: 640/163Kb lim: 2048 exec/s: 0 rss: 63Mb L: 236/2048 MS: 2 ShuffleBytes-EraseBytes-
パターン:新しいプロジェクトを登録する
ユースケース: OSS-Fuzz(またはプライベートインスタンス)にプロジェクトを追加する
projects/<your-project>/ に次の 3 つのファイルを作成します。
1. project.yaml - プロジェクトのメタデータ:
homepage: "https://github.com/yourorg/yourproject"
language: c++
primary_contact: "[email protected]"
main_repo: "https://github.com/yourorg/yourproject"
fuzzing_engines:
- libfuzzer
sanitizers:
- address
- undefined
2. Dockerfile - ビルドの依存関係:
FROM gcr.io/oss-fuzz-base/base-builder
RUN apt-get update && apt-get install -y \
autoconf \
automake \
libtool \
pkg-config
RUN git clone --depth 1 https://github.com/yourorg/yourproject
WORKDIR yourproject
COPY build.sh $SRC/
3. build.sh - ハーネスをビルドするスクリプト:
#!/bin/bash -eu
./autogen.sh
./configure --disable-shared
make -j$(nproc)
# Build harnesses
$CXX $CXXFLAGS -std=c++11 -I. \
$SRC/yourproject/fuzz/harness.cc -o $OUT/harness \
$LIB_FUZZING_ENGINE ./libyourproject.a
# Copy corpus and dictionary if available
cp $SRC/yourproject/fuzz/corpus.zip $OUT/harness_seed_corpus.zip
cp $SRC/yourproject/fuzz/dictionary.dict $OUT/harness.dict
OSS-Fuzz の Docker イメージ
ハーネスは Docker コンテナ内でビルドおよび実行されます。すべてのプロジェクトでランナーイメージを共有しますが、各プロジェクトには独自のビルドイメージがあります。
イメージの階層
イメージは次の順序でビルドされます。
- base_image - 特定の Ubuntu バージョン
- base_clang - Clang コンパイラー。
base_imageをベースにしています - base_builder - ビルドの依存関係。
base_clangをベースにしています- 言語固有のバリアント:
base_builder_goなど - 一覧については /oss-fuzz/infra/base-images/ を参照してください
- 言語固有のバリアント:
- プロジェクト独自の Docker イメージ - プロジェクト固有の依存関係。
base_builderまたは言語固有のバリアントをベースにしています
ランナーイメージ(別途使用)
- base_runner - ハーネスを実行します。
base_clangをベースにしています - base_runner_debug - デバッグツールを含みます。
base_runnerをベースにしています
高度な使い方
ヒントとコツ
| ヒント | 役立つ理由 |
|---|---|
| ソースコードを手動でコピーしない | プロジェクトの Dockerfile が最新バージョンをすでに取得している可能性があります |
| 既存のプロジェクトを確認する | 例については oss-fuzz/projects を参照してください |
| ハーネスを別のリポジトリに置く | curl-fuzzer のように、構成をすっきりさせられます |
| 特定のコンパイラーバージョンを使う | ベースイメージによって一貫性のあるビルド環境を利用できます |
| 依存関係を Dockerfile にインストールする | OSS-Fuzz への登録に承認が必要になる場合があります |
重要度スコア
OSS-Fuzz は重要度スコアを使って、プロジェクトの受け入れを評価します。スコアの仕組みについては、こちらの例を参照してください。
スコアが低いプロジェクトも、プライベートな OSS-Fuzz インスタンスには追加できる場合があります。
独自のインスタンスをホストする
OSS-Fuzz はオープンソースであるため、次の用途向けに独自のインスタンスをホストできます。
- 公開 OSS-Fuzz の対象とならないプライベートプロジェクト
- 重要度スコアが低いプロジェクト
- カスタムのファジングインフラストラクチャが必要な場合
アンチパターン
| アンチパターン | 問題 | 正しいアプローチ |
|---|---|---|
| build.sh でソースを手動で取得する | 最新バージョンが使用されません | git clone は Dockerfile に任せます |
| コードを OSS-Fuzz リポジトリにコピーする | 保守が難しく、分離の原則に反します | 外部のハーネスリポジトリを参照します |
| ベースイメージのバージョンを無視する | ビルドに一貫性がなくなります | 提供されたベースイメージとコンパイラを使用します |
| ローカルテストを省略する | CI リソースを無駄に消費します | PR の前に helper.py をローカルで使用します |
| ビルド状況を確認しない | ビルドの失敗に気づけません | ビルド状況ページを定期的に確認します |
ツール固有のガイダンス
libFuzzer
OSS-Fuzz では、C/C++ プロジェクトのファジングエンジンとして主に libFuzzer を使用します。
ハーネスのシグネチャ:
extern "C" int LLVMFuzzerTestOneInput(const uint8_t *data, size_t size) {
// Your fuzzing logic
return 0;
}
build.sh でのビルド:
$CXX $CXXFLAGS -std=c++11 -I. \
harness.cc -o $OUT/harness \
$LIB_FUZZING_ENGINE ./libproject.a
統合のヒント:
- OSS-Fuzz が提供する
$LIB_FUZZING_ENGINE変数を使用します -fsanitize=fuzzerの追加は自動的に処理されます- 可能な場合は静的ライブラリにリンクします
AFL++
OSS-Fuzz は、代替のファジングエンジンとして AFL++ をサポートしています。
project.yaml で有効にする:
fuzzing_engines:
- afl
- libfuzzer
統合のヒント:
- AFL++ のハーネスは libFuzzer のハーネスと併用できます
- パフォーマンスを向上させるには、永続モードを使用します
- エンジン固有のコンパイルフラグは OSS-Fuzz が処理します
Atheris(Python)
C 拡張を含む Python プロジェクト向けです。
ハーネス:
import atheris
import sys
import cbor2
@atheris.instrument_func
def TestOneInput(data):
fdp = atheris.FuzzedDataProvider(data)
try:
cbor2.loads(data)
except (cbor2.CBORDecodeError, ValueError):
pass
def main():
atheris.Setup(sys.argv, TestOneInput)
atheris.Fuzz()
if __name__ == "__main__":
main()
build.sh でのビルド:
# allow-legacy-python: build.sh runs inside the oss-fuzz container, where the shims are absent.
pip3 install .
for fuzzer in $(find $SRC -name 'fuzz_*.py'); do
compile_python_fuzzer $fuzzer
done
統合のヒント:
- OSS-Fuzz が提供する
compile_python_fuzzerヘルパーを使用します - ブログ記事「Python C 拡張を継続的にファジングする」を参照してください
Rust プロジェクト
project.yaml で有効にする:
language: rust
fuzzing_engines:
- libfuzzer
sanitizers:
- address # Only AddressSanitizer supported for Rust
build.sh でのビルド:
cargo fuzz build -O --debug-assertions
cp fuzz/target/x86_64-unknown-linux-gnu/release/fuzz_target_1 $OUT/
統合のヒント:
- Rust が libfuzzer でサポートするのは AddressSanitizer のみです
- ローカル開発には cargo-fuzz を使用します
- Rust 固有のコンパイルは OSS-Fuzz が処理します
トラブルシューティング
| 問題 | 原因 | 解決策 |
|---|---|---|
| 依存関係が見つからずビルドに失敗する | 依存関係が Dockerfile にありません | Dockerfile に apt-get install または同等のコマンドを追加します |
| ハーネスが直ちにクラッシュする | 入力検証がありません | ハーネスにサイズチェックを追加します |
| カバレッジが 0% になる | ハーネスが対象コードに到達していません | ハーネスが実際に対象の関数を呼び出しているか確認します |
| ビルドがタイムアウトする | ビルドプロセスが複雑です | build.sh を最適化し、並列ビルドを検討します |
| ビルド中にサニタイザーエラーが発生する | フラグに互換性がありません | OSS-Fuzz の環境変数で提供されるフラグを使用します |
| ソースコードが見つからない | Dockerfile の作業ディレクトリが間違っています | WORKDIR を設定するか、絶対パスを使用します |
関連スキル
この手法を使用するツール
| スキル | 適用方法 |
|---|---|
| libfuzzer | OSS-Fuzz が使用する主要なファジングエンジン |
| aflpp | OSS-Fuzz がサポートする代替のファジングエンジン |
| atheris | OSS-Fuzz で Python プロジェクトのファジングに使用されます |
| cargo-fuzz | OSS-Fuzz で Rust プロジェクトに使用されます |
関連する手法
| スキル | 関係 |
|---|---|
| coverage-analysis | OSS-Fuzz は helper.py を介してカバレッジレポートを生成します |
| address-sanitizer | OSS-Fuzz プロジェクトのデフォルトのサニタイザー |
| fuzz-harness-writing | OSS-Fuzz にプロジェクトを登録するうえで不可欠です |
| corpus-management | OSS-Fuzz は登録済みプロジェクトのコーパスを管理します |
リソース
主要な外部リソース
OSS-Fuzz 公式ドキュメント OSS-Fuzz プラットフォームへの登録、ハーネスの作成、トラブルシューティングを網羅した包括的なドキュメントです。
入門ガイド 要件や承認プロセスを含む、新しいプロジェクトを OSS-Fuzz に登録するための手順を段階的に説明します。
cbor2 の OSS-Fuzz 統合 PR C 拡張機能を含む Python プロジェクトを OSS-Fuzz に登録した実例です。以下の内容を紹介します。
- 初期提案とプロジェクトの紹介
- 重要度スコアの評価
- 完全な実装(project.yaml、Dockerfile、build.sh、ハーネス)
Fuzz Introspector のケーススタディ Fuzz Introspector を使ってカバレッジを分析し、ファジングの障害要因を特定する例と解説です。
動画リソース
登録やハーネス開発に関するワークショップの録画やチュートリアルについては、OSS-Fuzz のドキュメントをご確認ください。