1 ポイント 投稿者 GN⁺ 2024-03-20 | 1件のコメント | WhatsAppで共有
  • CVE-2023-6241 は Arm Mali GPU のメモリ管理ユニットにおける論理バグで、悪意ある Android アプリがカーネル MTE が有効な Pixel 8 でも任意のカーネルコード実行と root 権限の取得に到達できる
  • 影響対象は Command Stream Frontend(CSF) を使う最新の Arm Mali GPU デバイスで、Google Pixel 7・Pixel 8 が含まれる
  • 脆弱性は、JIT メモリ拡張中にロックが外れる短い区間を利用し、GPU マッピングと backing page 配列の間に不整合を作る方式で動作する
  • エクスプロイトは、解放済み backing page に残った GPU マッピングを利用し、そのページを GPU コンテキストの PGD として再利用させたうえで、カーネルメモリとカーネルコードをマッピングする
  • MTE はポインタとメモリタグの不一致を検出するが、この攻撃フローは GPU が物理アドレスへ直接アクセスし、MTE の保護範囲外で進む

脆弱性の範囲とパッチ状況

  • CVE-2023-6241 は Arm Mali GPU の脆弱性で、悪意ある Android アプリがデバイス上で任意のカーネルコード実行と root 権限を得られる
  • 2023年11月15日に Arm へ報告され、2023年12月14日に公開された Arm Mali driver r47p0 で修正された
  • Android の修正は 2024年3月のセキュリティアップデート に含まれる
  • 影響対象は CSF(Command Stream Frontend) 機能を使用する最新の Arm Mali GPU デバイスで、Google Pixel 7 と Pixel 8 が例として挙げられている
  • Pixel 8 でカーネル MTE を有効にした状態でも、エクスプロイトの動作が確認された

Arm64 MTE の防御モデル

  • MTE(Memory Tagging Extension) は最新の Arm プロセッサのハードウェア機能で、メモリ破損を検出するためにポインタとメモリブロックのタグを比較する
  • Arm64 ポインタは 64 ビットだが、実際のアプリケーションアドレス空間は通常 52 ビット以下のため、上位ビットの一部をタグ保存に使える
  • 線形オーバーフローでは隣接するメモリブロックのタグがポインタタグと異なる可能性があり、use-after-free では解放・再割り当て過程でのタグ変更により不一致が発生し得る
  • kCFI のような後段の緩和策とは異なり、MTE はメモリ破損が最初に発生した時点で検出しようとする初期段階の緩和策である
  • タグビット数には限りがあるため衝突は避けられず、4 ビットタグだけを使っても任意の成功率は 1/16 に下がる
  • Spectre のようなサイドチャネル攻撃でポインタとメモリブロックの値を漏えいさせれば、正しいタグを合わせて MTE を回避できるが、こうした漏えいは主にローカル攻撃者にとって可能なものだ
  • 現在、Google Pixel 8 だけが開発者向けオプションで MTE の有効化を許可しており、MTE はデフォルトでは無効になっている
  • カーネルで MTE を有効にするには追加手順が必要である

Mali JIT メモリで発生するレース

  • Mali GPU ドライバを使うユーザーアプリは、ドライバファイルを開き、ioctl 呼び出しで kbase_context カーネルオブジェクトを作成・初期化する
  • kbase_context は GPU デバイスとユーザー空間アプリケーションの間で共有される複数種類のメモリを管理する
  • Mali GPU のメモリ領域は kbase_va_region で表現され、nr_pages は仮想サイズ、gpu_alloc->nents は実際の backing page 数を表す
  • JIT メモリは、カーネルドライバが寿命を管理する native memory であり、アプリは GPU コマンドで JIT メモリを割り当てたり解放したりする
  • CSF GPU では、ソフトウェアコマンドとハードウェアコマンドがそれぞれ別のキューに置かれる
    • KBASE_IOCTL_KCPU_QUEUE_CREATEkbase_kcpu_command_queue を作成できる
    • KBASE_IOCTL_KCPU_QUEUE_ENQUEUE でコマンドをキューに入れる
    • BASE_KCPU_COMMAND_TYPE_JIT_ALLOCBASE_KCPU_COMMAND_TYPE_JIT_FREE が JIT の割り当て・解放に使われる
  • kbase_jit_allocate は解放済み JIT メモリプールから再利用可能な領域を探し、物理サイズが足りなければ kbase_jit_grow で backing page を増やす
  • kbase_jit_growkbase_mem_pool_grow 呼び出し中に kctx->reg_lockkctx->mem_partials_lock を一時的に解放することがある
  • kctx->reg_lock はメモリ領域への同時アクセスを保護するため、ロックが外れる区間がレースウィンドウになる

