Googleは、個々の脆弱性の発見と修正だけに頼るのではなく、本番環境でアプリケーションが必要としないIOCTLコマンドを制限することで、AndroidのGPU攻撃対象領域を縮小することを推奨しています。この取り組みは、Android Red TeamとArmがMali GPUおよびそのドライバーを分析するために協力した結果であり、SELinuxを使用して不要な機能へのアクセスを防ぐことに重点を置いています。
GPUは複雑で、システム内で高い権限を持つため、攻撃者にとって魅力的な標的となっており、この取り組みはセキュリティ上重要です。記事によると、2021年以降にAndroidカーネルドライバーを利用したエクスプロイトの大半はGPUを標的としており、攻撃は主に、UMDとして知られるユーザーモードドライバーと、KMD、つまり高い権限を持つカーネルモードドライバーとの間のインターフェースに集中していました。
なぜ攻撃対象領域の縮小が優先事項なのか?
このインターフェースを通過する悪意のある入力は、メモリ破損につながる欠陥を悪用する可能性があります。Googleは、不要な経路にアクセスできないようにすることが、保護レベルを高める効果的で、多くの場合より迅速な手段になると考えています。これは、ソフトウェアバグの発見と修正を継続する取り組みと並行して行われます。
Armとの共同分析には、Androidデバイスの約45%で使用されているMaliドライバーが含まれており、セキュリティリスクをもたらす一方で、本番環境でデバイスを動作させるためには不要な攻撃対象領域の部分を特定するのに役立ちました。その結果、ポリシーはGPUドライバーの入出力を表すIOCTLコマンドに重点を置きました。IOCTLコマンドは、攻撃対象領域の重要な一部です。
提案されたアプローチでは、Maliのコマンドを3つのカテゴリーに分類します。
- 制限されないコマンド:通常の動作に必要であり、アプリケーションから引き続き利用できます。
- 計測およびツール用コマンド:GPUの性能を監視するために、性能分析およびデバッグツールが使用します。
- 制限対象コマンド:本番アプリケーションが使用することを想定していないコマンドです。GPU開発用に設計されたコマンドに加え、デバイスの現行UMDバージョンでは使用されなくなった古いコマンドも含まれます。
このポリシーは、本番環境で古いコマンドとデバッグコマンドを遮断し、計測コマンドへのアクセスをshellまたはデバッグ可能とマークされたアプリケーションに限定することを目的としています。一方、本番用コマンドは通常のアプリケーションから引き続き利用できます。
SELinuxポリシーの段階的な導入
Googleは、正当なアプリケーションが動作しなくなる可能性を抑えるため、段階的なアプローチを採用しました。プロセスは任意のポリシーから始まり、計測コマンドを禁止するgpu_hardenという新しいSELinux属性を作成し、その影響をテストするために特定のシステムアプリケーション群へ適用しました。この段階では、アクセスを直ちに禁止するのではなく、allowxpermルールを使用してアクセス試行を記録し、拒否ログを監視して障害が発生していないことを確認しました。
アプローチの安全性を確認した後、ポリシーはより厳格なデフォルトモデルへ移行し、計測コマンドへのアクセスを許可するgpu_debugというドメインを作成しました。これにより、アプリケーションはデフォルトで保護され、開発者には特定のケースで例外が認められます。
- root権限を持つデバイス上でアプリケーションを実行する。
- アプリケーションのマニフェストファイルでandroid:debuggable="true"プロパティを設定する。
- アプリケーション固有のSELinuxポリシーで恒久的な例外を要求する。
デバイスへのポリシー適用手順
Googleは、パートナーやより広範なエコシステムが同様の仕組みを導入できるよう、一般的なポリシーロジックを各デバイスやドライバーの詳細から分離するガイダンスを提供しています。プロセスは、Androidプラットフォームレベルのsystem/sepolicyにある一般的なマクロモジュールを使用することから始まります。このモジュールは/sepolicy/public/te_macrosファイルにあり、デバイスのポリシーがフィルタリングすべきIOCTLコマンドのリストを渡せるようにします。
このモジュールは、すべてのアプリケーション、つまりappdomainに制限されないコマンドのリストへのアクセスを許可し、デバッグ可能なアプリケーションの場合には、計測用の機密コマンドへのアクセスをshellやrunas_appなどのデバッグツールに限定するよう設計されています。また、アプリケーションの対象SDKバージョンに基づいて高い権限を持つコマンドを遮断し、古いアプリケーションとの互換性を維持します。
次に、デバイス開発者は、device/your_company/your_device/sepolicy/ioctl_macrosなど、デバイス固有のSELinuxポリシーディレクトリ内にioctl_macrosファイルを作成し、GPUドライバー固有のコマンドリストを定義します。Googleは、少なくとも本番用コマンド、計測コマンド、デバッグコマンドについて別々のリストを用意し、ドライバー固有の16進数表記のIOCTL番号を含めることを推奨しています。
Armは、r54p2リリースのDocumentation/ioctl-categories.rstファイルで、自社のIOCTLコマンドの正式な分類を提供しています。また、このリストは今後のドライバーリリースに伴って更新され続けるとしています。
適用前のテスト
次の段階では、デバイスのポリシーディレクトリにgpu.teファイルを作成し、一般的なマクロモジュールを呼び出して、あらかじめ定義したデバイスラベルとIOCTLリストを渡すことで、GPUデバイスノードにポリシーを適用します。
Googleは、SELinuxポリシーの開発を、テスト、調整、適用を含む反復的なプロセスにすべきだと強調しています。この方法により、実際の利用状況に関するデータを収集し、例外が必要となる可能性のあるケースを発見し、最初から広範な制限を適用するのではなく、ポリシーの範囲を段階的に拡大できます。
Googleは、攻撃対象領域の縮小は既知の脆弱性から保護するだけでなく、まだ発見されていない脆弱性や将来発生する可能性のある脆弱性も、制限された経路を通じてアクセスできない状態にできると考えています。このアプローチを拡大するには、Android、デバイスメーカー、エコシステムパートナー間の協力が必要です。Androidのセキュリティチームは、こうした対策をより広範に導入できるよう支援することに取り組んでいると述べています。