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 /*
// * SPDX-FileCopyrightText: 2015-2022 Espressif Systems (Shanghai) CO LTD
// Licensed under the Apache License, Version 2.0 (the "License"); *
// you may not use this file except in compliance with the License. * SPDX-License-Identifier: Apache-2.0
// 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.
#include <stdio.h> #include <stdio.h>
#include <string.h> #include <string.h>
@ -266,3 +258,33 @@ TEST_CASE("Open & write & close through VFS passes performance test", "[vfs]")
#endif #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 * 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); _lock_acquire(&s_fd_table_lock);
for (int i = min_fd; i < max_fd; ++i) { for (int i = min_fd; i < max_fd; ++i) {
if (s_fd_table[i].vfs_index != -1) { if (s_fd_table[i].vfs_index != -1) {
free(s_vfs[i]); free(s_vfs[index]);
s_vfs[i] = NULL; s_vfs[index] = NULL;
for (int j = min_fd; j < i; ++j) { for (int j = min_fd; j < i; ++j) {
if (s_fd_table[j].vfs_index == index) { if (s_fd_table[j].vfs_index == index) {
s_fd_table[j] = FD_TABLE_ENTRY_UNUSED; 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; s_fd_table[i].local_fd = i;
} }
_lock_release(&s_fd_table_lock); _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; return ret;
} }

View File

@ -2089,7 +2089,6 @@ components/vfs/include/esp_vfs_eventfd.h
components/vfs/include/esp_vfs_semihost.h components/vfs/include/esp_vfs_semihost.h
components/vfs/test/test_vfs_access.c components/vfs/test/test_vfs_access.c
components/vfs/test/test_vfs_append.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_lwip.c
components/vfs/test/test_vfs_paths.c components/vfs/test/test_vfs_paths.c
components/vfs/test/test_vfs_select.c components/vfs/test/test_vfs_select.c