AFL++ を活用したより効果的なファスティングテストのためのヒント

2026/10/28 18:46

AFL++ を活用したより効果的なファスティングテストのためのヒント

RSS: https://news.ycombinator.com/rss

要約▶

Japanese Translation:

6 年間の約 1,000 プロジェクトのテストに基づき、著者は AFL++ が Linux 上の C/C++ fuzzing プラットフォームとして決定版であると主張し、ファジー化されていないソフトウェアにはほぼ間違いなくバグが含まれていることを確認しています。速度を損なうことなく脆弱性の検出を最大化するためには、公式文書で強調されている特定のハイパフォーマンス構成を採用すべきです。主要な最適化策には、クラッシュ間でプログラムの状態を維持するパシストンモードの利用(通常は 10 倍ほど高速化)、

afl-gcc-fast
とともに
-fsanitize=address,undefined
および他のフラグでサニタイザーを設定することが含まれます。具体的なチューニングも不可欠であり、デフォルトの 4KiB リミットを超えて
max_malloc_fill_size
を増やすことで use-after-free エラーを検出し、
detect_stack_use_after_return
を有効化し、GCC の libstdc++ で
-D_GLIBCXX_DEBUG
を用いてコンテナオーバーフローを検出します。さらに、単一の翻訳単位(instrumented target と uninstrumented library)でビルドすることで静的関数の設定を簡略化でき、テスト設計ではグローバル状態の干渉を最小限に抑え、ASan による読み取りミスを防ぐために直接バッファ渡しを避け、ファイル入力は
memfd_create
を使用する必要があります。これらのターゲット指向な調整により、デフォルト設定で見逃されがちな重要なメモリ安全性の問題を発見でき、大規模な fuzzing キャンペーンの徹底的さを大幅に向上させます。

本文

ファジングテストで見落とされる不具合を発見するための実践ガイド

ファジングテストはソフトウェアの不具合を機械的に発見するために極めて効果的ですが、実際には軽視され、十分に利用されていないのが現状です。複雑な入力を安定的に受け入れる必要があるプログラムにおいて、もしファジングが行われていない場合、少なくとも 1 つの不具合が浮き彫りにされる可能性が極めて高いです。

過去 6 年にわたり約 1,000 プロジェクトのファジングを行った経験から、**「低く垂れ下がった果実(容易に入手できる不具合)」**を見つけるためのヒントをまとめました。

本稿では、ソースコードが利用可能な C/C++ ターゲットに対し、特に glibc ベースの Linux 配布版上で動作する AFL++ の使い方について解説します。これらのテクニックは既存のファジングテストでも適用可能であり、以前見逃された不具合を発見できる可能性があります。


(1) センサイザーとアサーションの強化

アサーションを増やすことはより効果的なファジングにつながります。Address Sanitizer(ASan) と Undefined Behavior Sanitizer(UBSan) を併用することを強く推奨します。

環境設定とコンパイルオプション

デフォルトの設定では不十分なため、以下のオプションを適切に設定してください。

afl-gcc-fast -g3 -fsanitize=address,undefined ...

ASan のカスタマイズ

ASAN_OPTIONS
環境変数で以下のように設定し、感度を調整します。デバッグ時には
symbolize=0
を除いてデフォルトに近い状態にします。

export ASAN_OPTIONS="abort_on_error=1:halt_on_error=1:symbolize=0"

特定の不具合を検出するための追加設定

ファジング速度は若干低下しますが、以下のバグ検出能力の向上には十分な価値があります。

  • use-after-return(戻り後の使用)バグ:

    ASAN_OPTIONS+=":detect_stack_use_after_return=1"
    
  • use-after-free バグおよび全アロケーションのパターン埋め込み: デフォルトでは 4KiB 分のみパターンが埋められ、それ以降の未初期化メモリ(例:

    strlen
    のような文字列操作)でのバグが見逃されることがあります。これを防ぐには以下のように設定します。

    ASAN_OPTIONS+=":max_malloc_fill_size=$((1<<30))"
    

    (注:アロケーション全体をパターンで埋めることで、永続モード (

    persistent mode
    ) におけるテストの分離性が向上します)

C++ の特別なケース

