[cfe-dev] Security fail (memset being optimized away)

Mehdi AMINI via cfe-dev cfe-dev at lists.llvm.org
Fri Jan 4 03:13:35 PST 2019


On Thu, Jan 3, 2019 at 7:47 AM myLC at gmx.de via cfe-dev <
cfe-dev at lists.llvm.org> wrote:

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

Best,

-- 
Mehdi
-------------- next part --------------
An HTML attachment was scrubbed...
URL: <http://lists.llvm.org/pipermail/cfe-dev/attachments/20190104/f491c78a/attachment.html>


More information about the cfe-dev mailing list