On Mon, Jun 07, 2021 at 09:48:41AM +0200, Richard Biener wrote:
> On Thu, 27 May 2021, Qing Zhao wrote:
> > @@ -5001,6 +5185,17 @@ gimplify_init_constructor (tree *expr_p, gimple_seq
> > *pre_p, gimple_seq *post_p,
> > /* If a single access to the target must be ensured and all
> > elements
> > are zero, then it's optimal to clear whatever their number.
> > */
> > cleared = true;
> > + else if (flag_trivial_auto_var_init > AUTO_INIT_UNINITIALIZED
> > + && !TREE_STATIC (object)
> > + && type_has_padding (type))
> > + /* If the user requests to initialize automatic variables with
> > + paddings inside the type, we should initialize the paddings
> > too.
> > + C guarantees that brace-init with fewer initializers than
> > members
> > + aggregate will initialize the rest of the aggregate as-if it
> > were
> > + static initialization. In turn static initialization
> > guarantees
> > + that pad is initialized to zero bits.
> > + So, it's better to clear the whole record under such
> > situation. */
> > + cleared = true;
> >
> > so here we have padding as well - I think this warrants to be controlled
> > by an extra option? And we can maybe split this out to a separate
> > patch? (the whole padding stuff)
> >
> > Clang does the padding initialization with this option, shall we be
> > consistent with Clang?
>
> Just for the sake of consistency? No. Is there a technical reason
> for this complication? Say we have
>
> struct { short s; int i; } a;
>
> what's the technical reason to initialize the padding? I might
> be tempted to use -ftrivial-auto-init but I'd definitely don't
> want to spend cycles/instructions initializing the padding in the
> above struct.
Yes, this is very important. This is one of the more common ways memory
content leaks happen in programs (especially the kernel). e.g.:
struct example {
short s;
int i;
};
struct example instance = { .i = foo };
While "s" gets zeroed, the padding may not, and may contain prior memory
contents. Having this be deterministically zero is important for this
feature. If the structure gets byte-copied to a buffer (e.g. syscall,
etc), the padding will go along for the ride.
--
Kees Cook