This is the mail archive of the gcc-bugs@gcc.gnu.org mailing list for the GCC project.


Index Nav: [Date Index] [Subject Index] [Author Index] [Thread Index]
Message Nav: [Date Prev] [Date Next] [Thread Prev] [Thread Next]
Other format: [Raw text]

[Bug rtl-optimization/69482] Writing through pointers to volatile not always preserved


https://gcc.gnu.org/bugzilla/show_bug.cgi?id=69482

--- Comment #5 from rguenther at suse dot de <rguenther at suse dot de> ---
On Wed, 27 Jan 2016, wipedout at yandex dot ru wrote:

> https://gcc.gnu.org/bugzilla/show_bug.cgi?id=69482
> 
> --- Comment #4 from wipedout at yandex dot ru ---
> Okay, suppose we have the following scenario. There's a third party library
> with an encryption function like this:
> 
>     void encrypt( void* data, void* key );
> 
> That function is compiled into as a static library and we cannot recompile it.
> We know that the function copies the key onto the stack and fails to overwrite
> it.
> 
> So we want to overwrite the stack after that function. Here's what we 
> could do:
> 
> 
>      void overwrite()
>      {
>           char array[SIZE];
>           memset_s( array, SIZE );
>      }
> 
>      void usefulFunction()
>      {
>          encrypt( something, key );
>          overwrite();
>      }
> 
> This would work the following way: first, `encrypt()` runs and leaves data on
> the stack. Then `overwrite()` runs, allocates an array which very likely
> overlaps with the area where `encrypt()` left the data and overwrites that
> array.
> 
> This "array is not used" optimization heuristic equally applies to the array in
> overwrite() and a later version of gcc may decide that no matter how the array
> is allocated it's not used and therefore no need to overwrite it.
> 
> Yes, I know that the trick relies on undefined behavior in the first place.

well, it doesn't rely on undefined behavior.  It relies on the compiler
not performing valid optimizations on it ;)

All it takes to make it work is declare 'array' itself volatile and
prevent the compiler from inlining 'overwrite' (otherwise the
stack-overwriting wouldn't work).

#include <stddef.h>
#include <string.h>

static void __attribute__((noinline))
overwrite (size_t n)
{
  volatile char array[n];
  unsigned i;
  for (i = 0; i < n; ++i)
    array[i] = 0;
}
extern void foo ();
void test()
{
    foo ();
    overwrite (1024);
}

works for me.  It may not be very fast (volatile char stores) though.

Index Nav: [Date Index] [Subject Index] [Author Index] [Thread Index]
Message Nav: [Date Prev] [Date Next] [Thread Prev] [Thread Next]