<div dir="ltr"><div dir="ltr"><div dir="ltr"><br></div><br><div class="gmail_quote"><div dir="ltr">On Thu, Jan 3, 2019 at 7:47 AM <a href="mailto:myLC@gmx.de">myLC@gmx.de</a> via cfe-dev <<a href="mailto:cfe-dev@lists.llvm.org">cfe-dev@lists.llvm.org</a>> wrote:<br></div><blockquote class="gmail_quote" style="margin:0px 0px 0px 0.8ex;border-left-width:1px;border-left-style:solid;border-left-color:rgb(204,204,204);padding-left:1ex">A few days ago Ilja van Sprundel held a talk at the 35C3 (Chaos Computer Club<br>
annual convention) calling it "Memsad - why clearing memory is hard".<br>
It can be found here:<br>
<br>
<a href="https://media.ccc.de/v/35c3-9788-memsad" rel="noreferrer" target="_blank">https://media.ccc.de/v/35c3-9788-memsad</a><br>
or here:<br>
<a href="https://www.youtube.com/watch?v=0WzjAKABSDk" rel="noreferrer" target="_blank">https://www.youtube.com/watch?v=0WzjAKABSDk</a><br>
<br>
The problem he described arises, when you have a buffer with sensitive content<br>
(crypto key) and try to clear this from memory, before the buffer goes out of<br>
scope:<br>
<br>
<br>
#include <string.h><br>
<br>
void foo( int x ) {<br>
     char buf[ 10 ];<br>
     size_t i;<br>
     for( i = 0; i < sizeof( buf ); ++i )<br>
         buf[ i ] = x++;<br>
// ...<br>
     memset( buf, 0, sizeof( buf ) );   // rightfully removed by optimizer<br>
}<br>
<br>
<br>
He showed how this sort of code could be found in many implementations, thus<br>
"leaking" sensitive information into memory (core dumps), which was intended<br>
to be overwritten. He described the problematic of finding a portable solution<br>
for a "forced memset".<br>
<br>
<br>
Purely out of curiosity, this made me wonder about how to force the execution<br>
of a function that would otherwise be optimized away - in a portable manner.<br>
I came up with these unsophisticated lines:<br>
<br>
<br>
#include <string.h><br>
<br>
void foo( int x ) {<br>
     char buf[ 10 ];<br>
     size_t i;<br>
     for( i = 0; i < sizeof( buf ); ++i )<br>
         buf[ i ] = x++;<br>
// ...<br>
     // Declare volvar as volatile pointer to function (void*, int, size_t ) returning void*:<br>
     void* ( *volatile volvar )( void*, int, size_t ) = &memset;<br>
     // Call memset from within this "black box":<br>
     ( *volvar )( buf, 0, sizeof( buf ) );<br>
}<br>
<br>
<br>
The idea behind this is simple. "volvar" is a volatile variable. Therefore,<br>
the compiler can make no assumptions on its contents at compile time. It<br>
cannot remove the function call, which is based on that variable's content<br>
(at that given time).<br>
<br>
This code looks portable to me. I tested it on "Compiler Explorer"<br>
( <a href="https://godbolt.org/" rel="noreferrer" target="_blank">https://godbolt.org/</a> ). It compiles without warnings on all targets I<br>
tested. Except for one, all contain the reference to memset and display the<br>
call. The exception is the PowerPC platform in conjunction with CLANG<br>
("power64le clang - trunk" and "powerpc64 clang - trunk". I'm guessing, that<br>
this is running "some version" of memset (inlined?) as well, but references<br>
to ".LC0@toc@ha" and such leave me puzzled.<br>
<br>
<br>
Without wanting to disturb too much, I'm asking about your opinion.<br>
Is this solution portable?<br>
Does it assure that the function call will not be optimized away?<br>
And - does the CLANG PowerPC version work as well?<br>
<br></blockquote><div><br></div><div>If I understand correctly what you're looking for, this should be relevant: <a href="https://github.com/google/benchmark/blob/master/include/benchmark/benchmark.h#L309-L312">https://github.com/google/benchmark/blob/master/include/benchmark/benchmark.h#L309-L312</a></div><div><br></div><div>Best,</div><div><br></div><div>-- </div><div>Mehdi</div><div><br></div></div></div></div>