rt-thread
rt-thread copied to clipboard
[Bug] sys_dup2在启用RT_USING_DFS_V2时会导致dfs_file_set_fpos报错
RT-Thread Version
master
Hardware Type/Architectures
all
Develop Toolchain
Other
Describe the bug
在启用RT_USING_DFS_V2情况下,假设设备uart0作为串口终端(shell console),正在调用dfs_file_read()读取数据时候,或者在serial_fops_read()函数被rt_wqueue_wait挂起的时候。
如果此时调用sys_dup2(fd, 0)函数,将会关闭uart0并更新dfs_fdtable,也就是说在dfs_file_read执行过程中file指针被修改了!!!
fdt->fds[0] = fdt->fds[fd];
具体解释见下面的dfs_file_read()函数
/* fpos lock */
off_t pos = dfs_file_get_fpos(file);
ret = rw_verify_area(file, &pos, len);
if (ret > 0)
{
len = ret;
if (dfs_is_mounted(file->vnode->mnt) == 0)
{
#ifdef RT_USING_PAGECACHE
if (file->vnode->aspace && !(file->flags & O_DIRECT))
{
ret = dfs_aspace_read(file, buf, len, &pos);
}
else
#endif
{
///////////////////////////////////////////////////////////////////////////
// 就是跑到这里的时候,sys_dup2被调用了,那么file指针对应的内容被更改了,且被关闭。
///////////////////////////////////////////////////////////////////////////
ret = file->fops->read(file, buf, len, &pos);
}
}
else
{
ret = -EINVAL;
}
}
/* fpos unlock */
///////////////////////////////////////////////////////////////////////////
// 由于file指针对应的内容被更改了,因此dfs_file_set_fpos中rt_take_sem将会奔溃
///////////////////////////////////////////////////////////////////////////
dfs_file_set_fpos(file, pos);
Other additional context
No response
就是跑到这里的时候,sys_dup2被调用了,那么file指针对应的内容被更改了,且被关闭。
我补充一下,file 对象和 fd 不是绑定的。dup2 后旧的 file 就被回收掉了。这里应该是典型的 UAF 漏洞导致崩溃。
rt_err_t sys_dup2(int oldfd, int newfd)
{
// 。。。
if (fdt->fds[newfd])
{
ret = dfs_file_close(fdt->fds[newfd]);
if (ret < 0)
{
goto exit;
}
fd_release(newfd); // 在这里做资源回收
}