Bug 87210 - [RFE] introduce build time options to zero initialize automatic stack variables
Summary: [RFE] introduce build time options to zero initialize automatic stack variables
Status: RESOLVED FIXED
Alias: None
Product: gcc
Classification: Unclassified
Component: middle-end (show other bugs)
Version: 8.0
: P3 enhancement
Target Milestone: 12.0
Assignee: qinzhao
URL:
Keywords:
: 70069 94855 (view as bug list)
Depends on:
Blocks:
 
Reported: 2018-09-03 19:44 UTC by P J P
Modified: 2021-11-29 06:28 UTC (History)
5 users (show)

See Also:
Host:
Target:
Build:
Known to work:
Known to fail:
Last reconfirmed: 2021-08-07 00:00:00


Attachments

Note You need to log in before you can comment on or make changes to this bug.
Description P J P 2018-09-03 19:44:45 UTC
Hello,

Please see:
  -> http://www.openwall.com/lists/kernel-hardening/2018/02/27/33
  -> http://www.openwall.com/lists/kernel-hardening/2018/02/27/41

Some time back, a proposal to zero(0) initialize various automatic stack variables(inc arrays/structs/etc.) inside kernel was proposed based on an experimental glibc patch, with an intention to remove kernel information leakage issues.


As from the reply, it would be nice to have four options/features available
from the compiler, from least to most performance impact:
 
 - initialize padding to zero when static initializers are used (this would 
   make foo = { .field = something }; identical to memset(&foo, 0, 
   sizeof(foo)); foo.field = something for all structures, but now, any 
   structures with padding _must_ use the latter to be safe, which is highly 
   error-prone).
 
 - initialize all uninitialized variables that contain a structure marked 
   with a special attribute (e.g.  __attribute__((force_initialize)) ).
 
 - initialize all uninitialized variables that are passed by reference (see 
   GCC_PLUGIN_STRUCTLEAK_BYREF_ALL).
 
 - initialize all uninitialized variables (-finit-local-vars seems to do 
   this)

The advent of h/w vulnerabilities like Spectre and Meltdown and more recently L1TF has not only opened a new research area but has also reiterated the importance of initializing memory bytes with known values.

Also see:
  -> https://googleprojectzero.blogspot.com/2018/06/detecting-kernel-memory-disclosure.html


Would it be possible to introduce new gcc(1) command-line options to initialize automatic stack variables(inc arrays/structs/etc.) of a program?

Thank you.
Comment 1 Andrew Pinski 2018-09-03 19:50:03 UTC
http://wiki.c2.com/?TheKenThompsonHack
Comment 2 joseph@codesourcery.com 2018-09-03 20:32:05 UTC
On Mon, 3 Sep 2018, pjp at fedoraproject dot org wrote:

> As from the reply, it would be nice to have four options/features available
> from the compiler, from least to most performance impact:
> 
>  - initialize padding to zero when static initializers are used (this would 
>    make foo = { .field = something }; identical to memset(&foo, 0, 
>    sizeof(foo)); foo.field = something for all structures, but now, any 
>    structures with padding _must_ use the latter to be safe, which is highly 
>    error-prone).

Presumably that sort of thing would need to come with a guarantee that 
SRA, structure assignment etc. preserve padding (rather than padding 
contents potentially being lost if a structure is subject to SRA)?

(Both are effectively treating padding like additional named fields for 
the purposes of code generation but without affecting what fields the 
front end associates initializers with.  I'd expect the performance costs 
of such guarantees associated with padding to be small.)
Comment 3 P J P 2019-02-15 11:55:46 UTC
Similar options under review for LLVM
  -> https://lists.llvm.org/pipermail/cfe-dev/2018-November/060172.html
Comment 4 Alexander Potapenko 2019-10-25 12:28:40 UTC
To give an update, upstream Clang now supports force initialization of stack variables under the -ftrivial-auto-var-init flag.

-ftrivial-auto-var-init=pattern initializes local variables with a 0xAA pattern (actually it's more complicated, see https://reviews.llvm.org/D54604)

-ftrivial-auto-var-init=zero provides zero-initialization of locals. This mode isn't officially supported yet and is hidden behind an additional -enable-trivial-auto-var-init-zero-knowing-it-will-be-removed-from-clang flag.
This is done to avoid creating a C++ dialect where all variables are zero-initialized.

Starting v5.2, Linux kernel has a CONFIG_INIT_STACK_ALL config that performs the build with -ftrivial-auto-var-init=pattern. This one isn't widely adopted yet, partially because initializing locals with 0xAA isn't fast enough.

Linus Torvalds is quite positive about zero-initializing the locals though, see https://lkml.org/lkml/2019/7/30/1303

So having a flag similar to -ftrivial-auto-var-init=zero in GCC will be appreciated by the Linux kernel community.
Comment 5 Andrew Pinski 2020-04-29 18:51:28 UTC
*** Bug 94855 has been marked as a duplicate of this bug. ***
Comment 6 qinzhao 2020-05-15 20:44:27 UTC
So, based on the previous discussion on the LLVM option 
-ftrivial-auto-var-init=[uninitialized|pattern|zero]

we can see:
-ftrivial-auto-var-init=pattern 

might not be a good idea due to the following:

1. performance data is not good;
2. doesn't really help improve the general situation. People see it as a debugging tool, not a "improve code quality and improve the life of kernel developers" tool. (Per Linus)

On the other hand,
-ftrivial-auto-var-init=zero

might be helpful to improve code quality and improve the life fo kernel developers. 

At the same time, a new variable attribute might be needed at the same time along with -ftrivial-auto-var-init=zero:

__attribute((uninitialized) 

to mark variables that are uninitialized intentionally for performance purpose.

In a summary, in GCC, we should provide:
1. add a new GCC option: -ftrivial-auto-var-init to initialize trivial auto variable to zero.
2. provide a new attribute for variable: __attribute((uninitialized) to mark variables that are uninitialized intentionally for performance purpose.
Comment 7 Andrew Pinski 2021-08-07 20:01:10 UTC
Confirmed.
Comment 8 Andrew Pinski 2021-08-07 20:04:34 UTC
*** Bug 70069 has been marked as a duplicate of this bug. ***
Comment 9 Andrew Pinski 2021-11-29 06:28:51 UTC
  -ftrivial-auto-var-init=[uninitialized|pattern|zero] Add initializations to automatic variables.