Is there a way to ensure that deallocated data is erased on the physical memory? E.G. If I have some super secret stored value like a private key in a swift class and I want make sure, that no trace is left on RAM after deallocation of that class.
For classes, you can zero-d out data during deinit.
Is there a special command, or a standard code snippid to do that properly?
I don't know if there is one, but if you can get the pointer to the data, you can use
memset. Though I do not know if it is safe enough for security purpose.
Is there a way to ensure that deallocated data is erased on the
Not really. There’s lots security theatre you can apply here, but it’s a rare day where those measures actually achieve anything. This question crops up regularly on DevForums, and you can find my standard responses on this thread (make sure to scroll down to the 17 Jul 2015 post).
Share and Enjoy
Quinn “The Eskimo!” @ DTS @ Apple
If I might add to what Quinn wrote, there are a lot of moving parts that are not under your control that can create copies of memory that you can't realistically control or even track. For example, Swift doesn't allow users to supplement the destructor logic of value types, so something like a
String could have been copied implicitly or explicitly many times over. Even if you don't store a password in a
String and even if you explicitly use a
class to store the password, the OS can move and copy memory around as it pleases (for example, paging).
Personally, what matters most is that sensitive data should never be reachable from long-lived data structures. In other words, if your program has the ability to "debug dump" internal state, then sensitive data shouldn't be in the output when the program is idle.
Ignoring the other concerns for a moment, I can answer the question about memset: it’s not sufficient. memset_s exists for this use case.
Does it help to call the destructor and overwrite all entries of a class with zeros or something less important before dereferencing?
In particular, the optimizer will eliminate the C function
memset if it can prove that it's the last thing that happens before an object is released to the system, because the
memset has no observable effect on the program's execution when that's the case (it effects the state of system memory, but that's outside the scope of the abstract machine that defines the language semantics).
memset_s is guaranteed to zero the memory, because it does not receive this special treatment from the optimizer. FWIW, I think it would be perfectly reasonable to have Swift map
memset_s (or other equivalent operation), to avoid this particular pitfall.
But: even securely zeroing a buffer doesn't guarantee that it's gone, since the compiler is free to generate temporary copies on the stack or in register or on the heap, and--since those have no name in the your program's source--you have no way to zero them.