Red Hat Enterprise Linux Tunable を使用して CVE-2017-5754、CVE-2017-5715 および CVE-2017-5753 で提供されているマイクロコードとセキュリティーパッチによるパフォーマンスへの影響を制御する方法

更新 -

概要

Red Hat Customer Portal Labs は、お使いのシステムがこの CVE の影響を受けるかどうかを検出する Spectre And Meltdown Detector を提供します。

先日公開された投機的実行に関する CVE は、各種プロセッサーのアーキテクチャーおよびプラットフォームに影響を与える、潜在的な 3 つの攻撃に対応しています。プラットフォームごとに、必要とする修正は多少異なります。この修正を適用するには、多くの場合、ハードウェアベンダーから提供されるマイクロコードのアップデートが必要になります。

これら 3 つの CVE で説明されているセキュリティーの脆弱性は、x86 (Intel チップセットおよび AMD チップセット)、System Z、Power、ARM を含む主要なハードウェアプラットフォームの最新のマイクロプロセッサーおよびオペレーティングシステムで発生しています。

Red Hat では、これらのセキュリティーの脆弱性に対応する、更新版のカーネルを公開しました。また、弊社ではセキュリティーの追加設定を必要としないことが優先されるため、上述のパッチはデフォルトで有効になっています。投機的実行は、パフォーマンスを最適化する技術で、このアップデートで (カーネルおよびマイクロコードの両方が) 変更され、ワークロードに関するパフォーマンスが低下する可能性があります。

システムが十分に保護されていると確信しているお客様は、保護メカニズムの一部またはすべてを無効にすることもできます。このアーティクルでは、セキュリティー上、保護メカニズムを有効にする選択をしたシステム管理者向けに、修正を有効または無効にした時のパフォーマンスを評価する方法について説明しています。

Retpoline カーネル

Red Hat は、バージョン RHEL-7.6 までの Red Hat Enterprise Linux で、カーネルの間接分岐に「Retpoline」コードシーケンスを使用し、これらの分岐と投機的実行を分離します。 上記の OS リリースで、Skylake より前の Intel プロセッサーの場合、Spectre バリアント 2 に対する緩和策として、ibrs 機能の代わりに Retpoline が使用されます。Skylake の場合は、Retpoline ではなく ibrs が使用されます。

今後リリースされる Red Hat Enterprise Linux 7.7 では、Skylake を含むすべての Intel プロセッサーの新規インストールはすべて、
Retpoline をデフォルトで使用する予定です。ただし、RHEL 7.6 以前のバージョンから RHEL-7.7 以降のバージョンへのアップデートでは、アップグレード前に使用していた既存の Spectre バリアント 2 への緩和策が維持されます。

ibrs を使用するアップデート済みのシステムはいずれも、カーネル起動時のコマンドラインに "spectre_v2=retpoline" フラグを追加するだけで、いつでも ibrs から Retpoline に切り替えることができます。

パッチを当てた GCC コンパイラーには Retpoline サポートが含まれ、これは Retpoline のパッチを当てたカーネルとサードパーティーのモジュールのコンパイルに必要となります。 アップデート前に提供されたサードパーティーのカーネルモジュールはいずれも、ソースから再度コンパイルする必要があります。 SystemTap は、カーネルモジュールを使用してカーネル領域でコードを実行する一例です。したがって、SystemTap にもパッチを当てたコンパイラーが必要になります。 カーネルモジュールが正常に動作しない場合は、カーネルモジュールのソフトウェアプロバイダーに連絡し、アップデートをリクエストしてください。

保護メカニズムの無効化

x86 の Red Hat Enterprise Linux カーネルでは、3 つの debugfs tunable により、アップデートしたカーネルの各種パッチの動作を制御します。 これら 3 つのパッチには、マイクロコードのアップデートが必要になります。このアップデートは、ハードウェアプラットフォームプロバイダーから取得してください。

