mcpField
A
address-sanitizer

address-sanitizer

github.com/trailofbitsテスト・品質7.9k5.4k 回インストール今日更新
リポジトリ

address-sanitizer について

AddressSanitizer(ASan)は、テストやファジングでメモリエラーを検出するコンパイル時インストルメンテーション技術です。実行時レポートで、バッファーオーバーフローや解放後使用などを特定できます。

主な機能

  1. 01メモリー操作へのコンパイル時インストルメンテーション
  2. 02オーバーフローや解放後使用の検出
  3. 03割り当て情報とスタックトレースの報告
  4. 04ASAN_OPTIONSによる動作設定
  5. 05複数のファザーとの連携

活用シーン

  1. 01C/C++プログラムのメモリエラー検出
  2. 02unsafeコードを含むRustプロジェクトのテスト
  3. 03ユニットテストでのメモリー破損の特定
  4. 04ファジングで見つかったクラッシュの調査

インストール

コマンドをコピーしてターミナルで実行します。

$npx skills add https://github.com/trailofbits/skills --skill address-sanitizer

インストール後、Claude Code で/address-sanitizerを入力して読み込まれたか確認します。

同梱ファイルagents/openai.yamlassets/trail-of-bits-mark.svg

詳細

AddressSanitizer(ASan)

AddressSanitizer(ASan)は、ソフトウェアテスト、特にファジングで広く使用されている、メモリエラー検出ツールです。バッファーオーバーフロー、解放後使用エラー、その他のメモリー安全性違反など、見過ごされる可能性のあるメモリー破損のバグを検出できます。

概要

ASan はメモリー脆弱性の特定に効果的なため、ファジングで標準的に使用されています。コンパイル時にコードを計測し、メモリー割り当てとアクセスを追跡することで、実行時に不正な操作を検出します。

主な概念
概念説明
計測ASan はコンパイル時にメモリー操作へ実行時チェックを追加します
シャドーメモリー割り当て状態を追跡するために、20TB の仮想メモリーをマッピングします
パフォーマンスコスト計測されていないコードと比較して約 2〜4 倍遅くなります
検出範囲バッファーオーバーフロー、解放後使用、二重解放、メモリーリークを検出します

適用するタイミング

この手法を適用する場合:

  • メモリー安全性の脆弱性を探すために C/C++ コードをファジングする場合
  • unsafe ブロックを含む Rust コードをテストする場合
  • メモリー破損に関連するクラッシュをデバッグする場合
  • メモリーエラーが疑われる単体テストを実行する場合

この手法を適用しない場合:

  • 本番コードを実行する場合(ASan によってセキュリティが低下する可能性があります)
  • プラットフォームが Windows または macOS の場合(ASan のサポートが限定的です)
  • パフォーマンスのオーバーヘッドがユースケースで許容できない場合
  • FFI を使用しない安全な言語のみをファジングする場合(例:純粋な Go、純粋な Java)

クイックリファレンス

タスクコマンド/パターン
ASan を有効にする(Clang/GCC)-fsanitize=address
詳細出力を有効にするASAN_OPTIONS=verbosity=1
リーク検出を無効にするASAN_OPTIONS=detect_leaks=0
エラー時に強制的に中断するASAN_OPTIONS=abort_on_error=1
複数のオプションASAN_OPTIONS=verbosity=1:abort_on_error=1

手順

ステップ 1:ASan を有効にしてコンパイルする

-fsanitize=address フラグを指定して、コードをコンパイルおよびリンクします。

clang -fsanitize=address -g -o my_program my_program.c

ASan がエラーを検出した際に、より詳しいスタックトレースを取得するため、-g フラグの使用を推奨します。

ステップ 2:ASan オプションを設定する

ASAN_OPTIONS 環境変数を設定して、ASan の動作を構成します。

export ASAN_OPTIONS=verbosity=1:abort_on_error=1:detect_leaks=0
ステップ 3:プログラムを実行する

ASan で計測されたバイナリを実行します。メモリーエラーが検出されると、ASan は詳細なレポートを出力します。

./my_program
ステップ 4:ファザーのメモリー制限を調整する

ASan は約 20TB の仮想メモリーを必要とします。ファザーのメモリー制限を無効にします。

  • libFuzzer:-rss_limit_mb=0
  • AFL++:-m none

よくあるパターン

パターン:ASan の基本的な統合

用途: ASan を使用する標準的なファジング設定

変更前:

clang -o fuzz_target fuzz_target.c
./fuzz_target

