Groups | Search | Server Info | Keyboard shortcuts | Login | Register [http] [https] [nntp] [nntps]


Groups > linux.kernel > #1370579 > unrolled thread

Re: [RFC 0/6] mmc: Field Firmware Update

Started byUlf Hansson <ulf.hansson@linaro.org>
First post2016-04-04 14:00 +0200
Last post2016-04-14 10:40 +0200
Articles 3 — 2 participants

Back to article view | Back to linux.kernel

This discussion starts older than the indexed window; earlier articles aren't shown. The article labeled Started by below is the oldest one visible, not the original post.


Contents

  Re: [RFC 0/6] mmc: Field Firmware Update Ulf Hansson <ulf.hansson@linaro.org> - 2016-04-04 14:00 +0200
    Re: [RFC 0/6] mmc: Field Firmware Update Gwendal Grignou <gwendal@chromium.org> - 2016-04-14 00:40 +0200
      Re: [RFC 0/6] mmc: Field Firmware Update Ulf Hansson <ulf.hansson@linaro.org> - 2016-04-14 10:40 +0200

#1370579 — Re: [RFC 0/6] mmc: Field Firmware Update

FromUlf Hansson <ulf.hansson@linaro.org>
Date2016-04-04 14:00 +0200
SubjectRe: [RFC 0/6] mmc: Field Firmware Update
Message-ID<rkbkK-2rF-17@gated-at.bofh.it>
On 2 April 2016 at 02:23, Gwendal Grignou <gwendal@chromium.org> wrote:
> On Thu, Jan 14, 2016 at 5:16 AM, Ulf Hansson <ulf.hansson@linaro.org> wrote:
>> On 28 December 2015 at 15:12, Alex Lemberg <Alex.Lemberg@sandisk.com> wrote:
>>> Hi Ulf,
>>>
>>> We succeeded to run FFU via new mmc multi-command ioctl without any code modification,
>>> but only by using Single Sector commands (CMD24).
>>>
>>> From running the FFU and from code review, we see two minor issues in this way of running FFU:
>>> 1. There is no support for Multiple Block write commands (CMD25) in existing IOCTL implementation -
>>
>> That's right. But I guess we cope without the multiple block support!?
>>
>> Although, I wonder how hard it would be to add it...
>>
>>> seems like there is no polling for the card status on data transfer completion.
>>
>> We should fix that!
>>
>> In the rpmb case, we check the status so we can probably trigger that
>> code to run for CMD24/25 as well.
>>
>>> (The kernel FFU implementation supports FFU using Multiple Block Write commands).
>>> 2. As you probably remember, there are two ways to install the new FW in the end of FFU process -
>>> In case MODE_OPERATION_CODES field is not supported by the device, the host sets to NORMAL state
>>
>> Before starting the update, you can find out which mode that is
>> supported and take relevant actions, right?
>>
>>> and initiates a CMD0/HW_Reset/Power cycle to install the new firmware.
>>
>> Yes, but that's fragile - as discussed earlier.
>>
>> What we really need to do is to also remove the "card" device from the
>> system, as otherwise we may have invalid data in its member variables
>> and who knows what issues that can cause to upper levels.
>>
>>> This sequence cannot be done via multi-command ioctl, and requires manual reset of the device/platform.
>>
>> Yepp, it seems so at least for now. Perhaps we can think of a way to
>> improve this?
>>
>>> (The kernel FFU implementation supports both FW install methods).
>>>
>>> For running FFU via new mmc multi-command ioctl, we have modified mmc-utils and add new functionality for FFU.
>>> Please let us know if you want us to submit the patch for mmc-utils FFU functionality via multi-command ioctl.
>>
>> Yes please. Don't forget to send this to Chris as well!
> I am arriving after the battle, but I have finally rebased the eMMC
> FFU kernel ffu code to 4.x. It is based on what Avi and Alex have
> written.
> As stated earlier, the advantage over using MMC_MUTLI_CMD is we can
> force a reset and rescan of the card without asking the user to reboot
> their machine.

No matter what, I think the problem is how you would *safely* deal
with the reset. Especially in the case when the eMMC already has an
mounted file system on it.

Just doing something that *might* work, isn't good enough to me.