CVE-2023-6241 のトリガーフロー

  • GPU が物理ページで backing されていないメモリ領域アドレスにアクセスすると、GPU メモリアクセスフォルトが発生する
  • kbase_mmu_page_fault_worker は領域が拡張可能かを確認したうえで、必要な backing page を即座に割り当ててマッピングできる
  • JIT 領域は作成時に KBASE_REG_PF_GROWKBASE_REG_GPU_WR を含む GROWABLE_FLAGS_REQUIRED 条件を満たす
  • JIT 領域の解放時に付く KBASE_REG_DONT_NEED フラグは、kbase_jit_grow 冒頭の kbase_mem_evictable_unmake で削除される
  • その結果、kbase_mem_pool_grow 実行中のレースウィンドウで同じ JIT 領域に GPU ページフォルトを起こすと、フォルトハンドラがその領域を拡張できる
  • フォルトハンドラが reg->gpu_alloc->nents を変えると、kbase_jit_grow が前もって保存した old_sizedelta の値が実際の状態とずれる
  • その後、kbase_alloc_phy_pages_helper_lockedkbase_mem_grow_gpu_mapping が stale な値で backing page の割り当てと GPU マッピングを行い、GPU マッピングと pages 配列の間に不整合が生じる
  • このレースは kbase_mem_pool_grow が大きなメモリ割り当てを含むため、容易に勝つことができる

GHSL-2023-005 パッチ以降に変わった攻撃方式

  • 以前の脆弱性 GHSL-2023-005 では、別スレッドが KBASE_IOCTL_MEM_COMMIT で JIT 領域を縮小し、old_sizedelta を無効化できた
  • GHSL-2023-005 のパッチ以降は、KBASE_IOCTL_MEM_COMMIT ioctl で JIT メモリサイズを変更できなくなった
  • CVE-2023-6241 では、レースウィンドウで領域を縮小できず、拡張することだけが可能である
  • 単に拡張する場合は、最後の一部の backing page が GPU にマッピングされないだけで、最初から連続マッピングされた形は維持されるため、直ちに問題にはならない
  • エクスプロイトは追加の GPU フォルトで unmapped gap の後ろに新しいマッピングを作り、その後の JIT 解放により、その gap 内部へ shrink 地点を合わせて悪用可能な状態を作る

GPU マッピング解除の脆弱な前提

  • kbase_mmu_teardown_pgd_pages は GPU ページテーブルをたどりながらエントリを invalid としてマークし、GPU アドレスマッピングを削除する
  • この関数は、高レベル PTE が invalid であれば、そのエントリがカバーする大きなアドレス範囲全体がすでに unmapped であると見なしてスキップする
  • レベル 2 PTE 1 つは 512 ページ範囲をカバーする
  • 正常な kbase_va_region では、マッピングされた仮想アドレスが常に領域の先頭から連続しており、中間に gap がないため、このスキップ動作は安全である
  • CVE-2023-6241 のエクスプロイトは、マッピングの間に unmapped gap を作ったうえで、shrink 開始地点を gap の中に置く
  • kbase_mmu_teardown_pgd_pages は invalid なレベル 2 PTE に遭遇して 512 ページをスキップするが、その後方の一部アドレスは実際にはマッピングされている可能性がある
  • 誤ってスキップされた GPU アドレスは、backing page が解放された後もその物理ページへのアクセスを維持する

