
Appleシリコン搭載MacのRosetta 2
Appleシリコン搭載Macは、Rosetta 2と呼ばれる変換メカニズムを使用してx86_64命令セット用にコンパイルされたコードを実行できます。ジャストインタイムと事前という2種類の変換が用意されています。
ジャストインタイム変換
ジャストインタイム(JIT)変換パイプラインでは、x86_64 Machオブジェクトがイメージ実行パスの早い段階で識別されます。これらのイメージが検出されると、カーネルは制御を動的リンクエディタ(dyld(1)
)ではなく特殊なRosetta変換スタブに委譲します。そのあと、この変換スタブがイメージの実行中にx86_64ページを変換します。この変換は完全にプロセス内で行われます。カーネルは、ページに障害が発生したときにバイナリに添付されたコード署名に対して各x86_64ページのコードハッシュを検証します。ハッシュの不一致が発生した場合、カーネルはそのプロセスに適した修復ポリシーを適用します。
事前変換
事前(AOT)変換パスでは、システムがそのコードの応答性に最適であると判断した時点で、x86_64バイナリがストレージから読み取られます。変換されたアーティファクトは、特殊なタイプのMachオブジェクトファイルとしてストレージに書き込まれます。そのファイルは実行可能イメージに似ていますが、別のイメージの変換された製品であることを示すためにマークが付けられています。
このモデルでは、AOTアーティファクトは、元のx86_64実行可能イメージからすべてのID情報を導出します。このバインディングを適用するために、特権付きユーザ空間エンティティは、Secure Enclaveによって管理されるデバイス固有の鍵を使用して変換アーティファクトに署名します。この鍵は、制限された資格を使用して特権付きユーザ空間エンティティとして識別される特権付きユーザ空間エンティティにのみ解放されます。変換アーティファクト用に作成されたコードディレクトリには、元のx86_64実行可能イメージのコードディレクトリハッシュが含まれています。変換アーティファクト自体の署名は、補助的署名と呼ばれます。
AOTパイプラインはJITパイプラインと同様に開始され、カーネルは動的リンクエディタ(dyld(1)
)ではなくRosettaランタイムに制御を委譲します。ただし、Rosettaランタイムはプロセス間通信(IPC)クエリをRosettaシステムサービスに送信し、Rosettaシステムサービスが現在の実行可能イメージに使用できるAOT変換があるかどうかを確認します。ある場合、Rosettaサービスはその変換へのハンドルを提供し、それがプロセスにマッピングされて実行されます。実行中にカーネルは、デバイス固有の署名鍵をルートとする署名によって認証される変換アーティファクトのコードディレクトリハッシュを適用します。元のx86_64イメージのコードディレクトリハッシュは、このプロセスには関与しません。
変換されたアーティファクトは、Rosettaサービス以外のエンティティはランタイムにアクセスできないData Vaultに保存されます。Rosettaサービスは、読み取り専用のファイル記述子を個々の変換アーティファクトに配付することにより、キャッシュへのアクセスを管理します。これにより、AOTアーティファクトのキャッシュへのアクセスが制限されます。このサービスのプロセス間通信と依存するフットプリントは、攻撃対象領域を制限するために意図的に非常に狭く保たれています。
元のx86_64イメージのコードディレクトリハッシュがAOT変換アーティファクトの署名にエンコードされたものと一致しない場合、この結果は無効なコード署名と同等であると見なされ、適切な適用アクションが実行されます。
リモートプロセスでカーネルにAOT変換された実行可能ファイルの資格またはその他のコードIDプロパティが照会されると、元のx86_64イメージのIDプロパティがカーネルに返されます。
静的信頼キャッシュの内容
macOS 11以降は、x86_64とarm64のコンピュータコードのスライスを含むMachの「ファット」バイナリと一緒に提供されます。Appleシリコン搭載Macでは、ユーザは、例えばネイティブのarm64バリアントのないプラグインを読み込むために、Rosettaパイプラインを介してシステムバイナリのx86_64スライスを実行することを決定できます。このアプローチをサポートするために、macOSと一緒に提供される静的信頼キャッシュには、一般的に、Machオブジェクトファイルごとに3つのコードディレクトリハッシュが含まれています:
arm64スライスのコードディレクトリハッシュ
x86_64スライスのコードディレクトリハッシュ
x86_64スライスのAOT変換のコードディレクトリハッシュ
RosettaのAOT変換手順は、変換がいつ実行されたか、またはどのデバイスで実行されたかに関係なく、任意の入力に対して同一の出力を再現するという点で決定論的です。
macOSのビルド中に、すべてのMachオブジェクトファイルは、ビルドされているmacOSのバージョンに関連付けられたRosetta AOT変換パイプラインを介して実行され、結果のコードディレクトリハッシュが信頼キャッシュに記録されます。効率のため、実際に変換された製品は、オペレーティングシステムと一緒に提供されず、ユーザが要求したときにオンデマンドで再構成されます。
x86_64イメージがAppleシリコン搭載Macで実行されているときに、そのイメージのコードディレクトリのハッシュが静的信頼キャッシュ内にある場合、結果のAOTアーティファクトのコードディレクトリのハッシュも静的信頼キャッシュにあると予想されます。署名機関はAppleのセキュアブートチェーンのルートであるため、このような製品はデバイス固有の鍵で署名されていません。
無署名のx86_64コード
Appleシリコン搭載Macでは、有効な署名が添付されていない限り、ネイティブのarm64コードを実行することはできません。この署名は、非対称鍵ペアの秘密の半分に基づく実際のIDを持たないアドホックコード署名(codesign(1)
を参照)と同じくらいシンプルにすることができます(これは単にバイナリの認証されていない測定値です)。
変換されたx86_64コードは、バイナリ互換性のために、署名情報なしでRosettaを介して実行することが許可されています。デバイス固有のSecure Enclave署名手順を介してこのコードに特定のIDが伝達されることはなく、Intelプロセッサ搭載Macで実行されるネイティブの無署名のコードとまったく同じ制限で実行されます。