Edited at

ARMポインタ認証まとめ

文章にする時間がないので箇条書きで。


まとめ


  • ARMv8.3-Aの拡張仕様の1つ

  • 目的は攻撃者によるポインタ書き換えの検出


    • たぶんソフトウェアでも実装できるが、より安全で高速だと思われる


      • 性能評価結果はないのでどの程度性能が良いのかは不明





  • 攻撃者には生成できない認証コードをポインタに埋め込む


    • Aarch64だと仮想アドレスの一部は使われていないのでそこを利用する



    • 認証コードが埋め込まれたポインタは不正な仮想アドレスになる

    • ポインタ利用時には認証コードを検証し認証コードを削る

    • 認証に失敗したときはポインタ内の認証コード部分を壊すので、実際にポインタを利用しようとすると不正なアドレスとなり例外が発生しプログラムの実行が止まる



  • 認証コードの生成にはポインタ自体、秘密鍵、もう一つの何か(例:スタックポインタ)を用いる


    • 秘密鍵はシステムレジスタに保持され攻撃者はアクセスできない


      • 後述の新規命令でのみ利用できる



    • 5種類の鍵が存在するが違いはあまり理解していない(Linuxは1つしか使っていない)

    • 認証コードを生成するアルゴリズムはQARMA



  • 専用命令


    • ポインタに認証コードを付加するpac*命令, 認証コードを検証してポインタを元に戻すaut*命令がある

    • CPUに機能がない場合だとNOP扱いになる命令(例:paciasp)と、通常の命令(例:pacia)が存在する

    • 最初は前者のみサポート

    • 実際の使われ方はこのプレゼン資料(pdf)を参照



  • Linux 5.0でカーネル側のサポート機能が入る


    • exec時に秘密鍵を設定したり、コンテキストスイッチ時に鍵を切り替えたりする

    • 5.0ではポインタ認証が使えるのはユーザプロセスのみでカーネルでは使えない



  • コンパイラのオプションで上記命令を埋め込むことでポインタ認証をプログラムで利用する


    • GCCだと-msign-return-address

    • 引数は不明だがLLVMも対応ずみらしい




参考資料