Quellcode durchsuchen

spiffs: add init checks for partition alignment and data types

Closes https://github.com/espressif/esp-idf/issues/8593
Ivan Grokhotkov vor 3 Jahren
Ursprung
Commit
6a172b419f
1 geänderte Dateien mit 47 neuen und 16 gelöschten Zeilen
  1. 47 16
      components/spiffs/esp_spiffs.c

+ 47 - 16
components/spiffs/esp_spiffs.c

@@ -163,20 +163,55 @@ static esp_err_t esp_spiffs_init(const esp_vfs_spiffs_conf_t* conf)
         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) {
         ESP_LOGE(TAG, "esp_spiffs could not be malloced");
         return ESP_ERR_NO_MEM;
     }
-    memset(efs, 0, sizeof(esp_spiffs_t));
 
     efs->cfg.hal_erase_f       = spiffs_api_erase;
     efs->cfg.hal_read_f        = spiffs_api_read;
     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.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->by_label = conf->partition_label != NULL;
@@ -189,42 +224,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 = malloc(efs->fds_sz);
+    efs->fds = calloc(efs->fds_sz, 1);
     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);
         return ESP_ERR_NO_MEM;
     }
-    memset(efs->fds, 0, efs->fds_sz);
 
 #if SPIFFS_CACHE
     efs->cache_sz = sizeof(spiffs_cache) + conf->max_files * (sizeof(spiffs_cache_page)
                           + efs->cfg.log_page_size);
-    efs->cache = malloc(efs->cache_sz);
+    efs->cache = calloc(efs->cache_sz, 1);
     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);
         return ESP_ERR_NO_MEM;
     }
-    memset(efs->cache, 0, efs->cache_sz);
 #endif
 
     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) {
-        ESP_LOGE(TAG, "work buffer could not be malloced");
+        ESP_LOGE(TAG, "work buffer could not be allocated");
         esp_spiffs_free(&efs);
         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) {
-        ESP_LOGE(TAG, "spiffs could not be malloced");
+        ESP_LOGE(TAG, "spiffs could not be allocated");
         esp_spiffs_free(&efs);
         return ESP_ERR_NO_MEM;
     }
-    memset(efs->fs, 0, sizeof(spiffs));
 
     efs->fs->user_data = (void *)efs;
     efs->partition = partition;