著者:
(1)ゼイン・ワイスマン、ウースター工科大学、マサチューセッツ州ウースター、米国{[email protected]}
(2)トーマス・アイゼンバルト、リューベック大学、リューベック、SH、ドイツ {[email protected]}
(3)Thore Tiemann、リューベック大学、リューベック、SH、ドイツ {[email protected]}
(4) Berk Sunar、ウースター工科大学、マサチューセッツ州ウースター、米国 {[email protected]}。
Linuxカーネルベースの仮想マシン(KVM)[29]は、最新のCPUで利用可能なIntel VT-xやAMD-Vなどのハードウェア支援仮想化機能を抽象化します。ネイティブに近い実行をサポートするために、既存のカーネルモードとユーザーモードに加えて、ゲストモードがLinuxカーネルに追加されます。Linuxゲストモードの場合、KVMはハードウェアをハードウェア仮想化モードに移行させ、リング0とリング3の権限を複製します。[1]
KVM では、I/O 仮想化は主に、VM を作成したプロセス (VMM またはハイパーバイザーと呼ばれる) によってユーザー空間で実行されます。これは、通常、別のハイパーバイザー プロセスを必要とした以前のハイパーバイザーとは対照的です [41]。KVM ハイパーバイザーは、各 VM ゲストに、ゲストを作成したプロセスのメモリ領域とは別の独自のメモリ領域を提供します。これは、カーネル空間から作成されたゲストにも、ユーザー空間から作成されたゲストにも当てはまります。各 VM は Linux ホスト上のプロセスにマップされ、ゲストに割り当てられた各仮想 CPU はそのホスト プロセス内のスレッドです。VM のユーザー空間ハイパーバイザー プロセスは、特権実行が必要な場合にのみ KVM にシステム コールを行うため、コンテキストの切り替えが最小限に抑えられ、VM からカーネルへの攻撃対象領域が削減されます。この設計により、あらゆる種類のアプリケーションのパフォーマンスが向上するだけでなく、個々のプログラムをサンドボックス化したり、多くの VM が同時に実行されるクラウド環境をサポートしたりするのに特に便利な軽量ハイパーバイザーの開発が可能になりました。
クラウド コンピューティングのモデルとしてますます人気が高まっているのが、サーバーレス コンピューティングです。このモデルでは、CSP がユーザーのコードを実行するサーバーのスケーラビリティと可用性を管理します。サーバーレス コンピューティングの実装の 1 つに、Function-as-a-Service (FaaS) があります。このモデルでは、クラウド ユーザーは、サービス プロバイダーのアプリケーション プログラミング インターフェイス (API) を通じて必要に応じて呼び出される関数を定義し (そのため、「Function-as-a-Service」と呼ばれます)、CSP はユーザーの関数を実行するサーバー上のリソース割り当てを管理します (そのため、「サーバーレス コンピューティング」と呼ばれます。ユーザーはサーバー管理を行いません)。同様に、Container-as-a-Service (CaaS) コンピューティングでは、コンテナー (ポータブルなランタイム パッケージ) をオンデマンドで実行します。FaaS と CaaS の集中型サーバー管理は、CSP とユーザーの両方にとって経済的に魅力的です。CSP は、ユーザーのワークロードを自由に管理し、運用コストを最小限に抑えるように最適化し、ユーザーが使用した実行時間に対して支払う柔軟な価格設定を実装できます。ユーザーはサーバー インフラストラクチャの設計や管理について心配する必要がないため、開発コストが削減され、メンテナンス コストが比較的小さく予測可能なレートで CSP にアウトソーシングされます。
FaaS および CaaS プロバイダーは、さまざまなシステムを使用して実行中の機能とコンテナーを管理します。Docker、Podman、LXD などのコンテナー システムは、サンドボックス化されたアプリケーションをあらゆる環境でパッケージ化して実行するための便利で軽量な方法を提供します。ただし、多くの従来のクラウド コンピューティングで使用される仮想マシンと比較すると、コンテナーは分離性が低く、したがってセキュリティも低くなります。近年、主要な CSP は、従来のコンテナーを軽量仮想化でサポートしてセキュリティを強化する microVM を導入しています。[1、55] KVM によるハードウェア仮想化の効率性と microVM の軽量設計により、仮想化、コンテナー化、またはコンテナーのようなシステム内のコードは、仮想化されていないコードとほぼ同じ速度で実行でき、オーバーヘッドは従来のコンテナーと同等です。
Firecracker [1] は、AWS Lambda FaaS と AWS Fargate CaaS の各ワークロードを別々の VM に分離するために AWS が開発したマイクロ VM です。x86 または ARM Linux-KVM ホスト上の Linux ゲストのみをサポートし、ゲスト システムで使用できるデバイスの数は限られています。これらの制限により、Firecracker はコード ベースのサイズと実行中の VM のメモリ オーバーヘッドが非常に軽量で、起動やシャットダウンも非常に高速です。さらに、KVM を使用すると、一部の仮想化機能がカーネル システム コールによって処理され、ホスト OS が VM を標準プロセスとして管理するため、Firecracker の要件が軽減されます。Rust で記述されたコード ベースが小さいため、Firecracker は以前のバージョンでセキュリティ上の欠陥が特定されているにもかかわらず、非常に安全であると考えられています (CVE-2019-18960 を参照)。興味深いことに、Firecracker のホワイト ペーパーでは、マイクロアーキテクチャ攻撃は攻撃者モデル [1] の範囲内であると宣言していますが、ゲスト カーネルとホスト カーネルに対する一般的な安全なシステム構成の推奨事項以外に、マイクロアーキテクチャ攻撃に対する詳細なセキュリティ分析や特別な対策が欠けています。Firecracker のドキュメントでは、具体的な対策のリストを含むシステム セキュリティの推奨事項 [8] が提供されており、これについてはセクション 2.6.1 で説明します。
2018年のメルトダウン[32]攻撃は、投機的にアクセスされたデータをキャッシュサイドチャネルにエンコードすることで、セキュリティ境界を越えてデータを盗み出すことができることを示しました。これはすぐに、Fallout [14]、Rogue In-flight Data Load (RIDL) [50]、TSX Asynchronous Abort (TAA) [50]、Zombieload [46]など、マイクロアーキテクチャデータサンプリング(MDS)と呼ばれる一連の同様の攻撃につながりました。これらの攻撃はすべて、投機的実行を悪用するために同じ一般的なパターンに従います。
(1)被害者は秘密データを扱うプログラムを実行し、秘密データはキャッシュまたはCPUバッファを通過します。
(2)攻撃者は、秘密データが必要になるとCPUが誤って予測するような特別に選択された命令を実行する。CPUは秘密データを攻撃者の命令に転送する。
(3)転送された秘密データは、攻撃者がアクセスを許可されている配列へのメモリ読み取りのインデックスとして使用され、その配列の特定の行がキャッシュされる。
(4) CPUはデータのチェックを終え、秘密データが誤って転送されたと判断し、実行状態を転送前の状態に戻しますが、キャッシュの状態は元に戻りません。 (5) 攻撃者は配列全体を調べて、どの行がキャッシュされたかを確認します。その行のインデックスが秘密データの値です。
元の Meltdown 脆弱性はキャッシュ転送をターゲットにしており、キャッシュ内に存在する任意のメモリ アドレスからこの方法でデータを抽出できました。MDS 攻撃は、オンコア マイクロアーキテクチャ内のより小さく、より具体的なバッファーをターゲットにしているため、関連性はあるものの、まったく異なる方法で軽減される別の種類の攻撃です。Meltdown は、比較的頻繁に更新されず、すべてのコア、スレッド、プロセスで共有されるメイン メモリをターゲットにしていますが、MDS 攻撃は、コアにローカルで (スレッド間で共有される場合もありますが)、実行中に頻繁に更新されるバッファーをターゲットにする傾向があります。
2.4.1 基本的な MDS バリアント。図 1 は、Intel CPU に対する主要な既知の MDS 攻撃経路と、Intel およびそれらを報告した研究者がさまざまなバリアントに付けた名前を示しています。最も大まかに言えば、Intel は、データが投機的に転送される特定のバッファーによって CPU の MDS 脆弱性を分類しています。これは、これらのバッファーがさまざまな操作に使用される傾向があるためです。RIDL MDS 脆弱性は、CPU のロード ポートからリークするバリアントの場合はマイクロアーキテクチャ ロード ポート データ サンプリング (MLPDS)、CPU の LFB からリークするバリアントの場合はマイクロアーキテクチャ フィル バッファー データ サンプリング (MFBDS) に分類できます。同様に、Intel は Fallout 脆弱性をマイクロアーキテクチャ ストア バッファー データ サンプリング (MSBDS) と呼んでいます。これは、ストア バッファーからのリークを伴うためです。ベクター レジスタ サンプリング (VRS) は、ストア バッファーを通過するときにベクター操作によって処理されるデータをターゲットとする MSBDS のバリアントです。 VERWバイパスは、
MFBDS のマイクロコード修正により、古くなった潜在的に機密のデータを LFB にロードします。漏洩の基本的なメカニズムは同じで、VERW バイパスは MFBDS の特殊なケースと見なすことができます。L1 データ エビクション サンプリング (L1DES) は MFBDS の別の特殊なケースで、L1 データ キャッシュから追い出されたデータが LFB を通過し、MDS 攻撃に対して脆弱になります。特に、L1DES は攻撃者が CPU 内の機密データの存在を実際にトリガーできるケースです (追い出すことによって)。一方、他の MDS 攻撃は、被害者のプロセスが機密データに直接アクセスして適切な CPU バッファーに取り込むことに依存しています。
2.4.2 Medusa。Medusa [37] は、Intel が MLPDS の亜種 [25] として分類した MDS 攻撃のカテゴリです。Medusa の脆弱性は、Intel プロセッサの書き込み結合 (WC) バッファ内のストアを投機的に結合するために使用する不完全なパターン マッチング アルゴリズムを悪用します。Intel は WC バッファをロード ポートの一部と見なしているため、この脆弱性を MLPDS のケースとして分類しています。Medusa の亜種には 3 つが知られており、それぞれ書き込み結合バッファの異なる機能を悪用して投機的なリークを引き起こします。
キャッシュ インデックス作成:障害が発生したロードは、一致するキャッシュ ライン オフセットを持つ以前のロードと投機的に結合されます。
非整列ストアからロードへの転送:有効なストアの後に、不整列メモリ障害をトリガーする依存ロードが実行されると、WC からのランダム データが転送されます。
シャドウ REP MOV : 障害のある REP MOV 命令の後に従属ロードが続くと、別の REP MOV のデータがリークされます。
2.4.3 TSX 非同期アボート。ハードウェア脆弱性 TSX 非同期アボート (TAA) [24] は、MDS 攻撃を実行するための異なる投機メカニズムを提供します。標準的な MDS 攻撃は、標準的な投機実行で制限されたデータにアクセスしますが、TAA は TSX によって実装されているアトミック メモリ トランザクションを使用します。アトミック メモリ トランザクションが非同期アボートに遭遇すると (たとえば、別のプロセスがトランザクションで使用するためにマークされたキャッシュ ラインを読み取ったり、トランザクションがフォールトに遭遇したりした場合)、トランザクション内のすべての操作は、トランザクション開始前のアーキテクチャ状態にロールバックされます。ただし、このロールバック中は、すでに実行を開始しているトランザクション内の命令は、他の MDS 攻撃の手順 (2) と (3) のように、投機実行を継続できます。TAA は、TSX をサポートするすべての Intel プロセッサに影響します。他の MDS 攻撃の影響を受けない特定の新しいプロセッサの場合、TAA [24] から保護するために、MDS 軽減策または TAA 固有の軽減策 (TSX の無効化など) をソフトウェアで実装する必要があります。
2.4.4 緩和策。Meltdownおよび MDS クラスの脆弱性は低レベルのマイクロアーキテクチャ操作を悪用しますが、ほとんどの脆弱な CPU ではマイクロコード ファームウェア パッチで緩和できます。
ページ テーブルの分離。歴史的に、カーネル ページ テーブルはユーザー レベルのプロセス ページ テーブルに含まれており、ユーザー レベルのプロセスが最小限のオーバーヘッドでカーネルにシステム コールを実行できるようにしています。ページ テーブル分離 (最初に Gruss らによって KAISER [19] として提案) は、必要最小限のカーネル メモリのみをユーザー ページ テーブルにマップし、カーネルのみがアクセスできる 2 番目のページ テーブルを導入します。ユーザー プロセスがカーネル ページ テーブルにアクセスできないため、カーネル メモリのごく一部を除くすべてのアクセスは、Meltdown 攻撃が開始される下位レベルのキャッシュに到達する前に停止されます。
バッファ上書き。オンコアCPUバッファを標的とするMDS攻撃には、より低レベルでより的を絞った防御が必要です。Intelは、第1レベルデータ(L1d)キャッシュ(キャッシュタイミングサイドチャネル攻撃の一般的な標的)がフラッシュされるか、VERW命令が実行されたときに脆弱なバッファを上書きするマイクロコードアップデートを導入しました[25]。カーネルは、信頼できないプロセスに切り替えるときにバッファ上書きをトリガーすることで、MDS攻撃から保護できます。
バッファ上書き緩和策はMDS攻撃をその発生源で標的としますが、控えめに言っても不完全です。SMTが有効になっている場合、プロセスは同じコアで同時に実行されているスレッドからの攻撃に対して脆弱なままです(両方のスレッドが脆弱なバッファを共有し、アクティブなプロセスがどちらのスレッドでも実際に変更されないため)。さらに、最初のバッファ上書きマイクロコードの更新の直後に、RIDLチームは、一部のSkylake CPUでバッファが古くて機密性の高い可能性のあるデータで上書きされ[50]、緩和策を有効にしてSMTを無効にしても脆弱なままであることを発見しました。さらに他のプロセッサはTAA MDS攻撃に対して脆弱ですが、非TAA MDS攻撃に対しては脆弱ではなく、バッファ上書きマイクロコードの更新を受け取っていないため、MDS攻撃を防ぐためにTSXを完全に無効にする必要があります[20、24]。
2.5 スペクター
2018年、Jan HornとPaul Kocher [30]はそれぞれ独立して最初のSpectre亜種を報告しました。それ以来、多くの異なるSpectre亜種[22、30、31、33]とサブ亜種[10、13、16、28、52]が発見されています。Spectre攻撃は、CPUにアーキテクチャ上アクセスできないメモリに投機的にアクセスさせ、データをアーキテクチャ状態に漏らします。したがって、すべてのSpectre亜種は3つのコンポーネントで構成されています[27]。
最初のコンポーネントは、投機的に実行される Spectre ガジェットです。Spectre の亜種は通常、悪用する予測ミスの原因によって区別されます。たとえば、条件付き直接分岐の結果は、パターン履歴テーブル (PHT) によって予測されます。PHT の予測ミスにより、ロード命令とストア命令の境界チェックが投機的にバイパスされる可能性があります [13、28、30]。間接ジャンプの分岐先は、分岐ターゲット バッファー (BTB) によって予測されます。攻撃者が BTB の予測ミスの結果に影響を与えることができれば、投機的なリターン指向プログラミング攻撃が可能になります [10、13、16、30]。リターン命令の実行中に戻りアドレスを予測するリターン スタック バッファー (RSB) による予測についても同様です [13、31、33]。最近の結果では、RSB がアンダーフローした場合、一部の最新 CPU が戻りアドレス予測に BTB を使用していることが示されています [52]。 Spectre攻撃のもう一つの原因は、ストアからロードへの依存関係の予測です。ロードが以前のストアに依存しないと誤って予測された場合、古いデータに対して投機的に実行され、投機的なストアバイパスにつながる可能性があります[22]。これらのガジェットはすべてデフォルトでは悪用できませんが、ここで説明する他の2つのコンポーネントに依存しています。
2 つ目の要素は、攻撃者が前述のガジェットへの入力をどのように制御するかです。攻撃者は、ユーザー入力、ファイル コンテンツ、ネットワーク パケット、またはその他のアーキテクチャ メカニズムを通じて、ガジェットの入力値を直接定義できる可能性があります。一方、攻撃者は、ロード値インジェクション [12] または浮動小数点値インジェクション [42] を通じて、ガジェットに一時的にデータを注入できる可能性があります。攻撃者は、投機ウィンドウ中にどのデータまたは命令がアクセスまたは実行されるかに影響を与えることができれば、ガジェットの入力をうまく制御できます。
3 番目のコンポーネントは、投機的なマイクロアーキテクチャ状態をアーキテクチャ状態に転送し、投機的にアクセスされたデータを永続的な環境に持ち出すために使用される隠れチャネルです。キャッシュ隠れチャネル [39、40、54] は、被害者のコードが投機的にアクセスされた秘密データ [30] に応じて一時的なメモリ アクセスを実行する場合に適用されます。秘密が投機的にアクセスされ、オンコア バッファーにロードされた場合、攻撃者は MDS ベースのチャネル [14、46、50] に依存して、持ち出されたデータを攻撃者のスレッドに一時的に転送し、そこでデータがキャッシュ隠れチャネルなどを介してアーキテクチャ状態に転送されます。最後に、被害者が秘密データに依存するコードを実行する場合、攻撃者はポートの競合を観察することで秘密を知ることができます [3、11、18、43、44]。
2.5.1 緩和策。さまざまな Spectre バリアントを緩和するために、多くの対策が開発されました。特定の Spectre バリアントは、3 つの必須コンポーネントのうちの 1 つが削除されると、事実上無効になります。Spectre ガジェットへの入力を制御できない攻撃者が攻撃を成功させる可能性は低くなります。投機的状態をアーキテクチャ状態に変換するための秘密チャネルが利用できない場合も同様です。ただし、通常、これを保証するのは難しいため、Spectre 対策は主に予測ミスの阻止に重点を置いています。重要なコード セクションの前に lfence 命令を挿入すると、この時点以降の投機的実行が無効になるため、一般的な対策として使用できます。ただし、パフォーマンスのオーバーヘッドが大きいため、より具体的な対策が開発されました。Spectre-BTB 対策には、Retpoline [48] や、IBRS、STIBP、IBPB [23] などのマイクロコード更新が含まれます。 Spectre-RSB および Spectre-BTB-via-RSB は、RSB に値を入力して悪意のあるエントリを上書きし、RSB のアンダーフローを防ぐか、IBRS マイクロコードの更新をインストールすることで軽減できます。Spectre-STL は、SSBD マイクロコードの更新 [23] によって軽減できます。攻撃者が共有分岐予測バッファを改ざんするのを阻止するもう 1 つの抜本的なオプションは、SMT を無効にすることです。SMT を無効にすると、同時実行テナント間で分岐予測ハードウェア リソースが効果的に分割されますが、パフォーマンスが大幅に低下します。
Firecracker は、サーバーレスおよびコンテナアプリケーション向けに特別に構築されており [1]、現在は AWS の Fargate CaaS および Lambda FaaS で使用されています。これらのサービス モデルの両方において、Firecracker は個々の Fargate タスクまたは Lambda イベントをサポートする主要な分離システムです。また、これらのサービス モデルは両方とも、比較的小規模で存続期間の短いタスクを大量に実行できるように設計されています。AWS は、最終的に Firecracker となった分離システムの設計要件を次のように列挙しています。
分離: 複数の機能が同じハードウェア上で実行されても安全であり、権限の昇格、情報漏洩、秘密チャネル、その他のリスクから保護されている必要があります。
オーバーヘッドと密度:無駄を最小限に抑えながら、単一のマシンで何千もの機能を実行できる必要があります。
パフォーマンス:関数はネイティブで実行する場合と同様に動作する必要があります。パフォーマンスは一貫している必要があり、同じハードウェア上の近隣の動作から分離されている必要があります。
互換性: Lambda では、関数に任意の Linux バイナリとライブラリを含めることができます。これらは、コードの変更や再コンパイルなしでサポートされる必要があります。
高速切り替え:新しい機能を迅速に開始し、古い機能を迅速にクリーンアップできる必要があります。
ソフト割り当て: CPU、メモリ、その他のリソースをオーバーコミットすることが可能で、各機能は必要なリソースのみを消費し、権利のあるリソースは消費しない必要があります。[1]
私たちは特に、分離要件と、マイクロアーキテクチャ攻撃が Firecracker 脅威モデルの範囲内であると宣言されていることに関心があります。AWS の公開 Firecracker Git リポジトリの「設計」ページでは、分離モデルについて詳しく説明されており、図 2 に再現した便利な図が提供されています。この図は、主に権限昇格に対する保護に関するものです。保護の最外層は jailer で、コンテナ分離技術を使用して、VMM やその他の管理コンポーネントの実行中に Firecracker のホストカーネルへのアクセスを制限します。
Firecracker は、ホスト ユーザー空間で単一プロセスのスレッドとして実行されます。Firecracker プロセス内では、ユーザーのワークロードは他のスレッドで実行されます。ワークロード スレッドは、仮想マシンのゲスト オペレーティング システムと、ゲストで実行されているプログラムを実行します。仮想マシン ゲストでユーザーのコードを実行すると、ホストとの直接のやり取りは、KVM および Firecracker 管理スレッドの特定の部分との事前調整されたやり取りに制限されます。したがって、ホスト カーネルの観点からは、VMM とユーザーのコードを含む VM は同じプロセスで実行されます。これが、AWS が各 VM が単一プロセスに存在すると述べている理由です。ただし、VM はハードウェア仮想化技術によって分離されているため、ユーザーのコード、ゲスト カーネル、および VMM は別々のアドレス空間で動作します。したがって、ゲストのコードは、ゲストのアドレス空間にマップされていないため、アーキテクチャ上または一時的に VMM またはゲスト カーネルのメモリ アドレスにアクセスできません。残りのマイクロアーキテクチャ攻撃対象領域は、アドレス空間の境界を無視して CPU 内部バッファから情報を漏洩する MDS 攻撃と、攻撃者が他のプロセスの分岐予測を操作して自ら情報を漏洩する Spectre 攻撃に限定されます。
図 2 には示されていませんが、AWS の脅威モデルにとって同様に重要なのは、ハードウェアを共有する場合の機能の分離です。これは、特にソフト割り当て要件を考慮すると重要です。ホスト カーネルが侵害されるとゲストのセキュリティが侵害される可能性があるだけでなく、ホスト ハードウェアをターゲットとするマイクロアーキテクチャ攻撃によってユーザー コードが直接脅かされる可能性もあります。単一の Firecracker プロセスには、ユーザーの機能を使用して仮想マシンを実行するために必要なすべてのスレッドが含まれているため、ソフト割り当てはホスト オペレーティング システムによって簡単に実行できます [1]。つまり、標準的な Linux プロセス分離システムが仮想マシン分離の上に配置されているということです。
2.6.1 Firecrackerのセキュリティ推奨事項。Firecrackerのドキュメントでは、マイクロアーキテクチャサイドチャネルから保護するために、以下の予防策も推奨されています[8]。
• SMTを無効にする
• カーネルページテーブル分離を有効にする
• カーネルのkame-pageマージを無効にする
• Spectre-BTB緩和策でコンパイルされたカーネルを使用する(例:x86のIBRSおよびIBPB)
• Spectre-PHTの緩和策を検証する
• L1TF緩和策を有効にする • Spectre-STL緩和策を有効にする
• Rowhammer 軽減策でメモリを使用する
• スワップを無効にするか、セキュアスワップを使用する
この論文は、CC BY-NC-ND 4.0 DEED ライセンスの下でarxiv で公開されています。
[1] 仮想化されたリング0とリング3は、ネイティブに近いコード実行が実現される主な理由の1つです。