volatile
иногда может быть излишним, так как это также повлияет на все другие варианты использования переменной.
Используйте memset_s
(начиная с C11): http://en.cppreference.com/w/c/string/byte/memset
memset может быть оптимизирован (согласно правилам «как если бы»), если к объекту, измененному этой функцией, не будет обращений снова до конца его жизни. По этой причине эту функцию нельзя использовать для очистки памяти (например, для заполнения массива, в котором хранится пароль, нулями). Эта оптимизация запрещена для memset_s: она гарантированно выполняет запись в память.
int secret_foo(void)
{
int key = get_secret();
/* use the key to do highly privileged stuff */
....
memset_s(&key, sizeof(int), 0, sizeof(int));
return result;
}
Вы можете найти другие решения для различных платформ/стандартов C здесь: https://www.securecoding.cert.org/confluence/display/c/MSC06-C.+Beware+of+compiler+optimizations
Дополнение: ознакомьтесь с этой статьей Недостаточно обнуления буфера, что указывает на другие проблемы (помимо обнуления фактического буфера):
Приложив немного осторожности и взаимодействуя с компилятором, мы можем обнулить буфер a, но это не то, что нам нужно. Что нам нужно сделать, так это обнулить каждое место, где могут храниться конфиденциальные данные. Помните, что основная причина, по которой у нас в памяти хранилась конфиденциальная информация, заключалась прежде всего в том, чтобы мы могли ее использовать; и это использование почти наверняка привело к копированию конфиденциальных данных в стек и в регистры.
Ваше значение key
могло быть скопировано компилятором в другое место (например, в регистр или во временный стек/память), и у вас нет возможности очистить это место.
person
fukanchik
schedule
26.05.2016
return result + (key = 0);
? - person Weather Vane   schedule 27.05.2016return result;
- person AlexD   schedule 27.05.2016