2022-12-21 :-(
_ 形容語句という言葉を知った
- ぼっち・ざ・ろっく
- マジック・ザ・ギャザリング
- ヴァッシュ・ザ・スタンピード
- ソニック・ザ・ヘッジホッグ
などのように「ザ」を用いた言葉である。
「ぼっち・ざ・ろっく」は「ロック界のぼっちちゃん」みたいな意味ぽいです。
_ ARM TrustZone for ARMv8-Mを利用した軽量メモリ保護RTOS
TrustZone
パーティショニング機構 (メモリなどの区画を区切り、 1 箇所が汚染されても他が汚染されないようにすること) を実現するために ARMv8-M Security Extensions (Cortex-M Security Extensions とも呼ばれる。以降 CSME と呼ぶ) を利用する。 CSME は TrustZone 技術に基づいた機能である。 (TrustZone は MPU によくあるような特権モード・非特権モードと似たものと考えてよさそう)
パーティショニング機構は特権モード・非特権モードを利用すれば MPU と OS によりソフトウェアでも実現できるが、オーバーヘッドが大きく(処理時間に影響)、 ソフトウェアも大きくなってしまう(メモリ使用量やストレージ使用量に影響) つまり結局ハードウェアに影響し、高くついてしまう。そこで TrustZone です(きゅぴーん)
CSME
CSME ではメモリアドレスのセキュリティ属性を以下 3 つに設定できる
- Secure (Secure Mode のみアクセス可能)
- Non-Secure Callable (Non-Secure からは制限付きでジャンプ可能)
- Non-Secure (常にアクセス可能)
つまり Non-Secure から Secure を呼ぶ (サービスコールのことです) ためには Non-Secure → Non-Secure Callable →Secure とシーケンスするわけである。Non-Secure Callable は橋渡しの位置づけとなる。
Non-Secure から Non-Secure Callable 呼ぶために SG 命令 (Secure Gateway) を使う。 SG 命令は Non-Secure Callable の関数で使う。関数の先頭で SG 命令を使う。SG が呼ばれた時点で自動で Secure Mode に遷移する。便利。
設計
本論文では Secure と Non-Secure に分けて設計する。つまりこれがパーティショニングとして働く。ここではユーザードメインを Non-Secure とし、システムドメインやカーネルを Secure とする。
- Secure : システムドメインやカーネル
- Non-Secure : ユーザードメイン
(ユーザードメインはユーザーランドと言い換えてよさそう。カーネルはカーネルだけど、システムドメインは Unix 系でいうならサービスとかデーモンの類いと考えればよさそう。 本論文ではセキュア領域と非セキュア領域でバイナリを分割する手法や、各々別の OS にしてしまう手法も紹介されているが、本論文で検討されたのはすべて単一のバイナリで実現する手法)
実装
実装する項目は以下の通り
- サービスコール用の Secure Gate の実装
- Non-Secure スタックの追加
- ディスパッチャの変更
- リンカスクリプト
サービスコール用の Secure Gate の実装
先ほど書いた Non-Secure → Non-Secure Callable →Secure を橋渡しするために Secure Gateway を実装する。実装にあたって考慮することが 2 つある。
- ポインタの検証
- レジスタのクリア
サービスコールにポインタを渡せるものがあるが、不正なポインタ ( Secure 領域を指すポインタ) を渡すとサービスコールが不正利用されてしまう可能性がある。そのため CSME の TT 命令でポインタのアドレスを取得し、そのアドレスが Secure 領域のものでないことを確認しておく。
Secure から Non-Secure にリターンするときスタックポインタに Secure の情報が残っていると Non-Secure 側に情報が漏れてしまう。リターンする前にスタックポインタとして利用するレジスタをクリアする。
以上のものを Secure Gateway 内に実装する。
Non-Secure スタックの追加
各タスクに Non-Secure 用にスタックを追加。ユーザードメインのタスクは Non-Secure で実行されて、サービスコールを呼ぶと Secure Mode となる。このとき他のタスクからサービスコールが呼ばれると Secure Mode のデータを操作される可能性がある。
それと ARMv8-M の仕様としてスタックポインタが Secure/Non-Secure Mode でバンクされているため。サービスコールの先頭でスタックポインタを Non-Secure から Secure へコピーしないといけない。
ディスパッチャの変更
上記のようにスタックポインタが Secure/Non-Secure の両方あるのでタスクを起動させるディスパッチャを変更しないといけない。スタックポインタの復元と、プロセッサモードを Secure/Non-Secure を切り替えるように変更する。
リンカスクリプト
シンボルが Secure/Non-Secure のアドレスにまとめて配置されるようにするためにリンカスクリプトを変更した。
評価
Secure/Non-Secure の切り替えが ARMv8-M によりおこなわれるので速くなった(雑)