New issue
Advanced search Search tips
Note: Color blocks (like or ) mean that a user may not be available. Tooltip shows the reason.

Issue 782903 link

Starred by 0 users

Issue metadata

Status: Fixed
Owner:
Last visit > 30 days ago
Closed: Nov 2017
Cc:
Components:
EstimatedDays: ----
NextAction: ----
OS: Chrome
Pri: 2
Type: Bug


Show other hotlists

Hotlists containing this issue:
Hotlist-1


Sign in to add a comment

cr50 upgrade doesn't work in recovery images

Project Member Reported by vapier@chromium.org, Nov 8 2017

Issue description

the postinst phase runs not only when doing an AU, but when running recovery.  it looks like the cr50 upgrade logic doesn't account for that and only works in the AU scenario.  recovery always fails.

the code currently does:

installer/chromeos_postinst.cc:TryCr50Update:
  /usr/share/cros/cr50-update.sh /

/usr/share/cros/cr50-update.sh:
  UPDATER="/usr/sbin/trunks_send"
  if ! "${UPDATER}" --help | grep -q '\--update'; then
    logit "${UPDATER} does not support cr50 updates, quitting."
    exit 1

aosp/system/tpm/trunks/trunks_send.cc:main
  TrunksDBusProxy proxy;
  if (!proxy.Init()) {
    LOG(ERROR) << "Failed to initialize dbus proxy.";
    return 1;
  }
...check command line flags...

the problem is that, in recovery images, dbus is not running.  so every `trunks_send` invocation fails here.  an example from an eve run:

