Merge branch 'bugfix/spiffs_check_part_alignment_v4.4' into 'release/v4.4'

spiffs: add init checks for partition alignment and data types (v4.4)

See merge request espressif/esp-idf!17835
This commit is contained in:
Ivan Grokhotkov 2022-05-03 17:01:50 +08:00
commit a615fccd01

View File

@ -179,20 +179,55 @@ static esp_err_t esp_spiffs_init(const esp_vfs_spiffs_conf_t* conf)
return ESP_ERR_INVALID_STATE; return ESP_ERR_INVALID_STATE;
} }
esp_spiffs_t * efs = malloc(sizeof(esp_spiffs_t)); const size_t flash_erase_sector_size = g_rom_flashchip.sector_size;
/* Older versions of IDF allowed creating misaligned data partitions.
* This would result in hard-to-diagnose SPIFFS failures due to failing erase operations.
*/
if (partition->address % flash_erase_sector_size != 0) {
ESP_LOGE(TAG, "spiffs partition is not aligned to flash sector size, please check the partition table");
/* No return intentional to avoid accidentally breaking applications
* which used misaligned read-only SPIFFS partitions.
*/
}
/* Check if the SPIFFS internal data types are wide enough.
* Casting -1 to the unsigned type produces the maximum value the type can hold.
* All the checks here are based on comments for the said data types in spiffs_config.h.
*/
if (partition->size / flash_erase_sector_size > (spiffs_block_ix) -1) {
ESP_LOGE(TAG, "spiffs partition is too large for spiffs_block_ix type");
return ESP_ERR_INVALID_ARG;
}
if (partition->size / log_page_size > (spiffs_page_ix) -1) {
/* For 256 byte pages the largest partition is 16MB, but larger partitions can be supported
* by increasing the page size (reducing the number of pages).
*/
ESP_LOGE(TAG, "spiffs partition is too large for spiffs_page_ix type. Please increase CONFIG_SPIFFS_PAGE_SIZE.");
return ESP_ERR_INVALID_ARG;
}
if (2 + 2 * (partition->size / (2 * log_page_size)) > (spiffs_obj_id) -1) {
ESP_LOGE(TAG, "spiffs partition is too large for spiffs_obj_id type. Please increase CONFIG_SPIFFS_PAGE_SIZE.");
return ESP_ERR_INVALID_ARG;
}
if (partition->size / log_page_size - 1 > (spiffs_span_ix) -1) {
ESP_LOGE(TAG, "spiffs partition is too large for spiffs_span_ix type. Please increase CONFIG_SPIFFS_PAGE_SIZE.");
return ESP_ERR_INVALID_ARG;
}
esp_spiffs_t * efs = calloc(sizeof(esp_spiffs_t), 1);
if (efs == NULL) { if (efs == NULL) {
ESP_LOGE(TAG, "esp_spiffs could not be malloced"); ESP_LOGE(TAG, "esp_spiffs could not be malloced");
return ESP_ERR_NO_MEM; return ESP_ERR_NO_MEM;
} }
memset(efs, 0, sizeof(esp_spiffs_t));
efs->cfg.hal_erase_f = spiffs_api_erase; efs->cfg.hal_erase_f = spiffs_api_erase;
efs->cfg.hal_read_f = spiffs_api_read; efs->cfg.hal_read_f = spiffs_api_read;
efs->cfg.hal_write_f = spiffs_api_write; efs->cfg.hal_write_f = spiffs_api_write;
efs->cfg.log_block_size = g_rom_flashchip.sector_size; efs->cfg.log_block_size = flash_erase_sector_size;
efs->cfg.log_page_size = log_page_size; efs->cfg.log_page_size = log_page_size;
efs->cfg.phys_addr = 0; efs->cfg.phys_addr = 0;
efs->cfg.phys_erase_block = g_rom_flashchip.sector_size; efs->cfg.phys_erase_block = flash_erase_sector_size;
efs->cfg.phys_size = partition->size; efs->cfg.phys_size = partition->size;
efs->by_label = conf->partition_label != NULL; efs->by_label = conf->partition_label != NULL;
@ -205,42 +240,38 @@ static esp_err_t esp_spiffs_init(const esp_vfs_spiffs_conf_t* conf)
} }
efs->fds_sz = conf->max_files * sizeof(spiffs_fd); efs->fds_sz = conf->max_files * sizeof(spiffs_fd);
efs->fds = malloc(efs->fds_sz); efs->fds = calloc(efs->fds_sz, 1);
if (efs->fds == NULL) { if (efs->fds == NULL) {
ESP_LOGE(TAG, "fd buffer could not be malloced"); ESP_LOGE(TAG, "fd buffer could not be allocated");
esp_spiffs_free(&efs); esp_spiffs_free(&efs);
return ESP_ERR_NO_MEM; return ESP_ERR_NO_MEM;
} }
memset(efs->fds, 0, efs->fds_sz);
#if SPIFFS_CACHE #if SPIFFS_CACHE
efs->cache_sz = sizeof(spiffs_cache) + conf->max_files * (sizeof(spiffs_cache_page) efs->cache_sz = sizeof(spiffs_cache) + conf->max_files * (sizeof(spiffs_cache_page)
+ efs->cfg.log_page_size); + efs->cfg.log_page_size);
efs->cache = malloc(efs->cache_sz); efs->cache = calloc(efs->cache_sz, 1);
if (efs->cache == NULL) { if (efs->cache == NULL) {
ESP_LOGE(TAG, "cache buffer could not be malloced"); ESP_LOGE(TAG, "cache buffer could not be allocated");
esp_spiffs_free(&efs); esp_spiffs_free(&efs);
return ESP_ERR_NO_MEM; return ESP_ERR_NO_MEM;
} }
memset(efs->cache, 0, efs->cache_sz);
#endif #endif
const uint32_t work_sz = efs->cfg.log_page_size * 2; const uint32_t work_sz = efs->cfg.log_page_size * 2;
efs->work = malloc(work_sz); efs->work = calloc(work_sz, 1);
if (efs->work == NULL) { if (efs->work == NULL) {
ESP_LOGE(TAG, "work buffer could not be malloced"); ESP_LOGE(TAG, "work buffer could not be allocated");
esp_spiffs_free(&efs); esp_spiffs_free(&efs);
return ESP_ERR_NO_MEM; return ESP_ERR_NO_MEM;
} }
memset(efs->work, 0, work_sz);
efs->fs = malloc(sizeof(spiffs)); efs->fs = calloc(sizeof(spiffs), 1);
if (efs->fs == NULL) { if (efs->fs == NULL) {
ESP_LOGE(TAG, "spiffs could not be malloced"); ESP_LOGE(TAG, "spiffs could not be allocated");
esp_spiffs_free(&efs); esp_spiffs_free(&efs);
return ESP_ERR_NO_MEM; return ESP_ERR_NO_MEM;
} }
memset(efs->fs, 0, sizeof(spiffs));
efs->fs->user_data = (void *)efs; efs->fs->user_data = (void *)efs;
efs->partition = partition; efs->partition = partition;