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

Reply via email to