> Also, by only sending a firmware name over the ioctl, we can use Kees'
> work for firmware validation (https://lwn.net/Articles/605432/).

The request_firmware() interface would indeed be good to use. Although
unless we can figure out a way on how to safely deal with reset, we
will have to live without request_firmware().

> To prevent downloading firmware from unknown source, we would reject
> some commands (like SWITCH with FFU_MODE) in the kernel
> MMC_IOC/MULTI_CMD ioctl handler.

I don't follow, can you elaborate on this please.

Kind regards
Uffe

[toc] | [next] | [standalone]


#1378328

FromGwendal Grignou <gwendal@chromium.org>
Date2016-04-14 00:40 +0200
Message-ID<rnBC2-8vj-31@gated-at.bofh.it>
In reply to#1370579
On Mon, Apr 4, 2016 at 4:50 AM, Ulf Hansson <ulf.hansson@linaro.org> wrote:
>
> On 2 April 2016 at 02:23, Gwendal Grignou <gwendal@chromium.org> wrote:
> > On Thu, Jan 14, 2016 at 5:16 AM, Ulf Hansson <ulf.hansson@linaro.org> wrote:
> >> On 28 December 2015 at 15:12, Alex Lemberg <Alex.Lemberg@sandisk.com> wrote:
>
> > I am arriving after the battle, but I have finally rebased the eMMC
> > FFU kernel ffu code to 4.x. It is based on what Avi and Alex have
> > written.
> > As stated earlier, the advantage over using MMC_MUTLI_CMD is we can
> > force a reset and rescan of the card without asking the user to reboot
> > their machine.
>
> No matter what, I think the problem is how you would *safely* deal
> with the reset. Especially in the case when the eMMC already has an
> mounted file system on it.

Assuming the firmware is not wiping data or resizing the available
space, the data in the flash is readable after the upgrade.
For the host point of view, a firmware update and a reset is
equivalent to a reset, that could happen during error recovery.
The only change are in the cid/csd//extcsd registers the firmware may
have updated.
The stack has to assume these registers are not constant and can
change after reset.

When looking into the mmc stack, AFAICT, the code that needs to get
device specifics always rely on fields that are re-generated by
mmc_card_inif() (card->ext_csd, output of mmc_decode_csd()/cid(() and
so on).
>
>
> Just doing something that *might* work, isn't good enough to me.
>
> > Also, by only sending a firmware name over the ioctl, we can use Kees'
> > work for firmware validation (https://lwn.net/Articles/605432/).
>
> The request_firmware() interface would indeed be good to use. Although
> unless we can figure out a way on how to safely deal with reset, we
> will have to live without request_firmware().
>
> > To prevent downloading firmware from unknown source, we would reject
> > some commands (like SWITCH with FFU_MODE) in the kernel
> > MMC_IOC/MULTI_CMD ioctl handler.
>
> I don't follow, can you elaborate on this please.

Today, an attacker with root access could break the chain of trust by
writing a firmware in the eMMC that corrupts data on the fly and
return infected code to the host after verification.
One way is to use firmware signed by the manufacturer, a stronger
approach is to enforce that the firmware is part of the root
partition.
To prevent a bad firmware from being downloaded, we have to make sure
downloading firmware using raw single or multi commands ioctls does
not work.

Gwendal.
>
>
> Kind regards
> Uffe

[toc] | [prev] | [next] | [standalone]


#1378599

FromUlf Hansson <ulf.hansson@linaro.org>
Date2016-04-14 10:40 +0200
Message-ID<rnKYF-7jf-7@gated-at.bofh.it>
In reply to#1378328
On 14 April 2016 at 00:33, Gwendal Grignou <gwendal@chromium.org> wrote:
> On Mon, Apr 4, 2016 at 4:50 AM, Ulf Hansson <ulf.hansson@linaro.org> wrote:
>>
>> On 2 April 2016 at 02:23, Gwendal Grignou <gwendal@chromium.org> wrote:
>> > On Thu, Jan 14, 2016 at 5:16 AM, Ulf Hansson <ulf.hansson@linaro.org> wrote:
>> >> On 28 December 2015 at 15:12, Alex Lemberg <Alex.Lemberg@sandisk.com> wrote:
>>
>> > I am arriving after the battle, but I have finally rebased the eMMC
>> > FFU kernel ffu code to 4.x. It is based on what Avi and Alex have
>> > written.
>> > As stated earlier, the advantage over using MMC_MUTLI_CMD is we can
>> > force a reset and rescan of the card without asking the user to reboot
>> > their machine.
>>
>> No matter what, I think the problem is how you would *safely* deal
>> with the reset. Especially in the case when the eMMC already has an
>> mounted file system on it.
>
> Assuming the firmware is not wiping data or resizing the available
> space, the data in the flash is readable after the upgrade.

This is exactly my point. You can no* assume anything about the card
after a firmware upgrade.

> For the host point of view, a firmware update and a reset is
> equivalent to a reset, that could happen during error recovery.
> The only change are in the cid/csd//extcsd registers the firmware may
> have updated.

Is that defined by the spec and are all eMMC vendors conforming to
your above statement?

> The stack has to assume these registers are not constant and can
> change after reset.
>
> When looking into the mmc stack, AFAICT, the code that needs to get
> device specifics always rely on fields that are re-generated by
> mmc_card_inif() (card->ext_csd, output of mmc_decode_csd()/cid(() and
> so on).
>>
>>
>> Just doing something that *might* work, isn't good enough to me.
>>
>> > Also, by only sending a firmware name over the ioctl, we can use Kees'
>> > work for firmware validation (https://lwn.net/Articles/605432/).
>>
>> The request_firmware() interface would indeed be good to use. Although
>> unless we can figure out a way on how to safely deal with reset, we
>> will have to live without request_firmware().
>>
>> > To prevent downloading firmware from unknown source, we would reject
>> > some commands (like SWITCH with FFU_MODE) in the kernel
>> > MMC_IOC/MULTI_CMD ioctl handler.
>>
>> I don't follow, can you elaborate on this please.
>
> Today, an attacker with root access could break the chain of trust by
> writing a firmware in the eMMC that corrupts data on the fly and
> return infected code to the host after verification.
> One way is to use firmware signed by the manufacturer, a stronger
> approach is to enforce that the firmware is part of the root
> partition.
> To prevent a bad firmware from being downloaded, we have to make sure
> downloading firmware using raw single or multi commands ioctls does
> not work.

I clearly see the benefit of using request_firmware() and I open to
adopt an in-kernel FFU solution that uses it, as long as a safe reset
can be managed.

However, whether it's more safe to hackers has nothing to do with it.
If a hacker becomes root on a device they can do all kind of magic
things, for example replacing a firmware in rootfs or sending ioctl
commands to a device node that has root permissions. To achieve
security, verification of a signatures are needed and currently the
request_firmware() API doesn't support this and nor does the eMMC
device itself (at least to my knowledge).

Regarding the safe reset, the only way I see how to deal with this, is
to force a reboot and prevent serving new read/write request after a
firmware upgrade. Although, perhaps you can think of something more
clever.

Kind regards
Uffe

[toc] | [prev] | [standalone]


Back to top | Article view | linux.kernel


csiph-web