Meltdownの対応によるパフォーマンス低下の懸念
「Linux Kernel」では「Meltdown」の対応パッチが取り込まれましたが、この対応によりパフォーマンス低下の懸念が報告されています。本質的には「CPU」の問題ですが、影響を受けるすべての「CPU」をユーザーに交換してもらうわけにも行かず、ソフトウェア面での対応がなされています。
パフォーマンスへの影響
これは対応パッチの出来の良し悪しに関する話ではなく、「Meltdown」の影響を低減する措置を取るには、パフォーマンスへの影響が避けられない、という話です。この脆弱性は「Windows」や「macOS」など他のOSでも発生する脆弱性です。
他のOSでもパフォーマンスの低下が懸念されており、おおよそ5%から30%程度のパフォーマンスが低下するのではないか、という懸念があります。
マッピング手法とTLBのフラッシュコスト
昔から「Linux Kernel」は、カーネルのメモリーを実行中の各プロセスのアドレス空間にマッピングしています。これはパフォーマンスが良い点と、「CPU」の「MMU(Memory Management Unit/メモリ管理ユニット)」が持つ「ユーザースペースがカーネルメモリーへアクセスを防止する機能」が信頼できると判断されていたためです。
例えば「x86_64/amd64」では、ユーザースペースは仮想アドレス空間の下位47bit(0 〜 0x7fffffffffff)に確保され、カーネルスペースのマッピングは「0xffff880000000000」以降に分散されて配置されます。
ユーザースペースはカーネル用に予約されたアドレス空間を見ることはできますが、ユーザースペースは実際にそれらのメモリーにアクセスすることはできません。
このマッピング手法にはいくつか問題(制約)がありましたが、この手法を採用しないと大幅にパフォーマンスが低下するため、長らくこの手法が採用されてきました。
この手法を採用することでユーザースペースとカーネルスペースの切替時(コンテキストスイッチ)に、「TLB(Translation Lookaside Buffer)」をフラッシュする必要がなくなります。
またカーネルスペースで使用するTLBエントリーもフラッシュせずに済みます。
「TLB」のフラッシュはコストがかかる操作です。
そのため例えばシステムコールを呼ぶなどコンテキストスイッチが起こる度に「TLB」のフラッシュを行っていては、十分なパフォーマンスを確保できません。
KASLR
「Linux Kernel」には仮想アドレス空間内のカーネルの配置位置をランダム化する「KASLR(Kernel Address Space Layout Randomization)」という仕組みが導入されています。「KASLR」により、カーネルがメモリー内のどこに存在しているのかを特定することが困難になり、特定のアドレス位置から侵入を試みる攻撃に対抗できるようになります。
カーネルの配置位置がユーザースペースに漏洩しない限り、攻撃者はカーネルの配置位置を把握することは困難です。
しかしサイドチャンネル攻撃により、そのメモリーアドレスが漏洩する問題が見つかりました。
これは「KASLR」が回避されたこと、及び、カーネルのメモリーを実行中の各プロセスのアドレス空間にマッピングする手法は危険であることを意味します。
KAISER
上記の問題は「KASLR」を回避する手法であり、これに対抗する「KAISER(Kernel Address Isolation to have Side-channels Efficiently Removed)」が登場しました。「KASLR」はアドレスマッピングの漏洩に対抗し、「KAISER」はデータの漏洩に対抗する仕組みです。
これらの仕組みを組み合わせることで、「Meltdown」のような脆弱性に対抗できるようになります。
2種類のページテーブル群を持つ
現在システムでは、各プロセスは単一のページテーブル群を持っています。「KAISER」では、これを2つにします。
一つは、本質的に現在のページテーブル群と同じです。
これにはカーネルスペースとユーザースペースのアドレスが含まれています。
このページテーブル群は、システムがカーネルモードで動作している時のみ使用されます。
もう一つは ユーザースペースのすべてのマッピングのコピーが含まれているシャドウページテーブルです。
ここに含まれるカーネル側の情報は、システムコールと割り込みを処理するために必要な情報を提供する最低限のカーネルスペースのマッピングが含まれています。
プロセスがユーザーモードで動作している時は、シャドウページテーブルが使用されます。
これによりカーネルのアドレススペースはプロセスから隠蔽され、サイドチャンネル攻撃に対抗できるようになります。
しかし2種類のページテーブル群を持つということは、コンテキストスイッチを行うたびにページテーブル群の切り替えが必要になります。
またコンテキストスイッチを行うたびに、「TLB」のフラッシュが必要になります。
この点がパフォーマンス低下の主な要因になっています。
PCIDによるパフォーマンス低下の軽減
最近のCPUは「PCID(Process Context Identifier)」という仕組みを提供しており、これを活用することでコンテキストスイッチを行うたびに「TLB」をフラッシュする必要がなくなります。つまりページテーブル切替時にかかるコストを大幅に削減することができます。
ただしコストを「0」にすることはできません。
KPTI
今回取り込まれた「Meltdown」の影響を低減するパッチは、「KPTI(Kernel page-table isolation)」と呼ばれています。「KAISER」が登場した頃は、まだ「Meltdown」の存在は知られていませんでした。
その後「Meltdown」の存在が明らかになり、上記に加えカーネルメモリーの内容も漏洩することが判明しました。
この「Meltdown」に対抗するため、「KAISER」が元々持っていた目的を見直し、「KAISER」を元に「KPTI」が作成されてました。
「KPTI」は、ユーザースペースからカーネルのページテーブルを分離します。
そして保護されたすべてのメモリー領域をユーザースペースへマップしないことで、「Meltdown」に対抗します。
「KAISER」がベースになっているため、「KAISER」が持っている性質も受け継いでいます。
つまりパフォーマンスへの影響があるということです。
Spectreに対応したパッチではない
「KPTI」は「Meltdown」に対抗したパッチであり、「Spectre」に対抗するパッチではありません。AMD製CPUはMeltdownの影響を受けない
「AMD」はAMD製のCPUが「Meltdown」の影響を受けないことを確認しており、AMD製のCPUを利用している環境では、「KPTI」は有効になりません。- Linux Will End Up Disabling x86 PTI For AMD Processors - Update: Now Disabled
- index : kernel/git/torvalds/linux.git
「KPTI」が取り込まれた当初は、AMD製のCPUでも「KPTI」が有効になっていました。
しかしその後AMD製のCPUでは「KPTI」が無効になるように修正されました。