Page 1 of 1

memset at the end of functions

Posted: Tue Mar 12, 2013 8:37 am
by BugInTheSYS
So today I read an article about how gcc and the like will optimize away memset() calls at the end of a function, which can be annoying when (e.g. in crypto applications) you want to be sure that you don't leave a footprint of sensitive data in memory. This type of optimization isn't new to the world, but new to gcc. (Apparently 4.7.2 and newer)

It is said that you can fix this behavior by inserting the statement
asm volatile("" ::: "memory");
after the memset call, so GCC will not reorder memory instructions. It's generally nice to know that command. So, if you're worried about people analyzing memory dumps of your programs, you know what to do... Also it's probably better to check the assembly code anyway.

Re: memset at the end of functions

Posted: Tue Mar 12, 2013 11:57 am
by bbguimaraes
Isn't there a switch among the ten thousand gcc switches to avoid that? I think that would be the standard solution (although I don't think people would go through that if it could be done this way).

Re: memset at the end of functions

Posted: Wed Mar 13, 2013 10:09 am
by Falco Girgis
I'm not sure whether there is a flag or not that you can pass to GCC (surely a lower optimization mode will get rid of that, but that probably isn't really a good way to avoid it).

It is a legitimate optimization.
Section 5.1.2.3 of the C Standard [ISO/IEC 9899:2011] states: wrote:In the abstract machine, all expressions are evaluated as specified by the semantics. An actual implementation need not evaluate part of an expression if it can deduce that its value is not used and that no needed side effects are produced (including any caused by calling a function or accessing a volatile object).
Other than for the reason previously stated, I can't think of any time you wouldn't want this optimization.

Just remember that even clearing out the data is not necessarily safe. If the data ever exists within RAM for any period of time, it is a potential security hazard. All you are doing with that memset() is reducing the size of this window.

I read that at least Windows (and probably all other modern OS's) zero out memory pages before giving them to an application. I can't see any way for a user-level application in a modern OS to access your application's virtual memory space. Whatever malicious piece of code would have to be executing within kernel-space to do such a thing...

Re: memset at the end of functions

Posted: Wed Mar 13, 2013 12:07 pm
by bbguimaraes

Re: memset at the end of functions

Posted: Thu Mar 14, 2013 8:49 am
by Falco Girgis
bbguimaraes wrote:Which reminds me of this:

http://nakedsecurity.sophos.com/2013/02 ... -its-keys/
Damn, that's a good article!


And for further reading on the memset optimization:
https://www.securecoding.cert.org/confl ... itive+data

I have to admit, though... The example given seems pretty damn weak in my book:

Code: Select all

void getPassword(void) {
  char pwd[64];
  if (GetPassword(pwd, sizeof(pwd))) {
    /* checking of password, secure operations, etc */
  }
  memset(pwd, 0, sizeof(pwd));
}
Even if that memset were optimized away, the function is ending. The statistical likelihood of future function calls' pushes to the stack not immediately overriding those 64 bytes with their own local storage is EXTREMELY low...

As I said, all you are doing is reducing the already extremely short window of time before that gets overwritten.