世界を動かす技術を、日本語で。

Linuxカーネルにおけるヒッグス・バグソン

概要

  • Gord という取引データ管理システムで、再現困難な higgs-bugson が発生
  • NFS+Kerberos認証 環境下で、ファイルコピー時に稀に -EACCES(Permission denied) エラー
  • バグ再現と原因特定のため、 FUSEファイルシステムbpftrace など多様な手法を利用
  • 原因は NFSクライアントのGSSシーケンス番号管理の不整合 による署名検証失敗
  • 過負荷時の再送信 で発生しやすく、根本的な解決にはカーネル側の修正が必要

GordのNFS+Kerberos環境で発生した謎のバグ調査記

  • 取引データを管理・配布する Gordシステム で、稀に -EACCES(Permission denied) エラー発生
  • NFSv3 のデフォルトセキュリティは脆弱で、 Kerberos認証 を併用
  • Kerberos利用時、ユーザー認証情報は rpc_gssdデーモン 経由でカーネルに供給
  • ファイルコピー時、権限設定が正しいにも関わらず、偶発的に失敗
  • Kerberos無効化 でエラーが消失し、認証関連の問題と推測

バグ再現への挑戦と調査手法

  • 長時間の書き込みテストや 大量並列コピー で再現性を検証
  • FUSE(Filesystem in USErspace) でメモリ上にランダムファイルを生成し、軽量なテスト環境構築
  • bpftrace でカーネル関数の戻り値(-EACCES)やコールスタックをリアルタイム監視
  • パケットキャプチャ(PCAP) と組み合わせて、問題発生時の詳細な状況を記録

バグの核心:GSSシーケンス番号の同期ズレ

  • NFSの RPCリクエスト はXIDで識別され、GSS認証は シーケンス番号 で署名
  • サーバ過負荷時、クライアントが同じXIDでリクエストを再送信
  • 再送信時、 新しいGSSシーケンス番号 が割り当てられる
  • サーバからのレスポンスが遅延し、古いGSSシーケンス番号で署名された応答が届く
  • カーネルは最新のシーケンス番号で検証するため、 署名不一致(GSS_S_BAD_SIG) で失敗
  • 3回連続で失敗すると、 -EACCES が返される
  • 再送信が連鎖的に失敗 することで、現象が自己増幅

再現性・本番との差異

  • テスト環境では 小型NFSサーバ で意図的に過負荷をかけ、同時多発的にバグを再現
  • 本番環境では、通常1〜2ジョブのみ失敗し、同時多発は稀
  • 再現性の低さ が調査を困難にしていた要因

まとめと教訓

  • NFS+Kerberos利用時の再送信と認証情報管理 の複雑さ
  • カーネルやプロトコルの 実装上の罠 が実運用で顕在化するリスク
  • eBPF/bpftraceやFUSE など現代的なツールの活用による効率的なデバッグ
  • 根本的な解決には NFSクライアントのGSSシーケンス番号管理ロジック の見直しが必要
  • ネットワーク・認証系の問題 は、偶発的エラーが深刻な障害の前兆となる可能性

参考用語

  • higgs-bugson :再現困難なバグの俗称
  • NFS(Network File System) :ネットワーク越しにファイルシステムを共有するプロトコル
  • Kerberos :チケットベースの認証プロトコル
  • rpc_gssd :NFS用Kerberos認証情報を管理するデーモン
  • FUSE :ユーザー空間でファイルシステムを実装できる仕組み
  • eBPF/bpftrace :Linuxカーネルの動的トレースツール
  • GSSAPI :汎用セキュリティサービスAPI
  • XID :RPCリクエストの識別子
  • GSSシーケンス番号 :Kerberos認証のための連番

Hackerたちの意見

「Higgs Bugson」って言葉、めっちゃ好き!普段はただ「このシステムは幽霊が出る」って呼んでるけど、こっちの方が断然いいね。

幽霊?いや、完全に憑かれてるよ。

よくあるハイゼンバグに慣れてたけど、Higgs-Bugsonの方が面白いと思う。

どんな時でも魔法なんてないよ。すべての振る舞いにはどこかに理由があるんだ。

https://lists.openwall.net/linux-kernel/2025/03/19/1374

新旧問わず、開発者にはカーネルに入るコミットメッセージにもっと注意を払ってほしいな。内容を本当に理解するには専門家が必要だけど、コミットメッセージの一般的なフォーマットやレイアウトは勉強になるよ。コミットメッセージは、読者やレビュアーが状況を把握するのに役立つし、下から上に積み上げていくためにも重要なんだ。開発チームが世界中に分散してるからこそ、こういう知識の整理が必要で、後世に残すためにも大事だよね。同僚に肩を叩いて「ちょっとこれ承認してくれない?ただの修正だから」って言うのとは全然違う。

