rust-sanitizers-miri について
sanitizer と Miri による Rust の実行時安全性検証を案内するエージェント向けスキルです。設定、テスト実行、レポートの読み方、CI への組み込みを扱います。
主な機能
- 01ASan、TSan、MSan、UBSan の実行
- 02Miri による unsafe Rust の検査
- 03sanitizer レポートの解釈
- 04Miri フラグの設定
- 05CI への Miri テストの統合
活用シーン
- 01unsafe Rust の未定義動作の調査
- 02sanitizer によるメモリエラーの検出
- 03Rust テストでのデータ競合の診断
- 04CI への Miri 検査の追加
インストール
コマンドをコピーしてターミナルで実行します。
$
npx skills add https:/ / github.com/ mohitmishra786/ low-level-dev-skills --skill rust-sanitizers-miriインストール後、Claude Code で/rust-sanitizers-miriを入力して読み込まれたか確認します。
同梱ファイルreferences/miri-ub-patterns.md
詳細
Rust のサニタイザーと Miri
目的
エージェント向けに、Rust の実行時安全性を検証する方法を説明します。RUSTFLAGS を使った ASan/TSan/MSan/UBSan、unsafe コードのコンパイル時 UB 検出に使う Miri、サニタイザーレポートの読み解き方を扱います。
使用する場面
- 「Rust コードで AddressSanitizer を実行する方法を教えてください」
- 「unsafe Rust のチェックに Miri を使う方法を教えてください」
- 「Rust プログラムで ThreadSanitizer を実行する方法を教えてください」
- 「unsafe Rust に UB があるかもしれません。検出する方法を教えてください」
- 「Rust の ASan レポートの読み解き方を教えてください」
- 「Rust のサニタイザーは stable で実行できますか?」
ワークフロー
1. Rust のサニタイザー(nightly が必要)
Rust のサニタイザーには nightly と、互換性のあるプラットフォームが必要です。
# Install nightly
rustup toolchain install nightly
rustup component add rust-src --toolchain nightly
# AddressSanitizer (Linux, macOS)
RUSTFLAGS="-Z sanitizer=address" \
cargo +nightly test -Zbuild-std \
--target x86_64-unknown-linux-gnu
# ThreadSanitizer (Linux)
RUSTFLAGS="-Z sanitizer=thread" \
cargo +nightly test -Zbuild-std \
--target x86_64-unknown-linux-gnu
# MemorySanitizer (Linux, requires all-instrumented build)
RUSTFLAGS="-Z sanitizer=memory -Zsanitizer-memory-track-origins" \
cargo +nightly test -Zbuild-std \
--target x86_64-unknown-linux-gnu
# UndefinedBehaviorSanitizer
RUSTFLAGS="-Z sanitizer=undefined" \
cargo +nightly test -Zbuild-std \
--target x86_64-unknown-linux-gnu
-Zbuild-std はサニタイザーを使って標準ライブラリを再ビルドします。正確な結果を得るために必要です。
2. stable でサニタイザーを使う方法
stable Rust では、サニタイザーがあらかじめ設定された Docker イメージと cross ツールを使うか、nightly イメージを使って Docker コンテナー内で cargo test を実行します。
または、nightly を使わずに、より簡単に UB をチェックするには、次のようにします。
# cargo-sanitize (wrapper)
cargo install cargo-sanitize
cargo sanitize address
3. Rust での ASan 出力の読み解き方
==12345==ERROR: AddressSanitizer: heap-buffer-overflow on address 0x602000000050
READ of size 4 at 0x602000000050 thread T0
#0 0x401234 in myapp::module::function /src/main.rs:15
#1 0x401567 in myapp::main /src/main.rs:42
0x602000000050 is located 0 bytes after a 40-byte region allocated at:
#0 0x... in alloc::alloc::alloc ...
#1 0x... in myapp::create_buffer /src/main.rs:10
Rust 固有のパターン:
| ASan エラー | Rust で考えられる原因 |
|---|---|
heap-buffer-overflow | unsafe によるスライス範囲外へのアクセス |
use-after-free | Vec の再割り当て後に unsafe ポインターを使用 |
stack-use-after-return | ローカル変数への参照を返す |
heap-use-after-free | drop() または Box::from_raw の後に使用 |
4. Miri — 未定義動作のインタープリター
Miri は Rust MIR を解釈し、サニタイザーでは見逃す可能性がある UB を検出します。
# Install Miri (requires nightly)
rustup +nightly component add miri
# Run tests under Miri
cargo +nightly miri test
# Run specific test
cargo +nightly miri test test_name
# Run a binary under Miri
cargo +nightly miri run
# Run with Stacked Borrows model (strict aliasing)
MIRIFLAGS="-Zmiri-strict-provenance" cargo +nightly miri test
# Disable isolation (allow file I/O, randomness)
MIRIFLAGS="-Zmiri-disable-isolation" cargo +nightly miri test
5. Miri が検出するもの
// 1. Dangling pointer use
unsafe {
let x = Box::new(42);
let ptr = Box::into_raw(x);
let _ = Box::from_raw(ptr); // drop
let _val = *ptr; // Miri: use of dangling pointer
}
// 2. Invalid enum discriminant
let x: u8 = 3;
let e = unsafe { std::mem::transmute::<u8, MyEnum>(x) };
// Miri: enum value has invalid tag
// 3. Uninitialized memory read
let uninit: MaybeUninit<u32> = MaybeUninit::uninit();
let val = unsafe { uninit.assume_init() }; // Miri: reading uninitialized bytes
// 4. Stacked borrows violation
let mut x = 5u32;
let ptr = &mut x as *mut u32;
let _ref = &x; // shared reference
unsafe { *ptr = 10; } // Miri: mutable access while shared borrow exists
// 5. Data races (with threads)
// Miri simulates sequential execution and detects races via Stacked Borrows
6. Rust の ThreadSanitizer
RUSTFLAGS="-Z sanitizer=thread" \
RUST_TEST_THREADS=8 \
cargo +nightly test -Zbuild-std \
--target x86_64-unknown-linux-gnu 2>&1 | head -50
TSan の出力:
WARNING: ThreadSanitizer: data race (pid=12345)
Write of size 4 at 0x7f... by thread T2 (mutexes: write M1):
#0 myapp::counter::increment src/counter.rs:10
Previous read of size 4 at 0x7f... by thread T1:
#0 myapp::counter::get src/counter.rs:5
7. MIRIFLAGS による Miri の設定
| フラグ | 効果 |
|---|---|
-Zmiri-disable-isolation | I/O、時計、乱数を許可 |
-Zmiri-strict-provenance | 厳密なポインター来歴(LLVM より厳格) |
-Zmiri-symbolic-alignment-check | より厳格なアライメントチェック |
-Zmiri-check-number-validity | 浮動小数点数/整数の妥当性をチェック |
-Zmiri-num-cpus=N | N 個の CPU をシミュレート(並行処理用) |
-Zmiri-seed=N | ランダムスケジューリングのシード |
-Zmiri-ignore-leaks | メモリーリークエラーを抑制 |
-Zmiri-tag-raw-pointers | 生ポインターの来歴を追跡 |
8. CI への統合
# GitHub Actions
- name: Miri
run: |
rustup toolchain install nightly
rustup +nightly component add miri
cargo +nightly miri test
env:
MIRIFLAGS: "-Zmiri-disable-isolation"
- name: ASan (nightly)
run: |
rustup component add rust-src --toolchain nightly
RUSTFLAGS="-Z sanitizer=address" \
cargo +nightly test -Zbuild-std \
--target x86_64-unknown-linux-gnu
関連スキル
- Rust のパニックを GDB/LLDB でデバッグするには、
skills/rust/rust-debuggingを使用します - C/C++ のサニタイザーの使い方や比較については、
skills/runtimes/sanitizersを使用します - unsafe Rust のパターンやレビュー用チェックリストについては、
skills/rust/rust-unsafeを使用します - サニタイザーエラーを引き起こす入力を生成するには、
skills/runtimes/fuzzingを使用します
コメント
Markdown 対応