Bugtraq mailing list archives

Re: When scrubbing secrets in memory doesn't work


From: Andy Polyakov <appro () fy chalmers se>
Date: Thu, 07 Nov 2002 09:08:13 +0100

On the surface, this looks fine, until you look at the ASM output, and
you see the call to memset has been removed by the optimizer because
szPwd is not read once the function completes. Hence, the secret data is
still floating in memory.

This optimization, common in most modern C/C++ compilers is often
referred to as "dead store removal."

Among a variety of tested compilers GCC>=3, SGI MIPSpro, and Microsoft
compilers were the only ones that actually eliminated the [inlined]
memset. Others preserved the inlined code [or call to memset for that
matter] at all optimization levels.

Thats why you have to declare such data volatile -- to prevent
optimizers from becoming too anxious to help.

Caveat lector! Both MIPSpro and Microsoft compilers effectively
ignore "volatilization" of pPwd. I mean even if you declare pPwd in
their example volatile, these two compilers still happily eliminate
the inlined memset, because volatile qualifier gets discarded at
"invocation" of memset [which compiler warns you about]. GCC>=3 is
apparently the only one that respects "volatilization" of pPwd.

It should also be noted that if you attempt to apply the first
workaround suggested my Michael Howard ("Touch secret data"), MIPSpro
and GCC>=3 nullify only the first byte of pPwd and leave the rest
intact!

The only thing that seem to work [on all affected platforms] is own
implementation of memset with internal "volatilization" of first
argument (second workaround proposed by Michael Howard):

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

which is safe at any optimization level [even if gets inlined].

Bottom line. "Volatilization" is indeed the answer, but it has to be
used in right place.

Cheers. A.


Current thread: