Add memory size check in tarball copying methods Change-Id: Id1190844a39daceaa114e0bfad9e4fe406b86c5e
diff --git a/sw/device/examples/hello_world_multicore/hello_world_multicore_sc_loaders_extflash.c b/sw/device/examples/hello_world_multicore/hello_world_multicore_sc_loaders_extflash.c index fcc9184..026607f 100644 --- a/sw/device/examples/hello_world_multicore/hello_world_multicore_sc_loaders_extflash.c +++ b/sw/device/examples/hello_world_multicore/hello_world_multicore_sc_loaders_extflash.c
@@ -6,13 +6,15 @@ #include "sw/device/lib/testing/test_framework/check.h" void load_smc(void) { - CHECK_DIF_OK( - load_file_from_tar("smc.bin", (void*)TOP_MATCHA_RAM_SMC_BASE_ADDR)); + CHECK_DIF_OK(load_file_from_tar( + "smc.bin", (void*)TOP_MATCHA_RAM_SMC_BASE_ADDR, + (TOP_MATCHA_RAM_SMC_BASE_ADDR + TOP_MATCHA_RAM_SMC_SIZE_BYTES))); } void load_kelvin(void) { - CHECK_DIF_OK(load_file_from_tar("kelvin.bin", - (void*)TOP_MATCHA_ML_TOP_DMEM_BASE_ADDR)); + CHECK_DIF_OK(load_file_from_tar( + "kelvin.bin", (void*)TOP_MATCHA_ML_TOP_DMEM_BASE_ADDR, + (TOP_MATCHA_ML_TOP_DMEM_BASE_ADDR + TOP_MATCHA_RAM_ML_DMEM_SIZE_BYTES))); } void load_init(void) { spi_flash_init(); }
diff --git a/sw/device/lib/spi_flash.c b/sw/device/lib/spi_flash.c index b418aee..8765118 100644 --- a/sw/device/lib/spi_flash.c +++ b/sw/device/lib/spi_flash.c
@@ -126,18 +126,25 @@ return kDifOk; } -dif_result_t load_file_from_tar(const char* filename, void* addr) { +dif_result_t load_file_from_tar(const char* filename, void* addr, + size_t max_mem_addr) { + if (!filename) { + return kDifBadArg; + } size_t size = 0; size_t bin_offset = find_file_in_tar(filename, /*start_cursor=*/0, &size, /*found_filename=*/NULL, /*max_filename_len=*/0); if (!bin_offset) return kDifError; + if ((size_t)addr + size > max_mem_addr) { + return kDifBadArg; + } return copy_flash_to_mem(bin_offset, size, addr); } dif_result_t load_file_prefix_from_tar(const char* file_prefix, void* addr, - size_t* tar_offset, char* filename, - size_t filename_len) { + size_t max_mem_addr, size_t* tar_offset, + char* filename, size_t filename_len) { if (!tar_offset || !file_prefix || !filename) { return kDifBadArg; } @@ -146,7 +153,9 @@ size_t bin_offset = find_file_in_tar(file_prefix, start_offset, &size, filename, filename_len); if (!bin_offset) return kDifOutOfRange; - + if ((size_t)addr + size > max_mem_addr) { + return kDifBadArg; + } // Update the tar_offset for the future call. *tar_offset = bin_offset + ((size + 511) & ~511); return copy_flash_to_mem(bin_offset, size, addr);
diff --git a/sw/device/lib/spi_flash.h b/sw/device/lib/spi_flash.h index b275836..746bc23 100644 --- a/sw/device/lib/spi_flash.h +++ b/sw/device/lib/spi_flash.h
@@ -18,11 +18,12 @@ dif_result_t spi_flash_read_page(uint32_t page, uint8_t* buf); /* Tar filesystem related methods */ -dif_result_t load_file_from_tar(const char* filename, void* addr); +dif_result_t load_file_from_tar(const char* filename, void* addr, + size_t max_mem_addr); dif_result_t load_file_prefix_from_tar(const char* file_prefix, void* addr, - size_t* bin_offset, char* filename, - size_t filename_len); + size_t max_mem_addr, size_t* bin_offset, + char* filename, size_t filename_len); #if defined(__cplusplus) }
diff --git a/sw/device/tests/kelvin/fpga_tests/kelvin_test_sc.c b/sw/device/tests/kelvin/fpga_tests/kelvin_test_sc.c index b8fcb06..b49225a 100644 --- a/sw/device/tests/kelvin/fpga_tests/kelvin_test_sc.c +++ b/sw/device/tests/kelvin/fpga_tests/kelvin_test_sc.c
@@ -31,8 +31,9 @@ spi_flash_init(); // Copy binary to SMC RAM. - CHECK_DIF_OK( - load_file_from_tar("smc.bin", (void*)TOP_MATCHA_RAM_SMC_BASE_ADDR)); + CHECK_DIF_OK(load_file_from_tar( + "smc.bin", (void*)TOP_MATCHA_RAM_SMC_BASE_ADDR, + (TOP_MATCHA_RAM_SMC_BASE_ADDR + TOP_MATCHA_RAM_SMC_SIZE_BYTES))); mmio_region_t ml_dmem = mmio_region_from_addr(TOP_MATCHA_ML_TOP_DMEM_BASE_ADDR); @@ -61,8 +62,11 @@ int test_num = 0; int failed_test = 0; while ((kelvin_load_result = load_file_prefix_from_tar( - "kelvin_", (void*)TOP_MATCHA_ML_TOP_DMEM_BASE_ADDR, &bin_offset, - kelvin_bin_name, sizeof(kelvin_bin_name))) != kDifOutOfRange) { + "kelvin_", (void*)TOP_MATCHA_ML_TOP_DMEM_BASE_ADDR, + (TOP_MATCHA_ML_TOP_DMEM_BASE_ADDR + + TOP_MATCHA_ML_TOP_DMEM_SIZE_BYTES), + &bin_offset, kelvin_bin_name, sizeof(kelvin_bin_name))) != + kDifOutOfRange) { CHECK_DIF_OK(kelvin_load_result, "Failed to load %s", kelvin_bin_name); test_num++; LOG_INFO("Test %d: Run kelvin binary %s", test_num, kelvin_bin_name);