none
VirtualUnlockを使用する意味は? RRS feed

  • 質問

  • いつもお世話になっております。アイルです。

     

    現在、セキュリティプログラミングについて学習しております。

    VirtualLock関数を使用し、「ページングファイル」に書き出されないようにしたメモリー空間を、VirtualUnlock関数を使用する意味はあるのでしょうか?

    以下のコードで、説明させていただきます。

      SYSTEM_INFO si;
      ::GetSystemInfo( & si );
      const DWORD virtual_memory_size = si.dwPageSize;
      // 1. メモリ確保
      void * pv = ::VirtualAlloc( nullptr, virtual_memory_size, MEM_RESERVE | MEM_COMMIT, PAGE_READWRITE );
      // 2. ページングファイルに書き込まれないようにする
      const BOOL b_lock = ::VirtualLock( pv, virtual_memory_size );
      if( b_lock != FALSE ) {
    
        // x. pv領域に個人情報などをかきこむ
    
        // 3. メモリを0に初期化
        ::RtlSecureZeroMemory( pv, virtual_memory_size );
        // 4. 個人情報などは入ってないので、ロックを解除する
        const BOOL b_unlock = ::VirtualUnlock( pv, virtual_memory_size );
        if( b_unlock != FALSE ) {
          // 5. メモリを解放
          const BOOL b_release = ::VirtualFree( pv, 0, MEM_RELEASE );
        }
      }
    


    VirtualUnlockを使用する意図として考えられるのが「3.メモリを0に初期化」を行ってからのVirtualUnlockです(個人的意見です)。

    ですが、VirtualUnlockとSecureZeroMemoryを行わずに「5.メモリを解放」を行うほうがコード量も少なくバグ混入の可能性も低いと思います。

    VirtualUnlockは何のために提供されているのでしょうか?

    ご教授のほどよろしくお願いいたします。

     

     

    2011年12月13日 3:33

回答

  • スワップアウトの禁止と言うのを、セキュリティだけで考えれば要らないのかもしれません。

    スワップアウトの禁止と言うのを、特別な処理速度を要する処理の為に使用するのであれば、

    特別な処理速度を要しなくなった時にメモリの内容を残したまま、スワップアウト可能に出来ます。

    VirtualLockも、VirtualUnlockも、セキュリティの対応の為だけに存在しているわけではありません。

     


    Sorry, I am not good at English.
    • 回答としてマーク アイル 2011年12月13日 7:12
    2011年12月13日 6:27

すべての返信

  • クリアしないのはまずいかも。
    「他から覗かれない」ためには、
     1.スワップに跡がのこらないこと
     2.メモリーに跡がのこらないこと
    と、できたら
     3.それっぽいウソッパチを書いおき、アホウを煙にまくこと
    が重要ですよね。

    2011年12月13日 4:52
  • 仲澤@失業者さん

    ご回答ありがとうございます。

     

    クリアしないことがまずいのは理解いたしました。

    ありがとうございます。

     

     

    仲澤@失業者さんのご回答で、「3. メモリを0に初期化」と「5. メモリを解放」のみでよいという認識に変わりました。

    ただ、やはり「4. ロック解除」が必要ないように思え、VirtualUnlockの使い道がわかりません。

    2011年12月13日 5:26
  • スワップアウトの禁止と言うのを、セキュリティだけで考えれば要らないのかもしれません。

    スワップアウトの禁止と言うのを、特別な処理速度を要する処理の為に使用するのであれば、

    特別な処理速度を要しなくなった時にメモリの内容を残したまま、スワップアウト可能に出来ます。

    VirtualLockも、VirtualUnlockも、セキュリティの対応の為だけに存在しているわけではありません。

     


    Sorry, I am not good at English.
    • 回答としてマーク アイル 2011年12月13日 7:12
    2011年12月13日 6:27
  • 仲澤@失業者さんへ:
    RtlSecureZeroMemory()でクリアーされているのでは?

    FC-Shiroさんへ:
    質問者さんは、セキュリティの手段としてスワップアウトの禁止を行っているのだと思います。

    質問者さんへ:
    ReadProcessMemory()などを使えば簡単にメモリーの内容を参照できます。それ以外にも方法はいろいろあります。また仮想マシン上で動作していた場合、仮想マシン内でページファイルに書き出されないようにしても、ハイパーバイザー側でページファイルに書き出すことは可能なはずです。「セキュリティプログラミング」(セキュアプログラミング?)とのことですが、守りたいものは何ですか?
    例えば.NET FrameworkにはSecureStringというクラスがありますが、これはメモリー内容を普段は暗号化しておき、必要になった時点で復号するというものです。こういうアプローチもある、ということで。MS SQL Serverで全ユーザーの生パスワード閲覧可能な脆弱性なんてものもありました。

    2011年12月13日 7:03
  • FC-Shiroさん

    ご回答ありがとうございます。

     

    納得いたしました。

    そのようなVirtualLockの使用方法もあったのですか。

    特別な処理速度が必要な場合は、AllocateUserPhysicalPagesを使用すると思っておりましたが、そういう訳でもないのですかね。

    2011年12月13日 7:12
  • 佐祐理さんへ。質問者さんの発言
    >ですが、VirtualUnlockとSecureZeroMemoryを行わずに「5.メモリを解放」を行うほうがコード量も少なくバグ混入の可能性も低いと思います。

    は、VirtualUnlock()も、RtlSecureZeroMemory()も行わないものと解釈しました。
    ちがったらごめんなさい。

    アイルさん、追加で、
     4.秘密の保持は短時間が望ましい。
    も気をつけましょう。

    また、個人的にはスワップアウトの禁止はセキュリティ上「必要」だと考えます。
    秘密情報をむりやりスワップアウトさせたあと、何らかの方法で
    電源をマニュアルで切らせる、その後でHDDをセクターリードしていけば、
    ウンがよければ見つかるかも。といった可能性が残されてしまいます。

    2011年12月13日 8:31
  • 仲澤@失業者さんへ

    > VirtualUnlock()も、RtlSecureZeroMemory()も行わないものと解釈しました

    そちらの解釈で間違っておりません。

    仲澤@失業者さんのご回答までは、行わないと記述しておりました。

     

    2011年12月13日 8:43
  • 佐祐理さんへ

    ご回答ありがとうございます。

     

    佐祐理さんのおっしゃる通り、セキュリティの手段としてスワップアウトを禁止にしております。

    ページングファイルに、個人情報などを書き出されたくなかったためです。

     

    現状は医療現場を想定してセキュアプログラミングについて学習しているつもりです。

    そのため、患者の情報に関するすべてを守りたいというものがあります。

    また、ご提示いただけた「MS SQL Serverで全ユーザーの生パスワード閲覧可能な脆弱性」を拝見いたしました。

    こちらを読むと、守りたいデータは、暗号化しておく必要があると認識いたしました。

    非常に参考になるご回答ありがとうございます。

    (守りたいものと大きく括るとネットワークも関連してくると思いますが、今回のスレッドでは考慮しておりません。)

    2011年12月13日 8:51
  • すみません、質問文を読み違えていました。
    2011年12月13日 9:00