# 機能設計書 61-fuzzer

## 概要

本ドキュメントは、Zigコンパイラに内蔵されているファジングテスト支援機能（fuzzer）の設計を記述する。この機能は、プログラムのテストケースを自動生成し、バグや脆弱性を発見するためのカバレッジガイド付きファジングを提供する。

### 本機能の処理概要

fuzzer機能は、Zigのテストフレームワークと連携して動作するファジングテスト支援ライブラリである。入力データを自動的に変異させながらテスト対象コードを繰り返し実行し、新しいコードパス（プログラムカウンタ）を発見することでテストカバレッジを向上させる。

**業務上の目的・背景**：ソフトウェアのセキュリティ脆弱性やバグを発見するためには、多様な入力パターンでのテストが必要である。手動でテストケースを作成するには限界があるため、自動的に入力を生成・変異させて未発見のバグを検出するファジングテストが重要となる。Zigコンパイラはこの機能を標準で内蔵することで、開発者が追加のツールなしにファジングテストを実行できる環境を提供する。

**機能の利用シーン**：
- ユニットテストでファジングテストを有効化した際に自動的に呼び出される
- パーサーやデコーダーなど、外部入力を処理するコードのテスト
- セキュリティ上重要なコードの堅牢性検証
- バグ再現のための最小入力ケースの生成

**主要な処理内容**：
1. SanitizerCoverage計装によるコードカバレッジの追跡
2. 入力データの変異（ミューテーション）による新規テストケース生成
3. 新しいプログラムカウンタを発見した入力の保存とコーパス管理
4. メモリマップドファイルによる入力データの永続化
5. 入力の最小化処理による再現ケースの簡素化

**関連システム・外部連携**：
- Zigのテストランナーと連携
- SanitizerCoverage計装コードとの連携
- ファイルシステム（キャッシュディレクトリ）へのアクセス

**権限による制御**：特になし。テスト実行時に自動的に有効化される。

## 関連画面

| 画面No | 画面名 | 関連種別 | 関連する操作・処理 |
|--------|--------|----------|------------------|
| 6 | テスト実行画面 | 補助機能 | ファジングテスト支援処理 |

## 機能種別

計算処理 / テスト自動化 / カバレッジ収集

## 入力仕様

### 入力パラメータ

| パラメータ名 | 型 | 必須 | 説明 | バリデーション |
|-------------|-----|-----|------|---------------|
| cache_dir_path | Slice | Yes | キャッシュディレクトリのパス | 有効なディレクトリパス |
| test_one | TestOne | Yes | テスト対象関数のポインタ | 有効な関数ポインタ |
| unit_test_name | Slice | Yes | ユニットテスト名 | 有効な文字列 |
| limit_kind | LimitKind | Yes | 実行制限の種類（永続/イテレーション回数） | forever または iterations |
| amount | u64 | No | イテレーション回数（limit_kindがiterationsの場合） | 正の整数 |

### 入力データソース

- テストフレームワークからの呼び出し
- コーパスディレクトリに保存された過去の入力ファイル
- SanitizerCoverage計装による実行時カバレッジデータ

## 出力仕様

### 出力データ

| 項目名 | 型 | 説明 |
|--------|-----|------|
| coverage | Coverage | カバレッジ情報（実行回数、ユニーク実行回数、発見PC数） |
| corpus_files | []u8 | 新規発見された入力ファイル群 |
| log_file | File | ファジング実行ログ |

### 出力先

- キャッシュディレクトリ内のコーパスファイル
- 共有カバレッジファイル（メモリマップドファイル）
- ログファイル（tmp/libfuzzer.log）

## 処理フロー

### 処理シーケンス

```
1. fuzzer_init: 初期化処理
   └─ キャッシュディレクトリのオープン、カバレッジファイルの準備

2. fuzzer_init_test: テスト初期化
   └─ テスト関数の登録、コーパスディレクトリの読み込み

3. fuzzer_main: メインファジングループ
   └─ 入力の変異 → テスト実行 → カバレッジ確認 → コーパス更新

4. cycle: 単一サイクルの実行
   ├─ コーパスから入力を選択
   ├─ ミューテーションを適用
   ├─ テスト関数を実行
   └─ 新規PCを発見した場合、入力を最小化して保存
```

### フローチャート

```mermaid
flowchart TD
    A[開始] --> B[fuzzer_init]
    B --> C[fuzzer_init_test]
    C --> D[コーパス読み込み]
    D --> E{ループ条件}
    E -->|継続| F[入力を選択]
    F --> G[ミューテーション適用]
    G --> H[テスト実行]
    H --> I{新規PC発見?}
    I -->|Yes| J[入力を最小化]
    J --> K[コーパスに保存]
    K --> E
    I -->|No| E
    E -->|終了| L[終了]
```

## ビジネスルール

### 業務ルール

| ルールNo | ルール名 | 内容 | 適用条件 |
|---------|---------|------|---------|
| BR-61-01 | 空入力の常時存在 | コーパスには常に空の入力が含まれる | 初期化時 |
| BR-61-02 | 入力最小化 | 新規PCを発見した入力はバイト単位で最小化される | 新規PC発見時 |
| BR-61-03 | 非決定性検出 | 空入力で異なるPCが検出された場合、非決定性として警告 | 空入力実行時 |
| BR-61-04 | ミューテーション確率調整 | 成功したミューテーションの選択確率が上昇 | 新規PC発見時 |

### 計算ロジック

**入力最小化アルゴリズム**：
1. 入力の各バイトを順番に削除
2. 削除後もfresh_pcsが維持されるか確認
3. 維持される場合は削除を確定、されない場合は元に戻す
4. 全バイトについて繰り返し

