RE: Re: Re: Re: [PATCH v3 4/4] mwifiex: pcie: extract wifi part from combo firmware during function level reset

2017-04-15 Thread Xinming Hu
Hi Brain,

> -Original Message-
> From: Brian Norris [mailto:briannor...@chromium.org]
> Sent: 2017年4月15日 0:56
> To: Xinming Hu
> Cc: Linux Wireless; Kalle Valo; Dmitry Torokhov; raja...@google.com;
> Amitkumar Karwar; Cathy Luo; Ganapathi Bhat
> Subject: [EXT] Re: Re: Re: [PATCH v3 4/4] mwifiex: pcie: extract wifi part 
> from
> combo firmware during function level reset
> 
> External Email
> 
> --
> Hi,
> 
> On Fri, Apr 14, 2017 at 03:28:28AM +, Xinming Hu wrote:
> > According to the firmware download protocol, every CMD should not exceed
> MWIFIEX_UPLD_SIZE.
> > we can add a sanity check , like,
> > if (data_len > MWIFIEX_UPLD_SIZE - sizeof(fwdata->header))
> > *error*
> 
> I was primarily interested in protecting the kernel itself. Once the kernel 
> starts
> parsing the firmware, we have to make sure a bad firmware file won't end up
> with us looping infinitely, reading/writing invalid memory, or otherwise
> exposing security or stability issues. I wasn't necessarily interested in 
> validating
> every requirement of the end-point device. For example, we're not bothering
> checking the CRCs. I figured that this was all the job of your Wifi card's 
> boot
> ROM.
> 
> So, we *can* implement checks like this, but I'd really hope we don't need 
> this
> particular one, because your card should be taking care of that.
> 

Got it, we will keep in mind to check the possible overflow in future, either 
using general
protect or under limit by our device requirement.

> Please consider reviewing my latest submission.
> 

Sure.

Thanks,
Simon
> Regards,
> Brian


Re: Re: Re: [PATCH v3 4/4] mwifiex: pcie: extract wifi part from combo firmware during function level reset

2017-04-14 Thread Brian Norris
Hi,

On Fri, Apr 14, 2017 at 03:28:28AM +, Xinming Hu wrote:
> According to the firmware download protocol, every CMD should not exceed 
> MWIFIEX_UPLD_SIZE.
> we can add a sanity check , like,
> if (data_len > MWIFIEX_UPLD_SIZE - sizeof(fwdata->header))
>   *error*

I was primarily interested in protecting the kernel itself. Once the
kernel starts parsing the firmware, we have to make sure a bad firmware
file won't end up with us looping infinitely, reading/writing invalid
memory, or otherwise exposing security or stability issues. I wasn't
necessarily interested in validating every requirement of the end-point
device. For example, we're not bothering checking the CRCs. I figured that
this was all the job of your Wifi card's boot ROM.

So, we *can* implement checks like this, but I'd really hope we don't
need this particular one, because your card should be taking care of
that.

Please consider reviewing my latest submission.

Regards,
Brian


RE: Re: Re: [PATCH v3 4/4] mwifiex: pcie: extract wifi part from combo firmware during function level reset

2017-04-13 Thread Xinming Hu
Hi Brain,

