mirror of
https://github.com/espressif/esp-idf.git
synced 2026-09-22 13:01:16 +03:00
Merge branch 'bugfix/nvs-deinit-open-handle-leak_v6.1' into 'release/v6.1'
fix(nvs_flash): delete leftover handles on partition deinit (v6.1) See merge request espressif/esp-idf!51354
This commit is contained in:
@@ -899,6 +899,27 @@ TEST_CASE("deinit partition doesn't affect other partition's open handles", "[nv
|
||||
TEST_ESP_OK(nvs_flash_deinit_partition(TEST_SECONDARY_PARTITION_NAME));
|
||||
}
|
||||
|
||||
TEST_CASE("deinit with open handles frees them", "[nvs]")
|
||||
{
|
||||
// nvs_flash_deinit_partition must delete leftover open
|
||||
// handles (same as nvs_close), not only erase them from the C API handle list.
|
||||
TEST_ESP_OK(nvs_flash_erase_partition(TEST_3SEC_PARTITION_NAME));
|
||||
TEST_ESP_OK(nvs_flash_init_partition(TEST_3SEC_PARTITION_NAME));
|
||||
|
||||
nvs_handle_t handle_1;
|
||||
nvs_handle_t handle_2;
|
||||
TEST_ESP_OK(nvs_open_from_partition(TEST_3SEC_PARTITION_NAME, "ns1", NVS_READWRITE, &handle_1));
|
||||
TEST_ESP_OK(nvs_open_from_partition(TEST_3SEC_PARTITION_NAME, "ns2", NVS_READWRITE, &handle_2));
|
||||
CHECK(nvs::NVSPartitionManager::get_instance()->open_handles_size() == 2);
|
||||
|
||||
TEST_ESP_OK(nvs_flash_deinit_partition(TEST_3SEC_PARTITION_NAME));
|
||||
CHECK(nvs::NVSPartitionManager::get_instance()->open_handles_size() == 0);
|
||||
|
||||
// Stale handle ids must be harmless after deinit already freed the entries.
|
||||
nvs_close(handle_1);
|
||||
nvs_close(handle_2);
|
||||
}
|
||||
|
||||
TEST_CASE("nvs iterator nvs_entry_find invalid parameter test", "[nvs]")
|
||||
{
|
||||
// TC verifies that nvs_entry_find returns ESP_ERR_INVALID_ARG on invalid parameters.
|
||||
|
||||
@@ -1,5 +1,5 @@
|
||||
/*
|
||||
* SPDX-FileCopyrightText: 2015-2025 Espressif Systems (Shanghai) CO LTD
|
||||
* SPDX-FileCopyrightText: 2015-2026 Espressif Systems (Shanghai) CO LTD
|
||||
*
|
||||
* SPDX-License-Identifier: Apache-2.0
|
||||
*/
|
||||
@@ -139,6 +139,10 @@ esp_err_t nvs_flash_init_partition_bdl(const char* partition_label, esp_blockdev
|
||||
*
|
||||
* Default NVS partition is the partition with "nvs" label in the partition table.
|
||||
*
|
||||
* @note Prefer closing all open handles with nvs_close() before deinitializing.
|
||||
* Any handles still open for this partition are closed and freed here;
|
||||
* using them afterwards is invalid (nvs_close() on such a handle is a no-op).
|
||||
*
|
||||
* @return
|
||||
* - ESP_OK on success (storage was deinitialized)
|
||||
* - ESP_ERR_NVS_NOT_INITIALIZED if the storage was not initialized prior to this call
|
||||
@@ -150,6 +154,10 @@ esp_err_t nvs_flash_deinit(void);
|
||||
*
|
||||
* @param[in] partition_label Label of the partition
|
||||
*
|
||||
* @note Prefer closing all open handles with nvs_close() before deinitializing.
|
||||
* Any handles still open for this partition are closed and freed here;
|
||||
* using them afterwards is invalid (nvs_close() on such a handle is a no-op).
|
||||
*
|
||||
* @return
|
||||
* - ESP_OK on success
|
||||
* - ESP_ERR_NVS_NOT_INITIALIZED if the storage for given partition was not
|
||||
|
||||
@@ -85,8 +85,11 @@ static esp_err_t close_handles_and_deinit(const char* part_name)
|
||||
|
||||
auto it = find_if(begin(s_nvs_handles), end(s_nvs_handles), belongs_to_part);
|
||||
|
||||
// Same as nvs_close(): unlink first, then delete. Deleting while still linked
|
||||
// UAF-corrupts the intrusive list (hangs host tests).
|
||||
while (it != end(s_nvs_handles)) {
|
||||
s_nvs_handles.erase(it);
|
||||
delete static_cast<NVSHandleEntry*>(it);
|
||||
it = find_if(begin(s_nvs_handles), end(s_nvs_handles), belongs_to_part);
|
||||
}
|
||||
|
||||
|
||||
Reference in New Issue
Block a user