見出し画像

Rustでファジングテスト

こんにちは、株式会社LabBase(旧POL)でエンジニアをしているミズノです。
Cargoには便利なツールチェインがありますが、今回はファジングをサポートするcargo-fuzzを紹介します。

ファジングとは

ファジング英語: fuzzing)とは、コンピュータプログラムヘの入力として、無効なデータ、予期しないデータ、ランダムなデータを用いた自動化ないし半自動化されたソフトウェアテストの手法である。

Wikipedia

ファジングはセキュリティの調査などでも利用される方法ですが、ランダムなインプットを作成し、予期せぬバグを見つけることに役立ちます。

cargo-fuzz

cargo-fuzzはLLVMのlibFuzzerをベースにしたファジングサポートを提供します。インストールは以下のコマンド。

$ cargo install cargo-fuzz 

初期化

ツールチェインを入れたら、開発中のクレートで以下のコマンドを実行します。このコマンドでプロジェクト内にfuzzフォルダが作られると思います。これでファジングのコードをかける準備ができます。

$ cargo fuzz init

fuzz/fuzz_targetsフォルダ内のファイルがテストコードです。今回はi32型へのパースする処理に対してファジングを試します。サンプルコードは以下の通りです。

#![no_main]
use arbitrary::Arbitrary;
use libfuzzer_sys::fuzz_target;

#[derive(Arbitrary, Debug)]
struct Input {
    s: String,
}

fuzz_target!(|input: Input| {
    use fuzziest::parse_i32;
    parse_i32(&input.s);
});

Nightlyバージョンで実行

ファジングはstableバージョンのrustcではなく、Nightlyバージョンで動作します。事前にNightlyバージョンに変更しましょう。
Nightlyバージョンのインストールはこちら

$ rustup install nightly

デフォルトを切り替えます。

$ rustup default nightly

これで準備が整いました。それでは実行してみましょう。

$ cargo fuzz run [ターゲット名]

ターゲット名は以下のコードで調べることができます。

$ cargo fuzz list

ターミナル上で、次々にテストが実行されます。エラーが発生すると、以下のような表示が出ます。

────────────────────────────────────────────────────────────────────────────────

Failing input:

	fuzz/artifacts/fuzz_target_1/crash-32b2dcbdb3688e6114fabbf2a754789d8997efa2

Output of `std::fmt::Debug`:

	Input {
	    s: "エラーが起こった入力値",
	}

Reproduce with:

	cargo fuzz run fuzz_target_1 fuzz/artifacts/fuzz_target_1/crash-32b2dcbdb3688e6114fabbf2a754789d8997efa2

Minimize test case with:

	cargo fuzz tmin fuzz_target_1 fuzz/artifacts/fuzz_target_1/crash-32b2dcbdb3688e6114fabbf2a754789d8997efa2

────────────────────────────────────────────────────────────────────────────────

Minimize test case with  の下にコマンドが表示されていますが、これを実行すると今回エラーを発見したテストケースを保存し、ピンポイントで実行できるようになります。ファジングはマシン自体にかなり負荷をかけたり、時間がかかる場合があります。毎回テストを待つのは開発速度を落とすことにもなるので、効率よく試せるのはありがたいですね。

Rustの開発体験はCargoのおかげでとても良いですね。意外と知らないツールチェインがあるので開発体験を改善したい人はぜひ調べてみると良いと思います。

そして弊社ではRustゴリゴリ描きたいエンジニアを絶賛募集しています。お気軽にカジュアル面談を申し込んでください。カジュアル面談は選考要素0ですので、本当に気軽にご利用いただいて大丈夫です。
お待ちしています。

この記事が気に入ったらサポートをしてみませんか?