memset at the end of functions

Pertaining to any discovery, principle, or aspect of science and/or technology. Open debates and discussions are welcome. Also now dealing with any happening in the news.

Moderator: Geeks United

Post Reply
User avatar
BugInTheSYS
Chaos Rift Cool Newbie
Chaos Rift Cool Newbie
Posts: 88
Joined: Mon Feb 07, 2011 4:16 pm
Current Project: Vintage Roads
Favorite Gaming Platforms: PC
Programming Language of Choice: C++, Delphi
Location: Pinneberg, Germany
Contact:

memset at the end of functions

Post 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.
Someday, everything will go to /dev/null. - Bug's prophecy 13:37
User avatar
bbguimaraes
Chaos Rift Junior
Chaos Rift Junior
Posts: 294
Joined: Wed Apr 11, 2012 4:34 pm
Programming Language of Choice: c++
Location: Brazil
Contact:

Re: memset at the end of functions

Post 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).
User avatar
Falco Girgis
Elysian Shadows Team
Elysian Shadows Team
Posts: 10294
Joined: Thu May 20, 2004 2:04 pm
Current Project: Elysian Shadows
Favorite Gaming Platforms: Dreamcast, SNES, NES
Programming Language of Choice: C/++
Location: Studio Vorbis, AL
Contact:

Re: memset at the end of functions

Post 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...
User avatar
bbguimaraes
Chaos Rift Junior
Chaos Rift Junior
Posts: 294
Joined: Wed Apr 11, 2012 4:34 pm
Programming Language of Choice: c++
Location: Brazil
Contact:

Re: memset at the end of functions

Post by bbguimaraes »

User avatar
Falco Girgis
Elysian Shadows Team
Elysian Shadows Team
Posts: 10294
Joined: Thu May 20, 2004 2:04 pm
Current Project: Elysian Shadows
Favorite Gaming Platforms: Dreamcast, SNES, NES
Programming Language of Choice: C/++
Location: Studio Vorbis, AL
Contact:

Re: memset at the end of functions

Post 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.
Post Reply