Erratum
In my blog post yesterday concerning zeroing arrays without interference from compiler optimization I incorrectly claimed that the following code was guaranteed to zero an array on any conforming C compiler:static void * (* const volatile memset_ptr)(void *, int, size_t) = memset;
static void
secure_memzero(void * p, size_t len)
{
(memset_ptr)(p, 0, len);
}
void
dosomethingsensitive(void)
{
uint8_t key[32];
...
/* Zero sensitive information. */
secure_memzero(key, sizeof(key));
}
While I was correct in stating that the compiler is required to access
memset_ptr
and is forbidden from assuming that it will not
change to point at some other function, I was wrong to conclude that
these meant that the compiler could not avoid zeroing the buffer: The
requirement to access the memset_ptr
function pointer
does not equate to a requirement to make a call via that pointer.
As "davidtgoldblatt" pointed out on Hacker News, a compiler could opt to
load memset_ptr
into a register, compare it to
memset
, and only make the function call if they are unequal,
since a call to memset
in that place is known to have no
observable effect.
In light of this and other observations, I do not believe that there is any way to force a C99 compiler (i.e., one which conforms to the standard but is otherwise free to act as perversely as it wishes) to generate code to zero a specified non-volatile object.