Шаблон для выполнения автоматической перезаписи памяти при уничтожении

Это общий шаблон использования шаблонов для принудительной инициализации компилятором значений типов примитивов / POD (https://stackoverflow.com/a/11493744/16673 или же http://www.codeproject.com/Articles/825/Using-templates-for-initialization).

Существует ли подобный шаблон, который можно использовать для удаления значения, когда оно выходит из области видимости, из соображений безопасности, чтобы убедиться, что значение не осталось в стеке после разрушения переменной? Я боюсь, что наивная аналогичная реализация может не сработать, так как компилятор может игнорировать любые присвоения значению, выходящему за рамки, поскольку это значение может быть тривиально доказано, что оно больше не используется. Есть ли какое-то последовательное и достаточно портативное решение, например, с использованием летучих?

6

Решение

Вы можете использовать некоторые функции 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;
}

Конечно, вы также можете подкрепить это распределение кучей, если хотите. Если вам нужно перехитрить оптимизатор, вам, возможно, придется вывести скрайблер из его досягаемости.

3

Другие решения

В Windows API есть функция SecureZeroMemory. Вы можете посмотреть на его реализацию.

Однако, вообще говоря, компилятор вынужден выполнять изменчивые записи. Если вы сделали переменную volatile, она не сможет удалить записи.

4

По вопросам рекламы ammmcru@yandex.ru
Adblock
detector