Каков правильный способ очистки конфиденциальных данных из памяти в iOS?

Я хочу очистить конфиденциальные данные из памяти в моем приложении iOS. В Windows я использовал SecureZeroMemory. Теперь, в iOS, я использую простой старый memset, но я немного обеспокоен тем, что компилятор может его оптимизировать: https://buildsecurityin.us-cert.gov/bsi/articles/knowledge/coding/771-BSI.html

фрагмент кода:

 NSData *someSensitiveData;
 memset((void *)someSensitiveData.bytes, 0, someSensitiveData.length);

Ответ 1

Перефразируя 771-BSI (ссылка см. OP):

Способ избежать вызова memset, оптимизированного компилятором, - это снова получить доступ к буфере после вызова memset таким образом, чтобы заставить компилятор не оптимизировать местоположение. Это может быть достигнуто с помощью

*(volatile char*)buffer = *(volatile char*)buffer;

после вызова memset().

Фактически вы можете написать функцию secure_memset()

void* secure_memset(void *v, int c, size_t n) {
    volatile char *p = v;
    while (n--) *p++ = c;
    return v;
}

(Код, взятый из 771-BSI. Спасибо Даниэлю Треббиену за указание на возможный недостаток предыдущего предложения кода.)

Почему volatile предотвращает оптимизацию? См. fooobar.com/questions/64567/...

ОБНОВЛЕНИЕ Также читайте Чувствительные данные в памяти, потому что, если у вас есть противник в вашей системе iOS, вы уже более или менее ввернуты даже до того, как он попытается прочитать эту память. В сводке SecureZeroMemory() или secure_memset() действительно не помогают.

Ответ 2

Проблема NSData является неизменной, и вы не контролируете происходящее. Если буфер контролируется вами, вы можете использовать dataWithBytesNoCopy: length: и NSData будет действовать как обертка. По завершении вы можете записать свой буфер.