GCC の

libstdc++
とリンクする C++ をファジングする際は、追加のアサーションによりコンテナの境界外アクセスを検出するために、
-D_GLIBCXX_DEBUG
オプションを検討してください。これは ABI を変更するため注意が必要ですが、ファジングテストでは不整合が瞬時に浮き彫りになるため問題にはなりにくいです。


(2) 永続モード(Persistent Mode)を優先する

AFL++ はコードを書かずにプログラムを

in-place
でファジングすることも可能ですが、より強く推奨されるのは 永続モード です。

  • 通常のファジングに比べて約 10 倍高速。
  • 実装には
    afl-gcc-fast
    または
    afl-clang-fast
    を使用します。

自作テンプレート
fuzztmpl.c
の活用

公式テンプレートには重大な欠陥があるため、以下の自定義テンプレートを推奨します(Vim のバッファ等に読み込んで調整):

#include <unistd.h>

__AFL_FUZZ_INIT();

int main(void)
{
    __AFL_INIT();
    char *src = 0;
    unsigned char *buf = __AFL_FUZZ_TESTCASE_BUF;
    while (__AFL_LOOP(10000)) {
        int len = __AFL_FUZZ_TESTCASE_LEN;
        src = realloc(src, len);
        memcpy(src, buf, len);
        // ... send src to target ...
    }
}

重要: 元のテンプレートでは

buf
と
len
の扱いに不明瞭な制約があるため、本テンプレートの修正版を使用してください。

ソースコードの取り込み戦略

  • 翻訳ユニット(TU)の最小化: 21 世紀には 16 ビットマシンは存在しません。最大で 2 つの TU(計測済みコード用・未計測コード用)のみが必要で、後者は通常ライブラリとして扱います。
  • 効率的な include 構成:
    #include "src/utils.c"
    #include "src/parser.c"
    #include <unistd.h> // 他のソースが明示的に include しなければ見えません
    

このシンプルテクニックはビルド設定を大幅に簡素化します。

内部関数のテストとハサミ技法

プログラムの任意の関数(静的関数含む)を対象にファジング可能です。外部ヘッダーを含めずに、問題のあるシンボルのみを差し替える「ハサミ技法」で元のソースコードを変更せずにテストできます。

#define main oldmain
#  include "src/utils.c"
#  include "src/parser.c"
#undef main
#include <unistd.h>

これにより、ASan でコンパイルし、「この 50 バイトのファイルを開くとクラッシュ」といった簡潔なバグレポートを作成できます。


(4) ファジングテスト間の相互孤立化

テストは前のテストの影響を受けないべきです。永続モードではグローバル状態の残存が課題となります。

リセットすべき項目

  • グローバル変数(例:
    strtok
    の内部バッファなど)。
  • 未初期化のヒープメモリ。
  • ヒープアドレス(テスト間で変動するため、依存すると再現性が損なわれます)。

対策:

  • 未初期化メモリはゼロまたはパターンで埋める。
  • グローバル変数の使用を避けることリストに「ファジングテスト用」を追加する。

(5) テストバッファを直接渡さない(Critical Fix)

buf
と
len
をそのままターゲット関数に渡すことは最も一般的な間違いです。AFL++ が割り当てる下位バッファは
len
より大きく、ASan は入力超過読み込みを検出できないため危険です。

正しくはサイズに合ったコピーを使用

// BAD!
myprogram(buf, len); 

// GOOD: サイズに合わせたコピーを作成
char *src = ...; // ここでは適切なサイズのコピーを確保
myprogram(src, len); 
  • ヌル終端が必要な場合: 必ずヌルバイトを追加する。
  • 所有権を持つ型(
    std::string
    など)
    : コピーではなく参照渡し可能だが、ファジング用コピーを作る方が安全。
  • 所有権のない型(
    std::string_view
    など)
    : 自分自身のサイズに合ったコピーを作成する必要がある。

変更を加え、新たな発見があるか試みてください。


(6) メモリの解放は気にしない

ファジングテスト内でデストラクタの実行を省略し、メモリのみを管理するのが一般的です。

  • 理由: AFL++ はターゲットプロセスをリセットするため、メモリ不足になることはほぼありえません。
  • 利点: 未初期化メモリの汚染を防ぎ、テスト間の分離性を向上させます。

