テック技報最新号へ →
セキュリティ

ASan はリングバッファー内の範囲外読み取りを見逃す:UBSan と手動ポイズニングで補う

libslirp の CVE-2026-9539(4.9.2 で修正)は、有効データの末尾を越えても読み取りが確保済みのリングバッファー内に収まるため、ファザーが到達しても ASan では検知できなかった。UBSan の整数オーバーフロー検出を足すか、バッファーの未使用領域を ASan のポイズニングで禁止にして検知する。

@MalwareBibleJP · 2026-10-31
#fuzzing#asan#ubsan#memory-safety#libslirp#secure-coding

なぜ ASan で見つからないか

  • ASan は「確保されていないメモリー」へのアクセスを検知する。リングバッファーのように大きく確保した領域の中で、論理的に無効なデータ部分を読んでも、確保済み領域なのでエラーにならない。
  • 自前のメモリープール、アリーナ、固定長バッファーを使うコードは同じ盲点を持つ。

補う方法(Quarkslab の解説)

  1. UBSan で整数の異常を検知する: 読み取り量の計算でアンダーフローが起きていた。UBSan の整数オーバーフロー検出を有効にして再ビルドすると、ここで検知できる。
    bash
    clang -fsanitize=address,undefined,integer -fno-sanitize-recover=all ...

    (-fsanitize=integer は符号なしのラップアラウンドも検知するため、正当なラップを多用するコードでは誤検知が出る。対象を絞って使う。)

  2. 未使用領域を ASan でポイズニングする: バッファー全体をアクセス禁止として記録し、使用中の範囲だけを許可、使い終えた範囲は再び禁止にする。整数計算の副作用に頼らず、不正な読み取りそのものを検知できる。
    c
    #include <sanitizer/asan_interface.h>
    ASAN_POISON_MEMORY_REGION(buf, cap);           // 確保直後に全体を禁止
    ASAN_UNPOISON_MEMORY_REGION(buf + off, len);   // 有効データを書いた範囲だけ許可
    ASAN_POISON_MEMORY_REGION(buf + off, len);     // 消費したら再び禁止
  3. 状態を持つプロトコルのファジング: LibAFL-QEMU を基盤に、TCP の状態変化ごとの差分スナップショットを保存し、そこから別のパケットを送って探索する構成が紹介された。スナップショットと QEMU 向け ASan の併用ができないため、見つけたパケット列を別プロセスで再実行して ASan 検査とカバレッジ記録を行う。

防御側の対応

  • libslirp を 4.9.2 以降に更新する(QEMU などのユーザーモードネットワークで使われる)。悪用にはゲスト内の root か CAP_NET_RAW が必要。

出典

X の元の投稿を開く