6

使用模板强制编译器初始化原始/POD 类型值是一种常见模式(https://stackoverflow.com/a/11493744/16673http://www.codeproject.com/Articles/825/Using-用于初始化的模板)。

是否存在类似的模式,一旦出于安全原因,值超出范围时可用于擦除该值,以确保在变量被破坏后该值不会留在堆栈中?我担心一个幼稚的类似实现可能不起作用,因为编译器可以自由地忽略对超出范围的值的任何赋值,因为可以简单地证明该值不再被使用。是否有一些一致且合理便携的解决方案,例如使用易失性?

4

2 回答 2

4

Windows API 中有一个名为 SecureZeroMemory 的函数。你可以看看它的实现。

但是,一般来说,编译器被迫接受易失性写入。如果您将变量设置为 volatile,则它应该无法删除写入。

于 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 回答