例外事項

  • デストラクタもファジング対象にしたい場合:テスト内で使用する。
  • ファイルディスクリプタなどの他のリソースを使い尽くすリスクがある場合:クリーンアップが必要な場合があります。
  • アリーナアロケーションを使用している場合:解放を気にする必要はありません(アドレスが安定するため)。

(7) メモリアルファイルディスクリプタによる名目パス対策

多くの悪質なインターフェースは「ファイル名」のみを受け付け、自らを開くことを強いることがあります。並列ファジングや SSD の摩耗を考慮し、メモリアルファイルディスクリプタ(

memfd_create
) を使用します。

実装例

int fd = memfd_create("fuzz", 0);
assert(fd == 3); // ファイルディスクリプタが 3 に割り当てられるように仮定
while (...) {
    ftruncate(fd, 0);
    pwrite(fd, buf, len, 0);
    // /proc/self/fd/3 を名目パスとして使用
    myprogram("/proc/self/fd/3");
}
  • pwrite
    を使用することで、オフセットをファイル先頭(0)に固定できます。
  • ファイルはプロセス固有のため、並列ファジングにも対応可能です。

ディレクトリオブジェクトへの対応

  • 直接パス渡し:
    myprogram(fd);
  • FILE 型を受け付ける場合*:
    /proc
    パスではなく、
    fdmemopen
    を使用して作成し、
    fclose
    の心配をせずに渡します。
    myprogram(fdmemopen(buf, len, "rb"));
    

(8) ターゲットのバッファサイズを削減する

「寛容な」巨大な固定バッファ(例:65536 バイト)はバグを隠す原因となります。最悪ケース(オーバーフロー)への到達時間を増やしすぎないよう、バッファサイズを大幅に削減してください。

  • 推奨動作: 最大値(65536 など)から 16 など非常に小さなサイズに変更する実験を行ってください。
  • メリット: 短いバッファでクラッシュを見つけた場合、入力拡張して元のサイズでもクラッシュさせるのが容易です。これにより、入力の特性をより深く探索できます。

結論とサンプル

上記のテクニックは、本来気づかれなかった不具合を発見するために役立ちます。さらに望ましいのは、これらのファジング技術への認識が、ソフトウェア開発初期段階でのバグ防止に寄与することです。

  • テンプレート:
    fuzztmpl.c
    を活用し、堅牢なツールを活用してください。
  • スピード: これらのノウハウにより数分でファジングテストを構築できます。
  • 注意点: 手軽さゆえに慎重さを欠き、結果の記録・カタログ化がおろそかになる傾向があるため注意が必要です。

数千プロジェクトのファジングを通じて蓄積されたこれらの知見は、すぐに活用できる資産となります。

同じ日のほかのニュース

一覧に戻る →

2026/11/02 0:58

Show HN: HackerBooks – ハッカートビューのように、HN で言及された本のためのサービス

## Japanese Translation: このテキストは、マウス使用よりも効率を優先したアプリケーション内でのキーボードナビゲーションの習得に必要な手順を提供しています。核心的なメッセージは、特定のキーが本間の移動や異なるコンテンツビューへの瞬時のアクセスを可能にする直接コマンドとして機能することです。例えば、`/` を入力するとフォーカス検索バーが有効化され、`j` または `k` を押すことで家(Home)行から手を離さずにリスト内で縦方向に移動できます。`Enter` を押すとフォーカスされた本が開かれ、`Esc` はウィンドウを閉じたり前の画面に戻ったりします。また、`g` の組み合わせ(例:`g h`, `g t`, `g m`)は、ホーム、全時間最高位、最も推奨されるなどの特定セクションへの直接ジャンプを可能にします。さらに、`?` はヘルプコマンドを表示します。これらのショートカットにより、マウスへの依存が軽減され、カテゴリへの高速アクセスやデジタルライブラリの滑らかな管理が実現されます。結果として、このシステムはユーザーに対しインターフェースに対する即時の制御力を付与し、基本的なナビゲーションタスクを迅速なアクションに変換することで、全体の生産性と使いやすさを向上させます。なお、このガイドは現在の機能への参照ツールとしての役割に限定されています。

