# ファジング
## 定義
ファジング(fuzzing / fuzz testing)とは、*ファズエンジン(fuzzer)* を用いて大量の候補入力を生成し、*ファズドライバ* を経由して *ファズターゲット*(入力を処理するコード)に渡し、その挙動を観察してバグを見つけるテスト技法である。ファイルパーサ・圧縮アルゴリズム・ネットワークプロトコル実装・オーディオコーデックのような複雑な入力を扱うソフトウェアが典型的な対象になる。単純に乱数生成器のバイト列をそのまま流し込む「dumb fuzzing」から、コンパイラ計装(instrumentation)を通じて新しいコードパスに到達した入力を優先的に変異させる coverage-guided fuzzing まで洗練度に幅がある。ファジングは「見つけたバグが既にコミット済みである」ことを前提とする性質上、他のテスト・解析技法を置き換えるのではなく、エンジニアが想定しなかった入力を機械的に生成して**補完する**技法として位置づけられる。(Source: [[@2020__OReilly__Building Secure and Reliable Systems - Chapter 13 Testing Code]] ch.13 §Fuzz Testing, §How Fuzz Engines Work)
ファズエンジンはサニタイザ(ASan・UBSan・MSan 等)によるコンパイラ計装と組み合わさって初めて診断能力を十分に発揮する。サニタイザなしでファジングを行うことも可能だが、プログラムがクラッシュや終了という形で異常状態を外部に知らせない限り、不正な状態(未定義動作やメモリ破壊)は検出されないまま進行してしまう。ハンドアセンブルされたコードのようにコンパイラが計装できない部分は、サニタイザの死角になり偽陰性や偽陽性の温床になる。(Source: ch.13 §How Fuzz Engines Work)
ファズエンジンは*シードコーパス*(対象コードが期待する入力の代表例)を変異させて新しい入力を生成する。プロトコル・言語・フォーマットの仕様から得たキーワード辞書を与えると、パーサに拒否されずに奥まで到達する入力を生成しやすくなる。継続的ファジングは、日次ビルドでファザーをビルドし、クラッシュ情報を収集してイシュートラッカーに自動起票する仕組みであり、Google の [[ClusterFuzz]](スケーラブルなファジング基盤)と、それを OSS プロジェクト向けに提供する [[OSS-Fuzz]] が代表例である。OSS-Fuzz は公開から5か月で1000件超、その後は数万件のバグを発見したと報告されている。(Source: ch.13 §Continuous Fuzzing, §Example: ClusterFuzz and OSSFuzz)
## 有効なファズドライバを書くための指針
- **非決定性を避ける**: 乱数生成器やスレッド順序に依存する挙動は、クラッシュの再現性を損なう。
- **低速な操作を避ける**: コンソールログ・ディスク I/O は実行速度を落とす。ファザー専用ビルドでこれらを無効化する、あるいはメモリ上のファイルシステムを使う。
- **意図的なクラッシュを避ける**: ファズエンジンは意図的なクラッシュと意図しないクラッシュを区別できない。
- **改ざん検知不能な整合性チェック(CRC32・メッセージダイジェスト等)を外す**: ファズエンジンが正しいチェックサムを偶然生成することはまずないため、専用ロジックなしでは整合性チェックを通過できず、その先のコードに到達できない。`-DFUZZING_BUILD_MODE_UNSAFE_FOR_PRODUCTION` のようなプリプロセッサフラグでこの種のファザー向けビルドを有効化する慣行がある。
これらの性質(非決定性の排除・高速性)は、ファジングに限らず本章が扱う他の種類のテスト全般にも望ましい性質だとされる。(Source: ch.13 §Writing Effective Fuzz Drivers)
## 横断的知見
- (このconceptは現時点で `Building Secure and Reliable Systems` 第13章のみを情報源とする。複数ソースを突き合わせた横断的知見は今後の ingest で蓄積する。)
## 未解決の問い
- coverage-guided fuzzing がコードカバレッジで頭打ちになったとき、シードコーパスの改善・入力分割戦略の見直し・ハーネス自体の再設計のどれを優先すべきかの判断基準は、本章では「調査する価値がある」としか述べられておらず具体化されていない。
- ClusterFuzz のクラッシュ重複排除ヒューリスティクス(クラッシュ時のプログラム状態に基づく)は、本章では詳細が示されない。誤って別バグを同一視・同一バグを別物とみなす精度はどの程度か。
- 「known safe」関数として個別にサニタイザを無効化する判断(本章では慎重なレビュー後にのみ許容)を組織的にどう運用し、偽陰性の増加をどう監視すべきかは未検討。
- ファジングと [[テストカバレッジ]] が扱う伝統的な文/分岐/データフローカバレッジ規準との関係(ファジングが到達する `cov`/`ft` メトリクスは後者とどう対応するのか)は、両ソースを直接突き合わせた検討がまだない。
## 関連
- ソース: [[@2020__OReilly__Building Secure and Reliable Systems - Chapter 13 Testing Code]]
- 実体: [[ClusterFuzz]] / [[OSS-Fuzz]]
- 概念: [[テストカバレッジ]](到達度メトリクスという観点で接点がある)/ [[静的解析の開発者ワークフロー統合]](コンパイラ計装・CI/CD 統合という共通基盤を持つ姉妹概念)
## 出典
- Heather Adkins et al. (eds.), *Building Secure and Reliable Systems*, O'Reilly Media, 2020, Chapter 13.