<div dir="ltr"><div dir="ltr"><div dir="ltr"><div dir="ltr"><div dir="ltr"><div dir="ltr"><div dir="ltr"><div dir="ltr"><div dir="ltr"><div>It appears that the compiler explorer doesn't show the entire contents of the assembly. The missing part that matters is:</div><div><br></div><div>.LC0:<br>        .tc memset[TC],memset</div><div><br></div><div>So the pertinent sequence to do the indirect call to memset (I won't bother describing the concept of the TOC in excruciating detail, but it is a Table Of Contents that contains addresses to globals or in some case global values themselves):</div>addis 4, 2, .LC0@toc@ha # Load the bottom 16 bits of memset's TOC entry<br>ld 4, .LC0@toc@l(4)     # Load the high 16 bits of memset's TOC entry<br>std 4, 40(1)            # Store memset's TOC entry to the stack<br>ld 12, 40(1)            # Load the actual address of memset into R12<br>mtctr 12                # Move that value into the CTR (count register)<br>bctrl                   # Branch to address in the CTR<div><br></div><div><br></div><div>Hope that helps.</div><div>Nemanja<br></div></div></div></div></div></div></div></div></div></div><br><div class="gmail_quote"><div dir="ltr">On Thu, Jan 3, 2019 at 11:03 AM Keane, Erich 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:1px solid rgb(204,204,204);padding-left:1ex">I do not know PPC assembly, however note that Godbolt WILL highlight (with color) which assembly is the result of each line of code. See here: <a href="https://godbolt.org/z/PNPK4G" rel="noreferrer" target="_blank">https://godbolt.org/z/PNPK4G</a><br>
<br>
I note that changing the mem-set value is altering the load-immeidate line that is currently "li 4, 0".  Perhaps this is just being inlined?<br>
-----Original Message-----<br>
From: cfe-dev [mailto:<a href="mailto:cfe-dev-bounces@lists.llvm.org" target="_blank">cfe-dev-bounces@lists.llvm.org</a>] On Behalf Of <a href="mailto:myLC@gmx.de" target="_blank">myLC@gmx.de</a> via cfe-dev<br>
Sent: Thursday, January 3, 2019 7:48 AM<br>
To: <a href="mailto:cfe-dev@lists.llvm.org" target="_blank">cfe-dev@lists.llvm.org</a><br>
Subject: [cfe-dev] Security fail (memset being optimized away)<br>
<br>
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".<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 (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 "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".<br>
<br>
<br>
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.<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>
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).<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 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@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>
<br>
Thank you very much and a happy new year!<br>
        LC<br>
<br>
_______________________________________________<br>
cfe-dev mailing list<br>
<a href="mailto:cfe-dev@lists.llvm.org" target="_blank">cfe-dev@lists.llvm.org</a><br>
<a href="http://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-dev" rel="noreferrer" target="_blank">http://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-dev</a><br>
_______________________________________________<br>
cfe-dev mailing list<br>
<a href="mailto:cfe-dev@lists.llvm.org" target="_blank">cfe-dev@lists.llvm.org</a><br>
<a href="http://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-dev" rel="noreferrer" target="_blank">http://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-dev</a><br>
</blockquote></div>