public inbox for gcc@gcc.gnu.org
 help / color / mirror / Atom feed
* About BZ#87210 [RFE] To initialize automatic stack variables
       [not found] <1225413012.1679387.1550571810991.ref@mail.yahoo.com>
@ 2019-02-19 10:24 ` P J P
  2019-03-04 10:44   ` P J P
  2019-03-04 20:46   ` David Brown
  0 siblings, 2 replies; 11+ messages in thread
From: P J P @ 2019-02-19 10:24 UTC (permalink / raw)
  To: gcc

Hello,
  -> https://gcc.gnu.org/bugzilla/show_bug.cgi?id=87210

This RFE is about providing gcc option(s) to eliminate information leakage
issues from programs. Information leakage via uninitialised memory has beena chronic/recurring issue across all software. They are found quite often andmay lead to severe effects if found in system software/kernel, OR an applicationwhich handles sensitive information.
Various projects/efforts are underway to keep such information exposurefrom happening
* STACKLEAK - http://lkml.iu.edu/hypermail/linux/kernel/1810.3/00522.html
* KLEAK - https://netbsd.org/gallery/presentations/maxv/kleak.pdf* https://j00ru.vexillium.org/papers/2018/bochspwn_reloaded.pdf
But these are still external corrections to improve specific project and/orsoftware. It does not help to fix/eliminate all information leakage issues.
Automatic memory initialisation:

* https://lists.llvm.org/pipermail/cfe-dev/2018-November/060172.htmlhttps://reviews.llvm.org/D54604
It'd be immensely helpful and welcome if gcc(1) could provide compile/buildtime options to enable/disable - automatic memory initialisation.
Could we please consider it as more viable/useful option?
Thank you.---
  -P J P
http://feedmug.com

^ permalink raw reply	[flat|nested] 11+ messages in thread

* Re: About BZ#87210 [RFE] To initialize automatic stack variables
  2019-02-19 10:24 ` About BZ#87210 [RFE] To initialize automatic stack variables P J P
@ 2019-03-04 10:44   ` P J P
  2019-03-04 12:02     ` Richard Biener
  2019-03-04 20:46   ` David Brown
  1 sibling, 1 reply; 11+ messages in thread
From: P J P @ 2019-03-04 10:44 UTC (permalink / raw)
  To: Gcc Mailing List

On Tuesday, 19 February, 2019, 3:55:35 PM IST, P J P <pjp@fedoraproject.org> wrote:
>
>Hello,
>
>  -> https://gcc.gnu.org/bugzilla/show_bug.cgi?id=87210
>
>This RFE is about providing gcc option(s) to eliminate information leakage
>issues from programs. Information leakage via uninitialised memory has been
>a chronic/recurring issue across all software. They are found quite often
>and may lead to severe effects if found in system software/kernel, OR an
>application which handles sensitive information.
>
>Various projects/efforts are underway to keep such information exposure
>from happening
>
>* STACKLEAK - http://lkml.iu.edu/hypermail/linux/kernel/1810.3/00522.html
>* KLEAK - https://netbsd.org/gallery/presentations/maxv/kleak.pdf
>* https://j00ru.vexillium.org/papers/2018/bochspwn_reloaded.pdf
>
>But these are still external corrections to improve specific project and/or
>software. It does not help to fix/eliminate all information leakage issues.
>Automatic memory initialisation:
>
>* https://lists.llvm.org/pipermail/cfe-dev/2018-November/060172.html
>* https://reviews.llvm.org/D54604
>
>It'd be immensely helpful and welcome if gcc(1) could provide compile/build
>time options to enable/disable - automatic memory initialisation.
>
>Could we please consider it as more viable/useful option?

Ping...!
---
  -P J P
http://feedmug.com

^ permalink raw reply	[flat|nested] 11+ messages in thread

* Re: About BZ#87210 [RFE] To initialize automatic stack variables
  2019-03-04 10:44   ` P J P