変更後:

clang -fsanitize=address -g -o fuzz_target fuzz_target.c
ASAN_OPTIONS=verbosity=1:abort_on_error=1 ./fuzz_target
パターン:単体テストでの ASan

用途: 単体テストスイートで ASan を有効にする

変更前:

gcc -o test_suite test_suite.c -lcheck
./test_suite

変更後:

gcc -fsanitize=address -g -o test_suite test_suite.c -lcheck
ASAN_OPTIONS=detect_leaks=1 ./test_suite

高度な使い方

ヒントとコツ
ヒント役立つ理由
-g フラグを使用するデバッグに役立つ詳細なスタックトレースを取得できます
verbosity=1 を設定するプログラムの開始前に ASan が有効であることを確認できます
ファジング中はリーク検出を無効にするリーク検出では即座にクラッシュせず、出力が煩雑になります
abort_on_error=1 を有効にする一部のファザーでは _exit() ではなく abort() が必要です
ASan レポートを理解する

ASan がメモリーエラーを検出すると、次の情報を含む詳細なレポートを出力します。

  • エラーの種類:バッファーオーバーフロー、解放後使用など
  • スタックトレース:エラーが発生した場所
  • 割り当て/解放のトレース:メモリーが割り当て/解放された場所
  • メモリーマップ:エラー周辺のシャドーメモリーの状態

ASan レポートの例:

==12345==ERROR: AddressSanitizer: heap-buffer-overflow on address 0x60300000eff4 at pc 0x00000048e6a3
READ of size 4 at 0x60300000eff4 thread T0
    #0 0x48e6a2 in main /path/to/file.c:42
サニタイザーの併用

ASan は他のサニタイザーと併用して、包括的な検出を行えます。

clang -fsanitize=address,undefined -g -o fuzz_target fuzz_target.c
プラットフォーム固有の考慮事項

Linux:最良のパフォーマンスで ASan を完全にサポートします
macOS:サポートは限定的で、一部の機能が動作しない場合があります
Windows:実験的なサポートのため、本番環境でのファジングには推奨されません

アンチパターン

アンチパターン問題正しいアプローチ
本番環境で ASan を使用するアプリケーションのセキュリティが低下する可能性がありますASan はテスト時にのみ使用します
メモリ制限を無効にしない20TB の仮想メモリが原因で、ファザーがプロセスを終了させることがあります-rss_limit_mb=0 または -m none を設定します
リークレポートを無視するメモリリークはリソース管理に問題があることを示していますファジングキャンペーンの終了時にリークレポートを確認します

ツール固有のガイダンス

libFuzzer

ファザーとアドレスサニタイザーの両方を指定してコンパイルします。

clang++ -fsanitize=fuzzer,address -g harness.cc -o fuzz

RSS を無制限にして実行します。

./fuzz -rss_limit_mb=0

統合のヒント:

  • -fsanitize=fuzzer と -fsanitize=address は必ず組み合わせます
  • -g を指定すると、クラッシュレポートで詳細なスタックトレースを確認できます
  • クラッシュを適切に処理するため、ASAN_OPTIONS=abort_on_error=1 の使用を検討します

参照:libFuzzer:AddressSanitizer

AFL++

AFL_USE_ASAN 環境変数を使用します。

AFL_USE_ASAN=1 afl-clang-fast++ -g harness.cc -o fuzz

メモリ制限なしで実行します。

afl-fuzz -m none -i input_dir -o output_dir ./fuzz

統合のヒント:

  • AFL_USE_ASAN=1 を指定すると、適切なコンパイルフラグが自動的に追加されます
  • AFL++ のメモリ制限を無効にするには、-m none を使用します
  • カバレッジマップが大きいプログラムでは、AFL_MAP_SIZE の使用を検討します

参照:AFL++:AddressSanitizer

cargo-fuzz(Rust)

--sanitizer=address フラグを使用します。

cargo fuzz run fuzz_target --sanitizer=address

または、fuzz/Cargo.toml で設定します。

[profile.release]
opt-level = 3
debug = true

統合のヒント:

  • ASan は、unsafe な Rust コードや FFI 境界のファジングに役立ちます
  • 安全な Rust コードでは、コンパイラーがすでに多くのエラーを防ぐため、効果はそれほど大きくない場合があります
  • unsafe ブロック、raw ポインター、C ライブラリのバインディングに重点を置きます

参照:cargo-fuzz:AddressSanitizer

honggfuzz

ASan を使ってコンパイルし、honggfuzz とリンクします。

