- Zenbleed は、AMD Zen 2 系列で誤って予測された
vzeroupper の復旧を悪用し、同じ物理コアのベクタレジスタファイルに残ったデータを読み取れるようにする脆弱性
- CVE-2023-20593 として登録されており、Ryzen 3000/4000/5000 with Radeon Graphics/7020 with Radeon Graphics、Ryzen PRO、Threadripper 3000、EPYC “Rome” などの Zen 2 製品群が影響範囲に含まれる
- 攻撃は XMM Register Merge Optimization、レジスタリネーム、誤って予測された
vzeroupper が狭い時間窓内で連続すると成立し、strlen、memcpy、strcmp のような基本操作も観測対象になり得る
- 最適化された変種はコアあたり毎秒約 30KB を漏えいでき、VM・サンドボックス・コンテナ・プロセスの境界を越えて、同じ物理コアのレジスタファイル共有が問題となる
- AMD のマイクロコード更新の適用が推奨され、一時的に
DE_CFG[9] chicken bit を設定できるが性能コストが生じる可能性があり、SMT の無効化だけでは不十分
Zenbleed が狙う実行単位
- x86-64 CPU には 128 ビットの XMM ベクタレジスタがあり、最新の CPU はこれを 256 ビットの YMM、512 ビットの ZMM まで拡張している
- ベクタレジスタは数値計算だけでなく、glibc の
strcmp、memcpy、strlen のような標準 C ライブラリ関数でも使われる
- glibc の AVX2 最適化
strlen は、文字列内で最初の nul バイト位置を探すために複数のベクタ命令を組み合わせる
vpxor xmm0,xmm0,xmm0 で ymm0 の下位部分を 0 にする
vpcmpeqb ymm1,ymm0,[rdi] で文字列バイトと 0 バイトを比較する
vpmovmskb eax,ymm1 で比較結果を汎用レジスタへ移す
tzcnt eax,eax で最初の nul バイト位置を計算する
vzeroupper とレジスタファイル
vzeroupper はベクタレジスタの上位ビットを 0 にする命令
XMM と YMM レジスタを混在させると XMM レジスタが全幅へ昇格し、この過程で上位ビット依存が生じることがある
- glibc は不要なストールを避けるため、
vzeroupper を使って以後の結果が上位ビットに依存しないようにする
- CPU は各レジスタを固定された物理位置に置くのではなく、Register File と Register Allocation Table で物理レジスタの割り当てを管理する
XMM レジスタを 0 にするとき、CPU は実際のビットを保存せず RAT に z-bit フラグを設定できる
- このフラグは
YMM レジスタの上位・下位部分に独立して適用され得る
vzeroupper は z-bit を設定したあと、レジスタファイルから該当リソースを解放できる
投機実行の復旧で生じる脆弱性
- 現代の CPU は 投機実行 を使うため、誤って予測された分岐で実行された演算は巻き戻す必要がある
- 問題は、誤って予測された
vzeroupper が実行された後に復旧される際、z-bit だけを巻き戻しても、すでに解放されたレジスタファイルリソースの状態を正しく復元できない点
- 精密なスケジューリングにより、一部のプロセッサが誤って予測された
vzeroupper から不正確に復旧するようにできる
- この手法は CVE-2023-20593 であり、Zen 2 系列全体に影響する
- AMD Ryzen 3000 Series Processors
- AMD Ryzen PRO 3000 Series Processors
- AMD Ryzen Threadripper 3000 Series Processors
- AMD Ryzen 4000 Series Processors with Radeon Graphics
- AMD Ryzen PRO 4000 Series Processors
- AMD Ryzen 5000 Series Processors with Radeon Graphics
- AMD Ryzen 7020 Series Processors with Radeon Graphics
- AMD EPYC “Rome” Processors
攻撃条件と漏えい範囲
- バグを誘発するには、XMM Register Merge Optimization、レジスタリネーム、誤って予測された
vzeroupper が精密な時間窓内で連続する必要がある
- 例示の命令シーケンスは次の構造を使う
vcvtsi2s{s,d} で merge optimization を誘発する
vmovdqa でレジスタリネームを誘発する
- 条件分岐が taken であるにもかかわらず CPU が not-taken 経路を予測すると、
vzeroupper が誤って予測実行され、バグが発生する
strlen、memcpy、strcmp のような基本操作もベクタレジスタを使うため、システムのどこで実行されても観測対象になり得る
- 同じ物理コアで レジスタファイル が共有されるため、別の VM、サンドボックス、コンテナ、プロセスも影響範囲に入る
- 2 つのハイパースレッドは同じ物理レジスタファイルを共有する
- 最適化された攻撃の変種は、コアあたり毎秒約 30KB を漏えいでき、ログイン中ユーザーの暗号鍵やパスワードを監視するのに十分な速度
- 技術アドバイザリと関連コードは Google の security research repository で公開されている
- テスト用コードは Linux 向けに提供されているが、このバグは特定の OS に依存しないため、すべての OS が影響を受ける
発見方法: CPU ファジングと Oracle Serialization
- 脆弱性は ファジング によって発見された
- CPU 業界でもハードウェア欠陥を見つけるため、シリコン製造後検証(Post-Silicon Validation)を実施する
- 一般的なカバレッジベースのファジングとは異なり、CPU にはコードカバレッジに直接対応する指標がない
- 代わりに performance counters を使い、興味深いアーキテクチャイベントをファザーへフィードバックとして提供する
- この方法により、偶然には見つけにくい命令シーケンスを探索できる
- merge optimization のような機能を自動的に発見できた
- ソフトウェアファジングは通常クラッシュを探すが、任意生成された CPU プログラムではクラッシュ自体が正しい動作である場合もある
- 既存アプローチの 1 つである reversi は、任意の命令ごとに逆演算を生成し、最終状態が初期状態と異なるかを確認する
- x86 のような CISC アーキテクチャではテストケース生成が複雑になる
- もう 1 つの方式は oracle を使い、テスト対象 CPU と別の CPU またはシミュレータの結果を比較すること
- Oracle Serialization は 2 つのアイデアを組み合わせる
- 任意のプログラムを生成したあと、直列化された形へ自動変換する
- store/load barrier、speculation fence、cache line flush のような直列化要素を追加する
- 元のプログラムと直列化されたプログラムは性能特性が異なっても、同一の出力を生成しなければならない
- 最終状態が一致しなければマイクロアーキテクチャ上の実行エラーである可能性があり、この不一致が Zenbleed の発見につながった
対応と検出の限界
- 脆弱性は 2023 年 5 月 15 日に AMD へ報告された
- AMD は影響を受けるプロセッサ向けの マイクロコード更新 を配布した
- BIOS または OS ベンダーが、すでにこの更新を含むパッチを提供している可能性がある
- 推奨される対応は マイクロコード更新 の適用
- 更新を適用できない場合は、ソフトウェア回避策として
DE_CFG[9] chicken bit を設定できる
- 性能コストが生じる可能性がある
- Linux では
msr-tools で全コアに設定可能
- FreeBSD では
cpucontrol(8) を使用する
- 他の OS で MSR の設定方法が分からない場合は、ベンダーのサポートが必要
- SMT の無効化だけでは十分ではない
- 信頼できる攻撃検出手法は知られていない
- 特別なシステムコールや権限を必要としないため
vzeroupper の不適切な使用を静的に検出することもできない
1件のコメント
Hacker News のコメント
これは本当に見事で、VMで実行しているからといって安全とは限らないという教科書的な事例になり得る
VMエスケープは以前から知られていたが、今回のものはエスケープなしでも実行が単純で、見返りの大きい大規模な脆弱性
このバグがマイクロコードで修正されるからといって、似たような別のバグがないという意味ではない。多くのゼロデイは、公開されるずっと前から雇われブラックハットたちに知られていることが多い
近年見つかったCPU脆弱性:
https://en.wikipedia.org/wiki/Meltdown_(security_vulnerability)
https://en.wikipedia.org/wiki/Spectre_(security_vulnerability)
https://aepicleak.com/
https://en.wikipedia.org/wiki/Software_Guard_Extensions#SGAxe
https://en.wikipedia.org/wiki/Software_Guard_Extensions#LVI
https://en.wikipedia.org/wiki/Software_Guard_Extensions#Plundervolt
https://en.wikipedia.org/wiki/Software_Guard_Extensions/…
https://en.wikipedia.org/wiki/Software_Guard_Extensions#Enclave_attack
https://en.wikipedia.org/wiki/Software_Guard_Extensions/…
https://www.vusec.net/projects/crosstalk/
https://en.wikipedia.org/wiki/Hertzbleed
https://securityweek.com/amd-processors-expose-sensitive-data-new-squi…
大きな
switch文で命令を解釈しているのではなく、実際のCPU上で命令を実行し、CPUがデータや命令が重ならないと保証するいくつかのハードウェアフラグに依存している。CPUはそう約束するが、現実にその約束を守るのは難しいあちらはCPUがやるべきことを正確にやっていたにもかかわらず、タイミングベースで可能になったまったく新しい攻撃形態だった。一方、今回のZenbleedは、本来あってはならないデータがレジスタに残るという、より伝統的なバグに近い
こうした脆弱性の多くは、ソフトウェア側とハードウェア側が互いに十分に対話していないことから生じていると思う。ソフトウェア側は分離保証について仮定し、ハードウェア側はそうした仮定が生まれるときに十分な警告をしない
分岐予測は本質的にあまりにも複雑で、常にこうした脆弱性にさらされざるを得ないのか、あるいはコードパスと命令実行を直感的に理解する方法とあまりにも違うため、手遅れになるまで境界条件を思い浮かべにくいのか、という感じがする
CPUアーキテクチャの複雑さは、どこかの時点で推論するのが難しすぎるようになり、より単純に保つことによる性能損失を受け入れるようになるのだろうか?
それを指摘し、別のハイパーバイザーでエアギャップすべきだと勧めたが、いつも無視された。結局、損をするのはそちらだろう
エクスプロイトの tar ファイルの README には、より詳しい内容と公開スケジュールが含まれている
2023-05-09CPU 検証パイプラインのある構成要素が異常な結果を生成2023-05-12問題の切り分けと再現に成功し、調査を継続2023-05-14問題の範囲と深刻度を把握2023-05-15簡単なステータスレポートを作成して AMD PSIRT に共有2023-05-17AMD が報告を確認し、再現可能であることを認める2023-05-17信頼できる PoC の開発を完了し、AMD に共有2023-05-19主要なカーネルおよびハイパーバイザーベンダーへの通知を開始2023-05-23AMD から Rome 向けのベータ版マイクロコード更新を受領2023-05-24更新によって問題が修正されることを確認し、AMD に通知2023-05-30AMD がパートナーにセキュリティ通知を送ったと連絡2023-06-12状況と詳細を議論するため AMD とミーティング2023-07-20AMD が合意されたエンバーゴ日より早く、予告なしにパッチを公開2023-07-21修正が公開されたため、主要ディストリビューションにファームウェアパッケージ更新の準備を非公開で知らせようと提案2023-07-24公開 disclosure合意されたエンバーゴより早くパッチを公開し、その後で主要ディストリビューションにファームウェアパッケージを準備すべきだと非公開で知らせよう、という流れになった
amd-ucode 20230625.ee91452d-5がこの問題を修正するマイクロコード更新を含んでいるのか分かりにくいhttps://archlinux.org/packages/core/any/amd-ucode/ は 2023-07-25 11:48 UTC に最後に更新されており、https://git.kernel.org/pub/scm/linux/kernel/git/firmware/lin... では修正版が 2023-07-18 となっている
最初は PKGBUILD の
_tag=20230625とsource=("git+[https://git.kernel.org/pub/scm/linux/kernel/git/firmware/lin...](<https://git.kernel.org/pub/scm/…;)")のせいで、まだ 20230625 のファームウェアを使っているのだと思っていたしかし
_backports配列に 20 時間前に編集されたチェリーピックコミットが 2 つあり、https://gitlab.archlinux.org/archlinux/packaging/packages/li... のb250b32ab1d044953af2dc5e790819a7703b7ee6が先にリンクした kernel.org のコミットなので、最新の Arch は Zenbleed に対して脆弱ではないことを期待しているこれは本当に怖い。自分の Zen 2 マシンである Ryzen 3600 で、権限のないユーザーとしてエクスプロイトを実行し、バックグラウンドのテキストエディタ(Kate)に文字列をコピー&ペーストしたところ、数秒でその文字列の断片が zenbleed の出力に記録された
幸い、このエクスプロイトは特定のアセンブリルーチンに大きく依存しているため、ブラウザの JS や WASM から悪用するのは非常に難しそうだ。そうでなければ、悪意あるタブを数時間バックグラウンドで開いておくだけでも簡単に漏えいしていただろう
Fedora のメンテナーが新しいマイクロコードを配布し、カーネルが起動時に更新できるようになるのを待っているところ
同時に、V8 と SpiderMonkey のソフトウェアパッチがより早く、追加の緩和策になってくれることを願っている
ただし JS エクスプロイトにはデータを外へ持ち出す方法も必要になるはずで、それを完全に隠すのはかなり難しそうだ
"No such file or directory"と error 127 が出るOpenBSD が直近 3 日以内に AMD マイクロコードのロードを追加したのは、偶然ではないように感じる
https://news.ycombinator.com/item?id=36838511
AMDが影響を受けるプロセッサ向けのマイクロコード更新を出した、という表現は正確ではないと思う
AMDはfamily 17hモデル
0x31と0xa0向けのマイクロコード更新[0]を出しており、WikiChip[1]基準ではこれはRome、Castle Peak、Mendocinoに該当する現時点ではRenoir、Grey Hawk、Lucienne、Matisse、Van Gogh向けのマイクロコード更新はなさそうだ。幸い、新しいカーネルはこれらに対して単にchicken bitを設定でき、実際にそうしている[2]
[0] https://git.kernel.org/pub/scm/linux/kernel/git/firmware/lin...
[1] https://en.wikichip.org/wiki/amd/cpuid#Family_23_.2817h.29
[2] https://github.com/torvalds/linux/commit/522b1d69219d8f08317...
good_revsはここにある: https://github.com/torvalds/linux/commit/522b1d69219d8f08317...現在公開されているリビジョン(
Patch)はgit HEAD基準でここで確認できる: https://git.kernel.org/pub/scm/linux/kernel/git/firmware/lin...これを書いている時点では、5つの
good_revのうち公開されているのは2つだけだそのCeleronは50%オーバークロックで有名だった: https://ark.intel.com/content/www/us/en/ark/products/codenam...
関連部分を見ると、この手法はCVE-2023-20593で、すべてのZen 2クラスのプロセッサで動作し、少なくとも次の製品が含まれる
AMD Ryzen 3000 Series Processors
AMD Ryzen PRO 3000 Series Processors
AMD Ryzen Threadripper 3000 Series Processors
AMD Ryzen 4000 Series Processors with Radeon Graphics
AMD Ryzen PRO 4000 Series Processors
AMD Ryzen 5000 Series Processors with Radeon Graphics
AMD Ryzen 7020 Series Processors with Radeon Graphics
AMD EPYC “Rome” Processors
同じ手法や類似の手法が、より前のZen/Zen+や、より後のZen 3コアでも動作する可能性はあるが、まだ実証できていないのだろうか?
私の
AMD Ryzen 9 5950x Desktop ProcessorもZen 3に見えるので、大丈夫そうだ信頼できないワークロードを動かしているわけではないが、備えあれば憂いなしというから
サイトがトラフィックに押しつぶされて落ちている: https://web.archive.org/web/20230724143835/https://lock.cmpx...
ほとんどの場合、HNのトラフィックは毎秒100ページビューにもほぼ届かない
https://www.amd.com/en/resources/product-security/bulletin/a...
AMDのセキュリティ告知によると、非EPYC CPU向けのファームウェア更新は年末まで出ない。それまでユーザーはchicken bitをオフにして性能低下を受け入れなければならないのか?
見事であると同時に恐ろしい。10MBのサンプルを1分実行したところ、私のBitwardenパスワードの一部、sshログインパスワード、銀行の認証情報の断片を「漏えい」させることができ、簡単に再構成できた
記事が本当に良かった。ランダム生成プログラムが正しく実行されたかをどう判断できるかを扱った部分が特に良かった
当然のアプローチは、別のプロセッサやシミュレータのようなオラクルで実行し、同じように動作するかを見ること
しかし、狭いタイミングウィンドウでのマイクロアーキテクチャ上の効果を確認するには、同じプログラムにさまざまな stall、fence、nop などを入れて書くこともできる。シングルスレッドのコードでは出力に影響を与えてはいけないが、CPU 内部ではマイクロアーキテクチャ的にかなり違うことをすることになる。そうすれば、CPU が自分自身のオラクルになれる
chicken bit も気に入った