From 36620e1c5bc612c4c3493169793b7f82659da9bd Mon Sep 17 00:00:00 2001 From: Alexey Gerenkov Date: Tue, 13 Nov 2018 00:26:07 +0300 Subject: [PATCH] esp32: Fixes freezing core dump process when flash write address checks are enabled --- components/spi_flash/flash_ops.c | 25 +++++++++++++------- components/spi_flash/include/esp_spi_flash.h | 19 +++++++++++---- 2 files changed, 30 insertions(+), 14 deletions(-) diff --git a/components/spi_flash/flash_ops.c b/components/spi_flash/flash_ops.c index e555148455..7a5315cbf7 100644 --- a/components/spi_flash/flash_ops.c +++ b/components/spi_flash/flash_ops.c @@ -70,19 +70,26 @@ static spi_flash_counters_t s_flash_stats; #endif //CONFIG_SPI_FLASH_ENABLE_COUNTERS static esp_err_t spi_flash_translate_rc(esp_rom_spiflash_result_t rc); +static bool is_safe_write_address(size_t addr, size_t size); const DRAM_ATTR spi_flash_guard_funcs_t g_flash_guard_default_ops = { - .start = spi_flash_disable_interrupts_caches_and_other_cpu, - .end = spi_flash_enable_interrupts_caches_and_other_cpu, - .op_lock = spi_flash_op_lock, - .op_unlock = spi_flash_op_unlock + .start = spi_flash_disable_interrupts_caches_and_other_cpu, + .end = spi_flash_enable_interrupts_caches_and_other_cpu, + .op_lock = spi_flash_op_lock, + .op_unlock = spi_flash_op_unlock, +#if !CONFIG_SPI_FLASH_WRITING_DANGEROUS_REGIONS_ALLOWED + .is_safe_write_address = is_safe_write_address +#endif }; const DRAM_ATTR spi_flash_guard_funcs_t g_flash_guard_no_os_ops = { - .start = spi_flash_disable_interrupts_caches_and_other_cpu_no_os, - .end = spi_flash_enable_interrupts_caches_no_os, - .op_lock = 0, - .op_unlock = 0 + .start = spi_flash_disable_interrupts_caches_and_other_cpu_no_os, + .end = spi_flash_enable_interrupts_caches_no_os, + .op_lock = 0, + .op_unlock = 0, +#if !CONFIG_SPI_FLASH_WRITING_DANGEROUS_REGIONS_ALLOWED + .is_safe_write_address = 0 +#endif }; static const spi_flash_guard_funcs_t *s_flash_guard_ops; @@ -101,7 +108,7 @@ static const spi_flash_guard_funcs_t *s_flash_guard_ops; #define CHECK_WRITE_ADDRESS(ADDR, SIZE) #else /* FAILS or ABORTS */ #define CHECK_WRITE_ADDRESS(ADDR, SIZE) do { \ - if (!is_safe_write_address(ADDR, SIZE)) { \ + if (s_flash_guard_ops && s_flash_guard_ops->is_safe_write_address && !s_flash_guard_ops->is_safe_write_address(ADDR, SIZE)) { \ return ESP_ERR_INVALID_ARG; \ } \ } while(0) diff --git a/components/spi_flash/include/esp_spi_flash.h b/components/spi_flash/include/esp_spi_flash.h index aa6eeea753..254e408959 100644 --- a/components/spi_flash/include/esp_spi_flash.h +++ b/components/spi_flash/include/esp_spi_flash.h @@ -313,6 +313,10 @@ typedef void (*spi_flash_op_lock_func_t)(void); * @brief SPI flash operation unlock function. */ typedef void (*spi_flash_op_unlock_func_t)(void); +/** + * @brief Function to protect SPI flash critical regions corruption. + */ +typedef bool (*spi_flash_is_safe_write_address_t)(size_t addr, size_t size); /** * Structure holding SPI flash access critical sections management functions. @@ -332,6 +336,9 @@ typedef void (*spi_flash_op_unlock_func_t)(void); * - 'op_unlock' unlocks access to flash API internal data. * These two functions are recursive and can be used around the outside of multiple calls to * 'start' & 'end', in order to create atomic multi-part flash operations. + * 3) When CONFIG_SPI_FLASH_WRITING_DANGEROUS_REGIONS_ALLOWED is disabled, flash writing/erasing + * API checks for addresses provided by user to avoid corruption of critical flash regions + * (bootloader, partition table, running application etc.). * * Different versions of the guarding functions should be used depending on the context of * execution (with or without functional OS). In normal conditions when flash API is called @@ -343,10 +350,13 @@ typedef void (*spi_flash_op_unlock_func_t)(void); * For example structure can be placed in DRAM and functions in IRAM sections. */ typedef struct { - spi_flash_guard_start_func_t start; /**< critical section start function. */ - spi_flash_guard_end_func_t end; /**< critical section end function. */ - spi_flash_op_lock_func_t op_lock; /**< flash access API lock function.*/ - spi_flash_op_unlock_func_t op_unlock; /**< flash access API unlock function.*/ + spi_flash_guard_start_func_t start; /**< critical section start function. */ + spi_flash_guard_end_func_t end; /**< critical section end function. */ + spi_flash_op_lock_func_t op_lock; /**< flash access API lock function.*/ + spi_flash_op_unlock_func_t op_unlock; /**< flash access API unlock function.*/ +#if !CONFIG_SPI_FLASH_WRITING_DANGEROUS_REGIONS_ALLOWED + spi_flash_is_safe_write_address_t is_safe_write_address; /**< checks flash write addresses.*/ +#endif } spi_flash_guard_funcs_t; /** @@ -359,7 +369,6 @@ typedef struct { */ void spi_flash_guard_set(const spi_flash_guard_funcs_t* funcs); - /** * @brief Get the guard functions used for flash access *