@ 2019-03-04 12:02     ` Richard Biener
  0 siblings, 0 replies; 11+ messages in thread
From: Richard Biener @ 2019-03-04 12:02 UTC (permalink / raw)
  To: P J P; +Cc: Gcc Mailing List

On Mon, Mar 4, 2019 at 11:44 AM P J P <pjp@fedoraproject.org> wrote:
>
> On Tuesday, 19 February, 2019, 3:55:35 PM IST, P J P <pjp@fedoraproject.org> wrote:
> >
> >Hello,
> >
> >  -> https://gcc.gnu.org/bugzilla/show_bug.cgi?id=87210
> >
> >This RFE is about providing gcc option(s) to eliminate information leakage
> >issues from programs. Information leakage via uninitialised memory has been
> >a chronic/recurring issue across all software. They are found quite often
> >and may lead to severe effects if found in system software/kernel, OR an
> >application which handles sensitive information.
> >
> >Various projects/efforts are underway to keep such information exposure
> >from happening
> >
> >* STACKLEAK - http://lkml.iu.edu/hypermail/linux/kernel/1810.3/00522.html
> >* KLEAK - https://netbsd.org/gallery/presentations/maxv/kleak.pdf
> >* https://j00ru.vexillium.org/papers/2018/bochspwn_reloaded.pdf
> >
> >But these are still external corrections to improve specific project and/or
> >software. It does not help to fix/eliminate all information leakage issues.
> >Automatic memory initialisation:
> >
> >* https://lists.llvm.org/pipermail/cfe-dev/2018-November/060172.html
> >* https://reviews.llvm.org/D54604
> >
> >It'd be immensely helpful and welcome if gcc(1) could provide compile/build
> >time options to enable/disable - automatic memory initialisation.
> >
> >Could we please consider it as more viable/useful option?
>
> Ping...!

Patches welcome(?)

Richard.

> ---
>   -P J P
> http://feedmug.com

^ permalink raw reply	[flat|nested] 11+ messages in thread

* Re: About BZ#87210 [RFE] To initialize automatic stack variables
  2019-02-19 10:24 ` About BZ#87210 [RFE] To initialize automatic stack variables P J P
  2019-03-04 10:44   ` P J P
@ 2019-03-04 20:46   ` David Brown
  2019-03-05 18:37     ` Segher Boessenkool
  2019-03-06 13:43     ` Alexander Potapenko via gcc
  1 sibling, 2 replies; 11+ messages in thread
From: David Brown @ 2019-03-04 20:46 UTC (permalink / raw)
  To: P J P, gcc

On 19/02/2019 11:23, P J P wrote:
> Hello,
>    -> https://gcc.gnu.org/bugzilla/show_bug.cgi?id=87210
> 
> This RFE is about providing gcc option(s) to eliminate information leakage
> issues from programs. Information leakage via uninitialised memory has beena chronic/recurring issue across all software. They are found quite often andmay lead to severe effects if found in system software/kernel, OR an applicationwhich handles sensitive information.
> Various projects/efforts are underway to keep such information exposurefrom happening
> * STACKLEAK - http://lkml.iu.edu/hypermail/linux/kernel/1810.3/00522.html
> * KLEAK - https://netbsd.org/gallery/presentations/maxv/kleak.pdf* https://j00ru.vexillium.org/papers/2018/bochspwn_reloaded.pdf
> But these are still external corrections to improve specific project and/orsoftware. It does not help to fix/eliminate all information leakage issues.
> Automatic memory initialisation:
> 
> * https://lists.llvm.org/pipermail/cfe-dev/2018-November/060172.html
> * https://reviews.llvm.org/D54604
> It'd be immensely helpful and welcome if gcc(1) could provide compile/buildtime options to enable/disable - automatic memory initialisation.
> Could we please consider it as more viable/useful option?
> Thank you.---
>    -P J P
> http://feedmug.com
> 

This strikes me as getting the issue completely backwards.

It is not lack of initialisation of stack variables that leads to 
information leakage - it is a failure to clear the important data left 
behind on the stack.

The problem with information leakage is when you have something like:

void foo(void) {
	char key[20];
	strcpy(key, "Top secret!");
	usekey(&key);
	memset(key, 0, sizeof(key));	// optimised away by DSE
}

void bar(void) {
	foo();
	char stolen_key[40];	// Covering "key" and other stack
	steal_key(&stolen_key);
}


Forcing "stolen_key" to be zero initialised does not help anyone - 
options for that just make code slower and hide errors that would occur 
with other compiler options.  The challenge is to make sure /key/ is 
zeroed out after use - no matter what optimisations, and whether or not 
the "memset" is called.

gcc already has mechanisms for handling this.