Starting cr50 updater (//usr/share/cros/cr50-update.sh /)
Command: //usr/share/cros/cr50-update.sh /
[ERROR:buss.cc(427)] Failed to connect to the bus: Failed to connect to socket /run/dbus/system_bus_socket: No such file or directory
[ERROR:trunks_send.cc(868)] Failed to initialize dbus proxy.
Cr50 update attempt failed (1).
Failed to update cr50 firmware.

it's been this way at least since 9901.0.0 and with current 10109.0.0
 
is there a way to tell that the recovery image is running? 

gsctool could be used to talk to the tpm directly if trunks_send is not able to.

Comment 2 by hungte@chromium.org, Nov 14 2017

can gsctool hide the complicated logic, for example

 --mode=[auto|tpm|trunks] and defaults to auto?

Then we can start migrating everything to always use gsctool
As discussed before, I'd rather put the logic in the script using gsctool.

Comment 4 by hungte@chromium.org, Nov 14 2017

which script do you think it'll be?

Note that /usr/share/cros is not in PATH and hard to use.

We do really need a simple script for people (developers, parthers, whatever) to have a single command for updating CR50, otherwise, we'll see similar issues again and again because of different use cases (recovery, normal, factory, etc)
there is only one place where post install happens, and it invokes the same
script the init updater invokes. This would be a good script to put this
intelligence into. As you mention in #2 someone still has to specify
--mode, so there needs to be some intelligence outside of gsctool.

Comment 6 by vapier@chromium.org, Nov 14 2017

the scripts have access to the env var IS_RECOVERY_INSTALL (and the postinst code already sets up local vars like is_recovery_install) which you could key off of.

Comment 7 by hungte@chromium.org, Nov 14 2017

In additional to post install, there are other demands of updating Cr50.

At least I've seen:
 - Device PMs and ODMs want Cr50 to be updated to what release image contains ( https://chromium.googlesource.com/chromiumos/platform/factory/+/master/py/test/pytests/update_cr50_firmware.py )
 - ODM wants to update Cr50 in RMA process ( https://chromium-review.googlesource.com/#/c/chromiumos/platform/factory_installer/+/579407/ )
 - Recovery image run postinst under initramfs
 - Factory shim (probably with trunksd) run postionst under a system bootstrap from initramfs (but with real init started)
 - For developers and partners testing, they usually look for commands to update Cr50.
 - Some factories wanted to update Cr50 in netboot installation (although I think we did agree this should be no longer needed in future)

Do you think there can be a single command (or script) to perform the update easily and less painful, no need to worry about various conditions (CR50 is I2C or SPI, dbus is running or not, trunksd is running or not, ... etc), so all cases I've listed can do same thing, so there won't be duplicated logic?
we never cared about i2c vs SPI, we used to use USB, but not any more.

so, the only differentiating factor is if trunksd is running or not. If it is - we'd use trunks_send, if it is not - we'd use direct communications with /dev/tpm0


Comment 9 by vapier@chromium.org, Nov 14 2017

i'd recommend changing trunks_send to return a specific code if the dbus connection fails (the code i mentioned in comment #0).  if it returned a specific value (like "2" or "3"), the shell code could use that to determine whether trunks is alive.

alternatively, you could change the code to just always assume that `trunks_send --help` failing means it should fallback to manual update.

something like:
/usr/share/cros/cr50-update.sh
if ! help_output=$("${UPDATER}" --help); then
  logit "trunks does not seem to be running, falling back to direct upgrade"
  ...do whatever gsctool stuff you want...
  exit
fi

if echo "${help_output}" | grep -q -e '--update'; then
  logit "${UPDATER} does not support cr50 updates, quitting."
  exit 1
fi
Cc: apronin@chromium.org
come to think of it we don't even need to check what image we are in or if trunksd is running. Just try going over /dev/tmp0, and if failed - go try going through truks_send

Hung-Te, why are you saying that /usr/share/cros "is hard to use" ?
flipping the tests on their head like that sounds good to me too
Re#10

Simply slightly harder than usual commands.

It's not in PATH so when you do scripting or invoked from programs, you have to hard-code the complete path, and change it if someday you decide to move the program from cros to somewhere else.
Also it takes more time and space to teach partners for using a complete path.

But I'm fine if we're determined to have the script inside /usr/share/cros.
Project Member

Comment 13 by bugdroid1@chromium.org, Nov 22 2017

The following revision refers to this bug:
  https://chromium.googlesource.com/chromiumos/overlays/chromiumos-overlay/+/00473f61b4a73abd8dd1a9d52f3dfa4bcc11cefc

commit 00473f61b4a73abd8dd1a9d52f3dfa4bcc11cefc
Author: Vadim Bendebury <vbendeb@chromium.org>
Date: Wed Nov 22 05:36:20 2017

cr50-scripts: pick update mode at run time

The cr50-update.sh script could be invoked under different
circumstances, which dictate different modes of communicating with
the Cr50.

Instead of trying to figure out the invocation circumstances and
deciding what mode of operation to use, just try various modes and use
the first one which succeeds.

Various modes in order of priority are: USB, /dev/tpm0, trunks_send.

Also modified error reporting to see the error message in the log
properly split into lines (it was added as one long string before).

BRANCH=none
BUG= chromium:782903 

TEST=tried the script with and without trunksd running, and observed
     that update succeeds in both cases.

     Introduced an update error and observed that error message is
     added to the log entries as expected, one line at a time.

Change-Id: Iaa55e33b97ba936d29bc043e80f349ad8028a8c7
Signed-off-by: Vadim Bendebury <vbendeb@chromium.org>
Reviewed-on: https://chromium-review.googlesource.com/777886

[modify] https://crrev.com/00473f61b4a73abd8dd1a9d52f3dfa4bcc11cefc/chromeos-base/chromeos-cr50-scripts/files/cr50-update.sh
[rename] https://crrev.com/00473f61b4a73abd8dd1a9d52f3dfa4bcc11cefc/chromeos-base/chromeos-cr50-scripts/chromeos-cr50-scripts-0.0.1-r9.ebuild

Status: Fixed (was: Available)
verified successful recovery update on a Pyro

Comment 15 by dchan@chromium.org, Jan 22 2018

Status: Archived (was: Fixed)

Comment 16 by dchan@chromium.org, Jan 23 2018

Status: Fixed (was: Archived)

Sign in to add a comment