これらの debugfs tunable は、システムの起動時にカーネルコマンドラインで、またはランタイム時に debugfs コントロールから有効または無効にできます。この tunable は、pti (Page Table Isolation)、ibrs (Indirect Branch Restricted Speculation)、および retp (Retpoline) を制御します。CPU の種類によっては、起動時に検出したアーキテクチャーを保護するのに必要となるため、Red Hat では、これらの各機能をデフォルトで有効にしています。

このような保護メカニズムに対するセキュリティーの緩和策を無効にしてパフォーマンスロスを回復する場合には、これらの変更は、ランタイム時に設定するか、再起動しても永続されるように設定できます。

永続的に無効にする手順 (再起動後も有効)

1 つ目の方法として、以下のフラグを追加してカーネルのコマンドラインからパラメーターを無効にし、カーネルを再起動してこの設定を有効にする方法があります。これを設定するフラグがいくつかあります。たとえば以下のようになります。

     spectre_v2=off nopti

注記: 各パラメーターを個別に無効にできます。パフォーマンスの性質上、すべてのパラメーターを同時に無効にする必要はありません。

Red Hat では、'grubby' を使用してこのような変更を管理することをお勧めしています。 このツールの効果的な使用方法については、『システム管理者のガイド』の grubby のセクション を参照してください。

ランタイム時に無効にする手順 (システムを再起動すると設定が元に戻る)

2 つ目の方法として、以下の 3 つのコマンドを実行して、ランタイム時に無効にする方法があります。変更はすぐに有効になり、再起動の必要はありません。

    # echo 0 > /sys/kernel/debug/x86/pti_enabled
    # echo 0 > /sys/kernel/debug/x86/retp_enabled
    # echo 0 > /sys/kernel/debug/x86/ibrs_enabled

注記: この方法では、debugfs ファイルシステムをマウントしておく必要があります。さらに、上記の "retp_enabled" の変更は、RHEL7 システムのランタイム時のみ可能です。RHEL 6 システムでは、この tunable は読み取り専用となります。RHEL 7 では、debugfs はデフォルトでマウントされています。RHEL 6 では、以下のコマンドを実行して手動でマウントできます。

  mount -t debugfs nodev /sys/kernel/debug

変更の確認

これら CVE の修正が無効になっていることを確認するには、以下の 3 つのファイルの内容を確認して、値がすべて 0 に設定されていることをチェックします。

    # cat /sys/kernel/debug/x86/pti_enabled
    # cat /sys/kernel/debug/x86/retp_enabled
    # cat /sys/kernel/debug/x86/ibrs_enabled

上述の CVE フラグを無効にした場合でも、一部のアプリケーションではパフォーマンスロスがわずかに発生する可能性があります。

詳細:

