[cfe-dev] Security fail (memset being optimized away)
Paul Anderson via cfe-dev
cfe-dev at lists.llvm.org
Thu Jan 3 07:53:17 PST 2019
Hi:
There's a discussion of this very issue here:
https://wiki.sei.cmu.edu/confluence/display/c/MSC06-C.+Beware+of+compiler+optimizations
-Paul
On 1/3/2019 10:47 AM, myLC at gmx.de via cfe-dev 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?
>
>
> Thank you very much and a happy new year!
> LC
>
> _______________________________________________
> cfe-dev mailing list
> cfe-dev at lists.llvm.org
> http://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-dev
--
Paul Anderson, VP of Engineering, GrammaTech, Inc.
531 Esty St., Ithaca, NY 14850
Tel: +1 607 273-7340 x118; http://www.grammatech.com
More information about the cfe-dev
mailing list