fs: Fix fs_open resource leak when invoked on fs_file_t object in use

Fixes problem when fs_open invoked on fs_file_t object, which is already
holding information on opened file, overwrites references to other
memory objects within the fs_file_t object causing resource leak.
If fs_open is invoked on already used fs_file_t object, it will return
-EBUSY.

Note: The change requires that all fs_file_t objects should be
initialized to 0.

Fixes: #29478

Signed-off-by: Dominik Ermel <dominik.ermel@nordicsemi.no>
This commit is contained in:
Dominik Ermel 2021-01-25 16:27:57 +00:00 committed by Anas Nashif
parent 21329237e9
commit d4666f537c
2 changed files with 18 additions and 3 deletions

View file

@ -143,25 +143,30 @@ int fs_open(struct fs_file_t *zfp, const char *file_name, fs_mode_t flags)
return -EINVAL;
}
if (zfp->mp != NULL) {
return -EBUSY;
}
rc = fs_get_mnt_point(&mp, file_name, NULL);
if (rc < 0) {
LOG_ERR("%s:mount point not found!!", __func__);
return rc;
}
zfp->mp = mp;
if (((mp->flags & FS_MOUNT_FLAG_READ_ONLY) != 0) &&
(flags & FS_O_CREATE || flags & FS_O_WRITE)) {
return -EROFS;
}
CHECKIF(zfp->mp->fs->open == NULL) {
CHECKIF(mp->fs->open == NULL) {
return -ENOTSUP;
}
rc = zfp->mp->fs->open(zfp, file_name, flags);
zfp->mp = mp;
rc = mp->fs->open(zfp, file_name, flags);
if (rc < 0) {
LOG_ERR("file open error (%d)", rc);
zfp->mp = NULL;
return rc;
}

View file

@ -436,6 +436,10 @@ void test_file_open(void)
ret = fs_open(&filep, TEST_FILE, FS_O_READ);
zassert_equal(ret, 0, "Fail to open file");
TC_PRINT("\nDouble-open\n");
ret = fs_open(&filep, TEST_FILE, FS_O_READ);
zassert_equal(ret, -EBUSY, "Expected -EBUSY, got %d", ret);
TC_PRINT("\nReopen the same file");
ret = fs_open(&filep, TEST_FILE, FS_O_READ);
zassert_not_equal(ret, 0, "Reopen an opend file");
@ -827,6 +831,12 @@ void test_file_close(void)
ret = fs_close(&filep);
zassert_equal(ret, 0, "Fail to close file");
TC_PRINT("Reuse fs_file_t from closed file");
ret = fs_open(&filep, TEST_FILE, FS_O_READ);
zassert_equal(ret, 0, "Expected open to succeed, got %d", ret);
ret = fs_close(&filep);
zassert_equal(ret, 0, "Expected close to succeed, got %d", ret);
TC_PRINT("\nClose a closed file:\n");
filep.mp = &test_fs_mnt_1;
ret = fs_close(&filep);