提交 dff4961f 编写于 作者: Y YOUR_NAME

fix: 多进程情况下,pipe的内核操作节点存在使用脏私有字段dev,导致系统概率异常

问题场景描述:(1)进程A使用pipe获取操作fd,然后循环使用poll操作; (2)kill正在进行poll操作的进程A,
pipe的fd会被回收,当pipe的设备节点未注销;(3)进程B使用pipe获取操作fd,此时获取的内核操作节点
为进程A创建的,存在使用进程A的操作节点的私有字段。
解决方案:pipe每次调用如果操作节点存在,就更新私有字段

close: #I3HXIX
Signed-off-by: Nzff <zhangfanfan2@huawei.com>
Change-Id: Ic3b6a67ab5b3d9ea38e097ca69f26e5d93de9dfb
上级 7dd1a430
......@@ -223,6 +223,37 @@ static int pipe_close(struct file *filep)
*
****************************************************************************/
static void UpdateDev(struct pipe_dev_s *dev)
{
int ret;
struct Vnode *vnode = NULL;
struct pipe_dev_s *olddev = NULL;
struct drv_data *data = NULL;
VnodeHold();
ret = VnodeLookup(dev->name, &vnode, 0);
if (ret != 0)
{
VnodeDrop();
PRINT_ERR("[%s,%d] failed. err: %d\n", __FUNCTION__, __LINE__, ret);
return;
}
data = (struct drv_data *)vnode->data;
olddev = (struct pipe_dev_s *)data->priv;
if (olddev != NULL)
{
if (olddev->d_buffer != NULL)
{
free(olddev->d_buffer);
olddev->d_buffer = NULL;
}
pipecommon_freedev(olddev);
}
data->priv = dev;
VnodeDrop();
return;
}
int pipe(int fd[2])
{
struct pipe_dev_s *dev = NULL;
......@@ -256,22 +287,22 @@ int pipe(int fd[2])
snprintf_s(devname, sizeof(devname), sizeof(devname) - 1, "/dev/pipe%d", pipeno);
/* Check if the pipe device has already been created */
/* No.. Allocate and initialize a new device structure instance */
if ((g_pipecreated & (1 << pipeno)) == 0)
dev = pipecommon_allocdev(bufsize, devname);
if (!dev)
{
/* No.. Allocate and initialize a new device structure instance */
(void)sem_post(&g_pipesem);
errcode = ENOMEM;
goto errout_with_pipe;
}
dev = pipecommon_allocdev(bufsize, devname);
if (!dev)
{
(void)sem_post(&g_pipesem);
errcode = ENOMEM;
goto errout_with_pipe;
}
dev->d_pipeno = pipeno;
dev->d_pipeno = pipeno;
/* Check if the pipe device has already been created */
if ((g_pipecreated & (1 << pipeno)) == 0)
{
/* Register the pipe device */
ret = register_driver(devname, &pipe_fops, 0660, (void *)dev);
......@@ -286,7 +317,10 @@ int pipe(int fd[2])
g_pipecreated |= (1 << pipeno);
}
else
{
UpdateDev(dev);
}
(void)sem_post(&g_pipesem);
/* Get a write file descriptor */
......
Markdown is supported
0% .
You are about to add 0 people to the discussion. Proceed with caution.
先完成此消息的编辑!
想要评论请 注册