「通常のタイムアウトロジックは、必要な場合に再送信を処理できます。」NFSはTCPかUDPで動かせるけど、UDPを使ってるときに再送信は発生するの?

そうだよ!LinuxのNFSの再送信ロジックは、トランスポートに依存してないんだ(mount.nfsretransオプションを見てみて)。不思議なことに、TCPで動かしてると、NFS/SunRPCレベルとTCPレベルの両方で再送信が発生することもあるよ、設定次第だけどね。

これを強調したいな:>「KerberosでのNFSは安全でシンプル、実績もある。クレイジーなアーキテクチャがこんなにうまくいくなんて、バグがカーネルに現れたよ :-)」

すごくうまく動いてるからカーネルにバグが出た :-) ここで何を強調したいの?ほとんどのコードにはバグがあるよ。これは1997年に説明された実際の動作に従わなかった誰かのミスで、ミスは起こるものだよ。「安全」、「シンプル」、「戦闘テスト済み」、「クレイジーなアーキテクチャなし」のどれがこれを否定すると思う?それともCIFSやCephにはバグがないと思ってる?

Linuxカーネルは、もっと良いテスト方法を取り入れるべきだよ。今はほとんど肉体労働のCIに頼ってるから、正しく証明されたコードや不変契約に基づいてないんだよね。

「ヒッグス・バグソン」って呼ぶのはあんまり意味がないよね。ヒッグスには不確実なところも再現が難しいところもないし。見つけるのに時間がかかったのは、生成の断面積がすごく低いこと、崩壊のサインがバックグラウンドから分けにくいこと、存在していた特定のエネルギースケールがはっきりしていなかったこと、そしてLHCを作るのが(控えめに言って)難しくて高額だったから。ざっくり言うと、昔の物理学者としては悪い例えだけど、巨大なトウモロコシ畑の中で特定の種類の虫が隠れているのを見つけるのに、すごく弱い光を探している感じかな。しかも視力がすごく悪いから、想像もつかないほど優れた新しい眼鏡を発明しないといけなかった。さらに、探し始める前に、スイッチを入れたときに溶けないように新しいタイプの冷却装置を発明して、信じられないほど巨大な懐中電灯を作るために痛いほどの時間とお金を使わないといけなかった。もし、ほぼ確実に存在するソフトウェアのバグを見つけるのに、世界中のGPUクラスターの半分を3年間使わないといけないなら、それがヒッグス・バグソンだね。

本番環境で現れて、デバッグしようとすると消えちゃうバグは、だいたい「ハイゼンバグ」って呼ばれるね。

NFSについては、昔働いてたヘッジファンドのCTOの言葉が好きなんだ。「NFSはヘロインみたいなもんだ。最初はすごく感じるけど、結局は人生を台無しにする」って(ここは、NFSを使ってほぼすべてのことをやってた。異なるアプリケーションがNFSマウントの共有ファイルを介して通信してたし、ユーザーデスクトップ[Windows]とサーバー[Linux]の間で両方の権限を使うという変な設定もあった)。

こういうレビューに対して僕が抱く問題は、絶対的な表現になってることだね。確かにNFSは僕の人生を台無しにするかもしれないけど、他の選択肢よりも台無しにする度合いが少なければ、それでも勝ちだよ。

2020年代に入ってから、Linuxカーネルのリリース品質が少し落ちてる気がするのは僕だけ?90年代中頃以来、こんなに悪いのは初めてだと思う。ここ数年の経験では、xfsでデータ破損バグに遭遇したり、Wi-Fiのファームウェアやカーネルのリグレッション、amdgpuでのグラフィックアーティファクトやハードクラッシュがあった。2020年以前のメインラインリリースはすごく安定してたから、カーネルを疑う前に自分を疑うよ。みんなの頑張りには深く感謝してるけど、全体の複雑さがついに古いリリースエンジニアリングプロセスを圧倒する tipping point に達してる気がする。

なんでNFSv3を使ってるのか、NFSv4じゃなくて?

Kerberosは「楽しい」。いろんなWindowsのバージョンや暗号標準、Linuxのいろんなバージョン、成熟度の異なるJavaアプリの間で認証を提供するためにKerberosを使ってるシステムを管理しなきゃいけなかった。常に変な挙動の原因になってて、すべてのシステムの内部に埋もれなきゃいけなかった。記事とは直接関係ないけど、愚痴を言いたかっただけ。

NFSは普通、LinuxとWindowsが混在する環境でしか使われないよね。最も簡単な解決策は、NFSを避けること、特にWindowsをね。NFSだけでも十分厄介なのに、Windowsはもう狂気だよ。