2026/10/30 13:17

Nibnib:解凍速度が極めて高速な画像圧縮

## Japanese Translation: nibnib イメージ形式は、RP2350 マイクロコントローラ上で高速かつ決定論的なデコードを目的とした専用圧縮方式である。入力バイト 1 つあたり 2 ピクセルの並列デコードを行い、約 6 クロックサイクルで 1 ピクセル当りのデコードを完了し、4bpp の圧縮比を実現する。絶対値カラーを保持する標準的なパレット形式とは異なり、nibnib はパレットにカラーデルタを格納し、Floyd-Steinberg エラー拡散法を用いて人間の視覚感度特性をモデル化することで滑らかな領域での画質向上を図る。デコード処理は完全に決定論的であり、直前までにデコードされた最終ピクセルを 2 倍とし、ストリームからバイトを読み込みパレットでアップルックして加算し、入力バイト 1 つあたり 2 ピクセルの 16bpp(RGB 565)を生成する。一方、エンコーディングは非対称であり大幅に低速である。可能となるパレットとコードワードの組み合わせに対して探索を行い、立方体を小さなデルタ値および加重付きガウスランダムエントリで構成した初期化から始め、高品質な複製へデコード可能なエンコーディングを選択する。その貪欲的な左から右への探索手法のため、現時点ではシャープなエッジの右側に残留アーティファクトが生じるが、将来のバージョンでは右から左またはブーストロホン方式によるエンコーディングによりこの影響を低減することが可能である。イメージのレイアウトは、2 バイトで幅と高さを格納するヘッダー、256 エントリの 32 ビットパレット、そして各行が 2 ピクセルに続き ((width − 2)/2) バイトのパレットインデックスを持つ構成となっている。追加的なメタデータフィールドは存在せず、この形式はアーカイブストレージではなくリアルタイムレンダラーとの緊密な統合を意図している。元々 RP2350 での DVI 出力実験として開発された nibnib は、Apache License 2.0 または MIT ライセンスのいずれかを選択して vic-2350 リポジトリで入手可能である。

2026/10/30 12:06

新しい 3D テルマール化装衣が物体を赤外線カメラから消し去る

## Japanese 翻訳: 科学者が世界初の 3 次元熱的ステルス cloak を開発・検証しました。この装置は、物体を赤外線カメラから隠すだけでなく、極端な温度からも保護します。以前には特定の熱方向にのみ制限されていた 2 次元バージョンとは異なり、本システムは物体の形状や熱の接近方向に関わらず、熱エネルギーを隠された物体の周りに導きます。その結果、該区域は IR イメージングにおいて熱的に不存在するようになります。これは、3D メタルプリンティングでアルミニウム格子構造を製造し、残りの空間にゴム様の低い熱伝導率を持つ断熱材で充填することで実現されました。この cloak は、独立して 3 方向に構造が調整可能な新しい格子ベースの材料を使用し、より広い範囲の熱伝導率を実現することで、理想的なステルス特性に近い性能を達成します。赤外線カメラによる試験では、隠された領域周囲に熱が導かれながら周囲の温度パターンが維持され、内部温度が一様に保たれたことが確認されました。さらに、人頭形状などの複雑な 3D ジオメトリも成功して隠匿されています。この革新は、これまでの性能限界を克服し、複雑なジオメトリの保護を可能にする点において、熱管理技術における大きな飛躍を示します。潜在的な応用分野には、敏感な微チップの保護、電子機器の冷却、ならびに人員や装備を熱検知から守る防衛システムが含まれます。将来の研究では、これらの cloak が外部源だけでなく、隠された物体自体が生み出す熱を能動的に操作するように進化させることを目指しています。本研究は、イリノイ大学アーバナ・シャンペーン校のスェリー・チャン教授(Shelly Zhang)とデンマーク技術大学のアレクサンダー・シグムンド教授(Ole Sigmund)によって *Nature Communications* に掲載されました。研究支援は、国立科学財団、ビルーム財団、および空軍科学研究局から受けています。

AFL++ を活用したより効果的なファスティングテストのためのヒント | そっか~ニュース