
Linuxカーネルの競合状態をKCOVトレースを用いて調査するためのツールキット:並行実行とメモリアクセスを可視化するGUIおよびターミナルビューアに加え、自動A-B-A順序テストを提供します。
これは、Linux カーネルの競合状態を調査するためのツール群であり、また一般的なカーネルデバッグにも使用できます。
発表ブログ記事も参照してください: https://projectzero.google/2026/09/maccconc-race-condition.html
現在、3つのツールがあります:
これは Google の公式サポート製品ではありません。このプロジェクトは Google Open Source Software Vulnerability Rewards Program の対象外です。
まず、コミット dc5c6d008f48 を含むバージョンの LLVM を入手します。つまり、リリースブランチからではなく HEAD からビルドしたもの、またはバージョン >=23 のビルドです。 そのようなビルドは、例えば https://apt.llvm.org/ から入手できます。 Google の社員の場合は、http://go/maccconc-kernel-build-notes を参照してください。
必要なパッチが適用されたカーネルツリーを https://github.com/thejh/linux の kcov-tracing-full ブランチから入手します。
カーネルを設定およびビルドする際は、make 変数
CC / LLVM / LLVM_PREFIX を
https://docs.kernel.org/kbuild/llvm.html に記載されているとおりに設定し、正しい LLVM
ツールチェーンが使用されるようにしてください。
次の環境変数を設定すると、実行された基本ブロックに関するより明確な情報が得られ (GUI 用)、末尾呼び出し最適化による紛らわしいコールスタックを回避できます:
export KCFLAGS="-fno-optimize-sibling-calls -mllvm -sanitizer-coverage-prune-blocks=false"
カーネルを通常どおり設定します。既存の設定から始めない場合は、
make [...] kvm_guest.config から始めると便利かもしれません。
次のカーネル設定フラグが設定されていることを確認してください (例えば、ncurses 設定 UI make [...] nconfig を使用するか、.config の末尾に貼り付けることで設定できます):
# for core functionality
CONFIG_SMP=y
CONFIG_NR_CPUS=4
CONFIG_KASAN=y
CONFIG_KASAN_OUTLINE=y
CONFIG_KCOV=y
CONFIG_KCOV_EXT_RECORDS=y
CONFIG_KCOV_MEMORY=y
CONFIG_KALLSYMS_ALL=y
# to give the GUI information about source lines and inlining
CONFIG_DEBUG_INFO_DWARF5=y
# for communicating with the GUI
CONFIG_VSOCKETS=y
CONFIG_VIRTIO_VSOCKETS=y
CONFIG_VIRTIO_PCI=y
# for maximizing the potential for race conditions
CONFIG_PREEMPT=y
# for making virtual addresses at runtime the same as in vmlinux
CONFIG_RANDOMIZE_BASE=n
# needed for several samples
CONFIG_TMPFS=y
RCU が関与する競合状態をテストしたい場合は、次の設定も有効にできますが、これにより大幅な速度低下が発生し、現在は GUI を使用する場合にのみ正しく動作することに注意してください。
CONFIG_RCU_EXPERT=y
CONFIG_RCU_STRICT_GRACE_PERIOD=y
テストしたいカーネル機能は、モジュールとしてではなく、カーネルに組み込んでコンパイルされていることを確認してください。
ユーザー空間ツールはホストマシンでビルドすることを推奨します。特に GUI はゲストではなくホストで実行するように設計されています。
git とビルド依存関係をインストールします。Debian の場合:
sudo apt install git build-essential pkg-config libcapstone-dev libdw-dev libglfw3-dev
このリポジトリをクローンした後、サブモジュールをダウンロードします:
git submodule update --init --recursive
make でビルドします。
必要なカーネル設定フラグを有効にし、Linux ディストリビューションなどのディスクイメージを使用すれば、ビルドしたカーネルを通常の QEMU VM で起動できます。しかし、推奨される方法は、代わりに次のように kvmtool をインストールすることです:
git clone https://git.kernel.org/pub/scm/linux/kernel/git/will/kvmtool.git
cd kvmtool
make
make install
その後、次のようにしてビルドしたカーネルを起動できます ($HOME/bin が $PATH にあると仮定します):
lkvm run --kernel [path to kernel tree]/arch/x86/boot/bzImage --vsock 5 --console virtio
これにより、ホストファイルシステムの読み取り専用ビューが /host にマウントされた環境でシェルが得られます。最小限の rootfs は、/bin、/lib、/usr などへのこのホストファイルシステムへのシンボリックリンクで主に構成されています。/ と /host はどちらも 9p ファイルシステムです。
各起動後に、ゲストで debugfs と tmpfs を手動でマウントしてください:
sh-5.3# mount -t debugfs none /sys/kernel/debug
sh-5.3# mount -t tmpfs none /tmp
sh-5.3#
テストケースは、4つの関数を定義する C コードです:
void test_setup(void) { [...] }
void test_thread1(void) { [...] }
void test_thread2(void) { [...] }
void test_end(void) { [...] }
テストケースの各実行ごとに、最初に test_setup() が実行され、次に test_thread1() と test_thread2() が並行して実行され、最後に test_end() が実行されます。
テストケースは、次のように共有ライブラリとしてビルドする必要があります:
$ cc -shared -o [name].so [name].c -fPIC
testcase/ フォルダ内のサンプルテストケースは、次のように make でもビルドできます:
$ make testcase/demo-dup-vs-close.so
cc -shared -o testcase/demo-dup-vs-close.so testcase/demo-dup-vs-close.c -Wall
kcov-autorace ツールは、A-B-A 実行順序を自動的に探索できます。A-B-A 順序とは、スレッド A がある地点まで実行され、次にスレッド B が完全に実行され、その後スレッド A が実行を完了するものです。
ホストでテストケースをビルドした後、kcov-autorace ヘルパーを使用してゲストで実行できます。例えば:
sh-5.3# cd /host/{path to checkout on the host}
sh-5.3# ./kcov-autorace testcase/demo-dup-vs-close.so
loading kallsyms
RCU state (excluded): base=ffffffff82770100 len=500
loading testcase
initializing kcov
collecting A-B coverage
dup(5) = 6 (success)
testing candidates
dup(5) = -1 (Bad file descriptor)
dup(5) = -1 (Bad file descriptor)
dup(5) = -1 (Bad file descriptor)
dup(5) = 5 (success)
dup(5) = 6 (success)
dup(5) = 6 (success)
dup(5) = 6 (success)
dup(5) = 6 (success)
dup(5) = 6 (success)
dup(5) = 6 (success)
dup(5) = 6 (success)
stats: injection-failed:0 wait-timeout:7 reordered:4
sh-5.3#
これは、close(5) と dup(5) の A-B-A 順序が存在し、その結果 dup(5) が 5 を返すことを示しています。
kcov-autorace と他のツールは、ハードコードされたスピンウェイトタイムアウト
SPIN_LIMIT を使用していることに注意してください。
kcov-terminal ツールは、手動で指定した順序制約でテストケースを実行するために使用できます。これらは完全な順序を指定するものではなく、代わりに「A は B より前に発生すべき」という一連のルールです。
このツールは、kcov-autorace と同様にゲストで使用されます。
fstat() による UID と GID の読み取りが fchown() に対してアトミックでないことを示す順序制約で実行する、テストケース demo-inode-attr-change の使用例:
sh-5.3# ./kcov-terminal testcase/demo-inode-attr-change.so
uid=0 gid=0
===== filtered to interference set, no RCU core =====
LEGEND:
type: R=read W=write M=modify(read+write) F=free A=atomic