fs/vfs/fs_rename: fix directory move operation.

* Recurrency is removed from filesystem directory rename.
* Fixes use after free in buffer that was used as output and argument.

Signed-off-by: Tomasz 'CeDeROM' CEDRO <tomek@cedro.info>
This commit is contained in:
Liu, Richard Jiayang
2025-05-27 21:49:39 +02:00
committed by Xiang Xiao
parent f43d0f03c0
commit d2282ec26a
-39
View File
@@ -80,7 +80,6 @@ static int pseudorename(FAR const char *oldpath, FAR struct inode *oldinode,
* first, provided that it is not a directory. * first, provided that it is not a directory.
*/ */
next_subdir:
SETUP_SEARCH(&newdesc, newpath, true); SETUP_SEARCH(&newdesc, newpath, true);
ret = inode_find(&newdesc); ret = inode_find(&newdesc);
if (ret >= 0) if (ret >= 0)
@@ -120,16 +119,6 @@ next_subdir:
{ {
FAR char *subdirname; FAR char *subdirname;
inode_release(newinode);
/* Free memory may be allocated in previous loop */
if (subdir != NULL)
{
fs_heap_free(subdir);
subdir = NULL;
}
/* Yes.. In this case, the target of the rename must be a /* Yes.. In this case, the target of the rename must be a
* subdirectory of newinode, not the newinode itself. For * subdirectory of newinode, not the newinode itself. For
* example: mv b a/ must move b to a/b. * example: mv b a/ must move b to a/b.
@@ -145,14 +134,6 @@ next_subdir:
} }
newpath = subdir; newpath = subdir;
/* This can be a recursive case, another inode may already exist
* at oldpth/subdirname. In that case, we need to do this all
* over again. A nasty goto is used because I am lazy.
*/
RELEASE_SEARCH(&newdesc);
goto next_subdir;
} }
else else
{ {
@@ -354,7 +335,6 @@ static int mountptrename(FAR const char *oldpath, FAR struct inode *oldinode,
{ {
struct stat buf; struct stat buf;
next_subdir:
ret = oldinode->u.i_mops->stat(oldinode, newrelpath, &buf); ret = oldinode->u.i_mops->stat(oldinode, newrelpath, &buf);
if (ret >= 0) if (ret >= 0)
{ {
@@ -384,19 +364,8 @@ next_subdir:
} }
else else
{ {
/* Save subdir to free memory may be allocated in
* previous loop.
*/
FAR void *tmp = subdir;
ret = fs_heap_asprintf(&subdir, "%s/%s", newrelpath, ret = fs_heap_asprintf(&subdir, "%s/%s", newrelpath,
subdirname); subdirname);
if (tmp != NULL)
{
lib_free(tmp);
}
if (ret < 0) if (ret < 0)
{ {
subdir = NULL; subdir = NULL;
@@ -406,14 +375,6 @@ next_subdir:
newrelpath = subdir; newrelpath = subdir;
} }
/* This can be a recursive, another directory may already
* exist at the newrelpath. In that case, we need to
* do this all over again. A nasty goto is used because
* I am lazy.
*/
goto next_subdir;
} }
else else
{ {