カーネルコード実行につながる過程

  • JIT 領域を解放すると backing page は返却されるが、誤って残った GPU マッピングは解放済みページへ引き続きアクセスできる
  • 解放済み backing page は、その後ほかのカーネルページとして再利用され得る
  • 使われた手法の 1 つは、解放済み backing page を GPU kbase_contextPGD(page table global directory) として再利用させる方法である
  • Mali ドライバの backing page 割り当ては階層的に行われる
    • まず現在の kbase_contextkbase_mem_pool からページを取得する
    • 足りなければ pool->next_pool を使う
    • それでも不足する場合は、カーネルの buddy allocator を通じてページを直接割り当てる
  • pool->next_pool は Mali ドライバが管理し、すべての kbase_context が共有するメモリプールで、GPU コンテキストの PGD 割り当てにも使われる
  • 解放済みページが PGD として再利用されると、残っている GPU アドレスを通じて、その PGD を GPU から再び書き込める
  • PGD を書き換えると、任意のカーネルメモリとカーネルコードを GPU にマッピングできる
  • この状態でカーネルコードを書き換えて任意のカーネルコード実行が可能になり、カーネルデータを読み書きしてプロセスの credential 変更や SELinux の無効化も可能になる
  • Pixel 8 向けエクスプロイトと設定メモは GitHub Security Lab リポジトリ で公開されている

MTE 回避が可能な理由

  • このエクスプロイトフローには、MTE 専用の回避ステップは特に必要ない
  • MTE は、ポインタが指すメモリブロックのタグが一致するかを検査し、不正な逆参照を検出する機能である
  • CVE-2023-6241 のトリガー時点では pages 配列と GPU マッピングの間に不整合が生じるが、それぞれを個別に見ると invalid entry があるわけではない
  • kbase_mmu_teardown_pgd_pages が GPU マッピング削除をスキップすると、解放済みメモリページの物理アドレスが GPU ページテーブルに残る
  • GPU がこの解放済みページにアクセスするときは物理アドレスへ直接アクセスするため、ポインタ逆参照検査を経由しない
  • GPU メモリアクセスに MTE が及ぼす影響も明確ではない
  • 結果として、このバグはコプロセッサである GPU が物理メモリへ直接アクセスする経路を利用し、MTE の保護を回避する

MTE 後にも残る攻撃対象領域

  • CVE-2023-6241 は、カーネル MTE が有効な Pixel 8 でも単一のバグで任意のカーネルコード実行に到達できることを示している
  • MTE はメモリ破損の緩和における重要な進展であり、多くのメモリ破損脆弱性を悪用不能にし得るが、万能の防御策ではない
  • この事例では、GPU が物理メモリへ直接アクセスする方式で MTE を回避している
  • CPU 側のハードウェア・ソフトウェア緩和策が増えるほど、コプロセッサとそのカーネルドライバは引き続き強力な攻撃対象領域になり得る

