A new session or download must not retain the size of an earlier image. Otherwise a failed transfer can leave commands operating on stale or partially overwritten data. Only mark a download complete once all expected bytes have arrived.
Signed-off-by: Carlo Caione <[email protected]> --- drivers/fastboot/fb_command.c | 14 +++++++++++++- drivers/fastboot/fb_common.c | 3 ++- include/fastboot-internal.h | 3 +++ 3 files changed, 18 insertions(+), 2 deletions(-) diff --git a/drivers/fastboot/fb_command.c b/drivers/fastboot/fb_command.c index a2a89fc04f8..68983f5098a 100644 --- a/drivers/fastboot/fb_command.c +++ b/drivers/fastboot/fb_command.c @@ -272,6 +272,13 @@ static void getvar(char *cmd_parameter, char *response) fastboot_getvar(cmd_parameter, response); } +void fastboot_download_reset(void) +{ + image_size = 0; + fastboot_bytes_received = 0; + fastboot_bytes_expected = 0; +} + /** * fastboot_download() - Start a download transfer from the client * @@ -282,11 +289,11 @@ static void download(char *cmd_parameter, char *response) { char *tmp; + fastboot_download_reset(); if (!cmd_parameter) { fastboot_fail("Expected command parameter", response); return; } - fastboot_bytes_received = 0; fastboot_bytes_expected = hextoul(cmd_parameter, &tmp); if (fastboot_bytes_expected == 0) { fastboot_fail("Expected nonzero image size", response); @@ -370,6 +377,11 @@ void fastboot_data_download(const void *fastboot_data, */ void fastboot_data_complete(char *response) { + if (!fastboot_bytes_expected || fastboot_data_remaining()) { + fastboot_fail("Incomplete download", response); + return; + } + /* Download complete. Respond with "OKAY" */ fastboot_okay(NULL, response); printf("\ndownloading of %d bytes finished\n", fastboot_bytes_received); diff --git a/drivers/fastboot/fb_common.c b/drivers/fastboot/fb_common.c index 9184bc6346d..59a08018a79 100644 --- a/drivers/fastboot/fb_common.c +++ b/drivers/fastboot/fb_common.c @@ -15,6 +15,7 @@ #include <cpu_func.h> #include <env.h> #include <fastboot.h> +#include <fastboot-internal.h> #include <net.h> #include <vsprintf.h> @@ -261,5 +262,5 @@ void fastboot_init(void *buf_addr, u32 buf_size) (void *)CONFIG_FASTBOOT_BUF_ADDR; fastboot_buf_size = buf_size ? buf_size : CONFIG_FASTBOOT_BUF_SIZE; fastboot_set_progress_callback(NULL); - + fastboot_download_reset(); } diff --git a/include/fastboot-internal.h b/include/fastboot-internal.h index 610d4f91414..41411601da3 100644 --- a/include/fastboot-internal.h +++ b/include/fastboot-internal.h @@ -13,6 +13,9 @@ extern void *fastboot_buf_addr; */ extern u32 fastboot_buf_size; +/* Invalidate downloaded data when starting a new session or download. */ +void fastboot_download_reset(void); + /** * fastboot_progress_callback - callback executed during long operations */ -- 2.56.0