## データベース操作仕様

### 操作別データベース影響一覧

該当なし（ファイルシステムベースのデータ永続化）

## エラー処理

### エラーケース一覧

| エラーコード | エラー種別 | 発生条件 | 対処方法 |
|------------|----------|---------|---------|
| - | パニック | 初期化前のログ出力試行 | 適切な初期化順序の確認 |
| - | パニック | カバレッジファイルの不整合 | キャッシュのクリア |
| - | WouldBlock | 入力ファイルが別プロセスで使用中 | 別プロセスの終了を待つ |

### リトライ仕様

ファイルロックが取得できない場合はエラーを返す（リトライなし）

## トランザクション仕様

該当なし

## パフォーマンス要件

- ミューテーション処理: マイクロ秒オーダー
- メモリマップドファイルによる高速なI/O
- カバレッジ追跡のオーバーヘッド: 最小限

## セキュリティ考慮事項

- ファジング対象コードがクラッシュした場合でも入力ファイルは保持される
- 排他ロックによる複数プロセスの競合防止
- 共有カバレッジファイルへのアトミック操作

## 備考

- SanitizerCoverage（__sancov_*シンボル）との連携が必要
- ELFおよびMach-Oオブジェクト形式をサポート
- デバッグビルドでは DebugAllocator、リリースビルドでは smp_allocator を使用

---

## コードリーディングガイド

本機能を理解するために参照すべきファイルと、推奨する読み解き順序を以下に示す。

### 推奨読解順序

#### Step 1: データ構造を理解する

ファジングの中核となるデータ構造を理解することが重要。

| 順序 | ファイル | パス | 読解ポイント |
|-----|---------|------|-------------|
| 1-1 | fuzzer.zig | `lib/fuzzer.zig` | Executable, Instrumentation, Fuzzer構造体の定義 |

**読解のコツ**:
- `Executable`はカバレッジ追跡用のPCカウンタを管理
- `Instrumentation`は見たPCのビットセットを管理
- `Fuzzer`は入力コーパスとミューテーション履歴を管理

**主要処理フロー**:
- **62-82行目**: Executable構造体 - PCカウンタとカバレッジファイルの管理
- **268-327行目**: Instrumentation構造体 - 実行ごとのカバレッジ追跡
- **375-584行目**: Fuzzer構造体 - メインのファジングロジック

#### Step 2: エントリーポイントを理解する

| 順序 | ファイル | パス | 読解ポイント |
|-----|---------|------|-------------|
| 2-1 | fuzzer.zig | `lib/fuzzer.zig` | export関数群（fuzzer_init, fuzzer_init_test, fuzzer_main） |

**主要処理フロー**:
- **587-591行目**: `fuzzer_init` - グローバル初期化
- **612-615行目**: `fuzzer_init_test` - テストごとの初期化
- **626-631行目**: `fuzzer_main` - メインファジングループ

#### Step 3: ミューテーション処理を理解する

| 順序 | ファイル | パス | 読解ポイント |
|-----|---------|------|-------------|
| 3-1 | fuzzer.zig | `lib/fuzzer.zig` | Mutation列挙型と各ミューテーション処理 |

**主要処理フロー**:
- **748-894行目**: Mutation列挙型 - 全ミューテーション種別の定義
- **907-945行目**: `mutate`関数 - ミューテーションの適用

#### Step 4: メモリマップドリストを理解する

| 順序 | ファイル | パス | 読解ポイント |
|-----|---------|------|-------------|
| 4-1 | fuzzer.zig | `lib/fuzzer.zig` | MemoryMappedList構造体 |

**主要処理フロー**:
- **1306-1451行目**: MemoryMappedList - メモリマップドファイルベースのリスト実装

### プログラム呼び出し階層図

```
テストランナー
    │
    ├─ fuzzer_init (初期化)
    │      ├─ Executable.init
    │      └─ Instrumentation.init
    │
    ├─ fuzzer_init_test (テスト初期化)
    │      └─ Fuzzer.init
    │             ├─ コーパス読み込み
    │             └─ MemoryMappedList.create
    │
    └─ fuzzer_main (ファジング実行)
           └─ Fuzzer.cycle (繰り返し)
                  ├─ Mutation.mutate
                  ├─ Fuzzer.run
                  ├─ Instrumentation.isFresh
                  ├─ Fuzzer.minimizeInput
                  └─ Instrumentation.updateSeen
```

### データフロー図

```
[入力]                        [処理]                           [出力]

コーパスファイル ────────▶ Fuzzer.addInput ────────────▶ 入力バッファ
                                    │
                                    ▼
                           Mutation.mutate
                                    │
                                    ▼
                           test_one実行
                                    │
                                    ▼
PCカウンタ ──────────────▶ Instrumentation.isFresh
(__sancov_cntrs)                    │
                                    ▼
                           ┌─ 新規PC発見? ─┐
                           │              │
                           ▼              ▼
                    minimizeInput    次のサイクル
                           │
                           ▼
                    コーパス保存 ─────────▶ コーパスファイル
                           │
                           ▼
                    共有カバレッジ ────────▶ カバレッジファイル
                    更新
```

### 関連ファイル一覧

| ファイル | パス | 種別 | 役割 |
|---------|------|------|------|
| fuzzer.zig | `lib/fuzzer.zig` | ソース | ファジング機能のメイン実装 |
| fuzz.zig | `lib/std/Build/abi/fuzz.zig` | ソース | ファジングABI定義 |
| testing.zig | `lib/std/testing.zig` | ソース | テストフレームワークとの連携 |
