OpenResty XRay は、弊社が改良した動的トレーシング技術に基づいて開発されたパフォーマンス分析および問題診断プラットフォームです。Linux カーネル、Go、OpenResty/Nginx、PHP、Python、Perl など、さまざまな技術スタックやソフトウェアを分析・診断することができます。OpenResty XRay の開発とテストの過程で、オープンソースソフトウェアやツールチェーンに多くのバグを発見することがよくあります。OpenResty XRay動的トレーシング技術を前例のないレベルに引き上げています。弊社の様々な技術スタックやソフトウェア向けの分析ツールは、SystemTapDTraceeBPF 向けのオープンソースツールよりもはるかに複雑です。そのため、弊社のテストスイートは、Linux カーネル、eBPFLLVMSystemTapGDB などに前例のない負荷をかけることがよくあります。高負荷の方がより深いバグを捕捉することができます。

本記事では、Linux カーネルのトレースサブシステムにおける 2 つのバグについて紹介します。これらのバグは、Linux の動的トレーシング関連のすべてのツールやフレームワークに影響を与えます。OpenResty XRay はこれらのバグの 1 つを回避することができ、もう 1 つのバグについても顧客を保護することができます。

ユーザー空間メモリ読み取り時のカーネルデッドロック

Linux の公式メインラインカーネルの 5.19 から 6.2 シリーズには、比較的深刻な退行がありました。mm サブシステムのカーネル開発者がユーザー空間メモリ読み取りの実装方法を変更したことで、NMI コンテキスト(perf イベントなど)でトレースサブシステムがユーザー空間メモリを読み取る際にデッドロックが発生するようになりました。このバグは 6.3 シリーズで修正されました。オープンソースの eBPF ツールチェーン(perf や bcc を含む)はすべてこの影響を受けています。弊社はオープンソースの SystemTap にこのバグを回避するパッチを提出し、OpenResty XRay プラットフォームの eBPF+ ランタイムでこの問題を解決しました。このバグは、OpenResty XRay テストスイートを実行することで再現できます。

このことから、最新のメインラインカーネルをより積極的にテストする必要があることがわかります。そうしなければ、このような深刻な退行が多くのカーネルバージョンシリーズに影響を与えてしまいます。

弊社の経験上、Ubuntu や Debian は通常パッチをバックポートしません。一方、Red Hat は非常に勤勉にこれらのパッチをバックポートします(もちろん、時には Red Hat も問題のあるパッチをバックポートして新しいバグを導入することがあります。以下でそのような事例を見ることになります)。

カーネル内の x86 ブレークポイント挿入におけるデータ競合

Linux の公式メインラインカーネルの 5.2 から 5.4 シリーズには、深刻な退行がありました。ある開発者が x86(x86_64 を含む)上の動的ブレークポイント挿入コードをリファクタリングする際に、一時的に判断を誤りました。彼は並行性や並列アクセスの可能性を全く考慮せず、マルチスレッドシナリオを単純にシングルスレッドシナリオとして扱い、カーネルコンテキスト内でグローバル変数を保護なしに読み書きしました。これは極めて危険な行為です。

興味深いことに、元々影響を受けていなかった CentOS/RHEL 7 の 3.10 カーネルも影響を受けることになりました。これは Red Hat が勤勉にこの問題のあるパッチをバックポートしたためです。しばらくして Red Hat はこの退行の修正もバックポートしました。Ubuntu と Debian の 5.2 〜 5.4 カーネルは、通常通りこの修正をバックポートしませんでした。このバグは通常、多数の CPU コアがある場合にのみ発生します。OpenResty XRay 製品において、このバグを持つすべてのカーネルをブラックリストに登録しましたが、ユーザーは強制オプションを使用して私たちの保護を回避することができます。

このバグは、動的トレース、eBPF、SystemTap、Dtrace などに関連するすべての x86 ツールに影響を与えます。これを回避する(既知の)方法はありません。なぜなら、それがあまりにも低レベルで、特定のアーキテクチャの機械語命令レベルで直接発生するからです。

結論

本記事では、OpenResty XRay を使用して発見した Linux カーネルのトレースに関する 2 つのバグについて紹介しました。これらのバグは広範囲に影響を及ぼし、動的トレース技術に依存する多くのツールやフレームワークに影響を与えました。これらのバグが発生した原因と影響、そしてメインラインカーネルで修正された時期について説明しました。この記事が、同様の問題に直面する他の開発者やユーザーの助けとなり、定期的なカーネルのテストと更新の重要性に対する認識を高めることを願っています。

OpenResty XRay について

OpenResty XRay動的トレーシング製品であり、実行中のアプリケーションを自動的に分析して、パフォーマンスの問題、動作の問題、セキュリティの脆弱性を解決し、実行可能な提案を提供いたします。基盤となる実装において、OpenResty XRay は弊社の Y 言語によって駆動され、Stap+、eBPF+、GDB、ODB など、様々な環境下で複数の異なるランタイムをサポートしております。

著者について

章亦春(Zhang Yichun)は、オープンソースの OpenResty® プロジェクトの創始者であり、OpenResty Inc. の CEO および創業者です。

章亦春(GitHub ID: agentzh)は中国江蘇省生まれで、現在は米国ベイエリアに在住しております。彼は中国における初期のオープンソース技術と文化の提唱者およびリーダーの一人であり、Cloudflare、Yahoo!、Alibaba など、国際的に有名なハイテク企業に勤務した経験があります。「エッジコンピューティング」、「動的トレーシング」、「機械プログラミング」 の先駆者であり、22 年以上のプログラミング経験と 16 年以上のオープンソース経験を持っております。世界中で 4000 万以上のドメイン名を持つユーザーを抱えるオープンソースプロジェクトのリーダーとして、彼は OpenResty® オープンソースプロジェクトをベースに、米国シリコンバレーの中心部にハイテク企業 OpenResty Inc. を設立いたしました。同社の主力製品である OpenResty XRay動的トレーシング技術を利用した非侵襲的な障害分析および排除ツール)と OpenResty XRay(マイクロサービスおよび分散トラフィックに最適化された多機能ゲートウェイソフトウェア)は、世界中の多くの上場企業および大企業から高い評価を得ております。OpenResty 以外にも、章亦春は Linux カーネル、Nginx、LuaJITGDBSystemTapLLVM、Perl など、複数のオープンソースプロジェクトに累計 100 万行以上のコードを寄与し、60 以上のオープンソースソフトウェアライブラリを執筆しております。

翻訳

英語版の原文と日本語訳版(本文)をご用意しております。読者の皆様による他の言語への翻訳版も歓迎いたします。全文翻訳で省略がなければ、採用を検討させていただきます。心より感謝申し上げます!