From 97c2ae1138fb6370d4b45d1ba9251c95e26a685e Mon Sep 17 00:00:00 2001 From: Vadim Bendebury Date: Wed, 27 Sep 2017 12:03:29 -0700 Subject: [PATCH] gsctool: improve vendor command processing robustness With upcoming RMA authentication extensions the size of the vendor command responses is going to increase. Let's allow 500 bytes per response (the expected maximum is 80 bytes plus TPM header). BRANCH=cr50 BUG=b:37952913 TEST=verified that gsctool (aka usb_updater) still allows to retrieve Cr59 information and update Cr50 image. Change-Id: Ic61b6b89ffe20e534029bd12fea4140882a9afc8 Signed-off-by: Vadim Bendebury Reviewed-on: https://chromium-review.googlesource.com/690442 Reviewed-by: Mary Ruthven --- extra/usb_updater/usb_updater.c | 31 ++++++++++++++++++++----------- 1 file changed, 20 insertions(+), 11 deletions(-) diff --git a/extra/usb_updater/usb_updater.c b/extra/usb_updater/usb_updater.c index 0017667885..b69e60da8d 100644 --- a/extra/usb_updater/usb_updater.c +++ b/extra/usb_updater/usb_updater.c @@ -193,7 +193,12 @@ struct upgrade_pkt { }; } __packed; -#define MAX_BUF_SIZE (SIGNED_TRANSFER_SIZE + sizeof(struct upgrade_pkt)) + +/* + * This by far exceeds the largest vendor command response size we ever + * expect. + */ +#define MAX_BUF_SIZE 500 struct usb_endpoint { struct libusb_device_handle *devh; @@ -385,14 +390,12 @@ static int tpm_send_pkt(struct transfer_descriptor *td, unsigned int digest, /* Used by transfer to /dev/tpm0 */ static uint8_t outbuf[MAX_BUF_SIZE]; struct upgrade_pkt *out = (struct upgrade_pkt *)outbuf; - /* Use the same structure, it will not be filled completely. */ int len, done; int response_offset = offsetof(struct upgrade_pkt, command.data); void *payload; size_t header_size; uint32_t rv; - size_t rx_size = sizeof(struct upgrade_pkt) + - sizeof(struct first_response_pdu); + const size_t rx_size = sizeof(outbuf); debug("%s: sending to %#x %d bytes\n", __func__, addr, size); @@ -450,15 +453,21 @@ static int tpm_send_pkt(struct transfer_descriptor *td, unsigned int digest, return -1; } - /* - * Let's reuse the output buffer as the receve buffer; the combined - * size of the two structures below is sure enough for any expected - * response size. - */ switch (td->ep_type) { - case dev_xfer: - len = read(td->tpm_fd, outbuf, rx_size); + case dev_xfer: { + int read_count; + + len = 0; + do { + uint8_t *rx_buf = outbuf + len; + size_t rx_to_go = rx_size - len; + + read_count = read(td->tpm_fd, rx_buf, rx_to_go); + + len += read_count; + } while (read_count); break; + } case ts_xfer: len = ts_read(outbuf, rx_size); break;