diff options
author | Aseda Aboagye <aaboagye@google.com> | 2017-02-15 16:56:10 -0800 |
---|---|---|
committer | chrome-bot <chrome-bot@chromium.org> | 2017-02-18 17:26:59 -0800 |
commit | 114f5cee5ac4af758882a7557cbdf91fbc8e4698 (patch) | |
tree | 0afea58938e54b67116f861780d73cceb4a54f22 | |
parent | 4ed404432904c3f8e6c9d64e8bb306daf3c687f5 (diff) | |
download | chrome-ec-114f5cee5ac4af758882a7557cbdf91fbc8e4698.tar.gz |
g: extension: Add a whitelist for vendor commands.
The USB FW upgrade endpoint should really only accept vendor commands
required to perform the firmware update. This commit adds a whitelist
that is checked whenever a vendor command is received over this
endpoint.
The allowed commands over USB are the following:
- EXTENSION_POST_RESET
- VENDOR_CC_IMMEDIATE_RESET (only for dev images)
There is also functionality to have a whitelist for vendor commands that
come over the TPM interface.
BUG=chrome-os-partner:62815
BRANCH=None
TEST=Flash Cr50 with image containing this change. Verify that an
upgrade over USB to newer image works.
TEST=Try using usb_updater to send a vendor command that's not in the
whitelist. Verify that the vendor command is dropped.
Change-Id: I71f8ba090a1cc6c9e7c30ce0dd3c25259e8f292f
Signed-off-by: Aseda Aboagye <aaboagye@google.com>
Reviewed-on: https://chromium-review.googlesource.com/443447
Commit-Ready: Aseda Aboagye <aaboagye@chromium.org>
Tested-by: Aseda Aboagye <aaboagye@chromium.org>
Reviewed-by: Vadim Bendebury <vbendeb@chromium.org>
-rw-r--r-- | chip/g/usb_upgrade.c | 10 | ||||
-rw-r--r-- | common/extension.c | 48 | ||||
-rw-r--r-- | common/tpm_registers.c | 10 | ||||
-rw-r--r-- | include/extension.h | 18 |
4 files changed, 67 insertions, 19 deletions
diff --git a/chip/g/usb_upgrade.c b/chip/g/usb_upgrade.c index 82a9cadf21..1379e38c1d 100644 --- a/chip/g/usb_upgrade.c +++ b/chip/g/usb_upgrade.c @@ -152,11 +152,11 @@ static int try_vendor_command(struct consumer const *consumer, size_t count) queue_advance_head(consumer->queue, count); subcommand = (uint16_t *)(cmd_buffer + 1); - extension_route_command(be16toh(*subcommand), - subcommand + 1, - count - - sizeof(struct update_frame_header), - &response_size); + usb_extension_route_command(be16toh(*subcommand), + subcommand + 1, + count - + sizeof(struct update_frame_header), + &response_size); QUEUE_ADD_UNITS(&upgrade_to_usb, subcommand + 1, response_size); } diff --git a/common/extension.c b/common/extension.c index d28bfad337..63ae8f0495 100644 --- a/common/extension.c +++ b/common/extension.c @@ -10,10 +10,10 @@ #define CPRINTF(format, args...) cprintf(CC_EXTENSION, format, ## args) -uint32_t extension_route_command(uint16_t command_code, - void *buffer, - size_t in_size, - size_t *out_size) +static uint32_t extension_route_command(uint16_t command_code, + void *buffer, + size_t in_size, + size_t *out_size) { struct extension_command *cmd_p; struct extension_command *end_p; @@ -34,3 +34,43 @@ uint32_t extension_route_command(uint16_t command_code, *out_size = 0; return VENDOR_RC_NO_SUCH_COMMAND; } + +uint32_t usb_extension_route_command(uint16_t command_code, + void *buffer, + size_t in_size, + size_t *out_size) +{ + int is_allowed = 0; + + switch (command_code) { +#ifdef CR50_DEV + case VENDOR_CC_IMMEDIATE_RESET: +#endif /* defined(CR50_DEV) */ + case EXTENSION_POST_RESET: /* Always need to be able to reset. */ + is_allowed = 1; + break; + + default: + break; + } + + if (is_allowed) + return extension_route_command(command_code, buffer, in_size, + out_size); + + /* Otherwise, we don't allow this command. */ + CPRINTF("%s: ignoring vendor cmd %d\n", __func__, command_code); + *out_size = 0; + return VENDOR_RC_NO_SUCH_COMMAND; +} + +uint32_t tpm_extension_route_command(uint16_t command_code, + void *buffer, + size_t in_size, + size_t *out_size) +{ + /* + * TODO(aaboagye): Determine what commands (if any) should be filtered. + */ + return extension_route_command(command_code, buffer, in_size, out_size); +} diff --git a/common/tpm_registers.c b/common/tpm_registers.c index a70fd0e028..c2728522ae 100644 --- a/common/tpm_registers.c +++ b/common/tpm_registers.c @@ -626,11 +626,11 @@ static void call_extension_command(struct tpm_cmd_header *tpmh, *total_size -= sizeof(struct tpm_cmd_header); subcommand_code = be16toh(tpmh->subcommand_code); - rc = extension_route_command(subcommand_code, - tpmh + 1, - command_size - - sizeof(struct tpm_cmd_header), - total_size); + rc = tpm_extension_route_command(subcommand_code, + tpmh + 1, + command_size - + sizeof(struct tpm_cmd_header), + total_size); /* Add the header size back. */ *total_size += sizeof(struct tpm_cmd_header); tpmh->size = htobe32(*total_size); diff --git a/include/extension.h b/include/extension.h index 3b960f5439..28a0dc7d06 100644 --- a/include/extension.h +++ b/include/extension.h @@ -26,8 +26,12 @@ typedef enum vendor_cmd_rc (*extension_handler)(enum vendor_cmd_cc code, size_t command_size, size_t *response_size); -/* +/** * Find handler for an extension command. + * + * Use the interface specific function call in order to check the policies for + * handling the commands on that interface. + * * @param command_code Code associated with a extension command handler. * @param buffer Data to be processd by the handler, the same space * is used for data returned by the handler. @@ -36,10 +40,14 @@ typedef enum vendor_cmd_rc (*extension_handler)(enum vendor_cmd_cc code, * data returned by the handler. A single byte return * usually indicates an error and contains the error code. */ -uint32_t extension_route_command(uint16_t command_code, - void *buffer, - size_t command_size, - size_t *size); +uint32_t usb_extension_route_command(uint16_t command_code, + void *buffer, + size_t command_size, + size_t *size); +uint32_t tpm_extension_route_command(uint16_t command_code, + void *buffer, + size_t command_size, + size_t *size); /* Pointer table */ struct extension_command { |