Re: [PATCH 2/3] binder: do not initialize locals passed to copy_from_user()

[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]

 



On Wed, Feb 26, 2020 at 03:58:41PM +0100, Alexander Potapenko wrote:
> On Tue, Feb 25, 2020 at 4:24 PM Alexander Potapenko <glider@xxxxxxxxxx> wrote:
> >
> > On Tue, Feb 25, 2020 at 5:18 AM Kees Cook <keescook@xxxxxxxxxxxx> wrote:
> > >
> > > On Mon, Feb 24, 2020 at 04:35:00PM +0100, glider@xxxxxxxxxx wrote:
> > > > Certain copy_from_user() invocations in binder.c are known to
> > > > unconditionally initialize locals before their first use, like e.g. in
> > > > the following case:
> > > >
> > > >       struct binder_transaction_data tr;
> > > >       if (copy_from_user(&tr, ptr, sizeof(tr)))
> > > >               return -EFAULT;
> > > >
> > > > In such cases enabling CONFIG_INIT_STACK_ALL leads to insertion of
> > > > redundant locals initialization that the compiler fails to remove.
> > > > To work around this problem till Clang can deal with it, we apply
> > > > __do_not_initialize to local Binder structures.
> > >
> > > It should be possible to write a Coccinelle script to identify all these
> > > cases. (i.e. a single path from struct declaration to copy_from_user())
> > > and apply the changes automatically. This script could be checked into
> > > scripts/coccinelle/ to help keep these markings in sync...
> >
> > The following script:
> >
> > =================================
> > @local_inited_by_cfu@
> > attribute name __no_initialize;
> > identifier var;
> > type T;
> > statement stmt;
> > @@
> > T var
> > +__no_initialize
> > ;
> > if (copy_from_user(&var,..., sizeof(var))) stmt
> > =================================
> >
> > seems to do the job, but this transformation isn't idempotent: it
> > inserts __no_initialize every time Coccinelle is invoked.
> > It's hard to work around this problem, as attributes may only be parts
> > of +-lines (i.e. I cannot write a rule that matches "T var
> > __no_initialize")
> 
> This one:
> 
> ============================
> @match@
> type T;
> identifier var;
> statement stmt;
> fresh identifier var_noinit = var##" __no_initialize";
> @@
> -T var;
> +T var_noinit;
> ...
> if (copy_from_user(&var,..., sizeof(var))) stmt
> ============================
> is better, because it:
>  - uses a "fresh identifier" hack instead of dealing with attributes
> (which aren't supported by spatch 1.0.4)
>  - seems to be idempotent because of that hack.
> 
> I'll regenerate the binder patch using that script and will look into
> enhancing it and committing it to scripts/coccinelle.

Cool; sounds good!

-- 
Kees Cook
_______________________________________________
devel mailing list
devel@xxxxxxxxxxxxxxxxxxxxxx
http://driverdev.linuxdriverproject.org/mailman/listinfo/driverdev-devel



[Index of Archives]     [Linux Driver Backports]     [DMA Engine]     [Linux GPIO]     [Linux SPI]     [Video for Linux]     [Linux USB Devel]     [Linux Coverity]     [Linux Audio Users]     [Linux Kernel]     [Linux SCSI]     [Yosemite Backpacking]
  Powered by Linux