diff options
author | Rob Barnes <robbarnes@google.com> | 2021-09-17 09:42:53 -0600 |
---|---|---|
committer | Commit Bot <commit-bot@chromium.org> | 2021-09-20 13:17:52 +0000 |
commit | c1ef7c696c45632503165cbabb1e37cbabfbe448 (patch) | |
tree | b783829513b4f39cc6742aae2ae9d6c09f5a90f0 /common | |
parent | 217975bb1402f1ab76e84ebdf804884be6353924 (diff) | |
download | chrome-ec-c1ef7c696c45632503165cbabb1e37cbabfbe448.tar.gz |
ec_commands: Add ec_response_get_version_v1
A field (cros_fwid_rw) was added to ec_response_get_version and the
version was updated to v1. Some system components that still use v0
of the version host command fail because the size of the response
does not match the updated ec_response_get_version struct.
Restore ec_response_get_version to match v0. Create a new
ec_response_get_version_v1 structure with the added v1 fields.
This allows legacy code to continue using ec_response_get_version,
which matches the expected response size for the v0 command.
BUG=b:188073399,b:200075921
TEST=EC console 'version' works
Legacy 'ectool version' works with old an new EC firmware.
New 'ectool version' works with old and new EC firmware.
BRANCH=None
Change-Id: I51a052a550c2460f2604da8e04fc43c36acba4d5
Signed-off-by: Rob Barnes <robbarnes@google.com>
Reviewed-on: https://chromium-review.googlesource.com/c/chromiumos/platform/ec/+/3169100
Reviewed-by: caveh jalali <caveh@chromium.org>
Reviewed-by: Patryk Duda <patrykd@google.com>
Reviewed-by: Daisuke Nojiri <dnojiri@chromium.org>
Diffstat (limited to 'common')
-rw-r--r-- | common/system.c | 28 |
1 files changed, 18 insertions, 10 deletions
diff --git a/common/system.c b/common/system.c index 985d64752e..1670857241 100644 --- a/common/system.c +++ b/common/system.c @@ -1568,16 +1568,12 @@ DECLARE_CONSOLE_COMMAND(rflags, command_rflags, static enum ec_status host_command_get_version(struct host_cmd_handler_args *args) { - struct ec_response_get_version *r = args->response; + struct ec_response_get_version_v1 *r = args->response; enum ec_image active_slot = system_get_active_copy(); - /* Clear optional fields (i.e. cros_fwid). */ - memset(r, 0, sizeof(*r)); - strzcpy(r->version_string_ro, system_get_version(EC_IMAGE_RO), sizeof(r->version_string_ro)); - strzcpy(r->version_string_rw, - system_get_version(active_slot), + strzcpy(r->version_string_rw, system_get_version(active_slot), sizeof(r->version_string_rw)); switch (system_get_image_copy()) { @@ -1593,18 +1589,30 @@ host_command_get_version(struct host_cmd_handler_args *args) break; } + /* + * Assuming args->response is zero'd in host_command_process, so no need + * to zero uninitialized fields here. + */ if (args->version > 0 && IS_ENABLED(CONFIG_CROS_FWID_VERSION)) { strzcpy(r->cros_fwid_ro, system_get_cros_fwid(EC_IMAGE_RO), sizeof(r->cros_fwid_ro)); strzcpy(r->cros_fwid_rw, system_get_cros_fwid(EC_IMAGE_RW), sizeof(r->cros_fwid_rw)); } + + /* + * By convention, ec_response_get_version_v1 is a strict superset of + * ec_response_get_version(v0). The v1 response changes the semantics + * of one field (reserved to cros_fwid_ro) and adds one additional field + * (cros_fwid_rw). So simply adjusting the response size here is safe. + */ if (args->version == 0) - /* cros_fwid_rw[32] is not present in version 0 */ - args->response_size = - offsetof(struct ec_response_get_version, cros_fwid_rw); - else args->response_size = sizeof(struct ec_response_get_version); + else if (args->version == 1) + args->response_size = sizeof(struct ec_response_get_version_v1); + else + /* Shouldn't happen because of EC_VER_MASK */ + return EC_RES_INVALID_VERSION; return EC_RES_SUCCESS; } |