vfs: fix wrong VFS being freed when esp_vfs_register_fd_range fails

Closes https://github.com/espressif/esp-idf/pull/7413
This commit is contained in:
caixf 2021-08-13 13:30:28 +08:00 committed by Ivan Grokhotkov
parent 991874ae43
commit 6c3b528917
3 changed files with 40 additions and 19 deletions

View File

@ -1,16 +1,8 @@
// Copyright 2015-2017 Espressif Systems (Shanghai) PTE LTD
//
// Licensed under the Apache License, Version 2.0 (the "License");
// you may not use this file except in compliance with the License.
// You may obtain a copy of the License at
//
// http://www.apache.org/licenses/LICENSE-2.0
//
// Unless required by applicable law or agreed to in writing, software
// distributed under the License is distributed on an "AS IS" BASIS,
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
// See the License for the specific language governing permissions and
// limitations under the License.
/*
* SPDX-FileCopyrightText: 2015-2022 Espressif Systems (Shanghai) CO LTD
*
* SPDX-License-Identifier: Apache-2.0
*/
#include <stdio.h>
#include <string.h>
@ -266,3 +258,33 @@ TEST_CASE("Open & write & close through VFS passes performance test", "[vfs]")
#endif
}
static int vfs_overlap_test_open(const char * path, int flags, int mode)
{
return 0;
}
static int vfs_overlap_test_close(int fd)
{
return 0;
}
TEST_CASE("esp_vfs_register_fd_range checks for overlap", "[vfs]")
{
esp_vfs_t vfs1 = {
.open = vfs_overlap_test_open,
.close = vfs_overlap_test_close
};
TEST_ESP_OK(esp_vfs_register("/test", &vfs1, NULL));
int fd = open("/test/1", 0, 0);
TEST_ASSERT_NOT_EQUAL(-1, fd);
esp_vfs_t vfs2 = { };
esp_err_t err = esp_vfs_register_fd_range(&vfs2, NULL, fd, fd + 1);
close(fd);
TEST_ESP_OK(esp_vfs_unregister("/test"));
TEST_ESP_ERR(ESP_ERR_INVALID_ARG, err);
}

View File

@ -1,5 +1,5 @@
/*
* SPDX-FileCopyrightText: 2015-2021 Espressif Systems (Shanghai) CO LTD
* SPDX-FileCopyrightText: 2015-2022 Espressif Systems (Shanghai) CO LTD
*
* SPDX-License-Identifier: Apache-2.0
*/
@ -127,8 +127,8 @@ esp_err_t esp_vfs_register_fd_range(const esp_vfs_t *vfs, void *ctx, int min_fd,
_lock_acquire(&s_fd_table_lock);
for (int i = min_fd; i < max_fd; ++i) {
if (s_fd_table[i].vfs_index != -1) {
free(s_vfs[i]);
s_vfs[i] = NULL;
free(s_vfs[index]);
s_vfs[index] = NULL;
for (int j = min_fd; j < i; ++j) {
if (s_fd_table[j].vfs_index == index) {
s_fd_table[j] = FD_TABLE_ENTRY_UNUSED;
@ -143,9 +143,9 @@ esp_err_t esp_vfs_register_fd_range(const esp_vfs_t *vfs, void *ctx, int min_fd,
s_fd_table[i].local_fd = i;
}
_lock_release(&s_fd_table_lock);
}
ESP_LOGD(TAG, "esp_vfs_register_fd_range is successful for range <%d; %d) and VFS ID %d", min_fd, max_fd, index);
ESP_LOGW(TAG, "esp_vfs_register_fd_range is successful for range <%d; %d) and VFS ID %d", min_fd, max_fd, index);
}
return ret;
}

View File

@ -2089,7 +2089,6 @@ components/vfs/include/esp_vfs_eventfd.h
components/vfs/include/esp_vfs_semihost.h
components/vfs/test/test_vfs_access.c
components/vfs/test/test_vfs_append.c
components/vfs/test/test_vfs_fd.c
components/vfs/test/test_vfs_lwip.c
components/vfs/test/test_vfs_paths.c
components/vfs/test/test_vfs_select.c