mirror of
https://github.com/apache/nuttx.git
synced 2026-05-28 20:08:15 +08:00
fs/inode: use file_allocate,file_dup to avoid racecondition to allocate fd
issue description: task A: NSH: 1.open-> reboot->sync->task_fsfsync 2.nx_vopen-> context switch 3.fdlist_allocate: ----> 4.fsync->file_sync->assert(inode or priv is empty) (new fd with empty filep) 5.file_vopen: (init empty filep) 6.return fd Task A allocates a new fd with an empty filep in fdlist_allocate. Before it can fully initialize the filep in file_vopen, the NSH task triggers a file - system sync operation. The sync operation encounters the empty filep associated with the newly allocated fd, causing the assertion to fail and the system to crash. To resolve this race condition, we should modify the fd allocation process. Instead of allocating a new fd with an empty filep first and then initializing it later, we should use the file_allocate_from_inode function. This function allows us to initialize the file structure first and then bind it to the new filep when allocating the fd. By doing so, we ensure that the filep is always properly initialized before it is used in any file - system operations, thus preventing the assertion failure and the subsequent system crash. Signed-off-by: dongjiuzhu1 <dongjiuzhu1@xiaomi.com>
This commit is contained in:
+11
-9
@@ -315,24 +315,26 @@ static int nx_vopen(FAR struct fdlist *list,
|
||||
int ret;
|
||||
int fd;
|
||||
|
||||
/* Allocate a new file descriptor for the inode */
|
||||
|
||||
fd = fdlist_allocate(list, oflags, 0, &filep);
|
||||
if (fd < 0)
|
||||
filep = file_allocate();
|
||||
if (filep == NULL)
|
||||
{
|
||||
return fd;
|
||||
return -ENOMEM;
|
||||
}
|
||||
|
||||
/* Let file_vopen() do all of the work */
|
||||
|
||||
ret = file_vopen(filep, path, oflags, getumask(), ap);
|
||||
file_put(filep);
|
||||
if (ret < 0)
|
||||
{
|
||||
fdlist_close(list, fd);
|
||||
file_deallocate(filep);
|
||||
return ret;
|
||||
}
|
||||
|
||||
fd = fdlist_dupfile(list, oflags, 0, filep);
|
||||
if (fd < 0)
|
||||
{
|
||||
file_close(filep);
|
||||
file_deallocate(filep);
|
||||
}
|
||||
|
||||
return fd;
|
||||
}
|
||||
|
||||
|
||||
Reference in New Issue
Block a user