FPGA開発日記

カテゴリ別記事インデックス https://msyksphinz.github.io/github_pages , English Version https://fpgadevdiary.hatenadiary.com/

RISC-VのePMP(PMP Enhancements)仕様について概観する

RISC-VのPrivileged仕様Version 1.12 ではePMPレジスタ群(PMP Enhancements)についての仕様が検討されている。 これについて調査してみよう。

仕様書は以下に置いてある。誰でもダウンロードできる。

https://raw.githubusercontent.com/riscv/riscv-tee/main/Smepmp/Smepmp.pdf

そもそものモチベーションは、現状のPMPはスーパバイザモードについてのみ適用されており、マシンモードでは適用することが出来ない。これではマシンモードと非特権モードを使った攻撃を防ぐことが出来ない。

現在のスーパバイザモードを使った攻撃手法として以下が紹介されている:

  • SMAP(Supervisor memory Access Prevention) : 特定のコードパスをたどらない限り、OSが非特権プロセスのメモリにアクセスできないようにするもの
  • SMEP(supervisor Memory Execution Prevention) : OSが常に非特権プロセスのメモリを実行できないようにするもの

これについては、sstatus.SUMビットによるSMAPのサポートと、Uビットでマークされた仮想メモリページの実行を常に拒否するSMEPのサポートが、Privilege Specで義務付けられているSupervisor mode (OS)の特権ですでに行われている。

これに対して、マシンモードでもさらにPMPが適用できるようにするのがePMPの主たる目的だ。このために、以下のレジスタを定義する。

  • Machine Security Configuration (mseccfg)

    • Machine modeでのみアクセス可能
    • 64ビット幅。RV64では0x747、RV32では0x747(下位32ビット)、0x757(上位32ビット)のアドレスに割り当てられている。
  • mseccfgでは、ビット2にRule Locking Bypass (mseccfg.RLB)と呼ばれるフィールドを導入し、以下の機能を持たせている

      1. mseccfg.RLBが1の場合、ロックされたPMPルールの削除/変更が可能で、ロックされたPMPエントリの編集も可能
      1. mseccfg.RLBが0で、いずれかのルールまたはエントリ(無効化されたエントリを含む)でpmpcfg.Lが1の場合、mseccfg.RLBは0のままであり、mseccfg.RLBへのさらなる変更はPMPリセットまで無視される
  • mseccfgでは、ビット1にMachine Mode Whitelist Policy (mseccfg.MMWP)というフィールドを導入している

    • これはスティッキービットで、一度設定するとPMPをリセットするまで解除できない。
    • このビットがセットされると、MモードでマッチするPMPルールを持たないメモリ領域にアクセスする際のデフォルトのPMPポリシーが、無視ではなく拒否に変更されれる。
  • mseccfgでは、ビット0にMachine Mode Lockdown (mseccfg.MML)というフィールドを導入している

    • これはスティッキービットで、一度設定するとPMPのリセットがかかるまで解除できない
    • mseccfg.MMLが設定されると、システムの動作は次のように変わる
        1. pmpcfg.Lの意味が変わり、ルールをロックしてすべてのモードで強制するのではなく、セットされているときは M モード専用、セットされていないときは S/U モード専用としてルールをマークする
      • これまで予約されていたエンコーディングpmpcfg.RW=01とエンコーディングpmpcfg.LRWX=1111は、Shared-Regionをエンコードする
      • M-mode-onlyルールはMモードで強制され、SupervisorモードやUserモードでは拒否される。また、mseccfg.RLBが設定されていない限り、PMPのリセットが行われるまで、関連するコンフィグレーションやアドレスレジスタの変更が無視されるようにロックされる。S/U-mode-onlyルールはSupervisorおよびUserモードに適用され、Mモードでは拒否される。Shared-Regionルールはすべてのモードに適用されるが、pmpcfg.Lビットおよびpmpcfg.Xビットによる制限がある。
      • pmpcfg.Lが設定されていないShared-Regionルールは、MモードとS/Uモード間のデータ共有に使用されるため、実行は許可されない。Mモードはその領域への読み書きのアクセス権を持ち、S/Uモードはpmpcfg.Xが設定されていなければ読み書きのアクセス権、pmpcfg.Xが設定されていれば読み書きのアクセス権を持つ。
      • pmpcfg.Lが設定されているShared-Regionルールは、M-modeとS/U-modeの間でコードを共有するために使用することができるので、書き込みはでききない。M-modeとS/U-modeの両方が領域の実行アクセス権を持ち、pmpcfg.Xが設定されていればM-modeも読み取りアクセス権を持つ。ルールはロックされたままなので、関連するコンフィグレーションやアドレス・レジスタを変更しても、mseccfg.RLBが設定されていない限り、PMPのリセットまで無視される。
      • pmpcfg.LRWX=1111のエンコーディングは、MモードとS/Uモードの間でデータを共有する場合に使用できる。この場合、どちらのモードもその領域に対して読み取り専用のアクセスしかできない。ルールはロックされたままなので、関連するコンフィグレーションやアドレス・レジスタが変更されても、mseccfg.RLBが設定されていない限り、PMPのリセットまで無視される。
        1. 実行可能権限でMモード専用またはロックされた共有領域ルールを追加することはできず、そのようなpmpcfgの書き込みは無視され、pmpcfgは変更されまない。の制限は、起動時などに mseccfg.RLB を設定することで一時的に解除できる。
        1. マシンモードの特権を持つコードの実行は、実行可能な特権を持つ M モードオンリールールまたはロックされた Shared-Region ルールが一致するメモリ領域からのみ可能。
        1. mseccfg.MMLが設定されていない場合、pmpcfg.RW=01の組み合わせは、将来の標準的な使用のために予約されたままとなる。