8 KLPによるライブカーネルパッチ #
このドキュメントでは、KLP (カーネルライブパッチ)適用テクノロジーの基本原理について説明するとともに、SLE Live Patchingサービスの使用ガイドラインを提供します。
KLPは、Linuxカーネルを停止することなく、実行時にカーネルのパッチを適用するライブパッチ適用テクノロジーです。これにより、ミッションクリティカルなシステムにとって重要なシステムのアップタイム、つまりシステムの可用性が最大化されます。また、このテクノロジーによってカーネルの動的なパッチ適用が可能になるため、ユーザは、予定されたダウンタイムまで延期することなく、重要なセキュリティアップデートをインストールできます。
KLPを有効にするには、ライブパッチサービスを有効にし、パッチが利用可能になったときにパッチを適用する以外に特別な手順は必要ありません。サービスは通常のソフトウェア管理システムの一部で、パッチは通常のパッケージ管理ツールを使用してインストール(または削除)されます。特別なカーネルをインストールまたは手動で選択する必要はありません。
KLPパッチは、カーネル内の関数全体を置換することを目的としたカーネルモジュールです。カーネルライブパッチは基本的に、パッチが適用されたコードとカーネルのベースコードを実行時に統合するためのカーネル内インフラストラクチャを提供します。
このドキュメントで提供される情報は、AMD64/Intel 64およびPOWERアーキテクチャに関連しています。KLPはXenハイパーバイザーでサポートされています。
8.1 カーネルライブパッチの利点 #
KLPを使用したカーネルライブパッチは、重大な脆弱性の問題やシステムの安定性の問題があることがわかり、できるだけ早く修正する必要がある場合に、迅速に緊急対処するためのものです。緊急を要しない、予定されたアップデートには使用されません。
カーネルライブパッチの一般的な使用事例としては、起動に15分以上かかることも珍しくない、大容量のRAMを搭載したメモリデータベースなどのシステム、再起動なしで数週間または数カ月を要する大規模なシミュレーション、多数の顧客に継続的なサービスを提供するインフラストラクチャのビルディングブロックなどがあります。
カーネルライブパッチの主な利点は、短時間であってもカーネルを停止する必要がない点です。
KLPは、RPMパッケージ内の.ko
カーネルモジュールです。パッケージのインストールまたは更新時に、insmod
コマンドを使用してカーネルに挿入されます。カーネルライブパッチは、関数が実行中であってもカーネル内の関数全体を置換します。必要に応じて、更新されたKLPモジュールが既存のパッチを置換することもあります。
さらに、カーネルライブパッチは効率的です。他の標準のLinuxテクノロジーを活用するので、カーネルライブパッチには少量のコードしか含まれていません。
8.2 カーネルライブパッチの低レベルの関数 #
カーネルライブパッチは、ftraceインフラストラクチャを使用してパッチを実行します。AMD64/Intel 64アーキテクチャにおける実装は次のとおりです。
カーネル関数にパッチを適用する場合、カーネルライブパッチは、新しい関数へのジャンプを挿入するために、関数の冒頭にスペースを必要とします。このスペースは、関数のプロファイリングをオンにしたGCCによってカーネルのコンパイル時に割り当てられます。具体的には、5バイトの呼び出し命令がカーネル関数の冒頭に挿入されます。このようにインストルメント化されたカーネルの起動時に、プロファイリング中の呼び出しが5バイトのNOP (操作なし)命令に置換されます。
パッチの適用が開始されると、最初のバイトがINT3 (ブレークポイント)命令に置換されます。これにより、5バイトの命令を置換する際の不可分性が確保されます。他の4バイトは、新しい関数のアドレスに置換されます。最後に、最初のバイトがJMP (ロングジャンプ)命令コードに置換されます。
システム内の他のCPUの推論的なデコードキューをフラッシュするために、このプロセス全体を通してIPI NMIが使用されます。これにより、ごく短時間であってもカーネルを停止することなく、新しい関数に切り替えることができます。IPI NMIによる割り込みはマイクロ秒単位で測定することができ、いずれの場合でもカーネルの実行中に発生するので、サービスの中断とは見なされません。
呼び出し元にパッチが適用されることはありません。代わりに、呼び出し先のNOPが新しい関数へのJMPに置換されます。JMP命令は永久に残ります。これにより、構造体内でも関数ポインタが考慮されるので、パッチが適用されない場合に備えて古いデータを保存しておく必要はありません。
ただし、これらの手順だけでは十分ではありません。関数は不可分的に置換されるわけではないので、カーネルの一部で修正された新しい関数が引き続き、別の場所で古い関数を呼び出したり、その逆の呼び出しが行われたりすることがあります。関数インタフェースのセマンティクスがパッチで変更された場合は、混乱が生じます。
そのため、すべての関数が置換されるまで、カーネルライブパッチは、トランポリンに基づいた、RCU(読み取り-コピー-更新)に似たアプローチを使用して、それぞれのユーザ側スレッド、カーネルスレッド、カーネル割り込みで一貫性を確保します。カーネルの最初と最後にスレッド別のフラグが設定されます。これにより、古い関数は常に別の古い関数を呼び出し、新しい関数は常に新しい関数を呼び出すようになります。すべてのプロセスに「新しいユニバース」のフラグが設定されると、パッチの適用が完了し、トランポリンを削除することができます。コードは、パッチが適用された各関数の過度に長いジャンプを除き、パフォーマンスに影響を及ぼすことなく、フルスピードで動作することができます。
8.3 SLE Live Patchingのアクティベーション #
SLE Live Patchingをシステムでアクティベートするには、次の手順に従います。
SLESシステムを登録する必要があります。システムの登録は、システムのインストール中、またはインストール後に、YaSTの
モジュール(yast2 registration
)を使用して行います。SLESシステムはすでに登録しているものの、SLE Live Patchingをまだアクティベートしていない場合は、yast2 registration
コマンドを実行し、 をクリックします。入手可能な拡張機能のリストで
を選択し、 をクリックします。ライセンス条項を確認し、
をクリックします。SLE Live Patchingの登録コードを入力し、
をクリックします。Live Patching
とSLE Live Patching Lifecycle Data
パターンがインストール用に自動的に選択される必要があり、依存関係を満たすために追加のパッケージがある場合があります。
8.4 パッチのインストールと削除 #
このセクションでは、KLPパッチを検索、インストール、および削除する方法について説明します。
8.4.1 KLPパッチのインストール #
新しいパッチをインストールする前に、
klp status
コマンドを実行して、現在のステータスをクエリします。このステータスは、in_progress
ではなく、ready
である必要があります。前のパッチインストールが完了するまで、新しいパッチを適用することはできません。スリープ状態のすべてのプロセスがウェイクアップし、処理を完了するまで、古いカーネル関数の呼び出しが完全になくなるわけではありません。これにはかなりの時間がかかることがあります。古いカーネル関数を使用するスリープ状態のプロセスがセキュリティ上の問題になるとは考えられません。(長期のin_progress
ステータスの管理については、8.6項 「カーネル実行スレッドのスタック」を参照してください。)通常のパッケージ管理システム、
zypper
またはYaSTを使用して、使用可能なパッチを表示およびインストールします。次の例では、使用可能なパッチを検索し、最新のパスをインストールします。すべてのパッチを順番にインストールする必要はありません。使用可能な複数のパッチがある場合は、最新のものをインストールします。tux >
sudo
zypper se kernel-livepatch | kernel-livepatch-5_3_18-8_16-default | Kernel live patch module | package | kernel-livepatch-5_3_18-8_19-default | Kernel live patch module | package | kernel-livepatch-5_3_18-8_22-default | Kernel live patch module | packagetux >
sudo
zypper in kernel-livepatch-5_3_18-8_22-default
8.4.2 KLPパッチの削除 #
KLPパッチを削除する必要がある場合は、他のパッケージと同様にzypper
を使用します。zypper
を使用して、インストール済みのライブパッチパッケージを一覧にし、kernel-livepatch
を検索します。
tux >
sudo
zypper se -kernel-livepatch | kernel-livepatch-5_3_18-8_16-default | Kernel live patch module | package | kernel-livepatch-5_3_18-8_19-default | Kernel live patch module | package i | kernel-livepatch-5_3_18-8_22-default | Kernel live patch module | package
zypper
を使用してパッチを削除します。tux >
sudo
zypper rm kernel-livepatch-5_3_18-8_22-defaultinitrd
が自動的に再構築するのを待機し、マシンを再起動します。
8.5 klp
ツール #
いくつかのカーネルライブパッチ管理タスクはklp
ツールで簡素化することができます。使用可能なコマンドは次のとおりです。
klp status
カーネルライブパッチ適用の全体的なステータス(
ready
またはin_progress
)を表示します。klp patches
ロードされたKLPパッチのリストを表示します。
klp blocking
カーネルライブパッチ適用の完了を妨げているプロセスのリストを表示します。デフォルトでは、PIDのみが列挙されます。
-v
を指定すると、コマンドラインが出力されます(可能な場合)。-vv
は、スタックトレースを表示します。
詳細については、man klp
を参照してください。
8.6 カーネル実行スレッドのスタック #
カーネルライブパッチを処理するには、カーネルスレッドを準備する必要があります。サードパーティソフトウェアはカーネルライブパッチをサポートしていない場合があり、カーネル実行スレッドを生成する場合があります。このようなスレッドによって、パッチ適用プロセスが無期限にブロックされます。緊急措置として、0
を/sys/kernel/livepatch/*/transition/
に書き込む(アスタリスクワイルドカードをファイル名で置き換える)ことにより、すべての実行スレッドが安全チェックポイントを通過するのを待たずにパッチ適用プロセスの完了を強制することができます。この手順を実行する前に、SUSEのサポートにお問い合わせください。
8.7 パッチのライフサイクル #
ライブパッチの有効期限はzypper lifecycle
を使用して参照できます。(パッケージ
lifecycle-data-sle-module-live-patching がインストールされていることを確認してください。)
パッチの有効期限に達した場合、今後そのカーネルバージョン用のライブパッチは提供されません。ライブパッチのライフサイクル期間が終わる前に、カーネルの更新を計画してください。
zypper lifecycle
の詳細については、『管理ガイド』の「ライフサイクル情報の表示」を参照してください。
8.8 カーネルライブパッチテクノロジーの範囲 #
カーネルライブパッチは、関数の置き換えに基づいています。カーネルライブパッチでは、データ構造の変更は間接的にしか実行できません。そのため、カーネルのデータ構造の変更には特別な注意が必要です。変更が大規模な場合は、再起動が必要になることもあります。また、カーネルライブパッチでは、1つのコンパイラを使用して古いカーネルをコンパイルし、別のコンパイラを使用してパッチをコンパイルするような状況に対処できない場合があります。
カーネルライブパッチの動作により、カーネルスレッドを生成するサードパーティモジュールのサポートは限定的です。
8.9 SLE Live Patchingの範囲 #
SUSE Common Vulnerability Scoring System (CVSS; SUSE CVSSはCVSS v3.0システムをベースにしています)レベル7+脆弱性の修正や、システムの安定性またはデータの破損に関連するバグ修正は、SLEライブパッチの適用範囲内で出荷されます。前述の基準を満たすすべての種類の修正についてライブパッチを生成できるわけではありません。技術的な理由でカーネルライブパッチの生成が実行不可能な場合、SUSEは修正をスキップする権利を有します。SUSE CVSSの評価の基礎であるCVSSの詳細については、https://www.first.org/cvss/を参照してください。
8.10 サポートプロセスとの相互作用 #
SUSEのサポートを利用して技術的な問題を解決する間に、いわゆるProgram Temporary Fix (PTF)を受け取ることがあります。PTFは、SLE Live Patchingの基盤を成すパッケージをはじめ、さまざまなパッケージについて発行されることがあります。
前のセクションに記載された条件に適合するカーネルライブパッチのPTFは、通常どおりにインストールできます。SUSEでは、当該のシステムを再起動する必要がないこと、将来のライブアップデートが問題なく適用されることを確認します。
ベースカーネルについて発行されたPTFによって、ライブパッチ適用プロセスが中断されます。まず、PTFカーネル全体を実行時に置換することはできないので、PTFカーネルのインストール時には再起動が必要になります。次に、定期保守のアップデートについてライブパッチが発行された場合、PTFを置換するには、再起動がもう一度必要になります。
SLE Live Patchingの他のパッケージに関するPTFは、通常の保証を含む通常のPTFと同様に処理できます。