First, there is a way to tell gcc that something in memory will be read, 
even though it doesn't look like it:

void foo(void) {
     char key[20];
     strcpy(key, "Top secret");
     usekey(key);
     memset(key, 0, sizeof(key));
     {
         typedef struct { char x[20]; } XS;
         XS *p = (XS *) key;
         asm("" : "+m" (*p));
     }
}

Next, to automate the clearing of the key regardless of how and when the 
function "foo" is exited and whether or not "memset" is called, we can 
use the "cleanup" attribute:

static void clearKey(char (*key)[20]) {
     memset(key, 0, 20);
     {
         typedef struct { char x[20]; } XS;
         XS *p = (XS *) key;
         asm("" : "+m" (*p));
     }
}

void foo2(void) {
     char key[20] __attribute__((cleanup(clearKey)));
     strcpy(key, "Top secret");
     usekey(key);
}

This stops information leakage where it should be stopped - once the 
information is no longer used.  Forcing initialisation of stack 
variables would put it in the wrong place, when the stack space is reused.

And the code generated here is as good as it gets - no efficiency is lost.


So as far as I can see, gcc has all the bits it needs - it just needs a 
nicer and simpler syntax.  Something like an attribute "secure" which 
will generate and use an appropriately sized zeroing function on scope 
exit.  Ideally, this could be attached to a type as well as a variable.

(I have no idea how simple or difficult this task might be.)


^ permalink raw reply	[flat|nested] 11+ messages in thread

* Re: About BZ#87210 [RFE] To initialize automatic stack variables
  2019-03-04 20:46   ` David Brown
@ 2019-03-05 18:37     ` Segher Boessenkool
  2019-03-05 20:37       ` David Brown
  2019-03-06 13:43     ` Alexander Potapenko via gcc
  1 sibling, 1 reply; 11+ messages in thread
From: Segher Boessenkool @ 2019-03-05 18:37 UTC (permalink / raw)
  To: David Brown; +Cc: P J P, gcc

Hi!

On Mon, Mar 04, 2019 at 09:45:37PM +0100, David Brown wrote:
> Forcing "stolen_key" to be zero initialised does not help anyone - 
> options for that just make code slower and hide errors that would occur 
> with other compiler options.  The challenge is to make sure /key/ is 
> zeroed out after use - no matter what optimisations, and whether or not 
> the "memset" is called.

Yup.

> gcc already has mechanisms for handling this.
> 
> First, there is a way to tell gcc that something in memory will be read, 
> even though it doesn't look like it:
> 
> void foo(void) {
>     char key[20];
>     strcpy(key, "Top secret");
>     usekey(key);
>     memset(key, 0, sizeof(key));
>     {
>         typedef struct { char x[20]; } XS;
>         XS *p = (XS *) key;
>         asm("" : "+m" (*p));
>     }
> }

You need to use "asm volatile" here.  In principle GCC can see all the
outputs of the asm are dead and delete all of the asm, otherwise.  But
you don't need an output for *p (or inout as you wrote), just an input
is fine.

> This stops information leakage where it should be stopped - once the 
> information is no longer used.  Forcing initialisation of stack 
> variables would put it in the wrong place, when the stack space is reused.

Letting one context/process/etc. handle both secret and non-secret data
is a recipe for disaster already.  If you do not fix that, all you can
hope for is some mitigation.

