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

Jonny Grant via cfe-dev cfe-dev at lists.llvm.org
Fri Jan 4 07:54:30 PST 2019



On 04/01/2019 15:41, myLC at gmx.de wrote:
> On 1/4/19 3:47 PM, Jonny Grant wrote:
>  > ...
>> Maybe add an abort()  ?
>>
>> eg
>>
>> inline void check_memset(void *s, int c, size_t n);
>> {
>>      const char * buf = (char*)buf;
>>      memset(2, 0, n);
>>
>>      if(0 != *buf)
>>      {
>>          abort();
>>      }
>> }
> 
> 
> I'm afraid, that won't cut it either. On the "Compiler Explorer"
> website ( https://godbolt.org/ ) you can see that many compilers
> implement "their own" inlined version of memset - especially
> when you turn on "max optimizations" (-O3). The compiler might
> simply decide to only clear the first byte as the rest is not
> being access anyhow...

Did you verify that in practice with my code? (optimising out memset)


I've not not time to run tests on godbolt.org

>> Or use a for loop to verify all bytes are now 0.
> 
> The compiler knows that the buffer has to be all zeros as it
> knows, it just cleared it before. This is basically a more
> complicated version of:
> {
>      int a = 0;
>      if( a != 0 )
>          abort();
> }
> This can never call abort and will therefore be removed
> completely.

Compilers are not static analysers, they don't know when ram addresses 
were touched as far as I am aware. Do you have a source for this 
information?


If you don't want to use libc memset() if you feel it might be lost, 
write your own. Or put those functions in a library that is not 
optimised at all.


Whatever you do. verify how it looks after compilation to be sure. Share 
your results, I'm interested to hear.
Jonny




More information about the cfe-dev mailing list