1件のコメント

 
GN⁺ 2024-03-20
Hacker News のコメント
  • ここでの要点は、GPUが以前から Android の悩みの種だったという点です。
    GPU は AP に対して非常に強いアクセス権限を持っているため、前段に設けた緩和策を事実上回避できます。ドライバのマッピングコードのバグは強力な攻撃プリミティブにつながり、実際の野生のエクスプロイトでも繰り返し悪用されてきました。結局、構造を再設計するまでは大きく変わるのは難しそうです。

    • 中途半端に作られたモバイル GPU は独自の MMU を入れるのをやめて、標準の 入出力 MMU を使うべきだと思います。
    • ここで AP とは何の意味ですか?
  • この脆弱性で興味深いのは、Arm Mali GPU のメモリ管理ユニットにある論理バグで、Memory Tagging Extensionを回避できるという点です。
    ところが記事の残りの部分は、実際の原因は競合状態であり、解放後使用はその結果だと説明しているように見えます。

  • 3月のアップデート前の GrapheneOS インストールにも影響があったのでしょうか?

    • GrapheneOS の主な目標の一つはセキュリティアップデートを可能な限り早く配布することなので、アップストリームでパッチが適用されているなら、GrapheneOS にはほぼ確実に含まれていたはずです。
      ときにはリリース前の AOSP セキュリティパッチレベルを採用したり、まだ公開されていない AOSP やカーネルソースのセキュリティ修正もバックポートします。
    • これは GPU 内部のハードウェアに近い問題、場合によってはファームウェア問題に関係しているように見えたので、3月のアップデート後も影響があると思っていました。そのアップデートは Bluetooth スタック関連だったので。
      追記: 無視してください。最近の GrapheneOS ブログにあった「MTE がすべてのシステムアプリにも適用される問題を見つけた」という記事と混同していました。GrapheneOS は 2024030600 リリースで「完全な 2024-03-05 セキュリティパッチレベル」を取り込んでいるので、このパッチも含まれているようです。
  • 確率的な Arm MTE のメモリ安全性は、決定論的な CHERI ハードウェアへ向かう足がかりである。https://saaramar.github.io/memory_safety_blogpost_2022/ および https://news.ycombinator.com/item?id=39668053
    正しい緩和策は、一次的な攻撃プリミティブ、つまりバグの根本原因を狙うべきである。ハードウェアによる解決策には CHERI(Morello, CheriIoT)、MTE があり、ソフトウェアによる緩和策には kalloc_type+dataPAC、AUTOSLAB、Firebloom、GuardedMemcpy、CastGuard、攻撃面の縮小がある。安全なプログラミング言語としては Rust と Swift がある。MTE と CHERI はうまくかみ合い、この領域のバグを根本原因から取り除く助けになる。MSR、MSRC、Azure Silicon は、最小の RISC-V コア仕様である RISC-V32E まで CHERI を縮小する方向を推進した
    Microsoft Research は IoT デバイス向けの CHERI ハードウェア/ソフトウェアスタックをオープンソースで公開した。https://msrc.microsoft.com/blog/2023/02/first-steps-in-cheri...
    CHERI ベースのマイクロコントローラは、命令セットアーキテクチャ(ISA)、アプリケーションバイナリインターフェース(ABI)、隔離モデル、ソフトウェアスタックの中核部を共同設計することで、非常に強いセキュリティ保証を得ることを目標としている。このマイクロコントローラは、CHERI-ISA 機能による空間安全性の決定論的緩和、ロードバリア・ゼロ化・回収・1ビット情報フロー制御によるヒープおよびコンパートメント間スタックの時間安全性の決定論的緩和、追加の CHERI-ISA 機能と小さなモニターによる細粒度のコンパートメント化を実現する
    David Chisnall、ケンブリッジ大学、https://lobste.rs/s/gnjx2n/c_can_be_memory_safe#c_9ohzku via https://eclypsium.com/blog/a-faster-path-to-memory-safety-ch...
    「複数の信頼できるコンピューティング基盤に含まれるオープンソースの C/C++ コードは約130億行あり、プロプライエタリコードを含めればさらに大きくなる。今すぐ全員が C/C++ の作成をやめ、すべてのソフトウェアエンジニアがレガシーコードを安全な言語で書き直すことに集中したとしても、すべてを置き換えるには5〜10年はかかるだろうし、長年検証されてきたコードを、安全な言語で許されるイディオムに合う別のアルゴリズムやデータ構造を必要とする新しいコードへ置き換える過程で、多くの論理バグも生まれる可能性が高い」
    「書き直しをせず、C/C++ コードの作成をやめるだけなら、一般的なコード置換速度では、信頼できるコンピューティング基盤が完全に安全になるまで約50年かかる。全員が C/C++ をやめることで合意しないなら、少なくとも100年だ」
    「一方で主要 CPU メーカーが5年以内に CHERI CPU を出荷するなら、プログラマーが行動を変えなくても、今日から15年以内に大半のマシン、とくに高価値なマシンはメモリ安全性を備えることになる」

    • 組み込み/IoT と似た用途の CHERI に関心があるなら、lowRISC では CHERIoT 向けの FPGA ベース評価プラットフォームをいくつか作っている: https://www.sunburst-project.org/
      1つ目は Sonata システムである: https://github.com/lowRISC/sonata-system。FPGA と複数の周辺機器およびヘッダーを備えた専用 PCB で構成される。PCB 設計は完了しており、Mouser 経由で入手できる予定で、ボードレイアウトまでオープンソースなので、望めば自分で組み立てることもできる。現在は FPGA 向け RTL に取り組んでいる。完成すれば、ドキュメントとツールまで備えた CHERIoT ベースのマイクロコントローラ型システムが得られる
      さらに Sonata と OpenTitan Earl Grey の Root of Trust を組み合わせた Symphony システムも作っている: https://github.com/lowRISC/symphony-system
    • Solaris SPARC ADI もある。Oracle と Solaris SPARC の現在の状況のせいでほとんど忘れられているが、惜しいところだ
    • これは CPU 外のハードウェアバグなので、CHERI がどう役立つのか分からない
      それに最後に見たとき、CHERI は健全ではなかった。その上でもメモリバグを書けたのだが、今は直ったのだろうか?
    • 「すべてを置き換えるには5〜10年」が年単位の話なら、楽観的すぎるように見える
      自転車置き場論争だけでもそれくらいかかりそうだ
    • 根本問題は、ユーザーが悪意あるコードを実行し、何らかの MMU ハッシュ衝突 を悪用する点にあるように見える
      このエクスプロイトは Rust を含め、ほとんどの言語で書けそうだ
  • ハードウェアが そこまで ひどいって? なんてことだ……

    • GPU ハードウェア にはバグが山ほどある。許容できるコストでドライバ側で回避できない問題のときだけ、ハードウェアを再製造する
      このやり方が可能なのは、GPU が CPU のように比較的直接的なハードウェアアクセスを許さないからだ
    • これは CPU 上で実行される ドライバのバグ
  • すばらしい研究と記事だが、GitHub のブログに載っているのは少し意外でもあり、うれしくもある。
    こうした研究を GitHub が行う「ビジネス上の理由」を知っている人はいるだろうか? 必ずしもビジネス上の理由が必要だという意味ではないが、ここで見かけて少し驚いた。

    • Man Yue Mo は GitHub に買収される前、Semmle で働いていた(https://blog.sonatype.com/steps-to-responsible-disclosurehttps://github.blog/2019-09-18-github-welcomes-semmle/)
      その研究機能が GitHub Security Lab へとつながった。Semmle は CodeQL を作り、現在は GitHub が提供している(https://docs.github.com/en/code-security/code-scanning/intro...)。GitHub と Microsoft は CodeQL を「深いセキュリティ洞察」と結び付けたいと考えている(https://www.microsoft.com/en-us/security/blog/2023/11/02/ann...)
      そのため、こうした斬新なセキュリティ研究に継続して資金を出しており、業界のセキュリティ実務者はそれに感謝している。
    • この作業は GitHub の Security Lab から出たもの: https://securitylab.github.com/
    • Microsoft に買収されたことで、この種の研究を支援するリソースが生まれた。
      GitHub アプリもあり、そのアプリのセキュリティは GitHub の範囲外ではない。攻撃者がスマートフォンに潜むアプリをインストールできれば、ユーザーのふりをしてさまざまなことができる。GitHub 上で影響力のある人なら被害はかなり大きくなり得るので、こうした脆弱性を見つけることは GitHub にとっても利益になる。
    • GitHub には Arm 向けのホスト型 Actions ランナーもある。
      そのため、MTE を利用したサンドボックス化のために、Arm ハードウェアのセキュリティ機能を確認・検証することに関心があるのかもしれない。
    • 実質的には 基礎研究に近いと思う [0]
      まず第一に考えれば、GitHub という製品に Android セキュリティ専門家が必ずしも必要なわけではない。しかし長期的には潜在的な利益がある。
      [0]: https://en.wikipedia.org/wiki/Basic_research
  • GPU がほとんどない、あるいはまったくない CPU とスマートフォンを作り、ビジネスフォンと呼んだ例がまだないのは驚きだ。
    セキュリティ、コスト、消費電力の面で明確な利点がありそうに見える。

    • 明確な欠点は、高解像度タッチスクリーンがないため Blackberry や Palm Treo に戻ることになる点だ。実際、それらはビジネスフォンとして売られていた。