honggfuzz -i input_dir -o output_dir -- ./fuzz_target_asan

ターゲットをコンパイルします。

hfuzz-clang -fsanitize=address -g target.c -o fuzz_target_asan

統合のヒント:

  • honggfuzz は、追加設定なしで ASan と適切に連携します
  • サニタイザーを使用しながらカバレッジを高めるには、フィードバック駆動モードを使用します
  • ASan によってメモリ使用量が増えるため、メモリ使用量を監視します

トラブルシューティング

問題原因解決策
ファザーがプロセスをすぐに終了させるASan の 20TB の仮想メモリに対してメモリ制限が低すぎます-rss_limit_mb=0(libFuzzer)または -m none(AFL++)を使用します
「ASan runtime not initialized」リンク順序が間違っているか、ランタイムがありませんコンパイル時とリンク時の両方で -fsanitize=address が使われていることを確認します
リークレポートで出力が埋まるLeakSanitizer がデフォルトで有効になっていますASAN_OPTIONS=detect_leaks=0 を設定します
パフォーマンスが低い(4 倍以上の速度低下)デバッグモードまたは最適化されていないビルドです-fsanitize=address とともに -O2 または -O3 を指定してコンパイルします
ASan が明らかなバグを検出しないバイナリが計測されていませんASAN_OPTIONS=verbosity=1 を指定し、ASan が起動情報を出力することを確認します
誤検知インターセプターの競合です特定のライブラリで既知の問題がないか、ASan FAQ を確認します

関連スキル

この手法を使用するツール
スキル適用方法
libfuzzer-fsanitize=fuzzer,address を指定してコンパイルすると、メモリエラー検出機能を備えたファジングを統合できます
aflppコンパイル時に AFL_USE_ASAN=1 環境変数を使用します
cargo-fuzz--sanitizer=address フラグを使用して、Rust のファズターゲットで ASan を有効にします
honggfuzzASan で計測されたファジングを行うには、-fsanitize=address を指定してターゲットをコンパイルします
関連手法
スキル関係
undefined-behavior-sanitizer包括的なバグ検出(未定義動作とメモリエラー)のために、ASan と併用されることがよくあります
fuzz-harness-writingハーネスは、ASan が検出したクラッシュを処理し、誤検知を避けられるように設計する必要があります
coverage-analysisカバレッジガイド付きファジングは、ASan がメモリエラーを検出できるコードパスの実行に役立ちます

リソース

主な外部リソース

Google Sanitizers Wiki の AddressSanitizer

ASan の公式ドキュメントでは、以下の内容を扱っています:

  • アルゴリズムと実装の詳細
  • 検出されるエラータイプの完全なリスト
  • パフォーマンス特性とオーバーヘッド
  • プラットフォーム固有の動作
  • 既知の制限と非互換性

SanitizerCommonFlags

すべてのサニタイザーで共有される共通の設定フラグ:

  • verbosity:診断出力レベルを制御します
  • log_path:サニタイザーの出力をファイルにリダイレクトします
  • symbolize:レポート内のシンボル解決を有効化/無効化します
  • external_symbolizer_path:カスタムシンボライザーを使用します

AddressSanitizerFlags

ASan 固有の設定オプション:

  • detect_leaks:メモリリーク検出を制御します
  • abort_on_error:エラー時に abort() を呼び出すか _exit() を呼び出すかを指定します
  • detect_stack_use_after_return:スタックの use-after-return バグを検出します
  • check_initialization_order:初期化順序のバグを検出します

AddressSanitizer FAQ

よくある落とし穴と解決策:

  • リンク順序の問題
  • 他のツールとの競合
  • プラットフォーム固有の問題
  • パフォーマンスチューニングのヒント

Clang AddressSanitizer ドキュメント

Clang 固有のガイダンス:

  • コンパイルフラグとオプション
  • 他の Clang 機能との相互作用
  • サポートされているプラットフォームとアーキテクチャ

GCC インストルメンテーションオプション

GCC 固有の ASan ドキュメント:

  • GCC 固有のフラグと動作
  • Clang 実装との違い
  • GCC におけるプラットフォームサポート

AddressSanitizer: A Fast Address Sanity Checker (USENIX 論文)

技術的な詳細を含む原著論文:

  • シャドウメモリのアルゴリズム
  • 仮想メモリ要件(歴史的には 16TB、現在は約 20TB)
  • パフォーマンスベンチマーク
  • 設計上の決定とトレードオフ

コメント