> -Original Message-
> From: Brian Norris [mailto:briannor...@chromium.org]
> Sent: 2017年4月14日 1:50
> To: Xinming Hu
> Cc: Linux Wireless; Kalle Valo; Dmitry Torokhov; raja...@google.com;
> Amitkumar Karwar; Cathy Luo; Ganapathi Bhat
> Subject: [EXT] Re: Re: [PATCH v3 4/4] mwifiex: pcie: extract wifi part from
> combo firmware during function level reset
> 
> External Email
> 
> --
> Hi,
> 
> On Thu, Apr 13, 2017 at 06:47:59AM +, Xinming Hu wrote:
> > > -Original Message-
> > > From: Brian Norris [mailto:briannor...@chromium.org]
> > > Sent: 2017年4月11日 9:37
> > > To: Xinming Hu
> > > Cc: Linux Wireless; Kalle Valo; Dmitry Torokhov; raja...@google.com;
> > > Amitkumar Karwar; Cathy Luo; Xinming Hu; Ganapathi Bhat
> > > Subject: [EXT] Re: [PATCH v3 4/4] mwifiex: pcie: extract wifi part
> > > from combo firmware during function level reset
> > >
> > > External Email
> > >
> 
> > > On Mon, Apr 10, 2017 at 09:09:34AM +, Xinming Hu wrote:
> > > > +   while (1) {
> > > > +   if (offset + sizeof(fwdata.header) >= firmware_len) {
> > > > +   mwifiex_dbg(adapter, ERROR,
> > > > +   "extract wifi-only firmware 
> > > > failure!");
> > > > +   ret = -1;
> > > > +   goto done;
> > > > +   }
> > > > +
> > > > +   memcpy(, firmware + offset,
> > > > +  sizeof(fwdata.header));
> > >
> > > Do you actually need to copy this? Can't you just keep a pointer to the
> location?
> > > e.g.
> > >
> > >   const struct mwifiex_fw_data *fwdata; ...
> > >   fwdata = firmware + offset;
> > >
> >
> > Ok.
> >
> > > > +   dnld_cmd = le32_to_cpu(fwdata.header.dnld_cmd);
> > > > +   data_len = le32_to_cpu(fwdata.header.data_length);
> > > > +
> > > > +   switch (dnld_cmd) {
> > > > +   case MWIFIEX_FW_DNLD_CMD_1:
> > > > +   if (!cmd7_before) {
> > > > +   mwifiex_dbg(adapter, ERROR,
> > > > +   "no cmd7 before cmd1!");
> > > > +   ret = -1;
> > > > +   goto done;
> > > > +   }
> > > > +   offset += data_len + sizeof(fwdata.header);
> > >
> > > Technically, we need an overflow check to make sure that 'data_len'
> > > isn't some bogus value that overflows 'offset'.
> > >
> >
> > There is the sanity check for the offset after bypass CMD1/5/7 in the
> > start of while-loop, enhanced in v4 as, if (offset >= firmware_len)
> 
> That's not an enhancement!! That's a *weaker* condition, and it's wrong.
> If 'offset == firmware_len - 1', then we'll still be out of bounds when we 
> read
> the next header at 'offset + {1, 2, 3, ...}'.
> 
> My point was that adding 'data_len' might actually overflow the u32, not that
> the bounds check ('offset + sizeof(...header) >= firmware_len') was wrong.
> 
> For this kind of overflow check, you need to do the check here, not after 
> you've
> saved the new offset.
> 
> e.g., suppose data_len = 0xfff0. Then:
> 
>   offset += data_len + sizeof(fwdata.header); =>
>   offset += 0xfff0 + 16;
> =>
>   offset += 0;
> 
> and then...we have an infinite loop. Changing the bounds check at the start of
> the loop does nothing to help this.
> 
> Something like this (put before the addition) is sufficient, I think:
> 
>   if (offset + data_len + sizeof(fwdata.header) < data_len)
>   ... error ...
> 

Thanks for the explain.
According to the firmware download protocol, every CMD should not exceed 
MWIFIEX_UPLD_SIZE.
we can add a sanity check , like,
if (data_len > MWIFIEX_UPLD_SIZE - sizeof(fwdata->header))
*error*

Thanks
Simon
> Or this would actually all be slightly cleaner if you just did this outside 
> the
> 'switch':
> 
>   // Presuming you already did the check for
>   //  offset + sizeof(fwdata.header) >= firmware_len
>   offset += sizeof(fwdata.header);
> 
> Then inside this 'case', you have:
> 
>   if (offset + data_len < data_len)
>   ... error out ...
>   offset += data_len;
> 
> > > > +   break;
> > > > +   case MWIFIEX_FW_DNLD_CMD_5:
> > > > +   offset += data_len + sizeof(fwdata.header);
> > >
> > > Same here.
> > >
> > > > +   break;
> > > > +   case MWIFIEX_FW_DNLD_CMD_6:
> > >
> > > Can we have a comment, either here or above this function, to
> > > describe what this sequence is? Or particularly, what is this terminating
> condition? "CMD_6"
> > > doesn't really tell me that this is the start of the Wifi blob.
> > >
> > > > +   offset += data_len + sizeof(fwdata.header);
> > >
> >
> > The sequence have been added to function comments in v4.
> >
> > >