ここからは、各 CVE バリアントの詳細を説明します。

  • CVE-2017-5753 (バリアント #1/Spectre) は、分岐中の境界検査に関する脆弱性となります。この問題は、カーネルパッチで修正されます。バリアント #1 の保護は常に有効になっており、このパッチを無効にすることはできません。バリアント #1 に対する Red Hat のパフォーマンステストでは、測定可能な影響は見られませんでした。

  • CVE-2017-5715 (バリアント #2/Spectre) は、間接分岐ポイズニング攻撃で、データ漏洩が発生する可能性があります。この攻撃により、仮想化ゲストが、ホストシステムからメモリーを読み込むことができるようになります。この問題は、マイクロコードの適用に加え、ゲストとホストの仮想化ソフトウェアにカーネルと仮想化のアップデートを適用することで修正されます。この脆弱性には、マイクロコードとカーネルのアップデートパッチが必要になります。バリアント #2 の動作は、マイクロコードと連動する ibrs tunable または retp tunable で制御します。引き続き ibpb tunable を確認できますが、読み取り専用で、カーネルにより設定されます。

  • CVE-2017-5754 (バリアント #3/Meltdown) の脆弱性では、投機的なキャッシュロードを使用して、ローカルの攻撃者がメモリーの内容を読み取ることができます。この問題は、カーネルパッチで修正されます。バリアント #3 の動作は、pti tunable (nopti/pti_enabled) で制御します。

前述したように、ハードウェアベンダーからマイクロコードのアップデートを提供された場合は、そのアップデートをハードウェアにインストールしてバリアント 2 から保護する必要があります。マイクロコードのアップデートについては、ハードウェアベンダーにお問い合わせください。

pti (Page Table Isolation)

"nopti"/pti_enabled は、ユーザーランドで実行中に、カーネルのページテーブルを分離させる KPTI (Kernel Page Table Isolation) 機能を制御します。この機能は、 CVE-2017-5754 (別称、バリアント #3 (Meltdown)) に対応しています。

お客様およびベンダーは、システムの起動時に nopti をカーネルコマンドラインに渡すか、ランタイム時に以下の debugfs コントロールを使用して動的に、PTI 機能を無効にできます。

    # echo 0 > /sys/kernel/debug/x86/pti_enabled

ibrs (Indirect Branch Restricted Speculation)

"noibrs"/ibrs_enabled は、(マイクロコードのアップデート後に) SPEC_CTRL が cpuid に存在する場合に、SPEC_CTRL の MSR (model-specific register) で IBRS 機能を制御します。ibrs_enabled を 1 (spectre_v2=ibrs) に設定すると、カーネルは ibrs で実行します。これにより、カーネル領域を攻撃から保護します (ハイパースレッドおよび同時マルチスレッド攻撃からも保護されます)。IBRS を 2 (spectre_v2=ibrs_always) に設定すると、ユーザーランドおよびカーネルの両方を ibrs で実行します。この設定は、ハイパースレッドおよび同時マルチスレッド攻撃からもユーザー領域を保護し、以前の AMD プロセッサーの一部でもデフォルトになります (ファミリー 10h、12h、および 16h)。この機能は、CVE-2017-5715 (バリアント #2) に対応します。

ibrs_enabled を 3 に設定すると、ユーザーランドのみを ibrs で実行します。これは、Retpoline (spectre_v2=retpoline,ibrs_user) と併用して、ibrs_always と同様のセキュリティーを提供しますが、パフォーマンスのオーバーヘッドは減ります。

マイクロコードの ibrs 実装は、システムの起動時に、noibrs をカーネルのコマンドラインに渡すか、以下の debugfs コントロールを動的に使用して無効にできます。

    # echo 0 > /sys/kernel/debug/x86/ibrs_enabled

ibpb (Indirect Branch Prediction Barriers)

注記: ibpb チューニングノブは読み取り専用になり、ibrs または retp を設定すると、カーネルにより設定されます。ibrs と同様に、ibpb を正しく動作 (および設定) させるために、マイクロコードをアップデートする必要があります。

ibpb は、(マイクロコードのアップデート後に) IBPB_SUPPORT または SPEC_CTRL のいずれかが cpuid に存在する場合に、PRED_CMD の MSR (model-specific register) で IBPB 機能を制御します。ibpb_enabled を 1 に設定すると、間接分岐予測のコンテンツをフラッシュする IBPB バリアがユーザーモードまたはゲストモードで実行され、ユーザーおよびゲストモードが同一ホストの別のアプリケーションまたは仮想マシンを攻撃しないようにコンテキストが切り替えられます。仮想マシンを、別の仮想マシンから保護するには、ibrs_enabled を 2 に設定していても、ibpb_enabled=1 を設定する必要があります。この機能は、CVE-2017-5715 (バリアント #2) に対応します。

アーキテクチャーのデフォルト

デフォルトでは、アーキテクチャーに適用する適切な tunable は、検出されたアーキテクチャーに従って、システムの起動時に自動的に有効になります。 Intel のガイダンス (https://software.intel.com/security-software-guidance/api-app/sites/default/files/Retpoline-A-Branch-Target-Injection-Mitigation.pdf) によると、Retpoline と IBRS の両方は、Spectre バリアント 2 の緩和策です。Retpoline は、パフォーマンスへの影響は少なくなる見込みです。

Intel CPU がベースの Red Hat Enterprise Linux のデフォルト設定:

以下は、カーネルコマンドラインパラメーターが指定されていない場合の、カーネルのデフォルト設定です。

Skylake より前の CPU すべてと、 新しい Red Hat Enterprise Linux 7.7 以降のインストールでサポートされる Skylake の場合:

pti=1 ibrs=0 retp=1 ibpb=1-> 修正のバリアント #1 #2 #3

RHEL-7.7 より前のインストールでサポートされる Skylake CPU の場合:

pti=1 ibrs=1 retp=0 ibpb=1-> 修正のバリアント #1 #2 #3

マイクロコードのアップデートが提供されていない、以前の Intel システムの場合:

pti=1 retp=1 ibrs=0 ibpb=0 -> 修正のバリアント #1 #3

AMD CPU がベースの Red Hat Enterprise Linux のデフォルト設定:
基本的なハードウェア実装が異なるため、AMD X86 システムはバリアント #3 の攻撃を受けません。正しいデフォルト値は、起動シーケンス時の動的チェックに基づいて、AMD ハードウェアに設定されます。

pti=0 ibrs=0 ibpb=1 retp=1 -> 修正のバリアント #1 #2 (マイクロコードのアップデートが適用された場合)
pti=0 ibrs=2 ibpb=1 retp=1 -> 修正のバリアント #1 #2 (マイクロコードをアップデートせずに間接分岐予測を無効にできる、以前のプロセッサーの場合)

注記: tunable を表示するために、ベンダーが提供するマイクロコードパッチを適用する必要があります。

s390x デフォルト
s390x は Spectre (バリアント 1 と 2) の影響を受けますが、Meltdown (バリアント 3) の影響は受けません。

この機能がマイクロコードで利用可能な場合は、バリアント 1 (ppa15) の緩和策は常に有効です。これは動的に有効または無効に切り替えることができないため、カーネルパラメーター noaltinstr からでしか、命令パッチを完全に無効にすることはできません。
バリアント 2 の場合、緩和策は bpb 機能から実行できます。ppa15 の場合は、この機能がマイクロコードで利用可能な場合は、この緩和策は常に有効です。これは、動的に有効または無効にすることはできませんが、デフォルトで有効になっているカーネルパラメーター nobp があり、これはカーネルパラメーター nobp=off で無効にできます。(このパッチは big hammer アプローチを採用していますが、これがパフォーマンスに与える影響は非常に大きくなります)。

IBM POWER デフォルト
Spectre (バリアント 1 と 2) の緩和策は、ベンダーからのシステムファームウェアで提供されます。Linux では現在、これらの緩和策を無効にする tunable はありません。バリアント 3 の緩和策は、Linux カーネルが提供し、システムファームウェアに依存することはありません (ただし、システムファームウェアによるサポートがある場合には、最適化された実装が使用されます)。これはデフォルトで有効になっており、カーネルコマンドラインのパラメーター (no_rfi_flush または nopti) で起動時に無効にするか、ランタイムで以下のいずれかの tunable で無効にできます。

zstream/errata の最初のアップデートの場合:
/sys/devices/system/cpu/rfi_flush

今後、zstream/errata にアップデートがあれば、上記の tunable は次のように変更してください:
/sys/kernel/debug/powerpc/rfi_flush

自動化のチューニング

以下の方法で、カスタマイズした tuned-adm プロファイルに上述のチューニングコマンドを追加すると、これらの設定を制御できます。

「How to create a customized tuned profile」

注記 バリアント #1 #2 #3 のセキュリティー修正は、デフォルトで有効になります。したがって、セキュリティー修正を無効にする場合に限り、カスタムの tuned プロファイルを作成する必要があります。