Calling this "secure" is false advertising :-(  It is better than not
clearing such (stack) buffers, absolutely.


Segher

^ permalink raw reply	[flat|nested] 11+ messages in thread

* Re: About BZ#87210 [RFE] To initialize automatic stack variables
  2019-03-05 18:37     ` Segher Boessenkool
@ 2019-03-05 20:37       ` David Brown
  2019-03-05 21:17         ` Martin Sebor
  2019-03-06  1:51         ` Segher Boessenkool
  0 siblings, 2 replies; 11+ messages in thread
From: David Brown @ 2019-03-05 20:37 UTC (permalink / raw)
  To: Segher Boessenkool; +Cc: P J P, gcc



On 05/03/2019 19:37, Segher Boessenkool wrote:
> Hi!
> 
> On Mon, Mar 04, 2019 at 09:45:37PM +0100, David Brown wrote:
>> Forcing "stolen_key" to be zero initialised does not help anyone -
>> options for that just make code slower and hide errors that would occur
>> with other compiler options.  The challenge is to make sure /key/ is
>> zeroed out after use - no matter what optimisations, and whether or not
>> the "memset" is called.
> 
> Yup.
> 
>> gcc already has mechanisms for handling this.
>>
>> First, there is a way to tell gcc that something in memory will be read,
>> even though it doesn't look like it:
>>
>> void foo(void) {
>>      char key[20];
>>      strcpy(key, "Top secret");
>>      usekey(key);
>>      memset(key, 0, sizeof(key));
>>      {
>>          typedef struct { char x[20]; } XS;
>>          XS *p = (XS *) key;
>>          asm("" : "+m" (*p));
>>      }
>> }
> 
> You need to use "asm volatile" here.  In principle GCC can see all the
> outputs of the asm are dead and delete all of the asm, otherwise.  But
> you don't need an output for *p (or inout as you wrote), just an input
> is fine.

There are no outputs from this asm - only an input.  gcc "asm" without 
any outputs is always treated as volatile (since otherwise the asm 
statement would have been pointless).  But if you prefer, there is no 
harm in writing "asm volatile" - arguably it is clearer.

<https://gcc.gnu.org/onlinedocs/gcc-8.2.0/gcc/Extended-Asm.html#Volatile-1>

For added paranoia, you may want to include a cache flush.

> 
>> This stops information leakage where it should be stopped - once the
>> information is no longer used.  Forcing initialisation of stack
>> variables would put it in the wrong place, when the stack space is reused.
> 
> Letting one context/process/etc. handle both secret and non-secret data
> is a recipe for disaster already.  If you do not fix that, all you can
> hope for is some mitigation.

Certainly there are all sorts of considerations for making code secure - 
or rather, for making the code more secure.  You can never be entirely 
secure, all you can do is reduce the possibilities of attacks or leaks, 
and reduce the consequences of them, until you have something that is 
good enough for its purpose.  Carefully splitting responsibilities 
between processes or contexts is one mechanism of many - as is ensuring 
that secret data is properly erased.

> 
> Calling this "secure" is false advertising :-(  It is better than not
> clearing such (stack) buffers, absolutely.
> 

I'm confident that there could be better choices of attribute name than 
"secure".  I just can't think of any off-hand!

> 
> Segher
> 

^ permalink raw reply	[flat|nested] 11+ messages in thread

* Re: About BZ#87210 [RFE] To initialize automatic stack variables
  2019-03-05 20:37       ` David Brown
@ 2019-03-05 21:17         ` Martin Sebor
  2019-03-05 23:08           ` Mark Wielaard
  2019-03-06  1:51         ` Segher Boessenkool
  1 sibling, 1 reply; 11+ messages in thread
From: Martin Sebor @ 2019-03-05 21:17 UTC (permalink / raw)
  To: David Brown, Segher Boessenkool; +Cc: P J P, gcc

On 3/5/19 1:36 PM, David Brown wrote:
> 
> 
> On 05/03/2019 19:37, Segher Boessenkool wrote:
>> Hi!
>>
>> On Mon, Mar 04, 2019 at 09:45:37PM +0100, David Brown wrote:
>>> Forcing "stolen_key" to be zero initialised does not help anyone -
>>> options for that just make code slower and hide errors that would occur
>>> with other compiler options.  The challenge is to make sure /key/ is
>>> zeroed out after use - no matter what optimisations, and whether or not
>>> the "memset" is called.
>>
>> Yup.
>>
>>> gcc already has mechanisms for handling this.
>>>
>>> First, there is a way to tell gcc that something in memory will be read,
>>> even though it doesn't look like it:
>>>
>>> void foo(void) {
>>>      char key[20];
>>>      strcpy(key, "Top secret");
>>>      usekey(key);
>>>      memset(key, 0, sizeof(key));
>>>      {
>>>          typedef struct { char x[20]; } XS;
>>>          XS *p = (XS *) key;
>>>          asm("" : "+m" (*p));
>>>      }
>>> }
>>
>> You need to use "asm volatile" here.  In principle GCC can see all the
>> outputs of the asm are dead and delete all of the asm, otherwise.  But
>> you don't need an output for *p (or inout as you wrote), just an input
>> is fine.
> 
> There are no outputs from this asm - only an input.  gcc "asm" without 
> any outputs is always treated as volatile (since otherwise the asm 
> statement would have been pointless).  But if you prefer, there is no 
> harm in writing "asm volatile" - arguably it is clearer.
> 
> <https://gcc.gnu.org/onlinedocs/gcc-8.2.0/gcc/Extended-Asm.html#Volatile-1>
> 
> For added paranoia, you may want to include a cache flush.
> 
>>
>>> This stops information leakage where it should be stopped - once the
>>> information is no longer used.  Forcing initialisation of stack
>>> variables would put it in the wrong place, when the stack space is 
>>> reused.
>>
>> Letting one context/process/etc. handle both secret and non-secret data
>> is a recipe for disaster already.  If you do not fix that, all you can
>> hope for is some mitigation.
> 
> Certainly there are all sorts of considerations for making code secure - 
> or rather, for making the code more secure.  You can never be entirely 
> secure, all you can do is reduce the possibilities of attacks or leaks, 
> and reduce the consequences of them, until you have something that is 
> good enough for its purpose.  Carefully splitting responsibilities 
> between processes or contexts is one mechanism of many - as is ensuring 
> that secret data is properly erased.
> 
>>
>> Calling this "secure" is false advertising :-(  It is better than not
>> clearing such (stack) buffers, absolutely.
>>
> 
> I'm confident that there could be better choices of attribute name than 
> "secure".  I just can't think of any off-hand!

The SECURE project adds the function attribute stack_erase that
serves the purpose described above.  It works on stack frames by
design rather than applying to individual stack objects.
The presentation they delivered at Cauldron 2018 made it sound
like they were on track for submitting the  feature to GCC:

   https://www.youtube.com/watch?v=Lg_jJLtH7R0

Martin

^ permalink raw reply	[flat|nested] 11+ messages in thread

* Re: About BZ#87210 [RFE] To initialize automatic stack variables
  2019-03-05 21:17         ` Martin Sebor
@ 2019-03-05 23:08           ` Mark Wielaard
  0 siblings, 0 replies; 11+ messages in thread
From: Mark Wielaard @ 2019-03-05 23:08 UTC (permalink / raw)
  To: Martin Sebor; +Cc: Graham Markall, David Brown, Segher Boessenkool, P J P, gcc

On Tue, Mar 05, 2019 at 02:17:51PM -0700, Martin Sebor wrote:
> The SECURE project adds the function attribute stack_erase that
> serves the purpose described above.  It works on stack frames by
> design rather than applying to individual stack objects.
> The presentation they delivered at Cauldron 2018 made it sound
> like they were on track for submitting the  feature to GCC:
> 
>   https://www.youtube.com/watch?v=Lg_jJLtH7R0

The slides of that talk can be found here:
https://gmarkall.files.wordpress.com/2018/09/secure_and_gcc.pdf

^ permalink raw reply	[flat|nested] 11+ messages in thread

* Re: About BZ#87210 [RFE] To initialize automatic stack variables
  2019-03-05 20:37       ` David Brown
  2019-03-05 21:17         ` Martin Sebor
@ 2019-03-06  1:51         ` Segher Boessenkool
  2019-03-06 13:11           ` David Brown
  1 sibling, 1 reply; 11+ messages in thread
From: Segher Boessenkool @ 2019-03-06  1:51 UTC (permalink / raw)
  To: David Brown; +Cc: P J P, gcc

On Tue, Mar 05, 2019 at 09:36:56PM +0100, David Brown wrote:
> On 05/03/2019 19:37, Segher Boessenkool wrote:
> >On Mon, Mar 04, 2019 at 09:45:37PM +0100, David Brown wrote:
> >>void foo(void) {
> >>     char key[20];
> >>     strcpy(key, "Top secret");
> >>     usekey(key);
> >>     memset(key, 0, sizeof(key));
> >>     {
> >>         typedef struct { char x[20]; } XS;
> >>         XS *p = (XS *) key;
> >>         asm("" : "+m" (*p));
> >>     }
> >>}
> >
> >You need to use "asm volatile" here.  In principle GCC can see all the
> >outputs of the asm are dead and delete all of the asm, otherwise.  But
> >you don't need an output for *p (or inout as you wrote), just an input
> >is fine.
> 
> There are no outputs from this asm - only an input.

"+m" is an output.  There is only one colon before it, and besides, "+"
is only allowed on outputs.


Segher

^ permalink raw reply	[flat|nested] 11+ messages in thread

* Re: About BZ#87210 [RFE] To initialize automatic stack variables
  2019-03-06  1:51         ` Segher Boessenkool
@ 2019-03-06 13:11           ` David Brown
  0 siblings, 0 replies; 11+ messages in thread
From: David Brown @ 2019-03-06 13:11 UTC (permalink / raw)
  To: Segher Boessenkool; +Cc: P J P, gcc

On 06/03/2019 02:50, Segher Boessenkool wrote:
> On Tue, Mar 05, 2019 at 09:36:56PM +0100, David Brown wrote:
>> On 05/03/2019 19:37, Segher Boessenkool wrote:
>>> On Mon, Mar 04, 2019 at 09:45:37PM +0100, David Brown wrote:
>>>> void foo(void) {
>>>>     char key[20];
>>>>     strcpy(key, "Top secret");
>>>>     usekey(key);
>>>>     memset(key, 0, sizeof(key));
>>>>     {
>>>>         typedef struct { char x[20]; } XS;
>>>>         XS *p = (XS *) key;
>>>>         asm("" : "+m" (*p));
>>>>     }
>>>> }
>>>
>>> You need to use "asm volatile" here.  In principle GCC can see all the
>>> outputs of the asm are dead and delete all of the asm, otherwise.  But
>>> you don't need an output for *p (or inout as you wrote), just an input
>>> is fine.
>>
>> There are no outputs from this asm - only an input.
> 
> "+m" is an output.  There is only one colon before it, and besides, "+"
> is only allowed on outputs.
> 

My apologies - I had copied this from the wrong function in my code.
The "+m" makes this an input and an output - which in fact is good
enough here, since it forces the memset to be completed before the empty
asm code is run.  But it does mean the "output" should be used or it
risks being removed by the optimiser (when the "volatile" is omitted).

The asm line should have been:

	asm("" :: "m" (*p));

That makes it an input-only asm, which is automatically volatile.  It
may also aid optimisation in some cases, since the compiler knows the
value of "key" is unchanged after the assembly (unlike after the first
version of the asm).

^ permalink raw reply	[flat|nested] 11+ messages in thread

* Re: About BZ#87210 [RFE] To initialize automatic stack variables
  2019-03-04 20:46   ` David Brown
  2019-03-05 18:37     ` Segher Boessenkool
@ 2019-03-06 13:43     ` Alexander Potapenko via gcc
  1 sibling, 0 replies; 11+ messages in thread
From: Alexander Potapenko via gcc @ 2019-03-06 13:43 UTC (permalink / raw)
  To: David Brown; +Cc: P J P, gcc

On Mon, Mar 4, 2019 at 9:46 PM David Brown <david.brown@hesbynett.no> wrote:
>
> On 19/02/2019 11:23, P J P wrote:
> > Hello,
> >    -> https://gcc.gnu.org/bugzilla/show_bug.cgi?id=87210
> >
> > This RFE is about providing gcc option(s) to eliminate information leakage
> > issues from programs. Information leakage via uninitialised memory has beena chronic/recurring issue across all software. They are found quite often andmay lead to severe effects if found in system software/kernel, OR an applicationwhich handles sensitive information.
> > Various projects/efforts are underway to keep such information exposurefrom happening
> > * STACKLEAK - http://lkml.iu.edu/hypermail/linux/kernel/1810.3/00522.html
> > * KLEAK - https://netbsd.org/gallery/presentations/maxv/kleak.pdf* https://j00ru.vexillium.org/papers/2018/bochspwn_reloaded.pdf
> > But these are still external corrections to improve specific project and/orsoftware. It does not help to fix/eliminate all information leakage issues.
> > Automatic memory initialisation:
> >
> > * https://lists.llvm.org/pipermail/cfe-dev/2018-November/060172.html
> > * https://reviews.llvm.org/D54604
> > It'd be immensely helpful and welcome if gcc(1) could provide compile/buildtime options to enable/disable - automatic memory initialisation.
> > Could we please consider it as more viable/useful option?
> > Thank you.---
> >    -P J P
> > http://feedmug.com
> >
>
> This strikes me as getting the issue completely backwards.
>
> It is not lack of initialisation of stack variables that leads to
> information leakage - it is a failure to clear the important data left
> behind on the stack.
Well, yes and no.
If we consider only a handful of variables containing important data,
we can probably afford to annotate them to be cleared upon leaving the
function using an attribute you're suggesting below.
(Although humans are really bad at annotating code - such attributes
go out of sync in no time).
But e.g. in the Linux kernel even a leak of a single word or a pointer
can help malicious users to defeat ASLR, stack canaries etc.
Now, if we choose to clear _every_ local variable when we leave the
function, we'll have to memset the whole stack frame, which is costly
(as you mention, we don't want the memset to be optimized away).
At the same time, memsetting locals upon function entry gives us the
same result, but has a bigger optimization potential (most of the time
one won't have to pre-initialize anything, thanks to DSE).

> The problem with information leakage is when you have something like:
>
> void foo(void) {
>         char key[20];
>         strcpy(key, "Top secret!");
>         usekey(&key);
>         memset(key, 0, sizeof(key));    // optimised away by DSE
> }
>
> void bar(void) {
>         foo();
>         char stolen_key[40];    // Covering "key" and other stack
>         steal_key(&stolen_key);
> }
>
>
> Forcing "stolen_key" to be zero initialised does not help anyone -
> options for that just make code slower and hide errors that would occur
> with other compiler options.  The challenge is to make sure /key/ is
> zeroed out after use - no matter what optimisations, and whether or not
> the "memset" is called.
>
> gcc already has mechanisms for handling this.
>
> First, there is a way to tell gcc that something in memory will be read,
> even though it doesn't look like it:
>
> void foo(void) {
>      char key[20];
>      strcpy(key, "Top secret");
>      usekey(key);
>      memset(key, 0, sizeof(key));
>      {
>          typedef struct { char x[20]; } XS;
>          XS *p = (XS *) key;
>          asm("" : "+m" (*p));
>      }
> }
>
> Next, to automate the clearing of the key regardless of how and when the
> function "foo" is exited and whether or not "memset" is called, we can
> use the "cleanup" attribute:
>
> static void clearKey(char (*key)[20]) {
>      memset(key, 0, 20);
>      {
>          typedef struct { char x[20]; } XS;
>          XS *p = (XS *) key;
>          asm("" : "+m" (*p));
>      }
> }
>
> void foo2(void) {
>      char key[20] __attribute__((cleanup(clearKey)));
>      strcpy(key, "Top secret");
>      usekey(key);
> }
>
> This stops information leakage where it should be stopped - once the
> information is no longer used.  Forcing initialisation of stack
> variables would put it in the wrong place, when the stack space is reused.
>
> And the code generated here is as good as it gets - no efficiency is lost.
>
>
> So as far as I can see, gcc has all the bits it needs - it just needs a
> nicer and simpler syntax.  Something like an attribute "secure" which
> will generate and use an appropriately sized zeroing function on scope
> exit.  Ideally, this could be attached to a type as well as a variable.
>
> (I have no idea how simple or difficult this task might be.)
>
>


-- 
Alexander Potapenko
Software Engineer

Google Germany GmbH
Erika-Mann-Straße, 33
80636 München

Geschäftsführer: Paul Manicle, Halimah DeLaine Prado
Registergericht und -nummer: Hamburg, HRB 86891
Sitz der Gesellschaft: Hamburg

^ permalink raw reply	[flat|nested] 11+ messages in thread

end of thread, other threads:[~2019-03-06 13:43 UTC | newest]

Thread overview: 11+ messages (download: mbox.gz / follow: Atom feed)
-- links below jump to the message on this page --
     [not found] <1225413012.1679387.1550571810991.ref@mail.yahoo.com>
2019-02-19 10:24 ` About BZ#87210 [RFE] To initialize automatic stack variables P J P
2019-03-04 10:44   ` P J P
2019-03-04 12:02     ` Richard Biener
2019-03-04 20:46   ` David Brown
2019-03-05 18:37     ` Segher Boessenkool
2019-03-05 20:37       ` David Brown
2019-03-05 21:17         ` Martin Sebor
2019-03-05 23:08           ` Mark Wielaard
2019-03-06  1:51         ` Segher Boessenkool
2019-03-06 13:11           ` David Brown
2019-03-06 13:43     ` Alexander Potapenko via gcc

This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox;
as well as URLs for read-only IMAP folder(s) and NNTP newsgroup(s).