diff --git a/components/esp_rom/esp32c2/ld/esp32c2.rom.ld b/components/esp_rom/esp32c2/ld/esp32c2.rom.ld index 9b061ca5e4..032b6b23fc 100644 --- a/components/esp_rom/esp32c2/ld/esp32c2.rom.ld +++ b/components/esp_rom/esp32c2/ld/esp32c2.rom.ld @@ -272,15 +272,15 @@ PROVIDE( esp_flash_chip_driver_initialized = 0x40000430 ); PROVIDE( esp_flash_read_id = 0x40000434 ); PROVIDE( esp_flash_get_size = 0x40000438 ); PROVIDE( esp_flash_erase_chip = 0x4000043c ); -PROVIDE( esp_flash_erase_region = 0x40000440 ); +PROVIDE( rom_esp_flash_erase_region = 0x40000440 ); PROVIDE( esp_flash_get_chip_write_protect = 0x40000444 ); PROVIDE( esp_flash_set_chip_write_protect = 0x40000448 ); PROVIDE( esp_flash_get_protectable_regions = 0x4000044c ); PROVIDE( esp_flash_get_protected_region = 0x40000450 ); PROVIDE( esp_flash_set_protected_region = 0x40000454 ); PROVIDE( esp_flash_read = 0x40000458 ); -PROVIDE( esp_flash_write = 0x4000045c ); -PROVIDE( esp_flash_write_encrypted = 0x40000460 ); +PROVIDE( rom_esp_flash_write = 0x4000045c ); +PROVIDE( rom_esp_flash_write_encrypted = 0x40000460 ); PROVIDE( esp_flash_read_encrypted = 0x40000464 ); PROVIDE( esp_flash_get_io_mode = 0x40000468 ); PROVIDE( esp_flash_set_io_mode = 0x4000046c ); diff --git a/components/esp_rom/esp32c3/ld/esp32c3.rom.ld b/components/esp_rom/esp32c3/ld/esp32c3.rom.ld index b714646678..3e716947ea 100644 --- a/components/esp_rom/esp32c3/ld/esp32c3.rom.ld +++ b/components/esp_rom/esp32c3/ld/esp32c3.rom.ld @@ -267,8 +267,8 @@ PROVIDE( esp_flash_get_protectable_regions = 0x40000318 ); PROVIDE( esp_flash_get_protected_region = 0x4000031c ); PROVIDE( esp_flash_set_protected_region = 0x40000320 ); PROVIDE( esp_flash_read = 0x40000324 ); -PROVIDE( esp_flash_write = 0x40000328 ); -PROVIDE( esp_flash_write_encrypted = 0x4000032c ); +PROVIDE( rom_esp_flash_write = 0x40000328 ); +PROVIDE( rom_esp_flash_write_encrypted = 0x4000032c ); PROVIDE( esp_flash_read_encrypted = 0x40000330 ); PROVIDE( esp_flash_get_io_mode = 0x40000334 ); PROVIDE( esp_flash_set_io_mode = 0x40000338 ); diff --git a/components/esp_rom/esp32c5/mp/esp32c5/ld/esp32c5.rom.spiflash.ld b/components/esp_rom/esp32c5/mp/esp32c5/ld/esp32c5.rom.spiflash.ld index c7c934b1e8..fdcba90d73 100644 --- a/components/esp_rom/esp32c5/mp/esp32c5/ld/esp32c5.rom.spiflash.ld +++ b/components/esp_rom/esp32c5/mp/esp32c5/ld/esp32c5.rom.spiflash.ld @@ -51,15 +51,15 @@ esp_flash_chip_driver_initialized = 0x40000240; esp_flash_read_id = 0x40000244; esp_flash_get_size = 0x40000248; esp_flash_erase_chip = 0x4000024c; -esp_flash_erase_region = 0x40000250; +rom_esp_flash_erase_region = 0x40000250; esp_flash_get_chip_write_protect = 0x40000254; esp_flash_set_chip_write_protect = 0x40000258; esp_flash_get_protectable_regions = 0x4000025c; esp_flash_get_protected_region = 0x40000260; esp_flash_set_protected_region = 0x40000264; esp_flash_read = 0x40000268; -esp_flash_write = 0x4000026c; -esp_flash_write_encrypted = 0x40000270; +rom_esp_flash_write = 0x4000026c; +rom_esp_flash_write_encrypted = 0x40000270; esp_flash_read_encrypted = 0x40000274; esp_flash_get_io_mode = 0x40000278; esp_flash_set_io_mode = 0x4000027c; diff --git a/components/esp_rom/esp32c6/ld/esp32c6.rom.spiflash.ld b/components/esp_rom/esp32c6/ld/esp32c6.rom.spiflash.ld index 1ff2f58465..4954c044b7 100644 --- a/components/esp_rom/esp32c6/ld/esp32c6.rom.spiflash.ld +++ b/components/esp_rom/esp32c6/ld/esp32c6.rom.spiflash.ld @@ -50,15 +50,15 @@ esp_flash_chip_driver_initialized = 0x4000022c; esp_flash_read_id = 0x40000230; esp_flash_get_size = 0x40000234; esp_flash_erase_chip = 0x40000238; -esp_flash_erase_region = 0x4000023c; +rom_esp_flash_erase_region = 0x4000023c; esp_flash_get_chip_write_protect = 0x40000240; esp_flash_set_chip_write_protect = 0x40000244; esp_flash_get_protectable_regions = 0x40000248; esp_flash_get_protected_region = 0x4000024c; esp_flash_set_protected_region = 0x40000250; esp_flash_read = 0x40000254; -esp_flash_write = 0x40000258; -esp_flash_write_encrypted = 0x4000025c; +rom_esp_flash_write = 0x40000258; +rom_esp_flash_write_encrypted = 0x4000025c; esp_flash_read_encrypted = 0x40000260; esp_flash_get_io_mode = 0x40000264; esp_flash_set_io_mode = 0x40000268; diff --git a/components/esp_rom/esp32c61/ld/esp32c61.rom.spiflash.ld b/components/esp_rom/esp32c61/ld/esp32c61.rom.spiflash.ld index 6dd9e34a98..ed3450cde9 100644 --- a/components/esp_rom/esp32c61/ld/esp32c61.rom.spiflash.ld +++ b/components/esp_rom/esp32c61/ld/esp32c61.rom.spiflash.ld @@ -51,15 +51,15 @@ esp_flash_chip_driver_initialized = 0x40000240; esp_flash_read_id = 0x40000244; esp_flash_get_size = 0x40000248; esp_flash_erase_chip = 0x4000024c; -esp_flash_erase_region = 0x40000250; +rom_esp_flash_erase_region = 0x40000250; esp_flash_get_chip_write_protect = 0x40000254; esp_flash_set_chip_write_protect = 0x40000258; esp_flash_get_protectable_regions = 0x4000025c; esp_flash_get_protected_region = 0x40000260; esp_flash_set_protected_region = 0x40000264; esp_flash_read = 0x40000268; -esp_flash_write = 0x4000026c; -esp_flash_write_encrypted = 0x40000270; +rom_esp_flash_write = 0x4000026c; +rom_esp_flash_write_encrypted = 0x40000270; esp_flash_read_encrypted = 0x40000274; esp_flash_get_io_mode = 0x40000278; esp_flash_set_io_mode = 0x4000027c; diff --git a/components/esp_rom/esp32h2/ld/esp32h2.rom.spiflash.ld b/components/esp_rom/esp32h2/ld/esp32h2.rom.spiflash.ld index 834ef2afb8..94481c09cd 100644 --- a/components/esp_rom/esp32h2/ld/esp32h2.rom.spiflash.ld +++ b/components/esp_rom/esp32h2/ld/esp32h2.rom.spiflash.ld @@ -50,15 +50,15 @@ esp_flash_chip_driver_initialized = 0x40000224; esp_flash_read_id = 0x40000228; esp_flash_get_size = 0x4000022c; esp_flash_erase_chip = 0x40000230; -esp_flash_erase_region = 0x40000234; +rom_esp_flash_erase_region = 0x40000234; esp_flash_get_chip_write_protect = 0x40000238; esp_flash_set_chip_write_protect = 0x4000023c; esp_flash_get_protectable_regions = 0x40000240; esp_flash_get_protected_region = 0x40000244; esp_flash_set_protected_region = 0x40000248; esp_flash_read = 0x4000024c; -esp_flash_write = 0x40000250; -esp_flash_write_encrypted = 0x40000254; +rom_esp_flash_write = 0x40000250; +rom_esp_flash_write_encrypted = 0x40000254; esp_flash_read_encrypted = 0x40000258; esp_flash_get_io_mode = 0x4000025c; esp_flash_set_io_mode = 0x40000260; diff --git a/components/esp_rom/esp32s3/ld/esp32s3.rom.ld b/components/esp_rom/esp32s3/ld/esp32s3.rom.ld index 25e18af8e7..669fc6d0c8 100644 --- a/components/esp_rom/esp32s3/ld/esp32s3.rom.ld +++ b/components/esp_rom/esp32s3/ld/esp32s3.rom.ld @@ -318,8 +318,8 @@ PROVIDE( esp_flash_get_protectable_regions = 0x40001110 ); PROVIDE( esp_flash_get_protected_region = 0x4000111c ); PROVIDE( esp_flash_set_protected_region = 0x40001128 ); PROVIDE( esp_flash_read = 0x40001134 ); -PROVIDE( esp_flash_write = 0x40001140 ); -PROVIDE( esp_flash_write_encrypted = 0x4000114c ); +PROVIDE( rom_esp_flash_write = 0x40001140 ); +PROVIDE( rom_esp_flash_write_encrypted = 0x4000114c ); PROVIDE( esp_flash_read_encrypted = 0x40001158 ); PROVIDE( esp_flash_get_io_mode = 0x40001164 ); PROVIDE( esp_flash_set_io_mode = 0x40001170 ); diff --git a/components/spi_flash/esp_flash_api.c b/components/spi_flash/esp_flash_api.c index c6fa0e3cbe..69ba6f2b5d 100644 --- a/components/spi_flash/esp_flash_api.c +++ b/components/spi_flash/esp_flash_api.c @@ -557,9 +557,6 @@ esp_err_t IRAM_ATTR esp_flash_get_physical_size(esp_flash_t *chip, uint32_t *fla #ifndef CONFIG_SPI_FLASH_ROM_IMPL -/* Return true if regions 'a' and 'b' overlap at all, based on their start offsets and lengths. */ -inline static bool regions_overlap(uint32_t a_start, uint32_t a_len,uint32_t b_start, uint32_t b_len); - esp_err_t IRAM_ATTR esp_flash_get_size(esp_flash_t *chip, uint32_t *out_size) { esp_err_t err = rom_spiflash_api_funcs->chip_check(&chip); @@ -590,7 +587,21 @@ esp_err_t IRAM_ATTR esp_flash_erase_chip(esp_flash_t *chip) err = esp_flash_erase_region(chip, 0, size); return err; } +#endif // !CONFIG_SPI_FLASH_ROM_IMPL +#ifndef CONFIG_SPI_FLASH_ROM_IMPL +inline static IRAM_ATTR bool regions_overlap(uint32_t a_start, uint32_t a_len,uint32_t b_start, uint32_t b_len) +{ + uint32_t a_end = a_start + a_len; + uint32_t b_end = b_start + b_len; + return (a_end > b_start && b_end > a_start); +} + +/* ROM and patch information + * Latest: Fixed region check escape + * V2: Fixed size == 0 bug. + * V1 (ESP_ROM_HAS_ERASE_0_REGION_BUG): Added to ROM + */ esp_err_t IRAM_ATTR esp_flash_erase_region(esp_flash_t *chip, uint32_t start, uint32_t len) { esp_err_t err = rom_spiflash_api_funcs->chip_check(&chip); @@ -606,7 +617,7 @@ esp_err_t IRAM_ATTR esp_flash_erase_region(esp_flash_t *chip, uint32_t start, ui if (sector_size == 0 || (block_erase_size % sector_size) != 0) { return ESP_ERR_FLASH_NOT_INITIALISED; } - if (start > chip->size || start + len > chip->size) { + if (start > chip->size || len > chip->size - start) { return ESP_ERR_INVALID_ARG; } if ((start % chip->chip_drv->sector_size) != 0 || (len % chip->chip_drv->sector_size) != 0) { @@ -701,26 +712,45 @@ esp_err_t IRAM_ATTR esp_flash_erase_region(esp_flash_t *chip, uint32_t start, ui return rom_spiflash_api_funcs->flash_end_flush_cache(chip, err, bus_acquired, start, len); } - -#endif // !CONFIG_SPI_FLASH_ROM_IMPL - -#if defined(CONFIG_SPI_FLASH_ROM_IMPL) && ESP_ROM_HAS_ERASE_0_REGION_BUG - -/* ROM esp_flash_erase_region implementation doesn't handle 0 erase size correctly. +#else //!CONFIG_SPI_FLASH_ROM_IMPL +extern esp_err_t rom_esp_flash_erase_region(esp_flash_t *chip, uint32_t start, uint32_t len); +# if ESP_ROM_HAS_ERASE_0_REGION_BUG +// Usel ROM impl v1 but workaround ESP_ROM_HAS_ERASE_0_REGION_BUG and region check escape. +/* ROM V1 esp_flash_erase_region implementation doesn't handle 0 erase size correctly. * Check the size and call ROM function instead of overriding it completely. - * The behavior is slightly different from esp_flash_erase_region above, thought: + * The behavior is slightly different from latest esp_flash_erase_region above, thought: * here the check for 0 size is done first, but in esp_flash_erase_region the check is * done after the other arguments are checked. */ -extern esp_err_t rom_esp_flash_erase_region(esp_flash_t *chip, uint32_t start, uint32_t len); esp_err_t IRAM_ATTR esp_flash_erase_region(esp_flash_t *chip, uint32_t start, uint32_t len) { + esp_err_t err = rom_spiflash_api_funcs->chip_check(&chip); + if (err != ESP_OK) { + return err; + } if (len == 0) { return ESP_OK; } + if (len > chip->size - start) { + return ESP_ERR_INVALID_ARG; + } return rom_esp_flash_erase_region(chip, start, len); } -#endif // defined(CONFIG_SPI_FLASH_ROM_IMPL) && ESP_ROM_HAS_ERASE_0_REGION_BUG +# else +// Usel ROM impl v2 but workaround region check escape. +esp_err_t IRAM_ATTR esp_flash_erase_region(esp_flash_t *chip, uint32_t start, uint32_t len) +{ + esp_err_t err = rom_spiflash_api_funcs->chip_check(&chip); + if (err != ESP_OK) { + return err; + } + if (len > chip->size - start) { + return ESP_ERR_INVALID_ARG; + } + return rom_esp_flash_erase_region(chip, start, len); +} +# endif // ESP_ROM_HAS_ERASE_0_REGION_BUG +#endif // !CONFIG_SPI_FLASH_ROM_IMPL #ifndef CONFIG_SPI_FLASH_ROM_IMPL @@ -925,7 +955,10 @@ esp_err_t IRAM_ATTR esp_flash_read(esp_flash_t *chip, void *buffer, uint32_t add COUNTER_STOP(read); return err; } +#endif //!CONFIG_SPI_FLASH_ROM_IMPL +#ifndef CONFIG_SPI_FLASH_ROM_IMPL +//This checking is available only when !CONFIG_SPI_FLASH_ROM_IMPL #if CONFIG_SPI_FLASH_WARN_SETTING_ZERO_TO_ONE static esp_err_t IRAM_ATTR s_check_setting_zero_to_one(esp_flash_t *chip, uint32_t verify_address, uint32_t remain_verify_len, const uint32_t *to_write_buf, bool is_encrypted) { @@ -965,6 +998,7 @@ static esp_err_t IRAM_ATTR s_check_setting_zero_to_one(esp_flash_t *chip, uint32 } #endif //#if CONFIG_SPI_FLASH_WARN_SETTING_ZERO_TO_ONE +//This checking is available only when !CONFIG_SPI_FLASH_ROM_IMPL #if CONFIG_SPI_FLASH_VERIFY_WRITE static esp_err_t IRAM_ATTR s_verify_write(esp_flash_t *chip, uint32_t verify_address, uint32_t remain_verify_len, const uint32_t *expected_buf, bool is_encrypted) { @@ -1003,6 +1037,13 @@ static esp_err_t IRAM_ATTR s_verify_write(esp_flash_t *chip, uint32_t verify_add } #endif //#if CONFIG_SPI_FLASH_VERIFY_WRITE +/* ROM and patch information + * Latest: + - Provide debugging utils (CONFIG_SPI_FLASH_WARN_SETTING_ZERO_TO_ONE, CONFIG_SPI_FLASH_VERIFY_WRITE) + - Fixed region check escape + * V1: added to ROM + */ +//When use the ROM impl, can't use these debugging utils. esp_err_t IRAM_ATTR esp_flash_write(esp_flash_t *chip, const void *buffer, uint32_t address, uint32_t length) { esp_err_t ret = ESP_FAIL; @@ -1014,7 +1055,7 @@ esp_err_t IRAM_ATTR esp_flash_write(esp_flash_t *chip, const void *buffer, uint3 esp_err_t err = rom_spiflash_api_funcs->chip_check(&chip); VERIFY_CHIP_OP(write); CHECK_WRITE_ADDRESS(chip, address, length); - if (buffer == NULL || address > chip->size || address+length > chip->size) { + if (buffer == NULL || address > chip->size || length > chip->size - address) { return ESP_ERR_INVALID_ARG; } if (length == 0) { @@ -1124,14 +1165,23 @@ restore_cache: return err; } - -inline static IRAM_ATTR bool regions_overlap(uint32_t a_start, uint32_t a_len,uint32_t b_start, uint32_t b_len) +#else +extern esp_err_t rom_esp_flash_write(esp_flash_t *chip, const void *buffer, uint32_t address, uint32_t length); +// Usel ROM impl v1 but workaround region check escape. +esp_err_t IRAM_ATTR esp_flash_write(esp_flash_t *chip, const void *buffer, uint32_t address, uint32_t length) { - uint32_t a_end = a_start + a_len; - uint32_t b_end = b_start + b_len; - return (a_end > b_start && b_end > a_start); + esp_err_t err = rom_spiflash_api_funcs->chip_check(&chip); + if (err != ESP_OK) { + return err; + } + if (length > chip->size - address) { + return ESP_ERR_INVALID_ARG; + } + return rom_esp_flash_write(chip, buffer, address, length); } +#endif //!CONFIG_SPI_FLASH_ROM_IMPL +#ifndef CONFIG_SPI_FLASH_ROM_IMPL esp_err_t IRAM_ATTR esp_flash_read_encrypted(esp_flash_t *chip, uint32_t address, void *out_buffer, uint32_t length) { esp_err_t err = rom_spiflash_api_funcs->chip_check(&chip); @@ -1198,9 +1248,8 @@ IRAM_ATTR esp_err_t esp_flash_set_io_mode(esp_flash_t* chip, bool qe) } #endif //CONFIG_SPI_FLASH_ROM_IMPL -#if !CONFIG_SPI_FLASH_ROM_IMPL || ESP_ROM_HAS_ENCRYPTED_WRITES_USING_LEGACY_DRV -// use `esp_flash_write_encrypted` ROM version not in C3 and S3 - +#if !(CONFIG_SPI_FLASH_ROM_IMPL && !ESP_ROM_HAS_ENCRYPTED_WRITES_USING_LEGACY_DRV) +// use `esp_flash_write_encrypted` ROM version on chips later than C3 and S3 FORCE_INLINE_ATTR esp_err_t s_encryption_write_lock(esp_flash_t *chip) { #if CONFIG_IDF_TARGET_ESP32S2 esp_crypto_dma_lock_acquire(); @@ -1216,6 +1265,14 @@ FORCE_INLINE_ATTR esp_err_t s_encryption_write_unlock(esp_flash_t *chip) { return err; } +/* ROM and patch information + * Latest: + - Provide debugging utils (CONFIG_SPI_FLASH_WARN_SETTING_ZERO_TO_ONE, CONFIG_SPI_FLASH_VERIFY_WRITE) + - Fixed region check escape + * V2: Bug fixed + * V1 (ESP_ROM_HAS_ENCRYPTED_WRITES_USING_LEGACY_DRV): added to ROM but has bug + */ +//When use the ROM impl, can't use these debugging utils. esp_err_t IRAM_ATTR esp_flash_write_encrypted(esp_flash_t *chip, uint32_t address, const void *buffer, uint32_t length) { esp_err_t ret = ESP_FAIL; @@ -1232,7 +1289,7 @@ esp_err_t IRAM_ATTR esp_flash_write_encrypted(esp_flash_t *chip, uint32_t addres } CHECK_WRITE_ADDRESS(chip, address, length); - if (buffer == NULL || address + length > chip->size) { + if (buffer == NULL || address > chip->size || length > chip->size - address) { return ESP_ERR_INVALID_ARG; } @@ -1435,8 +1492,21 @@ restore_cache: return err; } - -#endif // !CONFIG_SPI_FLASH_ROM_IMPL || ESP_ROM_HAS_ENCRYPTED_WRITES_USING_LEGACY_DRV +#else +extern esp_err_t rom_esp_flash_write_encrypted(esp_flash_t *chip, uint32_t address, const void *buffer, uint32_t length); +// Usel ROM impl v2 but workaround region check escape. +esp_err_t IRAM_ATTR esp_flash_write_encrypted(esp_flash_t *chip, uint32_t address, const void *buffer, uint32_t length) +{ + esp_err_t err = rom_spiflash_api_funcs->chip_check(&chip); + if (err != ESP_OK) { + return err; + } + if (length > chip->size - address) { + return ESP_ERR_INVALID_ARG; + } + return rom_esp_flash_write_encrypted(chip, address, buffer, length); +} +#endif // !(CONFIG_SPI_FLASH_ROM_IMPL && !ESP_ROM_HAS_ENCRYPTED_WRITES_USING_LEGACY_DRV) //init suspend mode cmd, uses internal. esp_err_t esp_flash_suspend_cmd_init(esp_flash_t* chip) diff --git a/components/spi_flash/test_apps/esp_flash/main/test_esp_flash_drv.c b/components/spi_flash/test_apps/esp_flash/main/test_esp_flash_drv.c index 13163fe519..f56ed6059d 100644 --- a/components/spi_flash/test_apps/esp_flash/main/test_esp_flash_drv.c +++ b/components/spi_flash/test_apps/esp_flash/main/test_esp_flash_drv.c @@ -783,6 +783,41 @@ static void test_write_large_buffer(const esp_partition_t* part, const uint8_t * read_and_check(part, source, length); } +#if CONFIG_SPI_FLASH_DANGEROUS_WRITE_ALLOWED +static void test_write_over_boundary(const esp_partition_t* part) +{ + esp_flash_t* chip = part->flash_chip; + uint32_t flash_size; + esp_err_t err = esp_flash_get_size(chip, &flash_size); + TEST_ESP_OK(err); + const uint32_t SECTOR_SIZE = 4096; + uint8_t buf[0]; + + TEST_ASSERT_EQUAL(ESP_ERR_INVALID_ARG, esp_flash_erase_region(chip, 0, flash_size+SECTOR_SIZE)); + TEST_ASSERT_EQUAL(ESP_ERR_INVALID_ARG, esp_flash_erase_region(chip, SECTOR_SIZE, flash_size)); + TEST_ASSERT_EQUAL(ESP_ERR_INVALID_ARG, esp_flash_erase_region(chip, flash_size/2, flash_size/2 + SECTOR_SIZE)); + TEST_ASSERT_EQUAL(ESP_ERR_INVALID_ARG, esp_flash_erase_region(chip, flash_size/2 + SECTOR_SIZE, flash_size/2)); + TEST_ASSERT_EQUAL(ESP_ERR_INVALID_ARG, esp_flash_erase_region(chip, flash_size - SECTOR_SIZE, 2 * SECTOR_SIZE)); + TEST_ASSERT_EQUAL(ESP_ERR_INVALID_ARG, esp_flash_erase_region(chip, 2 * SECTOR_SIZE, flash_size - SECTOR_SIZE)); + TEST_ASSERT_EQUAL(ESP_ERR_INVALID_ARG, esp_flash_erase_region(chip, flash_size - SECTOR_SIZE, flash_size - SECTOR_SIZE)); + TEST_ASSERT_EQUAL(ESP_ERR_INVALID_ARG, esp_flash_erase_region(chip, flash_size - SECTOR_SIZE, UINT32_MAX - SECTOR_SIZE + 1)); + TEST_ASSERT_EQUAL(ESP_ERR_INVALID_ARG, esp_flash_erase_region(chip, UINT32_MAX - SECTOR_SIZE + 1, flash_size - SECTOR_SIZE)); + + TEST_ASSERT_EQUAL(ESP_ERR_INVALID_ARG, esp_flash_write(chip, buf, 0, flash_size+SECTOR_SIZE)); + TEST_ASSERT_EQUAL(ESP_ERR_INVALID_ARG, esp_flash_write(chip, buf, SECTOR_SIZE, flash_size)); + TEST_ASSERT_EQUAL(ESP_ERR_INVALID_ARG, esp_flash_write(chip, buf, flash_size/2, flash_size/2 + SECTOR_SIZE)); + TEST_ASSERT_EQUAL(ESP_ERR_INVALID_ARG, esp_flash_write(chip, buf, flash_size/2 + SECTOR_SIZE, flash_size/2)); + TEST_ASSERT_EQUAL(ESP_ERR_INVALID_ARG, esp_flash_write(chip, buf, flash_size - SECTOR_SIZE, 2 * SECTOR_SIZE)); + TEST_ASSERT_EQUAL(ESP_ERR_INVALID_ARG, esp_flash_write(chip, buf, 2 * SECTOR_SIZE, flash_size - SECTOR_SIZE)); + TEST_ASSERT_EQUAL(ESP_ERR_INVALID_ARG, esp_flash_write(chip, buf, flash_size - SECTOR_SIZE, flash_size - SECTOR_SIZE)); + TEST_ASSERT_EQUAL(ESP_ERR_INVALID_ARG, esp_flash_write(chip, buf, flash_size - SECTOR_SIZE, UINT32_MAX - SECTOR_SIZE + 1)); + TEST_ASSERT_EQUAL(ESP_ERR_INVALID_ARG, esp_flash_write(chip, buf, UINT32_MAX - SECTOR_SIZE + 1, flash_size - SECTOR_SIZE)); +} + +TEST_CASE_FLASH("Test flash write over boundary", test_write_over_boundary); +TEST_CASE_MULTI_FLASH("Test flash write over boundary", test_write_over_boundary); +#endif //CONFIG_SPI_FLASH_DANGEROUS_WRITE_ALLOWED + #if !CONFIG_SPI_FLASH_WARN_SETTING_ZERO_TO_ONE typedef struct { @@ -1096,3 +1131,16 @@ void test_flash_counter(const esp_partition_t* part) TEST_CASE_FLASH("SPI flash counter test", test_flash_counter); #endif //CONFIG_SPI_FLASH_ENABLE_COUNTERS + +#if CONFIG_SPI_FLASH_DANGEROUS_WRITE_FAILS +TEST_CASE("test writes to dangerous regions like bootloader", "[esp_flash]") +{ + TEST_ASSERT_EQUAL_HEX(ESP_ERR_INVALID_ARG, esp_flash_erase_region(NULL, CONFIG_BOOTLOADER_OFFSET_IN_FLASH, 4*4096)); + TEST_ASSERT_EQUAL_HEX(ESP_ERR_INVALID_ARG, esp_flash_erase_region(NULL, CONFIG_PARTITION_TABLE_OFFSET, 4096)); + char buffer[32] = {0xa5}; + // Encrypted writes to bootloader region not allowed + TEST_ASSERT_EQUAL_HEX(ESP_ERR_INVALID_ARG, esp_flash_write(NULL, buffer, CONFIG_BOOTLOADER_OFFSET_IN_FLASH, sizeof(buffer))); + // Encrypted writes to partition table region not allowed + TEST_ASSERT_EQUAL_HEX(ESP_ERR_INVALID_ARG, esp_flash_write(NULL, buffer, CONFIG_PARTITION_TABLE_OFFSET, sizeof(buffer))); +} +#endif //!CONFIG_SPI_FLASH_DANGEROUS_WRITE_FAILS diff --git a/components/spi_flash/test_apps/esp_flash/sdkconfig.ci.rom_impl b/components/spi_flash/test_apps/esp_flash/sdkconfig.ci.rom_impl index d878b890f7..9c1200bf04 100644 --- a/components/spi_flash/test_apps/esp_flash/sdkconfig.ci.rom_impl +++ b/components/spi_flash/test_apps/esp_flash/sdkconfig.ci.rom_impl @@ -1,2 +1,4 @@ CONFIG_ESP_TASK_WDT_EN=n CONFIG_SPI_FLASH_ROM_IMPL=y +# Unrelated to rom, but to test if the boundary checking works well +CONFIG_SPI_FLASH_DANGEROUS_WRITE_ALLOWED=y diff --git a/components/spi_flash/test_apps/esp_flash/sdkconfig.ci.verify b/components/spi_flash/test_apps/esp_flash/sdkconfig.ci.verify index 61d3f59eff..65fc51dfef 100644 --- a/components/spi_flash/test_apps/esp_flash/sdkconfig.ci.verify +++ b/components/spi_flash/test_apps/esp_flash/sdkconfig.ci.verify @@ -1,4 +1,6 @@ -CONFIG_ESP_TASK_WDT=n +CONFIG_ESP_TASK_WDT_INIT=n CONFIG_SPI_FLASH_VERIFY_WRITE=y CONFIG_SPI_FLASH_LOG_FAILED_WRITE=y CONFIG_SPI_FLASH_WARN_SETTING_ZERO_TO_ONE=y +# Unrelated to verify, but to test if the boundary checking works well +CONFIG_SPI_FLASH_DANGEROUS_WRITE_ALLOWED=y diff --git a/components/spi_flash/test_apps/flash_encryption/main/test_flash_encryption.c b/components/spi_flash/test_apps/flash_encryption/main/test_flash_encryption.c index 6ebfa46b52..caafad773a 100644 --- a/components/spi_flash/test_apps/flash_encryption/main/test_flash_encryption.c +++ b/components/spi_flash/test_apps/flash_encryption/main/test_flash_encryption.c @@ -372,6 +372,7 @@ TEST_CASE("test read & write encrypted data with large buffer in ram", "[flash_e free(buf); } +#if CONFIG_SPI_FLASH_DANGEROUS_WRITE_FAILS TEST_CASE("test encrypted writes to dangerous regions like bootloader", "[flash_encryption]") { TEST_ASSERT_EQUAL_HEX(ESP_ERR_INVALID_ARG, esp_flash_erase_region(NULL, CONFIG_BOOTLOADER_OFFSET_IN_FLASH, 4*4096)); @@ -382,4 +383,36 @@ TEST_CASE("test encrypted writes to dangerous regions like bootloader", "[flash_ // Encrypted writes to partition table region not allowed TEST_ASSERT_EQUAL_HEX(ESP_ERR_INVALID_ARG, esp_flash_write_encrypted(NULL, CONFIG_PARTITION_TABLE_OFFSET, buffer, sizeof(buffer))); } +#elif CONFIG_SPI_FLASH_DANGEROUS_WRITE_ALLOWED +TEST_CASE("Test flash encrypted write over boundary", "[flash_encryption]") +{ + esp_flash_t* chip = NULL; + uint32_t flash_size; + esp_err_t err = esp_flash_get_size(chip, &flash_size); + TEST_ESP_OK(err); + const uint32_t SECTOR_SIZE = 4096; + uint8_t buf[0]; + + TEST_ASSERT_EQUAL(ESP_ERR_INVALID_ARG, esp_flash_erase_region(chip, 0, flash_size+SECTOR_SIZE)); + TEST_ASSERT_EQUAL(ESP_ERR_INVALID_ARG, esp_flash_erase_region(chip, SECTOR_SIZE, flash_size)); + TEST_ASSERT_EQUAL(ESP_ERR_INVALID_ARG, esp_flash_erase_region(chip, flash_size/2, flash_size/2 + SECTOR_SIZE)); + TEST_ASSERT_EQUAL(ESP_ERR_INVALID_ARG, esp_flash_erase_region(chip, flash_size/2 + SECTOR_SIZE, flash_size/2)); + TEST_ASSERT_EQUAL(ESP_ERR_INVALID_ARG, esp_flash_erase_region(chip, flash_size - SECTOR_SIZE, 2 * SECTOR_SIZE)); + TEST_ASSERT_EQUAL(ESP_ERR_INVALID_ARG, esp_flash_erase_region(chip, 2 * SECTOR_SIZE, flash_size - SECTOR_SIZE)); + TEST_ASSERT_EQUAL(ESP_ERR_INVALID_ARG, esp_flash_erase_region(chip, flash_size - SECTOR_SIZE, flash_size - SECTOR_SIZE)); + TEST_ASSERT_EQUAL(ESP_ERR_INVALID_ARG, esp_flash_erase_region(chip, flash_size - SECTOR_SIZE, UINT32_MAX - SECTOR_SIZE + 1)); + TEST_ASSERT_EQUAL(ESP_ERR_INVALID_ARG, esp_flash_erase_region(chip, UINT32_MAX - SECTOR_SIZE + 1, flash_size - SECTOR_SIZE)); + + TEST_ASSERT_EQUAL(ESP_ERR_INVALID_ARG, esp_flash_write_encrypted(chip, 0, buf, flash_size+SECTOR_SIZE)); + TEST_ASSERT_EQUAL(ESP_ERR_INVALID_ARG, esp_flash_write_encrypted(chip, SECTOR_SIZE, buf, flash_size)); + TEST_ASSERT_EQUAL(ESP_ERR_INVALID_ARG, esp_flash_write_encrypted(chip, flash_size/2, buf, flash_size/2 + SECTOR_SIZE)); + TEST_ASSERT_EQUAL(ESP_ERR_INVALID_ARG, esp_flash_write_encrypted(chip, flash_size/2 + SECTOR_SIZE, buf, flash_size/2)); + TEST_ASSERT_EQUAL(ESP_ERR_INVALID_ARG, esp_flash_write_encrypted(chip, flash_size - SECTOR_SIZE, buf, 2 * SECTOR_SIZE)); + TEST_ASSERT_EQUAL(ESP_ERR_INVALID_ARG, esp_flash_write_encrypted(chip, 2 * SECTOR_SIZE, buf, flash_size - SECTOR_SIZE)); + TEST_ASSERT_EQUAL(ESP_ERR_INVALID_ARG, esp_flash_write_encrypted(chip, flash_size - SECTOR_SIZE, buf, flash_size - SECTOR_SIZE)); + TEST_ASSERT_EQUAL(ESP_ERR_INVALID_ARG, esp_flash_write_encrypted(chip, flash_size - SECTOR_SIZE, buf, UINT32_MAX - SECTOR_SIZE + 1)); + TEST_ASSERT_EQUAL(ESP_ERR_INVALID_ARG, esp_flash_write_encrypted(chip, UINT32_MAX - SECTOR_SIZE + 1, buf, flash_size - SECTOR_SIZE)); +} +#endif //CONFIG_SPI_FLASH_DANGEROUS_WRITE_FAILS + #endif // CONFIG_SECURE_FLASH_ENC_ENABLED diff --git a/components/spi_flash/test_apps/flash_encryption/sdkconfig.ci.rom_impl b/components/spi_flash/test_apps/flash_encryption/sdkconfig.ci.rom_impl index 1fe12679eb..cc20549732 100644 --- a/components/spi_flash/test_apps/flash_encryption/sdkconfig.ci.rom_impl +++ b/components/spi_flash/test_apps/flash_encryption/sdkconfig.ci.rom_impl @@ -3,3 +3,5 @@ CONFIG_SPI_FLASH_ROM_IMPL=y CONFIG_COMPILER_OPTIMIZATION_SIZE=y CONFIG_BOOTLOADER_COMPILER_OPTIMIZATION_SIZE=y CONFIG_COMPILER_OPTIMIZATION_ASSERTIONS_SILENT=y +# Unrelated to rom, but to test if the boundary checking works well +CONFIG_SPI_FLASH_DANGEROUS_WRITE_ALLOWED=y diff --git a/components/spi_flash/test_apps/flash_encryption/sdkconfig.ci.verify b/components/spi_flash/test_apps/flash_encryption/sdkconfig.ci.verify index f5ead70973..24b6431346 100644 --- a/components/spi_flash/test_apps/flash_encryption/sdkconfig.ci.verify +++ b/components/spi_flash/test_apps/flash_encryption/sdkconfig.ci.verify @@ -17,3 +17,6 @@ CONFIG_SECURE_FLASH_REQUIRE_ALREADY_ENABLED=y CONFIG_SPI_FLASH_VERIFY_WRITE=y CONFIG_SPI_FLASH_LOG_FAILED_WRITE=y CONFIG_SPI_FLASH_WARN_SETTING_ZERO_TO_ONE=y + +# Unrelated to verify, but to test if the boundary checking works well +CONFIG_SPI_FLASH_DANGEROUS_WRITE_ALLOWED=y diff --git a/components/spi_flash/test_apps/flash_mmap/sdkconfig.ci.release b/components/spi_flash/test_apps/flash_mmap/sdkconfig.ci.release index 6497a7f096..b7fc520a4c 100644 --- a/components/spi_flash/test_apps/flash_mmap/sdkconfig.ci.release +++ b/components/spi_flash/test_apps/flash_mmap/sdkconfig.ci.release @@ -1,4 +1,4 @@ -CONFIG_ESP_TASK_WDT=n +CONFIG_ESP_TASK_WDT_INIT=n CONFIG_COMPILER_OPTIMIZATION_SIZE=y CONFIG_BOOTLOADER_COMPILER_OPTIMIZATION_SIZE=y CONFIG_COMPILER_OPTIMIZATION_ASSERTIONS_SILENT=y diff --git a/components/spi_flash/test_apps/flash_mmap/sdkconfig.defaults b/components/spi_flash/test_apps/flash_mmap/sdkconfig.defaults index e58745b57a..08c7aa6508 100644 --- a/components/spi_flash/test_apps/flash_mmap/sdkconfig.defaults +++ b/components/spi_flash/test_apps/flash_mmap/sdkconfig.defaults @@ -1,3 +1,3 @@ -CONFIG_ESP_TASK_WDT=n +CONFIG_ESP_TASK_WDT_INIT=n CONFIG_PARTITION_TABLE_CUSTOM=y CONFIG_PARTITION_TABLE_CUSTOM_FILENAME="partitions.csv" diff --git a/docs/en/api-reference/peripherals/spi_flash/spi_flash_idf_vs_rom.rst b/docs/en/api-reference/peripherals/spi_flash/spi_flash_idf_vs_rom.rst index 83d78e6fcf..3211ab1888 100644 --- a/docs/en/api-reference/peripherals/spi_flash/spi_flash_idf_vs_rom.rst +++ b/docs/en/api-reference/peripherals/spi_flash/spi_flash_idf_vs_rom.rst @@ -36,3 +36,4 @@ Bugfixes Introduced in ESP-IDF but Not in Chip-ROM :esp32s3: - Fixed issue that only 16MB virtual address ranges can be mapped to read-only data on Flash. :esp32c3: - Fixed issue that only 128KB virtual address ranges can be mapped to instructions on Flash. :esp32c2: - Fixed issue that only at most 128KB virtual address ranges can be mapped to instructions on Flash. + - Fixed issue that address range may escape from checking for erasing and writing function when their sum overflows 32-bit boundary.