6

テンプレートを使用してコンパイラにプリミティブ/POD 型の値を初期化させるのは一般的なパターンです ( https://stackoverflow.com/a/11493744/16673またはhttp://www.codeproject.com/Articles/825/Using-初期化用のテンプレート)。

変数が破棄された後に値がスタックに残らないようにするために、セキュリティ上の理由から値が範囲外になったときに値を消去するために使用できる同様のパターンは存在しますか? 値がもはや使用されないことを自明に証明できるため、コンパイラはスコープ外になる値への割り当てを自由に無視できるため、単純な類似の実装は機能しない可能性があると思います。volatile を使用するなど、一貫性のある合理的に移植可能なソリューションはありますか?

4

2 に答える 2

4

Windows API には SecureZeroMemory という関数があります。その実装を見ることができます。

ただし、一般的に言えば、コンパイラは揮発性の書き込みを受け入れるように強制されます。変数を揮発性にすると、書き込みを削除できなくなります。

于 2012-09-04T08:19:12.047 に答える
3

いくつかの C++11 機能を使用して移植性を高めることもできますが、出発点としてはこれで十分な場合があります。

クラス

template<typename T>
class t_secure_destruct {
  static const size_t Size = sizeof(T);
  static const size_t Align = alignof(T);
public:
  t_secure_destruct() : d_memory() {
    new(this->d_memory)T;
  }

  ~t_secure_destruct() {
    reinterpret_cast<T*>(this->d_memory)->~T();
    this->scribble();
  }

  // @todo implement or delete op-assign and remaining constructors

public:
  T& get() {
    return *reinterpret_cast<T*>(this->d_memory);
  }

  const T& get() const {
    return *reinterpret_cast<const T*>(this->d_memory);
  }

private:
  void scribble() {
    for (size_t idx(0); idx < Size; ++idx) {
      this->d_memory[idx] = random();
    }
  }

private:
  __attribute__((aligned(Align))) char d_memory[Size];
};

デモ

#include <iostream>

class t_test {
public:
  t_test() : a(-1) {
    std::cout << "construct\n";
  }

  ~t_test() {
    std::cout << "destruct\n";
  }

public:
  void print() const {
    std::cout << "a = " << a << "\n";
  }

public:
  int a;
};

int main(int argc, const char* argv[]) {
  t_secure_destruct<t_test>test;
  test.get().print();
  test.get().a = 100;
  test.get().print();
  return 0;
}

もちろん、必要に応じて、ヒープ割り当てでその割り当てをバックアップすることもできます。オプティマイザーの裏をかく必要がある場合は、スクリブラーを手の届かないところに配置する必要がある場合があります。

于 2012-09-04T08:00:21.680 に答える